📚 Documentação inicial do ALETHEIA
- MANUAL-PRODUTO.md: Manual do usuário final - MANUAL-VENDAS.md: Estratégia comercial e vendas - MANUAL-TECNICO.md: Infraestrutura e deploy - README.md: Visão geral do projeto
This commit is contained in:
85
frontend/src/app/login/page.tsx
Normal file
85
frontend/src/app/login/page.tsx
Normal file
@@ -0,0 +1,85 @@
|
||||
'use client';
|
||||
import { useState } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import Link from 'next/link';
|
||||
import { useAuthStore } from '@/stores/authStore';
|
||||
|
||||
export default function LoginPage() {
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [error, setError] = useState('');
|
||||
const [loading, setLoading] = useState(false);
|
||||
const router = useRouter();
|
||||
const { setAuth } = useAuthStore();
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
setLoading(true);
|
||||
setError('');
|
||||
try {
|
||||
const API = process.env.NEXT_PUBLIC_API_URL || '';
|
||||
const res = await fetch(`${API}/api/auth/login`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email, password }),
|
||||
});
|
||||
const data = await res.json();
|
||||
if (!res.ok) throw new Error(data.detail || 'Credenciais inválidas');
|
||||
setAuth(data.access_token, data.user);
|
||||
router.push('/scan');
|
||||
} catch (err: any) {
|
||||
setError(err.message || 'Credenciais inválidas');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-dark flex items-center justify-center px-4 relative overflow-hidden">
|
||||
{/* Orbs */}
|
||||
<div className="orb orb-primary w-[400px] h-[400px] -top-[150px] -right-[100px]" />
|
||||
<div className="orb orb-accent w-[300px] h-[300px] bottom-[10%] -left-[100px]" />
|
||||
|
||||
<div className="relative z-10 w-full max-w-md animate-fade-up">
|
||||
{/* Logo */}
|
||||
<div className="text-center mb-10">
|
||||
<div className="w-16 h-16 rounded-2xl bg-gradient-to-br from-primary to-accent flex items-center justify-center mx-auto mb-4">
|
||||
<svg width="30" height="30" viewBox="0 0 24 24" fill="none" stroke="white" strokeWidth="2.5" strokeLinecap="round">
|
||||
<circle cx="12" cy="12" r="10" /><circle cx="12" cy="12" r="4" />
|
||||
</svg>
|
||||
</div>
|
||||
<h1 className="text-3xl font-black gradient-text">ALETHEIA</h1>
|
||||
<p className="text-gray-500 text-sm mt-1">A verdade sobre o que você come</p>
|
||||
</div>
|
||||
|
||||
<form onSubmit={handleSubmit} className="glass rounded-3xl p-10 space-y-5">
|
||||
<h2 className="text-xl font-bold">Entrar</h2>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm text-gray-400 mb-2">Email</label>
|
||||
<input type="email" value={email} onChange={e => setEmail(e.target.value)} required
|
||||
className="w-full px-4 py-3.5 rounded-xl bg-dark border border-dark-border text-white placeholder-gray-600 focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary/30 transition"
|
||||
placeholder="seu@email.com" />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm text-gray-400 mb-2">Senha</label>
|
||||
<input type="password" value={password} onChange={e => setPassword(e.target.value)} required
|
||||
className="w-full px-4 py-3.5 rounded-xl bg-dark border border-dark-border text-white placeholder-gray-600 focus:border-primary focus:outline-none focus:ring-1 focus:ring-primary/30 transition"
|
||||
placeholder="••••••••" />
|
||||
</div>
|
||||
|
||||
{error && <p className="text-danger text-sm">{error}</p>}
|
||||
|
||||
<button type="submit" disabled={loading} className="btn-glow w-full !text-center disabled:opacity-50">
|
||||
{loading ? 'Entrando...' : 'Entrar →'}
|
||||
</button>
|
||||
|
||||
<p className="text-center text-gray-500 text-sm">
|
||||
Não tem conta? <Link href="/register" className="text-primary hover:underline">Criar conta grátis</Link>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user