138 lines
6.5 KiB
TypeScript
138 lines
6.5 KiB
TypeScript
|
|
import React, { useState } from 'react';
|
|
import Link from 'next/link';
|
|
import { useRouter } from 'next/router';
|
|
import { Hexagon, ArrowRight, Lock, User } from 'lucide-react';
|
|
import Head from 'next/head';
|
|
|
|
export default function LoginPage() {
|
|
const router = useRouter();
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState('');
|
|
|
|
const handleLogin = async (e: React.FormEvent<HTMLFormElement>) => {
|
|
e.preventDefault();
|
|
setLoading(true);
|
|
setError('');
|
|
|
|
const formData = new FormData(e.currentTarget);
|
|
const username = formData.get('username') as string;
|
|
const password = formData.get('password') as string;
|
|
|
|
try {
|
|
const response = await fetch('/api/v1/auth/login', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ username, password })
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (data.success) {
|
|
// Also set REAL mode after successful login
|
|
localStorage.setItem('NEXUS_DATA_MODE', 'REAL');
|
|
router.push('/');
|
|
} else {
|
|
setError(data.error || 'Login failed');
|
|
}
|
|
} catch (err) {
|
|
setError('Network error. Please try again.');
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="min-h-screen flex items-center justify-center relative overflow-hidden bg-[#020202]">
|
|
<Head>
|
|
<title>NEXUS_MAT.OS</title>
|
|
</Head>
|
|
|
|
{/* Animated Background */}
|
|
<div className="absolute inset-0 bg-[url('https://grainy-gradients.vercel.app/noise.svg')] opacity-20"></div>
|
|
<div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[800px] h-[800px] bg-cyber-neon/5 rounded-full blur-[100px] pointer-events-none"></div>
|
|
|
|
<div className="w-full max-w-md p-8 relative z-10">
|
|
<div className="mb-10 text-center">
|
|
<Link href="/" className="inline-flex items-center gap-2 group cursor-pointer mb-6">
|
|
<Hexagon className="text-cyber-neon w-10 h-10 group-hover:rotate-180 transition-transform duration-700" />
|
|
<span className="text-3xl font-mono font-bold tracking-tighter text-white">
|
|
NEXUS_MAT<span className="text-cyber-neon">.OS</span>
|
|
</span>
|
|
</Link>
|
|
<h2 className="text-gray-400 font-mono text-sm tracking-widest">IDENTITY_VERIFICATION_PROTOCOL</h2>
|
|
</div>
|
|
|
|
<div className="bg-cyber-panel/40 backdrop-blur-md border border-white/10 p-8 rounded-lg shadow-2xl relative overflow-hidden group">
|
|
{/* Border Gradient Animation */}
|
|
<div className="absolute inset-0 border border-cyber-neon/0 group-hover:border-cyber-neon/50 transition-colors duration-500 rounded-lg pointer-events-none"></div>
|
|
|
|
<form onSubmit={handleLogin} className="space-y-6">
|
|
<div className="space-y-2">
|
|
<label className="text-xs font-mono text-cyber-neon">USER_ID</label>
|
|
<div className="relative">
|
|
<input
|
|
name="username"
|
|
type="text"
|
|
className="w-full bg-black/50 border border-gray-800 focus:border-cyber-neon text-white p-3 pl-10 rounded-sm outline-none transition-all font-mono"
|
|
placeholder="Enter username"
|
|
required
|
|
/>
|
|
<User className="absolute left-3 top-3 text-gray-500 w-4 h-4" />
|
|
</div>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<label className="text-xs font-mono text-cyber-neon">ACCESS_KEY</label>
|
|
<div className="relative">
|
|
<input
|
|
name="password"
|
|
type="password"
|
|
className="w-full bg-black/50 border border-gray-800 focus:border-cyber-neon text-white p-3 pl-10 rounded-sm outline-none transition-all font-mono"
|
|
placeholder="••••••••"
|
|
required
|
|
/>
|
|
<Lock className="absolute left-3 top-3 text-gray-500 w-4 h-4" />
|
|
</div>
|
|
</div>
|
|
|
|
{error && (
|
|
<div className="bg-red-900/20 border border-red-500 text-red-500 p-3 rounded text-xs font-mono">
|
|
{error}
|
|
</div>
|
|
)}
|
|
|
|
<button
|
|
type="submit"
|
|
disabled={loading}
|
|
className="w-full bg-cyber-neon text-black font-bold py-3 mt-4 hover:bg-white transition-colors flex items-center justify-center gap-2 font-mono uppercase tracking-wider"
|
|
>
|
|
{loading ? 'AUTHENTICATING...' : (
|
|
<>
|
|
INITIATE_SESSION <ArrowRight size={16} />
|
|
</>
|
|
)}
|
|
</button>
|
|
</form>
|
|
|
|
<div className="mt-6 flex justify-between items-center text-xs font-mono text-gray-500">
|
|
<Link href="/auth/register" className="hover:text-cyber-neon transition-colors">
|
|
[ CREATE_NEW_IDENTITY ]
|
|
</Link>
|
|
<a href="#" className="hover:text-white transition-colors">
|
|
FORGOT_KEY?
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="mt-8 text-center">
|
|
<p className="text-[10px] text-gray-700 font-mono">
|
|
SECURE CONNECTION ESTABLISHED <br />
|
|
ENCRYPTION: AES-256-GCM
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|