邀请码、端口修改

Change-Id: Idc325c5f970ade6c750cd09d3d3c32b803dd17e3
diff --git a/src/App.js b/src/App.js
index 922372c..43425fd 100644
--- a/src/App.js
+++ b/src/App.js
@@ -21,6 +21,7 @@
 // import UserDynamics from './pages/UserCenter/UserDynamics';
 import UserFriends from './pages/UserCenter/UserFriends';
 import UserCollect from './pages/UserCenter/UserCollect';
+import UserInvite from './pages/UserCenter/UserInvite';
 import SimpleUploader from './pages/PublishSeed/SimpleUploader';
 
 function RedirectToAuth() {
@@ -55,6 +56,7 @@
           {/* <Route path="/user/dynamics" component={UserDynamics} /> */}
           <Route path="/user/friends" component={UserFriends} />
           <Route path="/user/collections" component={UserCollect} />
+          <Route path="/user/invite" component={UserInvite} />
         </>
       </GroupProvider>
     </UserProvider>
diff --git a/src/pages/AuthPage/AuthPage.css b/src/pages/AuthPage/AuthPage.css
index 98e5532..6e8b965 100644
--- a/src/pages/AuthPage/AuthPage.css
+++ b/src/pages/AuthPage/AuthPage.css
@@ -1,109 +1,27 @@
-/* .auth-container {
-  display: flex;
-  align-items: center;
-  justify-content: flex-end;
-  min-height: 100vh;
-  font-family: Arial, sans-serif;
-  background: #333;
-  padding: 0 2rem;
-}
-
-.auth-container img {
-  margin-left: 250px; 
-}
-
-.auth-form-section {
-  background: #E4D8C9;
-  padding: 2rem;
-  border-radius: 10px;
-  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
-  width: 300px;
-  margin: 0 auto;
-  max-width: 400px;
-}
-
-.form-group {
-  margin-bottom: 1.2rem;
-  display: flex;
-  flex-direction: column;
-}
-
-label {
-  display: block;
-  font-size: 0.9rem;
-  margin-bottom: 0.5rem;
-  color: #4A3B34;
-}
-
-.form-input {
-  width: 100%;
-  padding: 0.8rem;
-  border: 1px solid #ddd;
-  border-radius: 5px;
-  font-size: 0.9rem;
-  box-sizing: border-box;
-}
-
-.auth-button {
-  padding: 0.8rem 8.4rem;
-  background: #BA929A;
-  color: #4A3B34;
-  border: none;
-  border-radius: 5px;
-  cursor: pointer;
-  font-size: 0.9rem;
-  display: inline-block;
-}
-
-.verify-button {
-  padding: 0.5rem 1rem;
-  background: #BA929A;
-  color: #4A3B34;
-  border: none;
-  border-radius: 5px;
-  cursor: pointer;
-  font-size: 0.8rem;
-  display: inline-block;
-}
-
-.link-button {
-  background: none;
-  border: none;
-  color: #4A3B34;
-  cursor: pointer;
-  font-size: 0.8rem;
-  padding: 0;
-}
-
-.forgot-password {
-  position: absolute;
-  right: 10px;
-  bottom: 5px;
-  font-size: 12px;
-  background: none;
-  border: none;
-  color: #4A3B34;
-  cursor: pointer;
-  text-decoration: underline;
-}
-
-.register-link, .login-link {
-  text-align: center;
-  font-size: 0.8rem;
-  margin-top: 1rem;
-} */
-
-
   .auth-container {
   display: flex;
   align-items: center;
-  justify-content: flex-end; /* 使卡片靠右 */
+  /* justify-content: flex-end; */
+  justify-content: space-between; 
   min-height: 100vh;
   font-family: Arial, sans-serif;
-  background: #333; 
+  background: #5F4437; 
   /* background: linear-gradient(180deg, #5F4437, #823c3c) */
   padding: 0 2rem; /* 添加左右内边距 */
 }
+
+  .logo-container {
+    flex: 1;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    padding: 2rem;
+  }
+
+  .site-logo {
+    width: 300px; /* 设置固定宽度 */
+    height: auto; /* 高度自适应,保持比例 */
+  }
   
   .auth-card {
     width: 100%;
diff --git a/src/pages/AuthPage/AuthPage.jsx b/src/pages/AuthPage/AuthPage.jsx
index e7f8f52..fe1b42b 100644
--- a/src/pages/AuthPage/AuthPage.jsx
+++ b/src/pages/AuthPage/AuthPage.jsx
@@ -1,8 +1,7 @@
 import { useState } from "react";
 import { Link } from "wouter";
 import "./AuthPage.css";
-import CryptoJS from "crypto-js";
-
+import logo from '../../assets/logo.png'; 
 
 function AuthPage() {
   const [activeTab, setActiveTab] = useState("login");
@@ -29,17 +28,13 @@
     register: {},
   });
 
-  const hashPassword = (password) => {
-    return CryptoJS.SHA256(password).toString(CryptoJS.enc.Hex);
-  };
-
   // Handle login form submission
   const handleLogin = async (e) => {
   e.preventDefault();
 
   const newErrors = {};
   if (!loginData.username) {
-    newErrors.username = "请输入用户名或邮箱";
+    newErrors.username = "请输入用户名";
   }
   if (!loginData.password) {
     newErrors.password = "请输入密码";
@@ -109,8 +104,6 @@
     return;
   }
 
-  const hashedPassword = hashPassword(registerData.password);
-
   try {
     const response = await fetch("/echo/user/register", {
       method: 'POST',
@@ -120,8 +113,8 @@
       body: JSON.stringify({
         username: registerData.username,
         email: registerData.email,
-        password: hashedPassword,
-        role: "user", // 默认角色,可根据实际情况调整
+        password: registerData.password, // 原始密码
+        role: "user",
         inviteCode: registerData.inviteCode,
       }),
     });
@@ -144,6 +137,7 @@
 };
 
 
+
   // Update login form data
   const updateLoginData = (field, value) => {
     setLoginData({
@@ -162,6 +156,10 @@
 
   return (
     <div className="auth-container">
+      <div className="logo-container">
+        <img src={logo} alt="Logo" className="site-logo" />
+      </div>
+
       <div className="auth-card">
         <div className="auth-header">
           <div className={`auth-tab ${activeTab === "login" ? "active" : ""}`} onClick={() => setActiveTab("login")}>
@@ -178,13 +176,13 @@
             <form className="auth-form" onSubmit={handleLogin}>
               {errors.login.message && <div className="error-message">{errors.login.message}</div>}
               <div className="form-group">
-                <label htmlFor="login-username">用户名/邮箱</label>
+                <label htmlFor="login-username">用户名</label>
                 <input
                   type="text"
                   id="login-username"
                   value={loginData.username}
                   onChange={(e) => updateLoginData("username", e.target.value)}
-                  placeholder="请输入用户名或邮箱"
+                  placeholder="请输入用户名"
                   required
                 />
                 {errors.login.username && <div className="error-message">{errors.login.username}</div>}
@@ -205,13 +203,13 @@
 
               <div className="form-group-inline">
                 <div className="checkbox-container">
-                  <input
+                  {/* <input
                     type="checkbox"
                     id="remember-me"
                     checked={loginData.rememberMe}
                     onChange={(e) => updateLoginData("rememberMe", e.target.checked)}
-                  />
-                  <label htmlFor="remember-me">记住我</label>
+                  /> */}
+                  {/* <label htmlFor="remember-me">记住我</label> */}
                 </div>
                 <Link to="/forgot-password" className="forgot-password">
                   忘记密码?
diff --git a/src/pages/UserCenter/UserInvite.css b/src/pages/UserCenter/UserInvite.css
new file mode 100644
index 0000000..8250e0b
--- /dev/null
+++ b/src/pages/UserCenter/UserInvite.css
@@ -0,0 +1,36 @@
+.user-invite-container {
+  padding: 24px;
+  background: #fff;
+  border-radius: 12px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+  max-width: 500px;
+  margin: 0 auto;
+  text-align: center;
+}
+
+.invite-button {
+  padding: 10px 20px;
+  background-color: #4a90e2;
+  color: white;
+  font-size: 16px;
+  border: none;
+  border-radius: 8px;
+  cursor: pointer;
+  margin-top: 12px;
+}
+
+.invite-button:disabled {
+  background-color: #cccccc;
+  cursor: not-allowed;
+}
+
+.invite-code {
+  margin-top: 20px;
+  font-size: 18px;
+  color: #333;
+}
+
+.invite-code span {
+  font-weight: bold;
+  color: #4a90e2;
+}
diff --git a/src/pages/UserCenter/UserInvite.jsx b/src/pages/UserCenter/UserInvite.jsx
new file mode 100644
index 0000000..aa6e559
--- /dev/null
+++ b/src/pages/UserCenter/UserInvite.jsx
@@ -0,0 +1,98 @@
+// import React, { useState } from 'react';
+// import './UserInvite.css';
+// import axios from 'axios';
+// import { useUser } from '../../context/UserContext'; // 根据实际路径调整
+
+// const UserInvite = () => {
+//   const { user } = useUser();
+//   const [inviteCode, setInviteCode] = useState('');
+//   const [loading, setLoading] = useState(false);
+
+//   const handleGenerateInvite = async () => {
+//     if (!user?.userId) {
+//       alert('未获取到用户信息,无法生成邀请码');
+//       return;
+//     }
+
+//     setLoading(true);
+//     try {
+//       const response = await axios.get('/echo/user/getInviteCode', {
+//         params: { user_id: user.userId },
+//       });
+//       setInviteCode(response.data.invite_code);
+//     } catch (error) {
+//       console.error('生成邀请码失败:', error);
+//       alert('生成邀请码失败,请稍后再试');
+//     }
+//     setLoading(false);
+//   };
+
+//   return (
+//     <div className="user-invite-container">
+//       <h2>邀请新用户</h2>
+//       <button className="invite-button" onClick={handleGenerateInvite} disabled={loading}>
+//         {loading ? '生成中...' : '生成邀请码'}
+//       </button>
+//       {inviteCode && (
+//         <div className="invite-code">
+//           邀请码:<span>{inviteCode}</span>
+//         </div>
+//       )}
+//     </div>
+//   );
+// };
+
+// export default UserInvite;
+
+import React, { useState } from 'react';
+import './UserInvite.css';
+import axios from 'axios';
+import { useUser } from '../../context/UserContext';
+
+const UserInvite = () => {
+  const { user } = useUser();
+  const [inviteCode, setInviteCode] = useState('');
+  const [loading, setLoading] = useState(false);
+
+  const handleGenerateInvite = async () => {
+    if (!user?.userId) {
+      alert('未获取到用户信息,无法生成邀请码');
+      return;
+    }
+
+    setLoading(true);
+    try {
+      const response = await axios.post('/echo/user/getInviteCode', {
+        user_id: user.userId,
+      });
+
+      const data = response.data;
+
+      if (data.status === 'success') {
+        setInviteCode(data.invite_code);
+      } else {
+        alert(`生成失败:${data.message}`);
+      }
+    } catch (error) {
+      console.error('生成邀请码失败:', error);
+      alert('生成邀请码失败,请稍后再试');
+    }
+    setLoading(false);
+  };
+
+  return (
+    <div className="user-invite-container">
+      <h2>邀请新用户</h2>
+      <button className="invite-button" onClick={handleGenerateInvite} disabled={loading}>
+        {loading ? '生成中...' : '生成邀请码'}
+      </button>
+      {inviteCode && (
+        <div className="invite-code">
+          邀请码:<span>{inviteCode}</span>
+        </div>
+      )}
+    </div>
+  );
+};
+
+export default UserInvite;
diff --git a/src/pages/UserCenter/UserNav.jsx b/src/pages/UserCenter/UserNav.jsx
index cc343b1..64dd375 100644
--- a/src/pages/UserCenter/UserNav.jsx
+++ b/src/pages/UserCenter/UserNav.jsx
@@ -13,6 +13,7 @@
     { to: '/user/groups', label: '我的群组' },
     { to: '/user/collections', label: '我的收藏' },
     { to: '/user/newbie-tasks', label: '新手考核' },
+    { to: '/user/invite', label: '邀请新用户' },
   ];
 
   // 判断路径是否是当前活动页面
@@ -36,37 +37,3 @@
 };
 
 export default UserNav;
-
-// import React from 'react';
-// import './UserNav.css';
-
-// const UserNav = ({ activeKey, onSelect }) => {
-//   const navLinks = [
-//     { key: 'profile', label: '个人资料' },
-//     // { key: 'dynamics', label: '我的动态' },
-//     // { key: 'friends', label: '我的好友' },
-//     // { key: 'groups', label: '我的群组' },
-//     // { key: 'collections', label: '我的收藏' },
-//     { key: 'newbieTasks', label: '新手考核' },
-//   ];
-
-//   return (
-//     <div className="user-nav-container">
-//       <nav className="user-nav">
-//         {navLinks.map(({ key, label }) => (
-//           <div
-//             key={key}
-//             className={`user-nav-item ${activeKey === key ? 'active' : ''}`}
-//             onClick={() => onSelect(key)}
-//             style={{ cursor: 'pointer' }}
-//           >
-//             {label}
-//           </div>
-//         ))}
-//       </nav>
-//     </div>
-//   );
-// };
-
-// export default UserNav;
-