SportBuddy/apps/frontend/src/app/auth/signin/page.tsx
2025-10-26 15:44:27 +01:00

158 lines
6.4 KiB
TypeScript

'use client';
import { useState } from 'react';
import { signIn } from '@/lib/auth-client';
import { useRouter } from 'next/navigation';
import Link from 'next/link';
import { Button } from '@/components/ui/Button';
import { Input } from '@/components/ui/Input';
export default function SignInPage() {
const router = useRouter();
const [formData, setFormData] = useState({
email: '',
password: '',
});
const [errors, setErrors] = useState<Record<string, string>>({});
const [isLoading, setIsLoading] = useState(false);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setIsLoading(true);
setErrors({});
// Basic validation
if (!formData.email || !formData.password) {
setErrors({ general: 'Všetky polia sú povinné' });
setIsLoading(false);
return;
}
try {
await signIn.email({
email: formData.email,
password: formData.password,
}, {
onSuccess: () => {
router.push('/dashboard');
router.refresh();
},
onError: (ctx) => {
setErrors({ general: ctx.error.message || 'Nesprávny email alebo heslo' });
},
});
} catch (error) {
setErrors({ general: 'Nastala chyba. Skúste to znova.' });
} finally {
setIsLoading(false);
}
};
return (
<main className="min-h-screen flex items-center justify-center p-4">
<div className="w-full max-w-md">
{/* Back Button */}
<Link
href="/"
className="inline-flex items-center gap-2 text-[color:var(--fluent-text-secondary)] hover:text-[color:var(--fluent-accent)] transition-colors duration-150 mb-6 group"
>
<svg className="w-5 h-5 transition-transform duration-150 group-hover:-translate-x-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M10 19l-7-7m0 0l7-7m-7 7h18" />
</svg>
<span className="text-[15px] font-medium">Späť na hlavnú stránku</span>
</Link>
{/* Header */}
<div className="text-center mb-10">
<div className="inline-flex items-center justify-center w-20 h-20 gradient-primary rounded-xl mb-5" style={{ boxShadow: 'var(--shadow-md)' }}>
<svg className="w-10 h-10 text-[color:var(--fluent-text-secondary)]" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12 2L2 7L12 12L22 7L12 2Z" fill="currentColor" fillOpacity="0.9"/>
<path d="M2 17L12 22L22 17" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
<path d="M2 12L12 17L22 12" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
<circle cx="12" cy="7" r="1.5" fill="rgba(250, 250, 250, 0.95)"/>
</svg>
</div>
<h1 className="text-4xl font-bold text-[color:var(--fluent-text)] mb-3">
Vitajte späť!
</h1>
<p className="text-lg text-[color:var(--fluent-text-secondary)]">
Prihláste sa do svojho účtu
</p>
</div>
{/* Form */}
<div className="acrylic-strong border border-[color:var(--fluent-border)] rounded-xl p-10 reveal-effect transition-all duration-200" style={{ boxShadow: 'var(--shadow-lg)' }}>
{errors.general && (
<div className="mb-6 p-4 bg-red-50/80 border-2 border-red-200 rounded-lg text-red-600 text-base font-medium dark:bg-red-900/30 dark:border-red-800 dark:text-red-400">
{errors.general}
</div>
)}
<form onSubmit={handleSubmit} className="space-y-6">
<div>
<label htmlFor="email" className="block text-base font-semibold text-[color:var(--fluent-text)] mb-2">
Email
</label>
<Input
id="email"
type="email"
value={formData.email}
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
placeholder="jan.novak@email.com"
disabled={isLoading}
autoComplete="email"
/>
</div>
<div>
<label htmlFor="password" className="block text-base font-semibold text-[color:var(--fluent-text)] mb-2">
Heslo
</label>
<Input
id="password"
type="password"
value={formData.password}
onChange={(e) => setFormData({ ...formData, password: e.target.value })}
placeholder="••••••••"
disabled={isLoading}
autoComplete="current-password"
/>
</div>
<div className="flex items-center justify-between text-base">
<label className="flex items-center cursor-pointer group">
<input
type="checkbox"
className="w-5 h-5 text-blue-600 border-2 border-[color:var(--fluent-border-strong)] rounded-full focus:ring-2 focus:ring-blue-500 focus:ring-offset-0 transition-all duration-200 cursor-pointer hover:border-blue-500"
/>
<span className="ml-2.5 text-[color:var(--fluent-text-secondary)] font-medium group-hover:text-[color:var(--fluent-text)] transition-colors">Zapamätať si ma</span>
</label>
<Link href="/auth/forgot-password" className="text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300 font-semibold hover:underline transition-colors">
Zabudli ste heslo?
</Link>
</div>
<Button
type="submit"
className="w-full"
size="lg"
disabled={isLoading}
>
{isLoading ? 'Prihlasovanie...' : 'Prihlásiť sa'}
</Button>
</form>
<div className="mt-8 text-center">
<p className="text-base text-[color:var(--fluent-text-secondary)]">
Nemáte účet?{' '}
<Link href="/auth/signup" className="text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300 font-semibold hover:underline">
Zaregistrujte sa
</Link>
</p>
</div>
</div>
</div>
</main>
);
}