登录页面增加查看密码和记住密码

This commit is contained in:
mtvpls
2025-12-04 10:03:10 +08:00
parent 7df4530bcf
commit 2fc0390209

View File

@@ -2,7 +2,7 @@
'use client';
import { AlertCircle, CheckCircle } from 'lucide-react';
import { AlertCircle, CheckCircle, Eye, EyeOff } from 'lucide-react';
import { useRouter, useSearchParams } from 'next/navigation';
import { Suspense, useEffect, useState } from 'react';
@@ -75,6 +75,8 @@ function LoginPageClient() {
const [error, setError] = useState<string | null>(null);
const [loading, setLoading] = useState(false);
const [shouldAskUsername, setShouldAskUsername] = useState(false);
const [rememberPassword, setRememberPassword] = useState(false);
const [showPassword, setShowPassword] = useState(false);
const { siteName } = useSite();
@@ -82,7 +84,26 @@ function LoginPageClient() {
useEffect(() => {
if (typeof window !== 'undefined') {
const storageType = (window as any).RUNTIME_CONFIG?.STORAGE_TYPE;
setShouldAskUsername(storageType && storageType !== 'localstorage');
const shouldAsk = storageType && storageType !== 'localstorage';
setShouldAskUsername(shouldAsk);
// 从localStorage读取记住的密码信息
const rememberedCredentials = localStorage.getItem('rememberedCredentials');
if (rememberedCredentials) {
try {
const credentials = JSON.parse(rememberedCredentials);
if (credentials.password) {
setPassword(credentials.password);
}
if (credentials.username && shouldAsk) {
setUsername(credentials.username);
}
setRememberPassword(true);
} catch (error) {
// 清除无效的数据
localStorage.removeItem('rememberedCredentials');
}
}
}
}, []);
@@ -104,6 +125,19 @@ function LoginPageClient() {
});
if (res.ok) {
// 处理记住密码逻辑
if (rememberPassword) {
const credentials: any = { password };
// 如果需要用户名且有用户名,就保存用户名
if (shouldAskUsername && username) {
credentials.username = username;
}
localStorage.setItem('rememberedCredentials', JSON.stringify(credentials));
} else {
// 如果不记住密码,清除已存储的信息
localStorage.removeItem('rememberedCredentials');
}
const redirect = searchParams.get('redirect') || '/';
router.replace(redirect);
} else if (res.status === 401) {
@@ -152,21 +186,51 @@ function LoginPageClient() {
<label htmlFor='password' className='sr-only'>
</label>
<input
id='password'
type='password'
autoComplete='current-password'
className='block w-full rounded-lg border-0 py-3 px-4 text-gray-900 dark:text-gray-100 shadow-sm ring-1 ring-white/60 dark:ring-white/20 placeholder:text-gray-500 dark:placeholder:text-gray-400 focus:ring-2 focus:ring-green-500 focus:outline-none sm:text-base bg-white/60 dark:bg-zinc-800/60 backdrop-blur'
placeholder='输入访问密码'
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<div className='relative'>
<input
id='password'
type={showPassword ? 'text' : 'password'}
autoComplete='current-password'
className='block w-full rounded-lg border-0 py-3 px-4 pr-12 text-gray-900 dark:text-gray-100 shadow-sm ring-1 ring-white/60 dark:ring-white/20 placeholder:text-gray-500 dark:placeholder:text-gray-400 focus:ring-2 focus:ring-green-500 focus:outline-none sm:text-base bg-white/60 dark:bg-zinc-800/60 backdrop-blur'
placeholder='输入访问密码'
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<button
type='button'
className='absolute inset-y-0 right-0 flex items-center pr-3 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200'
onClick={() => setShowPassword(!showPassword)}
>
{showPassword ? (
<EyeOff className='h-5 w-5' />
) : (
<Eye className='h-5 w-5' />
)}
</button>
</div>
</div>
{error && (
<p className='text-sm text-red-600 dark:text-red-400'>{error}</p>
)}
{/* 记住密码复选框 */}
<div className='flex items-center'>
<input
id='remember-password'
type='checkbox'
className='h-4 w-4 rounded border-gray-300 text-green-600 focus:ring-green-500 dark:border-gray-600 dark:bg-gray-700'
checked={rememberPassword}
onChange={(e) => setRememberPassword(e.target.checked)}
/>
<label
htmlFor='remember-password'
className='ml-2 block text-sm text-gray-700 dark:text-gray-300'
>
</label>
</div>
{/* 登录按钮 */}
<button
type='submit'