Initial commit

This commit is contained in:
2026-04-28 22:36:56 +08:00
commit 071ebf4b2a
26 changed files with 5853 additions and 0 deletions

View File

@@ -0,0 +1,97 @@
import React, { useState } from 'react';
import { BrainCircuit } from 'lucide-react';
import { cn } from '../../lib/utils';
interface LoginProps {
onLoginSuccess: (token: string) => void;
}
export function Login({ onLoginSuccess }: LoginProps) {
const [username, setUsername] = useState('admin');
const [password, setPassword] = useState('123456');
const [error, setError] = useState('');
const [isLoading, setIsLoading] = useState(false);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setError('');
setIsLoading(true);
try {
const response = await fetch('/api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password }),
});
if (response.ok) {
const data = await response.json();
onLoginSuccess(data.token);
} else {
const errData = await response.json();
setError(errData.error || '登录失败');
}
} catch (err) {
setError('网络异常,无法连接到后端验证');
} finally {
setIsLoading(false);
}
};
return (
<div className="flex h-screen w-full items-center justify-center bg-[#0a0a0a] text-gray-200">
<div className="absolute inset-0 z-0 opacity-10 bg-[radial-gradient(ellipse_at_center,_var(--tw-gradient-stops))] from-cyan-500 via-[#0a0a0a] to-transparent pointer-events-none"></div>
<div className="relative z-10 w-full max-w-md p-8 bg-[#111] border border-white/5 rounded-2xl shadow-2xl scale-in shadow-black/50">
<div className="flex flex-col items-center mb-8">
<div className="w-16 h-16 bg-white rounded-2xl flex items-center justify-center text-cyan-500 shadow-lg shadow-cyan-500/20 mb-4 overflow-hidden border border-white/10">
<img src="/Logo.png" alt="Logo" className="w-full h-full object-cover" />
</div>
<h1 className="text-2xl font-bold text-white tracking-wider mb-2"></h1>
<p className="text-sm text-gray-500">AI </p>
</div>
<form onSubmit={handleSubmit} className="space-y-6">
<div>
<label className="block text-xs font-medium text-gray-400 uppercase tracking-widest mb-2"></label>
<input
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
className="w-full bg-[#1a1a1a] border border-white/10 rounded-lg px-4 py-3 text-sm focus:outline-none focus:border-cyan-500/50 focus:ring-1 focus:ring-cyan-500/50 transition-all font-mono"
placeholder="输入账号"
/>
</div>
<div>
<label className="block text-xs font-medium text-gray-400 uppercase tracking-widest mb-2"></label>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
className="w-full bg-[#1a1a1a] border border-white/10 rounded-lg px-4 py-3 text-sm focus:outline-none focus:border-cyan-500/50 focus:ring-1 focus:ring-cyan-500/50 transition-all font-mono"
placeholder="输入密码"
/>
</div>
{error && <div className="text-red-400 text-sm font-medium p-3 bg-red-400/10 rounded-lg border border-red-500/20 text-center">{error}</div>}
<button
type="submit"
disabled={isLoading}
className={cn(
"w-full py-3.5 rounded-lg flex items-center justify-center gap-2 transition-all shadow-lg font-bold tracking-wider text-sm",
isLoading ? "bg-cyan-500/50 cursor-not-allowed" : "bg-cyan-500 hover:bg-cyan-400 text-black shadow-cyan-500/20 hover:shadow-cyan-500/40"
)}
>
{isLoading ? '验证中...' : '安全登录'}
</button>
</form>
<div className="mt-8 pt-6 border-t border-white/5 text-center px-4">
<p className="text-[10px] text-gray-600">访</p>
</div>
</div>
</div>
);
}