diff --git a/client/admin/deno.json b/client/admin/deno.json index 7145d9f..7b96bfa 100644 --- a/client/admin/deno.json +++ b/client/admin/deno.json @@ -19,9 +19,6 @@ "lodash": "https://esm.d8d.fun/lodash@4.17.21" }, "compilerOptions": { - "lib": ["dom", "dom.iterable", "esnext", "deno.ns"], - "jsx": "react", - "jsxFactory": "React.createElement", - "jsxFragmentFactory": "React.Fragment" + "lib": ["dom", "dom.iterable", "esnext", "deno.ns"] } } diff --git a/client/admin/deno.lock b/client/admin/deno.lock index ee3f14c..55a0db8 100644 --- a/client/admin/deno.lock +++ b/client/admin/deno.lock @@ -53,6 +53,7 @@ "https://esm.d8d.fun/@types/debug@~4.1.12/index.d.ts": "https://esm.d8d.fun/@types/debug@4.1.12/index.d.ts", "https://esm.d8d.fun/@types/follow-redirects@~1.14.4/index.d.ts": "https://esm.d8d.fun/@types/follow-redirects@1.14.4/index.d.ts", "https://esm.d8d.fun/@types/lodash-es@~4.17.12/index.d.ts": "https://esm.d8d.fun/@types/lodash-es@4.17.12/index.d.ts", + "https://esm.d8d.fun/@types/lodash@~4.17.16/index.d.ts": "https://esm.d8d.fun/@types/lodash@4.17.16/index.d.ts", "https://esm.d8d.fun/@types/mime-types@~2.1.4/index.d.ts": "https://esm.d8d.fun/@types/mime-types@2.1.4/index.d.ts", "https://esm.d8d.fun/@types/ms@~2.1.0/index.d.ts": "https://esm.d8d.fun/@types/ms@2.1.0/index.d.ts", "https://esm.d8d.fun/@types/proxy-from-env@~1.0.4/index.d.ts": "https://esm.d8d.fun/@types/proxy-from-env@1.0.4/index.d.ts", @@ -764,6 +765,8 @@ "https://esm.d8d.fun/isexe@3.1.1?target=denonext": "b3c61e7e70b9d56865de461fbcdae702ebf93743143457079a15a60e30dfcf83", "https://esm.d8d.fun/lodash-es@4.17.21/denonext/lodash-es.mjs": "83b25b8f85872b2805e6b0273c90d6c96960c80a710c55e89a7b399107fc6fa8", "https://esm.d8d.fun/lodash-es@4.17.21?target=denonext": "1252ccd86311d14f2dd05282cf3e40e1ff76bfa79c71ca49b903e902129944cb", + "https://esm.d8d.fun/lodash@4.17.21": "c2f90ffd948b7a30f054986888bdc2667824115fa48ad583ca8b3a579ca4a5a8", + "https://esm.d8d.fun/lodash@4.17.21/denonext/lodash.mjs": "9d2a44e584d91008f61f974c6d0a32bf9afb1563761e60c366af0a293e8c759b", "https://esm.d8d.fun/mime-db@1.52.0/denonext/mime-db.mjs": "f93feb3d7150014b71bd0d06c5bd819db56a089b31b8b79a3b0466bb37ef005e", "https://esm.d8d.fun/mime-types@2.1.35/denonext/mime-types.mjs": "704bdb318816fe1360c90a196f7cb3ba6e25fe207707cc2df873f890ad2e5f44", "https://esm.d8d.fun/mime-types@2.1.35?target=denonext": "e4cc9a1aabecc1be22d194375ec3b99cc9d51700cc4629ab689975451c0a8ce5", diff --git a/client/mobile/deno.lock b/client/mobile/deno.lock index b52a1a4..0ffa5bb 100644 --- a/client/mobile/deno.lock +++ b/client/mobile/deno.lock @@ -1,5 +1,19 @@ { "version": "4", + "specifiers": { + "npm:@types/node@*": "22.12.0" + }, + "npm": { + "@types/node@22.12.0": { + "integrity": "sha512-Fll2FZ1riMjNmlmJOdAyY5pUbkftXslB5DgEzlIuNaiWhXd00FhWxVC/r4yV/4wBb9JfImTu+jiSvXTkJ7F/gA==", + "dependencies": [ + "undici-types" + ] + }, + "undici-types@6.20.0": { + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==" + } + }, "redirects": { "https://esm.d8d.fun/@deno/shim-deno-test@^0.5.0?target=denonext": "https://esm.d8d.fun/@deno/shim-deno-test@0.5.0?target=denonext", "https://esm.d8d.fun/@deno/shim-deno@~0.18.0?target=denonext": "https://esm.d8d.fun/@deno/shim-deno@0.18.2?target=denonext", @@ -11,6 +25,7 @@ "https://esm.d8d.fun/@types/ms@~2.1.0/index.d.ts": "https://esm.d8d.fun/@types/ms@2.1.0/index.d.ts", "https://esm.d8d.fun/@types/proxy-from-env@~1.0.4/index.d.ts": "https://esm.d8d.fun/@types/proxy-from-env@1.0.4/index.d.ts", "https://esm.d8d.fun/@types/react-dom@~19.0.4/X-ZHJlYWN0QDE5LjAuMA/index.d.ts": "https://esm.d8d.fun/@types/react-dom@19.0.6/X-ZHJlYWN0QDE5LjAuMA/index.d.ts", + "https://esm.d8d.fun/@types/react-dom@~19.0.4/client.d.ts": "https://esm.d8d.fun/@types/react-dom@19.0.6/client.d.ts", "https://esm.d8d.fun/@types/react-dom@~19.0.6/X-ZHJlYWN0QDE5LjAuMA/client.d.ts": "https://esm.d8d.fun/@types/react-dom@19.0.6/X-ZHJlYWN0QDE5LjAuMA/client.d.ts", "https://esm.d8d.fun/@types/react@~19.0.12/index.d.ts": "https://esm.d8d.fun/@types/react@19.0.14/index.d.ts", "https://esm.d8d.fun/@types/react@~19.0.12/jsx-runtime.d.ts": "https://esm.d8d.fun/@types/react@19.0.14/jsx-runtime.d.ts", @@ -61,7 +76,9 @@ "https://esm.d8d.fun/@deno/shim-deno@0.18.2/denonext/shim-deno.mjs": "819d8ac34fdaf60658cf03d137f14adaff3f13a279ffd79cd8797d84a6ac46ab", "https://esm.d8d.fun/@deno/shim-deno@0.18.2?target=denonext": "ffa3ca347bb6b6530720158f307a2e31b16728fbb52e6432254a07d52fcbc404", "https://esm.d8d.fun/@heroicons/react@2.1.1/24/outline?deps=react@19.0.0": "d2c14cfd7f3090062c9f968f25d0ddbb277ca76055af1ac3fd22045276571a75", + "https://esm.d8d.fun/@heroicons/react@2.1.1/24/outline?deps=react@19.0.0,react-dom@19.0.0": "5e99f4d40ce60c55b5cf421c3cf3f13df1707cf53152e447b2332570412cd77a", "https://esm.d8d.fun/@heroicons/react@2.1.1/24/solid?deps=react@19.0.0": "546051c9fdfdca5c7d51cd4cf588fe709da509274c5fcf203d616a5e87bdd595", + "https://esm.d8d.fun/@heroicons/react@2.1.1/X-ZHJlYWN0LWRvbUAxOS4wLjAscmVhY3RAMTkuMC4w/denonext/24/outline.mjs": "640f934a0c987f682032049e5d4a455567db676de47bca0d44e76b72023661f7", "https://esm.d8d.fun/@heroicons/react@2.1.1/X-ZHJlYWN0QDE5LjAuMA/denonext/24/outline.mjs": "640f934a0c987f682032049e5d4a455567db676de47bca0d44e76b72023661f7", "https://esm.d8d.fun/@heroicons/react@2.1.1/X-ZHJlYWN0QDE5LjAuMA/denonext/24/solid.mjs": "dcbd0c377d92857b6eb23c7dbb2ee6e650b12aa6ae1ef7fcc10dc1964df8ba47", "https://esm.d8d.fun/@socket.io/component-emitter@3.1.2/denonext/component-emitter.mjs": "3c6c5f2d64d4933b577a7117df1d8855c51ff01ab3dea8f42af1adcb1a5989e7", @@ -158,11 +175,15 @@ "https://esm.d8d.fun/proxy-from-env@1.1.0?target=denonext": "bf02a050a1a6aa56ddba25dbea2c355da294630e5c5520fddea4b2f30a9292bc", "https://esm.d8d.fun/react-dom@19.0.0/X-ZHJlYWN0QDE5LjAuMA/denonext/client.mjs": "af662fd134eea98f37fdcea6142accd0f8a7d2e13c1c3c9e98dc37a8c7aad46b", "https://esm.d8d.fun/react-dom@19.0.0/X-ZHJlYWN0QDE5LjAuMA/denonext/react-dom.mjs": "a2f7bc344e1d5b7ca47e68665291e206ae4db17ee84f234f3d3e2533b9119f63", + "https://esm.d8d.fun/react-dom@19.0.0/client": "c972c16184c695fc5828dfa61d7f341edbc463d20d8108765c93a98027c24227", "https://esm.d8d.fun/react-dom@19.0.0/client?deps=react@19.0.0,react-dom@19.0.0": "eaf0dd9b4937f9f7674c02491ce718f461ad49377d8515e71c24ae841f407ded", + "https://esm.d8d.fun/react-dom@19.0.0/denonext/client.mjs": "af662fd134eea98f37fdcea6142accd0f8a7d2e13c1c3c9e98dc37a8c7aad46b", + "https://esm.d8d.fun/react-dom@19.0.0/denonext/react-dom.mjs": "a2f7bc344e1d5b7ca47e68665291e206ae4db17ee84f234f3d3e2533b9119f63", "https://esm.d8d.fun/react-dom@19.0.0?deps=react@19.0.0,react-dom@19.0.0": "0e49978c3f0fb4a94db9c9318aebd7e1b35651678050871a91ebb080cc3e1f83", "https://esm.d8d.fun/react-router@7.3.0/X-ZHJlYWN0LWRvbUAxOS4wLjAscmVhY3RAMTkuMC4w/denonext/dist/development/chunk-K6CSEXPM.mjs": "441898046ad7c4fd9a6b53e13a398c9c74c4412c519e942f82b8a77f7af9f9d6", "https://esm.d8d.fun/react-router@7.3.0/X-ZHJlYWN0LWRvbUAxOS4wLjAscmVhY3RAMTkuMC4w/denonext/react-router.mjs": "b0b05fcfc3a03c5f679cd0bc69ca19aa10abaa977395df00e86b3fb114e5e346", "https://esm.d8d.fun/react-router@7.3.0?deps=react@19.0.0,react-dom@19.0.0": "ad747718e32a45020d67eb4ff98f9734cb06a10ceb393baac0a965043e96cdf0", + "https://esm.d8d.fun/react@19.0.0": "ab1f4aa20ac56c237bbb204632bdb55f03a0ab005d21944eeb447e5e37879637", "https://esm.d8d.fun/react@19.0.0/X-ZHJlYWN0LWRvbUAxOS4wLjA/denonext/react.mjs": "87fdb28d39ca8983bdba3e7ec329305f95463cfc70c015b2620b4900fa15efdd", "https://esm.d8d.fun/react@19.0.0/denonext/jsx-runtime.mjs": "643b749fa9666fbf73619a99fd708722edb4acaa34c8cea7be783a3432367780", "https://esm.d8d.fun/react@19.0.0/denonext/react.mjs": "87fdb28d39ca8983bdba3e7ec329305f95463cfc70c015b2620b4900fa15efdd", diff --git a/client/mobile/hooks.tsx b/client/mobile/hooks.tsx index ba5fb97..77daeb8 100644 --- a/client/mobile/hooks.tsx +++ b/client/mobile/hooks.tsx @@ -57,24 +57,10 @@ const defaultThemeSettings: ThemeSettings = { }; // 创建认证上下文 -const AuthContext = createContext({ - user: null, - token: null, - login: async () => {}, - logout: async () => {}, - isAuthenticated: false, - isLoading: true -}); +const AuthContext = createContext(null); // 创建主题上下文 -const ThemeContext = createContext({ - isDark: false, - currentTheme: defaultThemeSettings, - updateTheme: () => {}, - saveTheme: async () => defaultThemeSettings, - resetTheme: async () => defaultThemeSettings, - toggleTheme: () => {} -}); +const ThemeContext = createContext(null); // 认证提供者组件 export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { @@ -107,7 +93,6 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children setLocalStorageWithExpiry('token', token, 24); // 24小时过期 setLocalStorageWithExpiry('user', user, 24); - return user; } catch (error) { console.error('登录失败:', error); throw error; @@ -255,18 +240,19 @@ export const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({ childre ); }; -// 主题hook -export const useTheme = () => useContext(ThemeContext); +// 使用上下文的钩子 +export const useAuth = () => { + const context = useContext(AuthContext); + if (!context) { + throw new Error('useAuth必须在AuthProvider内部使用'); + } + return context; +}; -// 认证hook -export const useAuth = () => useContext(AuthContext); - -// API hook -export const useApi = () => { - const { token } = useAuth(); - - return { - api, - isAuthenticated: !!token - }; -}; \ No newline at end of file +export const useTheme = () => { + const context = useContext(ThemeContext); + if (!context) { + throw new Error('useTheme必须在ThemeProvider内部使用'); + } + return context; +}; \ No newline at end of file diff --git a/client/mobile/mobile_app.tsx b/client/mobile/mobile_app.tsx index 0005428..497a07d 100644 --- a/client/mobile/mobile_app.tsx +++ b/client/mobile/mobile_app.tsx @@ -7,7 +7,8 @@ import { Navigate, useLocation, useNavigate, - Link + Link, + useRouteError } from 'react-router'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import dayjs from 'dayjs'; @@ -16,6 +17,7 @@ import { AuthProvider, ThemeProvider, useAuth } from './hooks.tsx'; import HomePage from './pages_index.tsx'; import LoginPage from './pages_login.tsx'; import { GlobalConfig } from "../share/types.ts"; +import { ExclamationTriangleIcon, HomeIcon, BellIcon, UserIcon } from '@heroicons/react/24/outline'; // 设置中文语言 dayjs.locale('zh-cn'); @@ -153,6 +155,42 @@ const PageNotFound = () => ( ); +// 添加错误页面组件 +const ErrorPage = () => { + const error = useRouteError() as any; + const errorMessage = error?.statusText || error?.message || '未知错误'; + + return ( +
+
+ +

出错了

+
抱歉,页面加载过程中发生错误
+ +
+

错误信息:

+

{errorMessage}

+ {error?.stack && ( +
+ 查看详细信息 +
+                {error.stack}
+              
+
+ )} +
+ + + 返回首页 + +
+
+ ); +}; + // 添加个人页面组件 const ProfilePage = () => (
@@ -232,7 +270,7 @@ const MobileLayout = () => { location.pathname === '/mobile' ? 'text-blue-600' : 'text-gray-500' }`} > -
🏠
+ 首页 { location.pathname === '/mobile/notifications' ? 'text-blue-600' : 'text-gray-500' }`} > -
🔔
+ 通知 { location.pathname === '/mobile/profile' ? 'text-blue-600' : 'text-gray-500' }`} > -
👤
+ 我的
@@ -265,11 +303,13 @@ const App = () => { const router = createBrowserRouter([ { path: '/', - element: + element: , + errorElement: }, { path: '/mobile/login', - element: + element: , + errorElement: }, { path: '/mobile', @@ -278,6 +318,7 @@ const App = () => { ), + errorElement: , children: [ { index: true,