pages_settings.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. import React from 'react'
  2. import { useForm } from 'react-hook-form'
  3. import { useMutation } from '@tanstack/react-query'
  4. import { UserAPI } from './api.ts'
  5. import { useAuth } from './hooks.tsx'
  6. export default function SettingsPage() {
  7. const { register, handleSubmit, formState: { errors } } = useForm<{
  8. nickname: string
  9. email: string
  10. phone?: string
  11. password?: string
  12. }>()
  13. const { mutate: updateUser, isPending } = useMutation({
  14. mutationFn: async (data: {
  15. nickname: string
  16. email: string
  17. phone?: string
  18. password?: string
  19. }) => {
  20. return UserAPI.updateCurrentUser({
  21. nickname: data.nickname,
  22. email: data.email,
  23. phone: data.phone,
  24. ...(data.password ? { password: data.password } : {})
  25. })
  26. },
  27. onSuccess: () => alert('更新成功'),
  28. onError: (error) => {
  29. console.error('更新失败:', error)
  30. alert('更新失败')
  31. }
  32. })
  33. const onSubmit = (data: {
  34. nickname: string
  35. email: string
  36. phone?: string
  37. password?: string
  38. }) => {
  39. updateUser(data)
  40. }
  41. return (
  42. <div className="p-4">
  43. <h1 className="text-2xl font-bold mb-4">设置</h1>
  44. <div className="bg-white rounded-lg shadow p-4 mb-4">
  45. <h2 className="text-lg font-semibold mb-4">编辑个人信息</h2>
  46. <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
  47. <div>
  48. <label className="block text-sm font-medium text-gray-700 mb-1">昵称</label>
  49. <input
  50. {...register('nickname', { required: '请输入昵称' })}
  51. 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"
  52. />
  53. {errors.nickname && <p className="mt-1 text-sm text-red-600">{errors.nickname.message}</p>}
  54. </div>
  55. <div>
  56. <label className="block text-sm font-medium text-gray-700 mb-1">邮箱</label>
  57. <input
  58. {...register('email', {
  59. required: '请输入邮箱',
  60. pattern: {
  61. value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
  62. message: '请输入有效的邮箱地址'
  63. }
  64. })}
  65. type="email"
  66. 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"
  67. />
  68. {errors.email && <p className="mt-1 text-sm text-red-600">{errors.email.message}</p>}
  69. </div>
  70. <div>
  71. <label className="block text-sm font-medium text-gray-700 mb-1">手机号</label>
  72. <input
  73. {...register('phone')}
  74. 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"
  75. />
  76. </div>
  77. <div>
  78. <label className="block text-sm font-medium text-gray-700 mb-1">新密码</label>
  79. <input
  80. {...register('password')}
  81. type="password"
  82. placeholder="留空则不修改密码"
  83. 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"
  84. />
  85. </div>
  86. <div className="flex space-x-3 pt-4">
  87. <button
  88. type="submit"
  89. disabled={isPending}
  90. 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"
  91. >
  92. {isPending ? '保存中...' : '保存'}
  93. </button>
  94. </div>
  95. </form>
  96. </div>
  97. </div>
  98. )
  99. }