完善个人中心页面

This commit is contained in:
Eamon
2026-09-04 13:21:47 +08:00
parent 6d6d300203
commit f59e929843
27 changed files with 614 additions and 414 deletions

View File

@@ -1,8 +1,9 @@
import { zodResolver } from "@hookform/resolvers/zod"
import { Eye, EyeOff } from "lucide-react"
import { useEffect, useState } from "react"
import { Controller, useForm } from "react-hook-form"
import { toast } from "sonner"
import { z } from "zod"
import { updateUserInfo } from "@/api/user"
import { Button } from "@/components/ui/button"
import {
Dialog,
@@ -15,51 +16,45 @@ import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
export type EditInfoValues = {
username: string
taobao: string
password: string
email: string
wechat: string
qq: string
wechat: string
taobao: string
email: string
}
const editInfoSchema = z.object({
username: z.string().trim().min(1, "请输入用户名"),
qq: z.string(),
wechat: z.string(),
taobao: z.string(),
password: z.string().min(1, "请输入密码"),
email: z
.string()
.refine(
v => !v || /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v),
"请输入正确的邮箱",
),
wechat: z.string(),
qq: z.string(),
})
interface EditInfoDialogProps {
open: boolean
onOpenChange: (open: boolean) => void
initialData?: EditInfoValues
onSave?: (data: EditInfoValues) => void
onSaved?: () => void
}
const DEFAULT_INITIAL_DATA: EditInfoValues = {
username: "191****1234",
taobao: "191****1234",
password: "********",
email: "123456123@qq.com",
wechat: "",
qq: "",
wechat: "",
taobao: "",
email: "",
}
export function EditInfoDialog({
open,
onOpenChange,
initialData = DEFAULT_INITIAL_DATA,
onSave,
onSaved,
}: EditInfoDialogProps) {
const [showPassword, setShowPassword] = useState(false)
const [submitting, setSubmitting] = useState(false)
const form = useForm<EditInfoValues>({
resolver: zodResolver(editInfoSchema),
@@ -72,9 +67,23 @@ export function EditInfoDialog({
}
}, [open, initialData, form])
const onSubmit = (data: EditInfoValues) => {
onSave?.(data)
const onSubmit = async (data: EditInfoValues) => {
setSubmitting(true)
const res = await updateUserInfo({
QQ: data.qq,
Wx: data.wechat,
TaoBao: data.taobao,
Email: data.email,
})
setSubmitting(false)
if (!res.success) {
toast.error(res.message)
return
}
toast.success("保存成功")
onOpenChange(false)
onSaved?.()
}
return (
@@ -88,18 +97,23 @@ export function EditInfoDialog({
<form className="space-y-4 mt-2" onSubmit={form.handleSubmit(onSubmit)}>
<div className="space-y-1.5">
<Label className="text-sm text-gray-600">用户名</Label>
<Label className="text-sm text-gray-600">QQ号</Label>
<Controller
name="username"
name="qq"
control={form.control}
render={({ field, fieldState }) => (
<>
<Input
{...field}
className="h-11 bg-gray-50 border-gray-200"
/>
<FieldError>{fieldState.error?.message}</FieldError>
</>
render={({ field }) => (
<Input {...field} className="h-11 bg-gray-50 border-gray-200" />
)}
/>
</div>
<div className="space-y-1.5">
<Label className="text-sm text-gray-600">微信号</Label>
<Controller
name="wechat"
control={form.control}
render={({ field }) => (
<Input {...field} className="h-11 bg-gray-50 border-gray-200" />
)}
/>
</div>
@@ -115,37 +129,6 @@ export function EditInfoDialog({
/>
</div>
<div className="space-y-1.5">
<Label className="text-sm text-gray-600">密码</Label>
<Controller
name="password"
control={form.control}
render={({ field, fieldState }) => (
<>
<div className="relative">
<Input
{...field}
type={showPassword ? "text" : "password"}
className="h-11 bg-gray-50 border-gray-200 pr-10"
/>
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600"
>
{showPassword ? (
<EyeOff className="h-4 w-4" />
) : (
<Eye className="h-4 w-4" />
)}
</button>
</div>
<FieldError>{fieldState.error?.message}</FieldError>
</>
)}
/>
</div>
<div className="space-y-1.5">
<Label className="text-sm text-gray-600">邮箱</Label>
<Controller
@@ -163,41 +146,12 @@ export function EditInfoDialog({
/>
</div>
<div className="space-y-1.5">
<Label className="text-sm text-gray-600">微信</Label>
<Controller
name="wechat"
control={form.control}
render={({ field }) => (
<Input
{...field}
placeholder="请输入"
className="h-11 bg-gray-50 border-gray-200"
/>
)}
/>
</div>
<div className="space-y-1.5">
<Label className="text-sm text-gray-600">QQ</Label>
<Controller
name="qq"
control={form.control}
render={({ field }) => (
<Input
{...field}
placeholder="请输入"
className="h-11 bg-gray-50 border-gray-200"
/>
)}
/>
</div>
<Button
type="submit"
disabled={submitting}
className="w-full h-11 mt-2 bg-blue-600 hover:bg-blue-700 text-white font-medium"
>
保存
{submitting ? "保存中..." : "保存"}
</Button>
</form>
</DialogContent>