浏览代码

邀请码,加载组件

liqiuying 2 月之前
父节点
当前提交
550226cce7
共有 4 个文件被更改,包括 115 次插入28 次删除
  1. 42 0
      components/LoadingContext.tsx
  2. 23 17
      entrypoints/popup/App.tsx
  3. 4 1
      entrypoints/popup/main.tsx
  4. 46 10
      entrypoints/popup/pages/Login.tsx

+ 42 - 0
components/LoadingContext.tsx

@@ -0,0 +1,42 @@
+// src/context/LoadingContext.tsx
+import React, { createContext, useContext, useState, ReactNode } from 'react';
+import { Loading } from '@alifd/next';
+
+interface LoadingContextType {
+  showLoading: (message?: string) => void;
+  hideLoading: () => void;
+  isLoading: boolean;
+}
+
+const LoadingContext = createContext<LoadingContextType | undefined>(undefined);
+
+export const LoadingProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
+  const [isLoading, setIsLoading] = useState(false);
+  const [message, setMessage] = useState<string>('');
+
+  const showLoading = (message = '') => {
+    setMessage(message);
+    setIsLoading(true);
+  };
+
+  const hideLoading = () => {
+    setIsLoading(false);
+    setMessage('');
+  };
+
+  return (
+    <LoadingContext.Provider value={{ showLoading, hideLoading, isLoading }}>
+      <Loading visible={isLoading} fullScreen tip={message}>
+        {children}
+      </Loading>
+    </LoadingContext.Provider>
+  );
+};
+
+export const useLoading = () => {
+  const context = useContext(LoadingContext);
+  if (!context) {
+    throw new Error('useLoading must be used within a LoadingProvider');
+  }
+  return context;
+};

+ 23 - 17
entrypoints/popup/App.tsx

@@ -9,6 +9,7 @@ import '@alifd/next/dist/next.css';
 import '@alifd/next/dist/next.min.css';
 import Login from './pages/Login'
 import DesignPic from './pages/DesignPic';
+import { useLoading } from '@/components/LoadingContext';
 
 // 创建一个保护路由组件
 function ProtectedRoute({ children }: { children: React.ReactNode }) {
@@ -48,6 +49,7 @@ function App() {
   const [count, setCount] = useState(0);
   const [isLoggedIn, setIsLoggedIn] = useState(false);
   const [userinfo, setUserinfo] = useState<any>(null);
+  const { showLoading, hideLoading } = useLoading();
 
   // 检查登录状态
   useEffect(() => {
@@ -74,25 +76,29 @@ function App() {
 
   // 处理登出逻辑
   const handleLogout = () => {
-    localStorage.removeItem('isLoggedIn');
-    localStorage.removeItem('access_token');
-    localStorage.removeItem('userinfo');
-    setIsLoggedIn(false);
+    showLoading("退出登录中...")
+    setTimeout(() => {
+      hideLoading()
+      localStorage.removeItem('isLoggedIn');
+      localStorage.removeItem('access_token');
+      localStorage.removeItem('userinfo');
+      setIsLoggedIn(false);
+    }, 500)
   };
 
   return (
-    <Router>
-      {/* 只在登录后显示导航栏 */}
-      {isLoggedIn && <Navigation onLogout={handleLogout} userinfo={userinfo} />}
+      <Router>
+        {/* 只在登录后显示导航栏 */}
+        {isLoggedIn && <Navigation onLogout={handleLogout} userinfo={userinfo} />}
 
-      <Routes>
-        <Route path="/login" element={<Login setIsLoggedIn={setIsLoggedIn} />} />
-        <Route path="/" element={
-          <ProtectedRoute>
-            <DesignPic />
-          </ProtectedRoute>
-        } />
-        {/* <Route path="/about" element={
+        <Routes>
+          <Route path="/login" element={<Login setIsLoggedIn={setIsLoggedIn} />} />
+          <Route path="/" element={
+            <ProtectedRoute>
+              <DesignPic />
+            </ProtectedRoute>
+          } />
+          {/* <Route path="/about" element={
           <ProtectedRoute>
             <About />
           </ProtectedRoute>
@@ -102,8 +108,8 @@ function App() {
             <Home />
           </ProtectedRoute>
         } /> */}
-      </Routes>
-    </Router>
+        </Routes>
+      </Router>
   );
 }
 

+ 4 - 1
entrypoints/popup/main.tsx

@@ -2,13 +2,16 @@
 import React from 'react';
 import { createRoot } from 'react-dom/client';
 import App from './App';
+import { LoadingProvider } from '@/components/LoadingContext';
 
 const container = document.getElementById('root');
 if (container) {
   const root = createRoot(container);
   root.render(
     <React.StrictMode>
-      <App />
+      <LoadingProvider>
+        <App />
+      </LoadingProvider>
     </React.StrictMode>
   );
 }

+ 46 - 10
entrypoints/popup/pages/Login.tsx

@@ -4,15 +4,18 @@ import { useNavigate } from 'react-router-dom';
 import { Input, Loading, Form, Grid } from '@alifd/next';
 const { Row, Col } = Grid
 import { CustomMessage } from '@/components/CustomMessage'
+import { useLoading  } from '@/components/LoadingContext';
 
 export default function Login({ setIsLoggedIn }: { setIsLoggedIn: (loggedIn: boolean) => void }) {
     const formRef = useRef<any>(null);
     const [username, setUsername] = useState('');
     const [password, setPassword] = useState('');
+    const [invitationCode, setInvitationCode] = useState('');
     const [loading, setLoading] = useState(false);
-    const [errors, setErrors] = useState<{ username?: string, password?: string, code?: string }>({}); // 添加 code 错误字段
+    const [errors, setErrors] = useState<{ username?: string, password?: string, code?: string, invitationCode?: string }>({});
     const [keys, setKeys] = useState('');
     const [validImg, setValidImg] = useState('');
+    const { showLoading, hideLoading } = useLoading();
     const navigate = useNavigate();
 
     // 添加验证码状态
@@ -23,7 +26,7 @@ export default function Login({ setIsLoggedIn }: { setIsLoggedIn: (loggedIn: boo
     }, [])
 
     const validateForm = () => {
-        const newErrors: { username?: string, password?: string, code?: string } = {};
+        const newErrors: { username?: string, password?: string, code?: string, invitationCode?: string } = {};
 
         if (!username.trim()) {
             newErrors.username = '请输入用户名';
@@ -40,6 +43,11 @@ export default function Login({ setIsLoggedIn }: { setIsLoggedIn: (loggedIn: boo
             newErrors.code = '请输入验证码';
         }
 
+        // 添加邀请码校验
+        if (!invitationCode.trim()) {
+            newErrors.invitationCode = '请输入邀请码';
+        }
+
         setErrors(newErrors);
         return Object.keys(newErrors).length === 0;
     };
@@ -64,7 +72,8 @@ export default function Login({ setIsLoggedIn }: { setIsLoggedIn: (loggedIn: boo
     const handleLogin = (values: any) => {
         if (!validateForm()) return
         try {
-            setLoading(true);
+            // setLoading(true);
+            showLoading('登录中...');
             const params = {
                 ...values,
                 key: keys
@@ -79,14 +88,16 @@ export default function Login({ setIsLoggedIn }: { setIsLoggedIn: (loggedIn: boo
             }).then(response => response.json()).then(res => {
                 const { msg = "", token = "", code } = res;
                 if (!code) {
-                    setLoading(false);
+                    // setLoading(false);
+                    hideLoading(); 
                     return false;
                 }
 
                 if (code == -1) {
                     evVerify()
                     CustomMessage.error(msg);
-                    setLoading(false);
+                    // setLoading(false);
+                    hideLoading(); 
                     return false;
                 }
                 fetch('https://user.landwu.com/api/user/getProfile', {
@@ -105,24 +116,26 @@ export default function Login({ setIsLoggedIn }: { setIsLoggedIn: (loggedIn: boo
                         localStorage.setItem("access_token", token);
                         localStorage.setItem('isLoggedIn', 'true');
                         setTimeout(() => {
-                            setLoading(false);
+                            // setLoading(false);
+                            hideLoading(); 
                             setIsLoggedIn(true);
                             // 跳转到首页
                             navigate('/');
                         }, 100)
                     }
                 }).catch(err => {
-                    setLoading(false);
+                    // setLoading(false);
+                    hideLoading(); 
                 })
             }).catch((e) => {
                 console.log("catch")
-                setLoading(false);
+                // setLoading(false);
+                hideLoading(); 
             });
         } catch (error) {
             console.error('登录请求失败:', error);
             CustomMessage.error('网络错误,请稍后重试');
-        } finally {
-            setLoading(false);
+             hideLoading(); 
         }
     };
 
@@ -182,6 +195,29 @@ export default function Login({ setIsLoggedIn }: { setIsLoggedIn: (loggedIn: boo
                             disabled={loading}
                         />
                     </Form.Item>
+                    <Form.Item
+                        label="邀请码"
+                        name="invitationCode"
+                        required
+                        help={errors.invitationCode}
+                        validateState={errors.invitationCode ? 'error' : undefined}>
+                        <Input
+                            htmlType="invitationCode"
+                            placeholder="请输入邀请码"
+                            value={invitationCode}
+                            onChange={(value) => {
+                                if (typeof value === 'string') {
+                                    setInvitationCode(value);
+                                } else {
+                                    setInvitationCode(String(value));
+                                }
+                                if (errors.invitationCode) {
+                                    setErrors({ ...errors, invitationCode: undefined });
+                                }
+                            }}
+                            disabled={loading}
+                        />
+                    </Form.Item>
                     <Row>
                         <Col span={16}>
                             <Form.Item