Files
xingrin/frontend/components/auth/change-password-dialog.tsx
2025-12-12 18:04:57 +08:00

120 lines
3.5 KiB
TypeScript

"use client"
import React from "react"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog"
import { useChangePassword } from "@/hooks/use-auth"
import { getErrorMessage } from "@/lib/api-client"
interface ChangePasswordDialogProps {
open: boolean
onOpenChange: (open: boolean) => void
}
export function ChangePasswordDialog({ open, onOpenChange }: ChangePasswordDialogProps) {
const [oldPassword, setOldPassword] = React.useState("")
const [newPassword, setNewPassword] = React.useState("")
const [confirmPassword, setConfirmPassword] = React.useState("")
const [error, setError] = React.useState("")
const { mutate: changePassword, isPending } = useChangePassword()
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault()
setError("")
if (newPassword !== confirmPassword) {
setError("新密码与确认密码不一致")
return
}
if (newPassword.length < 4) {
setError("新密码长度至少 4 位")
return
}
changePassword(
{ oldPassword, newPassword },
{
onSuccess: () => {
onOpenChange(false)
setOldPassword("")
setNewPassword("")
setConfirmPassword("")
},
onError: (err: unknown) => {
setError(getErrorMessage(err))
},
}
)
}
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-[400px]">
<DialogHeader>
<DialogTitle></DialogTitle>
<DialogDescription>
</DialogDescription>
</DialogHeader>
<form onSubmit={handleSubmit}>
<div className="grid gap-4 py-4">
<div className="grid gap-2">
<Label htmlFor="oldPassword"></Label>
<Input
id="oldPassword"
type="password"
value={oldPassword}
onChange={(e) => setOldPassword(e.target.value)}
required
autoFocus
/>
</div>
<div className="grid gap-2">
<Label htmlFor="newPassword"></Label>
<Input
id="newPassword"
type="password"
value={newPassword}
onChange={(e) => setNewPassword(e.target.value)}
required
/>
</div>
<div className="grid gap-2">
<Label htmlFor="confirmPassword"></Label>
<Input
id="confirmPassword"
type="password"
value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)}
required
/>
</div>
{error && (
<p className="text-sm text-destructive">{error}</p>
)}
</div>
<DialogFooter>
<Button type="button" variant="outline" onClick={() => onOpenChange(false)}>
</Button>
<Button type="submit" disabled={isPending}>
{isPending ? "保存中..." : "保存"}
</Button>
</DialogFooter>
</form>
</DialogContent>
</Dialog>
)
}