'use client' import { Suspense, useState, useMemo } from 'react' import { useSearchParams } from 'next/navigation' interface PasswordStrength { minLength: boolean hasUpper: boolean hasLower: boolean hasDigit: boolean hasSpecial: boolean score: number } function checkPassword(pw: string): PasswordStrength { const minLength = pw.length >= 8 const hasUpper = /[A-Z]/.test(pw) const hasLower = /[a-z]/.test(pw) const hasDigit = /[0-9]/.test(pw) const hasSpecial = /[^A-Za-z0-9]/.test(pw) const score = [hasUpper, hasLower, hasDigit, hasSpecial].filter(Boolean).length return { minLength, hasUpper, hasLower, hasDigit, hasSpecial, score } } const checks: { key: keyof PasswordStrength; label: string }[] = [ { key: 'minLength', label: '至少 8 位字符' }, { key: 'hasUpper', label: '包含大写字母' }, { key: 'hasLower', label: '包含小写字母' }, { key: 'hasDigit', label: '包含数字' }, { key: 'hasSpecial', label: '包含特殊字符' }, ] function SetupPasswordForm() { const searchParams = useSearchParams() const token = searchParams.get('token') || '' const [password, setPassword] = useState('') const [confirm, setConfirm] = useState('') const [error, setError] = useState('') const [success, setSuccess] = useState(false) const [loading, setLoading] = useState(false) const strength = useMemo(() => checkPassword(password), [password]) const isStrong = strength.minLength && strength.score >= 3 const passwordMismatch = confirm.length > 0 && password !== confirm async function handleSubmit(e: React.FormEvent) { e.preventDefault() setError('') if (!isStrong) { setError('请先满足密码复杂度要求') return } if (password !== confirm) { setError('两次输入的密码不一致') return } setLoading(true) try { const res = await fetch('/api/auth/setup-password', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ token, password }), }) const data = await res.json() if (!res.ok) { setError(data.error || '设置失败') } else { setSuccess(true) } } catch { setError('网络错误,请重试') } finally { setLoading(false) } } if (!token) { return (