Merge "amend"
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..be5152f
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,47 @@
+# Dependencies
+node_modules/
+*/node_modules/
+
+# Build outputs
+dist/
+build/
+
+# Environment files
+.env
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+# Logs
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Coverage directory used by tools like istanbul
+coverage/
+
+# nyc test coverage
+.nyc_output
+
+# Editor directories and files
+.vscode/
+.idea/
+*.swp
+*.swo
+*~
+
+# OS generated files
+.DS_Store
+.DS_Store?
+._*
+.Spotlight-V100
+.Trashes
+ehthumbs.db
+Thumbs.db
diff --git a/xiaohongshu-platform/.vscode/tasks.json b/xiaohongshu-platform/.vscode/tasks.json
new file mode 100644
index 0000000..02a7c1a
--- /dev/null
+++ b/xiaohongshu-platform/.vscode/tasks.json
@@ -0,0 +1,13 @@
+{
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "开发服务器",
+ "type": "shell",
+ "command": "npm run dev",
+ "group": "build",
+ "isBackground": true,
+ "problemMatcher": []
+ }
+ ]
+}
\ No newline at end of file
diff --git a/xiaohongshu-platform/index.html b/xiaohongshu-platform/index.html
new file mode 100644
index 0000000..b919940
--- /dev/null
+++ b/xiaohongshu-platform/index.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<html lang="zh-CN">
+ <head>
+ <meta charset="UTF-8" />
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+ <title>小红书创作服务平台</title>
+ </head>
+ <body>
+ <div id="root"></div>
+ <script type="module" src="/src/main.jsx"></script>
+ </body>
+</html>
diff --git a/xiaohongshu-platform/package.json b/xiaohongshu-platform/package.json
new file mode 100644
index 0000000..71f99ed
--- /dev/null
+++ b/xiaohongshu-platform/package.json
@@ -0,0 +1,30 @@
+{
+ "name": "xiaohongshu-platform",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "lint": "eslint .",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "react": "^18.3.1",
+ "react-dom": "^18.3.1",
+ "lucide-react": "^0.460.0",
+ "react-icons": "^5.4.0"
+ },
+ "devDependencies": {
+ "@eslint/js": "^9.13.0",
+ "@types/react": "^18.3.12",
+ "@types/react-dom": "^18.3.1",
+ "@vitejs/plugin-react": "^4.3.3",
+ "eslint": "^9.13.0",
+ "eslint-plugin-react": "^7.37.2",
+ "eslint-plugin-react-hooks": "^5.0.0",
+ "eslint-plugin-react-refresh": "^0.4.14",
+ "globals": "^15.11.0",
+ "vite": "^6.0.1"
+ }
+}
diff --git a/xiaohongshu-platform/src/App.css b/xiaohongshu-platform/src/App.css
new file mode 100644
index 0000000..3377645
--- /dev/null
+++ b/xiaohongshu-platform/src/App.css
@@ -0,0 +1,233 @@
+.app {
+ display: flex;
+ flex-direction: column;
+ min-height: 100vh;
+ background-color: #f5f5f5;
+}
+
+/* Header Styles */
+.header {
+ background: white;
+ border-bottom: 1px solid #e0e0e0;
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ z-index: 100;
+}
+
+.header-content {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 1rem 2rem;
+ max-width: 1200px;
+ margin: 0 auto;
+}
+
+.logo {
+ font-size: 1.5rem;
+ font-weight: bold;
+ color: #ff2442;
+ margin: 0;
+}
+
+.search-bar {
+ display: flex;
+ align-items: center;
+ background: #f8f8f8;
+ border-radius: 20px;
+ padding: 0.5rem 1rem;
+ flex: 1;
+ max-width: 400px;
+ margin: 0 2rem;
+}
+
+.search-bar input {
+ border: none;
+ background: none;
+ outline: none;
+ margin-left: 0.5rem;
+ width: 100%;
+}
+
+.header-actions {
+ display: flex;
+ gap: 1rem;
+ align-items: center;
+}
+
+.header-actions svg {
+ cursor: pointer;
+ color: #666;
+}
+
+/* Main Content */
+.main-content {
+ flex: 1;
+ padding-top: 80px;
+ padding-bottom: 80px;
+}
+
+.posts-container {
+ display: grid;
+ grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
+ gap: 1rem;
+ padding: 1rem;
+ max-width: 1200px;
+ margin: 0 auto;
+}
+
+/* Post Card Styles */
+.post-card {
+ background: white;
+ border-radius: 12px;
+ overflow: hidden;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+ transition: transform 0.2s ease;
+ cursor: pointer;
+}
+
+.post-card:hover {
+ transform: translateY(-2px);
+}
+
+.post-image {
+ width: 100%;
+ height: 200px;
+ overflow: hidden;
+}
+
+.post-image img {
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+}
+
+.post-content {
+ padding: 1rem;
+}
+
+.post-title {
+ font-size: 1rem;
+ font-weight: 600;
+ margin: 0 0 0.5rem 0;
+ color: #333;
+ line-height: 1.3;
+}
+
+.post-description {
+ font-size: 0.9rem;
+ color: #666;
+ margin: 0 0 1rem 0;
+ line-height: 1.4;
+}
+
+.post-author {
+ display: flex;
+ align-items: center;
+ margin-bottom: 1rem;
+}
+
+.author-avatar {
+ width: 24px;
+ height: 24px;
+ border-radius: 50%;
+ margin-right: 0.5rem;
+}
+
+.author-name {
+ font-size: 0.8rem;
+ color: #666;
+}
+
+/* Post Actions */
+.post-actions {
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+}
+
+.action-btn {
+ display: flex;
+ align-items: center;
+ gap: 0.3rem;
+ background: none;
+ border: none;
+ color: #666;
+ cursor: pointer;
+ font-size: 0.8rem;
+ padding: 0.3rem;
+ border-radius: 4px;
+ transition: all 0.2s ease;
+}
+
+.action-btn:hover {
+ background: #f0f0f0;
+}
+
+.action-btn.liked {
+ color: #ff4757;
+}
+
+.action-btn.saved {
+ color: #ffa502;
+}
+
+/* Bottom Navigation */
+.bottom-nav {
+ position: fixed;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ background: white;
+ border-top: 1px solid #e0e0e0;
+ display: flex;
+ justify-content: space-around;
+ padding: 0.5rem 0;
+ z-index: 100;
+}
+
+.nav-btn {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ background: none;
+ border: none;
+ color: #999;
+ cursor: pointer;
+ padding: 0.5rem;
+ transition: color 0.2s ease;
+}
+
+.nav-btn.active {
+ color: #ff2442;
+}
+
+.nav-btn span {
+ font-size: 0.7rem;
+ margin-top: 0.2rem;
+}
+
+/* Responsive Design */
+@media (max-width: 768px) {
+ .header-content {
+ padding: 1rem;
+ }
+
+ .search-bar {
+ margin: 0 1rem;
+ }
+
+ .posts-container {
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
+ padding: 0.5rem;
+ gap: 0.5rem;
+ }
+}
+
+@media (max-width: 480px) {
+ .posts-container {
+ grid-template-columns: repeat(2, 1fr);
+ }
+}
diff --git a/xiaohongshu-platform/src/App.jsx b/xiaohongshu-platform/src/App.jsx
new file mode 100644
index 0000000..503ca6b
--- /dev/null
+++ b/xiaohongshu-platform/src/App.jsx
@@ -0,0 +1,158 @@
+import React, { useState } from 'react';
+import { Heart, MessageCircle, Share2, Bookmark, Search, User, Home, Compass, Plus, Bell } from 'lucide-react';
+import './App.css';
+
+function App() {
+ const [posts, setPosts] = useState([
+ {
+ id: 1,
+ username: "创作者小红",
+ avatar: "/api/placeholder/40/40",
+ image: "/api/placeholder/300/400",
+ title: "今日OOTD分享 🌸",
+ content: "春日温柔穿搭,粉色系永远不会出错!",
+ likes: 1234,
+ comments: 89,
+ isLiked: false,
+ isSaved: false
+ },
+ {
+ id: 2,
+ username: "美食达人",
+ avatar: "/api/placeholder/40/40",
+ image: "/api/placeholder/300/400",
+ title: "超简单的蛋糕制作 🍰",
+ content: "零失败率的草莓蛋糕,新手也能做出完美作品!",
+ likes: 2567,
+ comments: 156,
+ isLiked: false,
+ isSaved: false
+ },
+ {
+ id: 3,
+ username: "旅行摄影师",
+ avatar: "/api/placeholder/40/40",
+ image: "/api/placeholder/300/400",
+ title: "云南大理古城 📸",
+ content: "漫步在石板路上,感受千年古城的魅力",
+ likes: 3421,
+ comments: 234,
+ isLiked: true,
+ isSaved: false
+ }
+ ]);
+
+ const [activeTab, setActiveTab] = useState('home');
+
+ const handleLike = (postId) => {
+ setPosts(posts.map(post =>
+ post.id === postId
+ ? { ...post, isLiked: !post.isLiked, likes: post.isLiked ? post.likes - 1 : post.likes + 1 }
+ : post
+ ));
+ };
+
+ const handleSave = (postId) => {
+ setPosts(posts.map(post =>
+ post.id === postId
+ ? { ...post, isSaved: !post.isSaved }
+ : post
+ ));
+ };
+
+ return (
+ <div className="app">
+ {/* Header */}
+ <header className="header">
+ <div className="header-content">
+ <h1 className="logo">小红书</h1>
+ <div className="search-bar">
+ <Search size={20} />
+ <input type="text" placeholder="搜索你感兴趣的内容" />
+ </div>
+ <div className="header-actions">
+ <Bell size={24} />
+ <User size={24} />
+ </div>
+ </div>
+ </header>
+
+ {/* Main Content */}
+ <main className="main-content">
+ <div className="posts-container">
+ {posts.map(post => (
+ <div key={post.id} className="post-card">
+ <div className="post-image">
+ <img src={post.image} alt={post.title} />
+ </div>
+ <div className="post-content">
+ <h3 className="post-title">{post.title}</h3>
+ <p className="post-description">{post.content}</p>
+ <div className="post-author">
+ <img src={post.avatar} alt={post.username} className="author-avatar" />
+ <span className="author-name">{post.username}</span>
+ </div>
+ <div className="post-actions">
+ <button
+ className={`action-btn ${post.isLiked ? 'liked' : ''}`}
+ onClick={() => handleLike(post.id)}
+ >
+ <Heart size={16} fill={post.isLiked ? '#ff4757' : 'none'} />
+ <span>{post.likes}</span>
+ </button>
+ <button className="action-btn">
+ <MessageCircle size={16} />
+ <span>{post.comments}</span>
+ </button>
+ <button className="action-btn">
+ <Share2 size={16} />
+ </button>
+ <button
+ className={`action-btn ${post.isSaved ? 'saved' : ''}`}
+ onClick={() => handleSave(post.id)}
+ >
+ <Bookmark size={16} fill={post.isSaved ? '#ffa502' : 'none'} />
+ </button>
+ </div>
+ </div>
+ </div>
+ ))}
+ </div>
+ </main>
+
+ {/* Bottom Navigation */}
+ <nav className="bottom-nav">
+ <button
+ className={`nav-btn ${activeTab === 'home' ? 'active' : ''}`}
+ onClick={() => setActiveTab('home')}
+ >
+ <Home size={24} />
+ <span>首页</span>
+ </button>
+ <button
+ className={`nav-btn ${activeTab === 'discover' ? 'active' : ''}`}
+ onClick={() => setActiveTab('discover')}
+ >
+ <Compass size={24} />
+ <span>发现</span>
+ </button>
+ <button
+ className={`nav-btn ${activeTab === 'create' ? 'active' : ''}`}
+ onClick={() => setActiveTab('create')}
+ >
+ <Plus size={24} />
+ <span>创作</span>
+ </button>
+ <button
+ className={`nav-btn ${activeTab === 'profile' ? 'active' : ''}`}
+ onClick={() => setActiveTab('profile')}
+ >
+ <User size={24} />
+ <span>我</span>
+ </button>
+ </nav>
+ </div>
+ );
+}
+
+export default App;
diff --git a/xiaohongshu-platform/src/index.css b/xiaohongshu-platform/src/index.css
new file mode 100644
index 0000000..9ef6886
--- /dev/null
+++ b/xiaohongshu-platform/src/index.css
@@ -0,0 +1,70 @@
+:root {
+ font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
+ line-height: 1.5;
+ font-weight: 400;
+
+ color-scheme: light dark;
+ color: rgba(255, 255, 255, 0.87);
+ background-color: #242424;
+
+ font-synthesis: none;
+ text-rendering: optimizeLegibility;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+a {
+ font-weight: 500;
+ color: #646cff;
+ text-decoration: inherit;
+}
+a:hover {
+ color: #535bf2;
+}
+
+body {
+ margin: 0;
+ display: flex;
+ place-items: center;
+ min-width: 320px;
+ min-height: 100vh;
+}
+
+h1 {
+ font-size: 3.2em;
+ line-height: 1.1;
+}
+
+button {
+ border-radius: 8px;
+ border: 1px solid transparent;
+ padding: 0.6em 1.2em;
+ font-size: 1em;
+ font-weight: 500;
+ font-family: inherit;
+ background-color: #1a1a1a;
+ color: white;
+ cursor: pointer;
+ transition: border-color 0.25s;
+}
+button:hover {
+ border-color: #646cff;
+}
+button:focus,
+button:focus-visible {
+ outline: 4px auto -webkit-focus-ring-color;
+}
+
+@media (prefers-color-scheme: light) {
+ :root {
+ color: #213547;
+ background-color: #ffffff;
+ }
+ a:hover {
+ color: #747bff;
+ }
+ button {
+ background-color: #f9f9f9;
+ color: #213547;
+ }
+}
diff --git a/xiaohongshu-platform/src/main.jsx b/xiaohongshu-platform/src/main.jsx
new file mode 100644
index 0000000..b9a1a6d
--- /dev/null
+++ b/xiaohongshu-platform/src/main.jsx
@@ -0,0 +1,10 @@
+import { StrictMode } from 'react'
+import { createRoot } from 'react-dom/client'
+import './index.css'
+import App from './App.jsx'
+
+createRoot(document.getElementById('root')).render(
+ <StrictMode>
+ <App />
+ </StrictMode>,
+)
diff --git a/xiaohongshu-platform/vite.config.js b/xiaohongshu-platform/vite.config.js
new file mode 100644
index 0000000..8b0f57b
--- /dev/null
+++ b/xiaohongshu-platform/vite.config.js
@@ -0,0 +1,7 @@
+import { defineConfig } from 'vite'
+import react from '@vitejs/plugin-react'
+
+// https://vite.dev/config/
+export default defineConfig({
+ plugins: [react()],
+})