flnxi-Wu/components/ChangePasswordModal.tsx
WuYongJie f646b71813
Some checks failed
CI Check / check (push) Has been cancelled
chore: 初始化本地仓库并同步最近改动
2025-11-18 17:50:16 +08:00

191 lines
6.2 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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'
interface ChangePasswordModalProps {
isOpen: boolean
onClose: () => void
isRequired?: boolean // 是否强制修改(首次登录)
onSuccess?: () => void
}
export default function ChangePasswordModal({
isOpen,
onClose,
isRequired = false,
onSuccess
}: ChangePasswordModalProps) {
const [oldPassword, setOldPassword] = useState('')
const [newPassword, setNewPassword] = useState('')
const [confirmPassword, setConfirmPassword] = useState('')
const [error, setError] = useState('')
const [loading, setLoading] = useState(false)
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
setError('')
if (!newPassword || !confirmPassword) {
setError('请填写所有字段')
return
}
if (newPassword.length < 6) {
setError('新密码长度至少为6位')
return
}
if (newPassword !== confirmPassword) {
setError('两次输入的密码不一致')
return
}
setLoading(true)
try {
const response = await fetch('/api/user/change-password', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
oldPassword: isRequired ? '88888888' : oldPassword,
newPassword
}),
})
const data = await response.json()
if (response.ok) {
// 清空表单
setOldPassword('')
setNewPassword('')
setConfirmPassword('')
setError('')
if (onSuccess) {
onSuccess()
} else {
onClose()
}
// 显示成功消息
alert('密码修改成功!')
} else {
setError(data.error || '修改密码失败')
}
} catch (error) {
console.error('修改密码错误:', error)
setError('修改密码失败,请稍后重试')
} finally {
setLoading(false)
}
}
if (!isOpen) return null
return (
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-[300] p-4">
<div className="bg-white dark:bg-gray-800 rounded-lg shadow-xl max-w-md w-full p-6">
<div className="flex items-center justify-between mb-4">
<h3 className="text-lg font-semibold text-gray-900 dark:text-white">
{isRequired ? '首次登录,请修改密码' : '修改密码'}
</h3>
{!isRequired && (
<button
onClick={onClose}
className="text-gray-400 hover:text-gray-600 dark:hover:text-gray-300"
>
<svg className="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
)}
</div>
{isRequired && (
<div className="mb-4 p-3 bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg">
<p className="text-sm text-yellow-800 dark:text-yellow-200">
⚠️ 您正在使用默认密码,为了账户安全,请立即修改密码。
</p>
</div>
)}
<form onSubmit={handleSubmit} className="space-y-4">
{!isRequired && (
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
旧密码
</label>
<input
type="password"
value={oldPassword}
onChange={(e) => setOldPassword(e.target.value)}
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white rounded-lg focus:ring-2 focus:ring-blue-500 outline-none"
placeholder="请输入旧密码"
required={!isRequired}
/>
</div>
)}
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
新密码
</label>
<input
type="password"
value={newPassword}
onChange={(e) => setNewPassword(e.target.value)}
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white rounded-lg focus:ring-2 focus:ring-blue-500 outline-none"
placeholder="请输入新密码(至少6位)"
required
minLength={6}
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
确认新密码
</label>
<input
type="password"
value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)}
className="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white rounded-lg focus:ring-2 focus:ring-blue-500 outline-none"
placeholder="请再次输入新密码"
required
minLength={6}
/>
</div>
{error && (
<div className="p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg">
<p className="text-sm text-red-800 dark:text-red-200">{error}</p>
</div>
)}
<div className="flex gap-3 justify-end">
{!isRequired && (
<button
type="button"
onClick={onClose}
className="px-4 py-2 border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-300 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors"
>
取消
</button>
)}
<button
type="submit"
disabled={loading}
className="px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
>
{loading ? '修改中...' : '确认修改'}
</button>
</div>
</form>
</div>
</div>
)
}