import { memo, useEffect, useState } from 'react' import { Dice5 } from 'lucide-react' import { useTranslation } from 'react-i18next' import { Button } from '@/components/ui/button' import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, } from '@/components/ui/dialog' import { Label } from '@/components/ui/label' import { PasswordInput } from '@/components/PasswordInput' import { userApi } from '@/api' import { toast } from 'sonner' import type { User } from '@/types' // 随机密码:12 位,大小写字母 + 数字,满足后端 min=6 function randomPassword(): string { const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789' let pwd = '' const array = new Uint32Array(12) crypto.getRandomValues(array) for (let i = 0; i < 12; i++) { pwd += chars[array[i] % chars.length] } return pwd } interface ResetPasswordDialogProps { user: User | null onClose: () => void /** 重置成功回调(提示信息由调用方决定) */ onReset: () => void } /** 管理员重置密码弹窗 — 重置后目标用户全部旧会话立即失效(后端递增 TokenVersion) */ export const ResetPasswordDialog = memo(function ResetPasswordDialog({ user, onClose, onReset, }: ResetPasswordDialogProps) { const { t } = useTranslation('users') const [password, setPassword] = useState('') const [submitting, setSubmitting] = useState(false) const [error, setError] = useState('') useEffect(() => { if (user) { setPassword('') setError('') } }, [user]) const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() if (password.length < 6) { setError(t('form.passwordMin')) return } if (!user) return setSubmitting(true) try { await userApi.resetPassword(user.id, password) onClose() onReset() } catch (err) { toast.error(err instanceof Error ? err.message : t('resetFailed')) } finally { setSubmitting(false) } } return ( !open && onClose()}> {t('resetPassword')} {t('resetDesc', { name: user?.username ?? '' })}
{ setPassword(e.target.value) setError('') }} autoComplete="new-password" required />
{error &&

{error}

}
) })