Your Name 37ac749071 fix: 修复前端代码质量问题
- 创建 Toast 通知组件,替换所有 alert() 调用
- 修复 useReview hook 内存泄漏(setInterval 清理)
- 移除所有 console.error 和 console.log 语句
- 为复制操作失败添加用户友好的 toast 提示

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-09 12:48:22 +08:00

243 lines
9.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

'use client'
import { useState } from 'react'
import { useRouter } from 'next/navigation'
import { useToast } from '@/components/ui/Toast'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/Card'
import { Button } from '@/components/ui/Button'
import { Input } from '@/components/ui/Input'
import {
ArrowLeft,
Lock,
Shield,
Smartphone,
Mail,
Key,
Eye,
EyeOff,
CheckCircle,
AlertTriangle
} from 'lucide-react'
export default function AgencyAccountSettingsPage() {
const router = useRouter()
const toast = useToast()
const [showOldPassword, setShowOldPassword] = useState(false)
const [showNewPassword, setShowNewPassword] = useState(false)
const [showConfirmPassword, setShowConfirmPassword] = useState(false)
const [passwordForm, setPasswordForm] = useState({
oldPassword: '',
newPassword: '',
confirmPassword: '',
})
const [isSaving, setIsSaving] = useState(false)
// 模拟账号安全状态
const securityStatus = {
phone: { bound: true, value: '138****8888' },
email: { bound: true, value: 'zhang@starmedia.com' },
twoFactor: { enabled: false },
}
const handleChangePassword = async () => {
if (!passwordForm.oldPassword || !passwordForm.newPassword || !passwordForm.confirmPassword) {
toast.error('请填写完整密码信息')
return
}
if (passwordForm.newPassword !== passwordForm.confirmPassword) {
toast.error('两次输入的新密码不一致')
return
}
if (passwordForm.newPassword.length < 8) {
toast.error('新密码长度不能少于8位')
return
}
setIsSaving(true)
await new Promise(resolve => setTimeout(resolve, 1000))
setIsSaving(false)
toast.success('密码修改成功')
setPasswordForm({ oldPassword: '', newPassword: '', confirmPassword: '' })
}
return (
<div className="space-y-6">
{/* 顶部导航 */}
<div className="flex items-center gap-4">
<button
type="button"
onClick={() => router.back()}
className="p-2 rounded-lg hover:bg-bg-elevated transition-colors"
>
<ArrowLeft size={20} className="text-text-secondary" />
</button>
<div>
<h1 className="text-2xl font-bold text-text-primary"></h1>
<p className="text-sm text-text-secondary mt-0.5"></p>
</div>
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
{/* 修改密码 */}
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Lock size={18} className="text-accent-indigo" />
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div>
<label className="text-sm text-text-secondary mb-1.5 block"></label>
<div className="relative">
<Input
type={showOldPassword ? 'text' : 'password'}
value={passwordForm.oldPassword}
onChange={(e) => setPasswordForm({ ...passwordForm, oldPassword: e.target.value })}
placeholder="请输入当前密码"
/>
<button
type="button"
onClick={() => setShowOldPassword(!showOldPassword)}
className="absolute right-3 top-1/2 -translate-y-1/2 text-text-tertiary hover:text-text-secondary"
>
{showOldPassword ? <EyeOff size={18} /> : <Eye size={18} />}
</button>
</div>
</div>
<div>
<label className="text-sm text-text-secondary mb-1.5 block"></label>
<div className="relative">
<Input
type={showNewPassword ? 'text' : 'password'}
value={passwordForm.newPassword}
onChange={(e) => setPasswordForm({ ...passwordForm, newPassword: e.target.value })}
placeholder="请输入新密码至少8位"
/>
<button
type="button"
onClick={() => setShowNewPassword(!showNewPassword)}
className="absolute right-3 top-1/2 -translate-y-1/2 text-text-tertiary hover:text-text-secondary"
>
{showNewPassword ? <EyeOff size={18} /> : <Eye size={18} />}
</button>
</div>
</div>
<div>
<label className="text-sm text-text-secondary mb-1.5 block"></label>
<div className="relative">
<Input
type={showConfirmPassword ? 'text' : 'password'}
value={passwordForm.confirmPassword}
onChange={(e) => setPasswordForm({ ...passwordForm, confirmPassword: e.target.value })}
placeholder="请再次输入新密码"
/>
<button
type="button"
onClick={() => setShowConfirmPassword(!showConfirmPassword)}
className="absolute right-3 top-1/2 -translate-y-1/2 text-text-tertiary hover:text-text-secondary"
>
{showConfirmPassword ? <EyeOff size={18} /> : <Eye size={18} />}
</button>
</div>
</div>
<Button
variant="primary"
className="w-full"
onClick={handleChangePassword}
disabled={isSaving}
>
{isSaving ? '保存中...' : '确认修改'}
</Button>
</CardContent>
</Card>
{/* 账号安全 */}
<Card>
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Shield size={18} className="text-accent-green" />
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
{/* 手机绑定 */}
<div className="flex items-center justify-between p-4 rounded-xl bg-bg-elevated">
<div className="flex items-center gap-3">
<div className="w-10 h-10 rounded-lg bg-accent-indigo/15 flex items-center justify-center">
<Smartphone size={20} className="text-accent-indigo" />
</div>
<div>
<p className="font-medium text-text-primary"></p>
<p className="text-sm text-text-secondary">
{securityStatus.phone.bound ? securityStatus.phone.value : '未绑定'}
</p>
</div>
</div>
<div className="flex items-center gap-2">
{securityStatus.phone.bound ? (
<CheckCircle size={18} className="text-accent-green" />
) : (
<AlertTriangle size={18} className="text-accent-amber" />
)}
<Button variant="secondary" size="sm">
{securityStatus.phone.bound ? '更换' : '绑定'}
</Button>
</div>
</div>
{/* 邮箱绑定 */}
<div className="flex items-center justify-between p-4 rounded-xl bg-bg-elevated">
<div className="flex items-center gap-3">
<div className="w-10 h-10 rounded-lg bg-accent-blue/15 flex items-center justify-center">
<Mail size={20} className="text-accent-blue" />
</div>
<div>
<p className="font-medium text-text-primary"></p>
<p className="text-sm text-text-secondary">
{securityStatus.email.bound ? securityStatus.email.value : '未绑定'}
</p>
</div>
</div>
<div className="flex items-center gap-2">
{securityStatus.email.bound ? (
<CheckCircle size={18} className="text-accent-green" />
) : (
<AlertTriangle size={18} className="text-accent-amber" />
)}
<Button variant="secondary" size="sm">
{securityStatus.email.bound ? '更换' : '绑定'}
</Button>
</div>
</div>
{/* 两步验证 */}
<div className="flex items-center justify-between p-4 rounded-xl bg-bg-elevated">
<div className="flex items-center gap-3">
<div className="w-10 h-10 rounded-lg bg-accent-amber/15 flex items-center justify-center">
<Key size={20} className="text-accent-amber" />
</div>
<div>
<p className="font-medium text-text-primary"></p>
<p className="text-sm text-text-secondary">
{securityStatus.twoFactor.enabled ? '已开启' : '未开启,建议开启以增强安全'}
</p>
</div>
</div>
<div className="flex items-center gap-2">
{securityStatus.twoFactor.enabled ? (
<CheckCircle size={18} className="text-accent-green" />
) : (
<AlertTriangle size={18} className="text-accent-amber" />
)}
<Button variant="secondary" size="sm">
{securityStatus.twoFactor.enabled ? '关闭' : '开启'}
</Button>
</div>
</div>
</CardContent>
</Card>
</div>
</div>
)
}