添加新手指南
Change-Id: Ida2104eac0c377b3a9ffdafa2c99d9fdafba6fec
diff --git a/src/App.js b/src/App.js
index e47e7e2..4a74de6 100644
--- a/src/App.js
+++ b/src/App.js
@@ -24,6 +24,7 @@
import UserInvite from './pages/UserCenter/UserInvite';
import UserInfo from './pages/UserInfo/UserInfo';
import UserLayout from './pages/UserCenter/UserLayout';
+import NewUserGuide from './pages/NewUserGuide/NewUserGuide';
function RedirectToAuth() {
if (typeof window !== 'undefined') {
@@ -73,6 +74,7 @@
<Route path="/messages" component={() => <PrivateRoute component={MessagePage} />} />
<Route path="/level" component={() => <PrivateRoute component={LevelPage} />} />
<Route path="/information/:userId" component={({ userId }) => <PrivateRoute component={() => <UserInfo userId={userId} />} />} />
+ <Route path="/new-user-guide" component={() => <PrivateRoute component={NewUserGuide} />} />
{/* 用户中心路由 */}
<Route path="/user/profile" component={() => (
diff --git a/src/components/Header.css b/src/components/Header.css
index f322e13..017ba1d 100644
--- a/src/components/Header.css
+++ b/src/components/Header.css
@@ -90,5 +90,28 @@
transform: scale(1.1); /* 选中项微微放大 */
line-height: 40px; /* 调整line-height,使文字更居中 */
}
+/* 新手指南按钮 */
+.guide-button {
+ display: flex;
+ align-items: center;
+ background-color: #a67c6a; /* 柔棕底色 */
+ color: #fff;
+ border: none;
+ border-radius: 20px;
+ padding: 6px 12px;
+ font-size: 16px;
+ font-weight: 500;
+ cursor: pointer;
+ transition: background-color 0.3s ease, transform 0.2s ease;
+}
+
+.guide-button:hover {
+ background-color: #8d6e63; /* 深一点 hover */
+ transform: scale(1.05);
+}
+
+.guide-button span {
+ user-select: none;
+}
diff --git a/src/components/Header.jsx b/src/components/Header.jsx
index 10e8efb..e0a8495 100644
--- a/src/components/Header.jsx
+++ b/src/components/Header.jsx
@@ -2,6 +2,7 @@
import './Header.css';
import logo from '../assets/logo.png';
import { useUser } from '../context/UserContext';
+import { BookOpen } from '@icon-park/react'; // 导入图标组件
const Header = () => {
const [currentPath, setCurrentPath] = useState(window.location.pathname);
@@ -39,7 +40,18 @@
<img src={logo} alt="网站 logo" className="logo" />
<span className="site-name">Echo</span>
</div>
- <div className="user-and-message">
+ <div className="user-and-message" style={{ display: 'flex', alignItems: 'center', gap: '12px' }}>
+ {/* 新手指南图标,放在头像左边 */}
+ <button
+ className="guide-button"
+ onClick={() => handleLinkClick('/new-user-guide')}
+ title="新手指南"
+ >
+ <BookOpen theme="outline" size="20" fill="#fff" />
+ <span style={{ marginLeft: '6px' }}>新手指南</span>
+ </button>
+
+
<a href="/user/profile">
<img
src={user?.avatarUrl}
diff --git a/src/context/UserContext.js b/src/context/UserContext.js
index 7b75005..c8c65e8 100644
--- a/src/context/UserContext.js
+++ b/src/context/UserContext.js
@@ -1,78 +1,3 @@
-// import React, { createContext, useContext, useState, useEffect } from 'react';
-
-// const avatarBaseUrl = process.env.REACT_APP_AVATAR_BASE_URL || '';
-
-// export const UserContext = createContext();
-
-// export const UserProvider = ({ children }) => {
-// const [user, setUser] = useState(null);
-// const [loading, setLoading] = useState(true);
-
-// // ✅ 标准化用户数据结构
-// const formatUser = (raw) => {
-// if (!raw) return null;
-// return {
-// userId: raw.userId || raw.id || null,
-// username: raw.username || '匿名用户',
-// avatarUrl: raw.avatarUrl ? `${avatarBaseUrl}${raw.avatarUrl}` : null,
-// ...raw, // 保留其它字段(如 email, level 等)
-// };
-// };
-
-// useEffect(() => {
-// const storedUser = localStorage.getItem('user');
-// if (storedUser) {
-// try {
-// const parsed = JSON.parse(storedUser);
-// setUser(formatUser(parsed));
-// } catch (err) {
-// console.error('本地用户信息解析失败:', err);
-// localStorage.removeItem('user');
-// setUser(null);
-// }
-// } else {
-// // 设置默认用户
-// const defaultUser = {
-// userId: 1,
-// username: '测试用户',
-// avatarUrl: null,
-// };
-// localStorage.setItem('user', JSON.stringify(defaultUser));
-// setUser(formatUser(defaultUser));
-// }
-// setLoading(false);
-// }, []);
-
-// const saveUser = (userData) => {
-// if (userData && (userData.userId || userData.id)) {
-// const formatted = formatUser(userData);
-// localStorage.setItem('user', JSON.stringify(userData)); // 原始数据存储
-// setUser(formatted); // 格式化后使用
-// } else {
-// console.error('无效的用户数据:', userData);
-// }
-// };
-
-// const logout = () => {
-// localStorage.removeItem('user');
-// setUser(null);
-// };
-
-// return (
-// <UserContext.Provider value={{ user, saveUser, logout, loading }}>
-// {children}
-// </UserContext.Provider>
-// );
-// };
-
-// export const useUser = () => {
-// const context = useContext(UserContext);
-// if (!context) {
-// throw new Error('useUser must be used within a UserProvider');
-// }
-// return context;
-// };
-
import React, { createContext, useContext, useState, useEffect } from 'react';
diff --git a/src/pages/Forum/posts-create/CreatePostPage.jsx b/src/pages/Forum/posts-create/CreatePostPage.jsx
index 28f1a20..5d8e0f2 100644
--- a/src/pages/Forum/posts-create/CreatePostPage.jsx
+++ b/src/pages/Forum/posts-create/CreatePostPage.jsx
@@ -14,7 +14,7 @@
return (
<div className="create-post-page">
- <CreatePost userId={user.user_id} />
+ <CreatePost userId={user.userId} />
</div>
);
};
diff --git a/src/pages/Forum/posts-main/components/PostList.jsx b/src/pages/Forum/posts-main/components/PostList.jsx
index 533e726..d5ff736 100644
--- a/src/pages/Forum/posts-main/components/PostList.jsx
+++ b/src/pages/Forum/posts-main/components/PostList.jsx
@@ -177,17 +177,20 @@
<div className="post-meta">
<span>发布时间:{timeText}</span>
<div className="post-actions">
- <button className="icon-btn" onClick={() => toggleLike(post.postNo, post.liked, post.user_id)}>
+ <button className="icon-btn" onClick={() => toggleLike(post.postNo, post.liked,user.userId
+)}>
<GoodTwo theme="outline" size="24" fill={post.liked ? '#f00' : '#fff'} />
<span>{post.likeCount}</span>
</button>
- <button className="icon-btn" onClick={() => toggleCollect(post.postNo, post.collected, post.user_id)}>
+ <button className="icon-btn" onClick={() => toggleCollect(post.postNo, post.collected, user.userId
+)}>
<Star theme="outline" size="24" fill={post.collected ? '#ffd700' : '#fff'} />
<span>{post.collectCount}</span>
</button>
{canDelete && (
- <button className="icon-btn" onClick={() => handleDeletePost(post.postNo, post.user_id)}>
+ <button className="icon-btn" onClick={() => handleDeletePost(post.postNo, user.userId
+)}>
<Delete theme="outline" size="24" fill="#333" />
</button>
)}
diff --git a/src/pages/NewUserGuide/NewUserGuide.css b/src/pages/NewUserGuide/NewUserGuide.css
new file mode 100644
index 0000000..7149447
--- /dev/null
+++ b/src/pages/NewUserGuide/NewUserGuide.css
@@ -0,0 +1,97 @@
+.new-user-guide-page {
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
+ background-color: #f8f3ef; /* 柔和米棕底色 */
+ min-height: 100vh;
+}
+
+.guide-container {
+ display: flex;
+ padding: 32px;
+ max-width: 1000px;
+ margin: 40px auto;
+ background-color: #fffaf7; /* 粉米背景 */
+ border-radius: 16px;
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
+}
+
+.guide-nav {
+ width: 200px;
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+ padding-right: 24px;
+ border-right: 2px solid #e2cfc3;
+}
+
+.guide-nav button {
+ background: none;
+ border: none;
+ font-size: 17px;
+ text-align: left;
+ padding: 10px 12px;
+ cursor: pointer;
+ border-radius: 8px;
+ transition: background 0.3s, color 0.3s;
+ color: #6b4f3b; /* 米棕文字色 */
+}
+
+.guide-nav button:hover {
+ background-color: #f3ded7; /* 柔和粉色hover */
+ color: #4b3325;
+}
+
+.guide-nav button.active {
+ background-color: #eecfc1; /* 活跃标签背景色 */
+ color: #3c271b;
+ font-weight: 600;
+}
+
+.guide-main {
+ flex: 1;
+ padding-left: 32px;
+}
+
+.guide-content h2 {
+ margin-bottom: 16px;
+ font-size: 24px;
+ color: #4e342e;
+ border-bottom: 2px solid #eecfc1;
+ padding-bottom: 6px;
+}
+
+.guide-content ul,
+.guide-content ol {
+ padding-left: 24px;
+ color: #5d4037;
+ line-height: 1.8;
+ font-size: 16px;
+}
+
+.guide-content li {
+ margin-bottom: 10px;
+}
+
+@media (max-width: 768px) {
+ .guide-container {
+ flex-direction: column;
+ padding: 20px;
+ }
+
+ .guide-nav {
+ width: 100%;
+ flex-direction: row;
+ border-right: none;
+ border-bottom: 2px solid #e2cfc3;
+ gap: 8px;
+ margin-bottom: 20px;
+ }
+
+ .guide-nav button {
+ flex: 1;
+ text-align: center;
+ }
+
+ .guide-main {
+ padding-left: 0;
+ }
+}
diff --git a/src/pages/NewUserGuide/NewUserGuide.jsx b/src/pages/NewUserGuide/NewUserGuide.jsx
new file mode 100644
index 0000000..4c4d634
--- /dev/null
+++ b/src/pages/NewUserGuide/NewUserGuide.jsx
@@ -0,0 +1,85 @@
+import Header from '../../components/Header';
+import React, { useState } from 'react';
+import './NewUserGuide.css';
+
+const NewUserGuide = () => {
+ const [activeTab, setActiveTab] = useState('terms');
+
+ const renderContent = () => {
+ switch (activeTab) {
+ case 'terms':
+ return (
+ <div className="guide-content">
+ <h2>名词解释</h2>
+ <p>在本平台中,我们使用以下术语:</p>
+ <ul>
+ <li><strong>种子:</strong> 表示可下载的资源文件索引信息。</li>
+ <li><strong>做种:</strong> 指上传资源供他人下载。</li>
+ <li><strong>分享率:</strong> 上传流量与下载流量的比值。</li>
+ <li><strong>魔力值:</strong> 用于奖励活跃用户的虚拟积分。</li>
+ {/* 可继续添加名词 */}
+ </ul>
+ </div>
+ );
+ case 'tutorial':
+ return (
+ <div className="guide-content">
+ <h2>详细教程</h2>
+ <ol>
+ <li>注册并完善个人资料</li>
+ <li>浏览并下载感兴趣的种子资源</li>
+ <li>做种、评论、评分获得积分</li>
+ <li>发布你的第一个种子</li>
+ {/* 可继续扩展详细步骤 */}
+ </ol>
+ </div>
+ );
+ case 'tasks':
+ return (
+ <div className="guide-content">
+ <h2>成长任务</h2>
+ <p>完成以下任务可快速熟悉平台并获得奖励:</p>
+ <ul>
+ <li>🎯 浏览任意种子页面</li>
+ <li>🗣️ 在论坛发一条评论</li>
+ <li>📤 上传你的第一个资源</li>
+ <li>🌟 连续登录 3 天</li>
+ </ul>
+ </div>
+ );
+ default:
+ return null;
+ }
+ };
+
+ return (
+ <div className="new-user-guide-page">
+ <Header />
+ <div className="guide-container">
+ <div className="guide-nav">
+ <button
+ className={activeTab === 'terms' ? 'active' : ''}
+ onClick={() => setActiveTab('terms')}
+ >
+ 名词解释
+ </button>
+ <button
+ className={activeTab === 'tutorial' ? 'active' : ''}
+ onClick={() => setActiveTab('tutorial')}
+ >
+ 详细教程
+ </button>
+ <button
+ className={activeTab === 'tasks' ? 'active' : ''}
+ onClick={() => setActiveTab('tasks')}
+ >
+ 成长任务
+ </button>
+ </div>
+ <div className="guide-main">{renderContent()}</div>
+ </div>
+ </div>
+ );
+};
+
+export default NewUserGuide;
diff --git a/src/pages/UserCenter/UserNav.jsx b/src/pages/UserCenter/UserNav.jsx
index 64dd375..3456195 100644
--- a/src/pages/UserCenter/UserNav.jsx
+++ b/src/pages/UserCenter/UserNav.jsx
@@ -12,7 +12,7 @@
{ to: '/user/friends', label: '我的好友' },
{ to: '/user/groups', label: '我的群组' },
{ to: '/user/collections', label: '我的收藏' },
- { to: '/user/newbie-tasks', label: '新手考核' },
+ // { to: '/user/newbie-tasks', label: '新手考核' },
{ to: '/user/invite', label: '邀请新用户' },
];