106 lines
4.1 KiB
TypeScript
106 lines
4.1 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { motion } from 'framer-motion';
|
|
import { UserRole } from '../types';
|
|
import { Button } from './Button';
|
|
import { Heart } from 'lucide-react';
|
|
|
|
interface LoginScreenProps {
|
|
onLogin: (role: UserRole) => void;
|
|
}
|
|
|
|
export const LoginScreen: React.FC<LoginScreenProps> = ({ onLogin }) => {
|
|
const [username, setUsername] = useState('');
|
|
const [password, setPassword] = useState('');
|
|
const [error, setError] = useState('');
|
|
|
|
const handleLogin = (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
const user = username.toLowerCase().trim();
|
|
const pass = password.trim();
|
|
|
|
if (pass !== 'password') {
|
|
setError('Wrong password! Hint: password');
|
|
return;
|
|
}
|
|
|
|
if (user === 'mom') {
|
|
onLogin('mom');
|
|
} else if (user === 'dad') {
|
|
onLogin('dad');
|
|
} else {
|
|
setError('Username must be "mom" or "dad"');
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="min-h-screen flex items-center justify-center p-4 bg-gray-900">
|
|
{/* Background decorative blobs */}
|
|
<div className="fixed top-0 left-0 w-64 h-64 bg-purple-600 rounded-full mix-blend-multiply filter blur-3xl opacity-20 animate-blob"></div>
|
|
<div className="fixed top-0 right-0 w-64 h-64 bg-blue-600 rounded-full mix-blend-multiply filter blur-3xl opacity-20 animate-blob animation-delay-2000"></div>
|
|
<div className="fixed -bottom-8 left-20 w-64 h-64 bg-pink-600 rounded-full mix-blend-multiply filter blur-3xl opacity-20 animate-blob animation-delay-4000"></div>
|
|
|
|
<motion.div
|
|
initial={{ y: 20, opacity: 0 }}
|
|
animate={{ y: 0, opacity: 1 }}
|
|
transition={{ duration: 0.5 }}
|
|
className="glass-panel p-8 rounded-[2.5rem] shadow-2xl w-full max-w-sm border border-white/10 relative z-10"
|
|
>
|
|
<div className="text-center mb-8">
|
|
<div className="w-20 h-20 bg-gradient-to-tr from-pink-500 to-blue-500 rounded-full mx-auto mb-4 flex items-center justify-center shadow-lg shadow-purple-500/20">
|
|
<Heart className="text-white fill-white" size={40} />
|
|
</div>
|
|
<h1 className="text-3xl font-black text-white tracking-tight">Welcome Home</h1>
|
|
<p className="text-gray-400 font-medium mt-1">Shared Calendar App</p>
|
|
</div>
|
|
|
|
<form onSubmit={handleLogin} className="space-y-4">
|
|
<div>
|
|
<input
|
|
type="text"
|
|
placeholder="Who are you? (mom/dad)"
|
|
value={username}
|
|
onChange={(e) => {
|
|
setUsername(e.target.value);
|
|
setError('');
|
|
}}
|
|
className="w-full px-6 py-4 rounded-2xl bg-gray-800 border-2 border-transparent focus:bg-gray-700 focus:border-blue-500 focus:ring-0 transition-all font-bold text-gray-200 placeholder-gray-500 outline-none"
|
|
/>
|
|
</div>
|
|
<div>
|
|
<input
|
|
type="password"
|
|
placeholder="Password"
|
|
value={password}
|
|
onChange={(e) => {
|
|
setPassword(e.target.value);
|
|
setError('');
|
|
}}
|
|
className="w-full px-6 py-4 rounded-2xl bg-gray-800 border-2 border-transparent focus:bg-gray-700 focus:border-blue-500 focus:ring-0 transition-all font-bold text-gray-200 placeholder-gray-500 outline-none"
|
|
/>
|
|
</div>
|
|
|
|
{error && (
|
|
<motion.p
|
|
initial={{ height: 0, opacity: 0 }}
|
|
animate={{ height: 'auto', opacity: 1 }}
|
|
className="text-red-400 text-sm font-bold text-center bg-red-900/20 py-2 rounded-xl border border-red-900/50"
|
|
>
|
|
{error}
|
|
</motion.p>
|
|
)}
|
|
|
|
<Button
|
|
type="submit"
|
|
className="w-full bg-gradient-to-r from-mom-primary to-dad-primary hover:from-pink-400 hover:to-blue-400 shadow-lg shadow-purple-900/50 text-white border-0"
|
|
>
|
|
Enter House
|
|
</Button>
|
|
</form>
|
|
|
|
<p className="text-center text-xs text-gray-500 mt-8 font-semibold">
|
|
Secure • Shared • Simple
|
|
</p>
|
|
</motion.div>
|
|
</div>
|
|
);
|
|
}; |