Files
aiops/frontend/src/components/system/ResetPasswordDialog.tsx
T
attacker 72bfb0e12d fix(i18n): 回退到稳定的 32% 覆盖率状态 (tsc + Vite 构建通过)
批量转换脚本引入的语法错误已回退,保留稳定的 i18n 转换:
- 翻译词典: 22 namespaces, 3600+ keys
- 已接入: 145+ 文件 (Dashboard/Login/K8s 主页面/Monitor/System/Deploy)
- 语言切换器在 Header 中可用 (🇨🇳/🇺🇸)
- tsc 零错误, Vite 构建成功
2026-07-03 02:02:29 +08:00

97 lines
3.8 KiB
TypeScript

// 管理员重置用户密码弹窗 // Logan.Li
import { useState } 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 { Key, Loader2 } from 'lucide-react';
import { useToast } from '@/hooks/use-toast';
import { userApi } from '@/api';
import { useTranslation } from 'react-i18next';
interface ResetPasswordDialogProps {
user: { id: number | string; username?: string; nickname?: string; authSource?: string } | null;
onClose: () => void;
}
export function ResetPasswordDialog({ user, onClose }: ResetPasswordDialogProps) {
const { t } = useTranslation();
const { toast } = useToast();
const [password, setPassword] = useState('');
const [confirm, setConfirm] = useState('');
const [saving, setSaving] = useState(false);
const isLdap = user?.authSource === 'ldap';
const canSubmit = password.length >= 6 && password === confirm && !isLdap;
const handleReset = async () => {
if (!user || !canSubmit) return;
setSaving(true);
try {
await userApi.resetUserPassword(user.id, password);
toast({ title: t('system.passwordReset'), description: `用户 ${user.nickname || user.username} 的新密码已生效` });
setPassword('');
setConfirm('');
onClose();
} catch (e: any) {
toast({ title: t('system.resetFailed'), description: e?.message || String(e), variant: 'destructive' });
} finally {
setSaving(false);
}
};
return (
<Dialog open={!!user} onOpenChange={(open) => { if (!open) { setPassword(''); setConfirm(''); onClose(); } }}>
<DialogContent className="bg-[var(--dg-bg-secondary)] border-[var(--dg-border)] sm:max-w-md">
<DialogHeader>
<DialogTitle className="text-[var(--dg-text-primary)] flex items-center gap-2">
<Key className="h-5 w-5 text-[var(--dg-blue)]" />
{t('system.resetPassword')}
</DialogTitle>
<DialogDescription className="text-[var(--dg-text-muted)]">
{user ? `为「${user.nickname || user.username}」设置新密码` : ''}
</DialogDescription>
</DialogHeader>
{isLdap ? (
<p className="text-sm dg-text-yellow/90 py-2">{t('system.ldapResetHint')}</p>
) : (
<div className="space-y-3 py-1">
<div>
<Label className="text-xs text-[var(--dg-text-muted)]">{t('system.newPassword')}</Label>
<Input
type="password"
value={password}
onChange={e => setPassword(e.target.value)}
placeholder={t('system.passwordMinLen')}
className="mt-1 h-9 bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)]"
/>
</div>
<div>
<Label className="text-xs text-[var(--dg-text-muted)]">{t('system.userConfirmPassword')}</Label>
<Input
type="password"
value={confirm}
onChange={e => setConfirm(e.target.value)}
placeholder={t('system.confirmNewPassword')}
className="mt-1 h-9 bg-[var(--dg-bg-tertiary)] border-[var(--dg-border)]"
/>
</div>
</div>
)}
<DialogFooter>
<Button variant="outline" className="border-[var(--dg-border)]" onClick={onClose}>{t('common.cancel')}</Button>
{!isLdap && (
<Button onClick={handleReset} disabled={!canSubmit || saving} className="bg-[var(--dg-blue)] hover:opacity-90">
{saving ? <Loader2 className="h-4 w-4 animate-spin mr-1" /> : null}
确认重置
</Button>
)}
</DialogFooter>
</DialogContent>
</Dialog>
);
}