Bläddra i källkod

新增设置页面,更新个人信息页面以包含导航按钮,优化用户体验和代码结构。

zyh 8 månader sedan
förälder
incheckning
d7b7a8df18
3 ändrade filer med 123 tillägg och 75 borttagningar
  1. 6 1
      client/mobile/mobile_app.tsx
  2. 7 74
      client/mobile/pages_profile.tsx
  3. 110 0
      client/mobile/pages_settings.tsx

+ 6 - 1
client/mobile/mobile_app.tsx

@@ -192,6 +192,7 @@ const ErrorPage = () => {
 };
 
 import ProfilePage from './pages_profile.tsx'
+import SettingsPage from './pages_settings.tsx'
 
 // 移动端布局组件 - 包含底部导航
 const MobileLayout = () => {
@@ -224,7 +225,7 @@ const MobileLayout = () => {
             <BellIcon className="w-6 h-6 mb-1" />
             <span className="text-xs">通知</span>
           </Link>
-          <Link 
+          <Link
             to="/mobile/profile"
             className={`flex flex-col items-center py-2 px-4 ${
               location.pathname === '/mobile/profile' ? 'text-blue-600' : 'text-gray-500'
@@ -273,6 +274,10 @@ const App = () => {
         {
           path: 'notifications',
           element: <NotificationsPage />
+        },
+        {
+          path: 'settings',
+          element: <SettingsPage />
         }
       ]
     },

+ 7 - 74
client/mobile/pages_profile.tsx

@@ -104,80 +104,13 @@ export default function ProfilePage() {
             <p className="text-gray-500">个人信息</p>
           </div>
         </div>
-      </div>
-      
-      <div className="bg-white rounded-lg shadow p-4 mb-4">
-        <h2 className="text-lg font-semibold mb-4">编辑信息</h2>
-        <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
-        <div>
-          <label className="block text-sm font-medium text-gray-700 mb-1">用户名</label>
-          <input
-            {...register('username')}
-            disabled
-            className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 bg-gray-100"
-          />
-        </div>
-
-        <div>
-          <label className="block text-sm font-medium text-gray-700 mb-1">昵称</label>
-          <input
-            {...register('nickname', { required: '请输入昵称' })}
-            className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
-          />
-          {errors.nickname && <p className="mt-1 text-sm text-red-600">{errors.nickname.message}</p>}
-        </div>
-
-        <div>
-          <label className="block text-sm font-medium text-gray-700 mb-1">邮箱</label>
-          <input
-            {...register('email', { 
-              required: '请输入邮箱',
-              pattern: {
-                value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
-                message: '请输入有效的邮箱地址'
-              }
-            })}
-            type="email"
-            className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
-          />
-          {errors.email && <p className="mt-1 text-sm text-red-600">{errors.email.message}</p>}
-        </div>
-
-        <div>
-          <label className="block text-sm font-medium text-gray-700 mb-1">手机号</label>
-          <input
-            {...register('phone')}
-            className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
-          />
-        </div>
-
-        <div>
-          <label className="block text-sm font-medium text-gray-700 mb-1">新密码</label>
-          <input
-            {...register('password')}
-            type="password"
-            placeholder="留空则不修改密码"
-            className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
-          />
-        </div>
-
-        <div className="flex space-x-3 pt-4">
-          <button
-            type="submit"
-            disabled={isPending}
-            className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50"
-          >
-            {isPending ? '保存中...' : '保存'}
-          </button>
-          <button
-            type="button"
-            onClick={() => navigate(-1)}
-            className="px-4 py-2 bg-gray-200 text-gray-800 rounded-md hover:bg-gray-300 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2"
-          >
-            返回
-          </button>
-        </div>
-      </form>
+        
+        <button
+          onClick={() => navigate('/mobile/settings')}
+          className="w-full mt-4 py-2 bg-blue-100 text-blue-600 rounded-md hover:bg-blue-200 transition-colors"
+        >
+          编辑个人信息
+        </button>
       </div>
       
       <div className="bg-white rounded-lg shadow mb-4">

+ 110 - 0
client/mobile/pages_settings.tsx

@@ -0,0 +1,110 @@
+import React from 'react'
+import { useForm } from 'react-hook-form'
+import { useMutation } from '@tanstack/react-query'
+import { UserAPI } from './api.ts'
+import { useAuth } from './hooks.tsx'
+
+export default function SettingsPage() {
+  const { register, handleSubmit, formState: { errors } } = useForm<{
+    nickname: string
+    email: string
+    phone?: string
+    password?: string
+  }>()
+
+  const { mutate: updateUser, isPending } = useMutation({
+    mutationFn: async (data: {
+      nickname: string
+      email: string
+      phone?: string
+      password?: string
+    }) => {
+      const res = await UserAPI.getUsers({ limit: 1 })
+      if (!res.data?.[0]?.id) throw new Error('用户ID不存在')
+      return UserAPI.updateUser(res.data[0].id, {
+        nickname: data.nickname,
+        email: data.email,
+        phone: data.phone,
+        ...(data.password ? { password: data.password } : {})
+      })
+    },
+    onSuccess: () => alert('更新成功'),
+    onError: (error) => {
+      console.error('更新失败:', error)
+      alert('更新失败')
+    }
+  })
+
+  const onSubmit = (data: {
+    nickname: string
+    email: string
+    phone?: string
+    password?: string
+  }) => {
+    updateUser(data)
+  }
+
+  return (
+    <div className="p-4">
+      <h1 className="text-2xl font-bold mb-4">设置</h1>
+      
+      <div className="bg-white rounded-lg shadow p-4 mb-4">
+        <h2 className="text-lg font-semibold mb-4">编辑个人信息</h2>
+        <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
+          <div>
+            <label className="block text-sm font-medium text-gray-700 mb-1">昵称</label>
+            <input
+              {...register('nickname', { required: '请输入昵称' })}
+              className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
+            />
+            {errors.nickname && <p className="mt-1 text-sm text-red-600">{errors.nickname.message}</p>}
+          </div>
+
+          <div>
+            <label className="block text-sm font-medium text-gray-700 mb-1">邮箱</label>
+            <input
+              {...register('email', { 
+                required: '请输入邮箱',
+                pattern: {
+                  value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
+                  message: '请输入有效的邮箱地址'
+                }
+              })}
+              type="email"
+              className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
+            />
+            {errors.email && <p className="mt-1 text-sm text-red-600">{errors.email.message}</p>}
+          </div>
+
+          <div>
+            <label className="block text-sm font-medium text-gray-700 mb-1">手机号</label>
+            <input
+              {...register('phone')}
+              className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
+            />
+          </div>
+
+          <div>
+            <label className="block text-sm font-medium text-gray-700 mb-1">新密码</label>
+            <input
+              {...register('password')}
+              type="password"
+              placeholder="留空则不修改密码"
+              className="w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
+            />
+          </div>
+
+          <div className="flex space-x-3 pt-4">
+            <button
+              type="submit"
+              disabled={isPending}
+              className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 disabled:opacity-50"
+            >
+              {isPending ? '保存中...' : '保存'}
+            </button>
+          </div>
+        </form>
+      </div>
+    </div>
+  )
+}