mirror of
https://github.com/MoonTechLab/LunaTV.git
synced 2026-02-27 23:34:48 +08:00
92 lines
3.2 KiB
TypeScript
92 lines
3.2 KiB
TypeScript
'use client';
|
|
|
|
import { useRouter, useSearchParams } from 'next/navigation';
|
|
import { Suspense, useState } from 'react';
|
|
|
|
import { ThemeToggle } from '@/components/ThemeToggle';
|
|
|
|
function LoginPageClient() {
|
|
const router = useRouter();
|
|
const searchParams = useSearchParams();
|
|
const [password, setPassword] = useState('');
|
|
const [error, setError] = useState<string | null>(null);
|
|
const [loading, setLoading] = useState(false);
|
|
|
|
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
|
e.preventDefault();
|
|
setError(null);
|
|
|
|
if (!password) return;
|
|
|
|
try {
|
|
setLoading(true);
|
|
const res = await fetch('/api/login', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ password }),
|
|
});
|
|
|
|
if (res.ok) {
|
|
const redirect = searchParams.get('redirect') || '/';
|
|
router.replace(redirect);
|
|
} else if (res.status === 401) {
|
|
setError('密码错误');
|
|
} else {
|
|
const data = await res.json().catch(() => ({}));
|
|
setError(data.error ?? '服务器错误');
|
|
}
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className='relative min-h-screen flex items-center justify-center px-4 overflow-hidden'>
|
|
<div className='absolute top-4 right-4'>
|
|
<ThemeToggle />
|
|
</div>
|
|
<div className='relative z-10 w-full max-w-md rounded-3xl bg-gradient-to-b from-white/90 via-white/70 to-white/40 dark:from-zinc-900/90 dark:via-zinc-900/70 dark:to-zinc-900/40 backdrop-blur-xl shadow-2xl p-10 dark:border dark:border-zinc-800'>
|
|
<h1 className='text-green-600 tracking-tight text-center text-3xl font-extrabold mb-8 bg-clip-text drop-shadow-sm'>
|
|
MoonTV
|
|
</h1>
|
|
<form onSubmit={handleSubmit} className='space-y-8'>
|
|
<div>
|
|
<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>
|
|
|
|
{error && (
|
|
<p className='text-sm text-red-600 dark:text-red-400'>{error}</p>
|
|
)}
|
|
|
|
<button
|
|
type='submit'
|
|
disabled={!password || loading}
|
|
className='inline-flex w-full justify-center rounded-lg bg-green-600 py-3 text-base font-semibold text-white shadow-lg transition-all duration-200 hover:from-green-600 hover:to-blue-600 disabled:cursor-not-allowed disabled:opacity-50'
|
|
>
|
|
{loading ? '登录中...' : '登录'}
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default function LoginPage() {
|
|
return (
|
|
<Suspense>
|
|
<LoginPageClient />
|
|
</Suspense>
|
|
);
|
|
}
|