mirror of
https://github.com/yyhuni/xingrin.git
synced 2026-02-10 00:13:17 +08:00
120 lines
3.5 KiB
TypeScript
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>
|
|
)
|
|
}
|