Files
meet-hub/src/pages/Auth.tsx
gpt-engineer-app[bot] bf7a9fad99 Changes
2025-12-18 08:06:31 +00:00

137 lines
4.6 KiB
TypeScript

import { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { useAuth } from '@/hooks/useAuth';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { toast } from '@/hooks/use-toast';
import { z } from 'zod';
const emailSchema = z.string().email('Invalid email address');
const passwordSchema = z.string().min(6, 'Password must be at least 6 characters');
export default function Auth() {
const [isLogin, setIsLogin] = useState(true);
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [name, setName] = useState('');
const [loading, setLoading] = useState(false);
const { signIn, signUp, user } = useAuth();
const navigate = useNavigate();
useEffect(() => {
if (user) {
navigate('/dashboard');
}
}, [user, navigate]);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
try {
emailSchema.parse(email);
passwordSchema.parse(password);
} catch (err) {
if (err instanceof z.ZodError) {
toast({ title: 'Validation Error', description: err.errors[0].message, variant: 'destructive' });
return;
}
}
setLoading(true);
if (isLogin) {
const { error } = await signIn(email, password);
if (error) {
toast({ title: 'Error', description: error.message, variant: 'destructive' });
} else {
navigate('/dashboard');
}
} else {
if (!name.trim()) {
toast({ title: 'Error', description: 'Name is required', variant: 'destructive' });
setLoading(false);
return;
}
const { error } = await signUp(email, password, name);
if (error) {
if (error.message.includes('already registered')) {
toast({ title: 'Error', description: 'This email is already registered. Please login instead.', variant: 'destructive' });
} else {
toast({ title: 'Error', description: error.message, variant: 'destructive' });
}
} else {
toast({ title: 'Success', description: 'Check your email to confirm your account' });
}
}
setLoading(false);
};
return (
<div className="min-h-screen flex items-center justify-center bg-background p-4">
<Card className="w-full max-w-md border-2 border-border shadow-md">
<CardHeader>
<CardTitle className="text-2xl">{isLogin ? 'Login' : 'Sign Up'}</CardTitle>
<CardDescription>
{isLogin ? 'Enter your credentials to access your account' : 'Create a new account to get started'}
</CardDescription>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-4">
{!isLogin && (
<div className="space-y-2">
<Label htmlFor="name">Name</Label>
<Input
id="name"
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
placeholder="Your name"
className="border-2"
/>
</div>
)}
<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<Input
id="email"
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="your@email.com"
className="border-2"
/>
</div>
<div className="space-y-2">
<Label htmlFor="password">Password</Label>
<Input
id="password"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="••••••••"
className="border-2"
/>
</div>
<Button type="submit" className="w-full shadow-sm" disabled={loading}>
{loading ? 'Loading...' : isLogin ? 'Login' : 'Sign Up'}
</Button>
</form>
<div className="mt-4 text-center">
<button
type="button"
onClick={() => setIsLogin(!isLogin)}
className="text-sm text-muted-foreground hover:underline"
>
{isLogin ? "Don't have an account? Sign up" : 'Already have an account? Login'}
</button>
</div>
</CardContent>
</Card>
</div>
);
}