[go: up one dir, main page]

0% found this document useful (0 votes)
20 views4 pages

New Text Document

The document is a React component for an authentication modal that allows users to log in or sign up. It includes form validation using Zod, handles loading states, and displays error messages when validation fails. The modal utilizes tabs to switch between login and signup forms, and integrates with an authentication context for user login and signup functionality.

Uploaded by

sanusaru29
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
20 views4 pages

New Text Document

The document is a React component for an authentication modal that allows users to log in or sign up. It includes form validation using Zod, handles loading states, and displays error messages when validation fails. The modal utilizes tabs to switch between login and signup forms, and integrates with an authentication context for user login and signup functionality.

Uploaded by

sanusaru29
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 4

import React, { useState } from 'react';

import { Button } from '@/components/ui/button';


import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Dialog, DialogContent, DialogTitle, DialogHeader } from
'@/components/ui/dialog';
import { useAuth } from '@/context/AuthContext';
import { toast } from 'sonner';
import { z } from 'zod';

interface AuthModalProps {
isOpen: boolean;
onClose: () => void;
}

const AuthModal: React.FC<AuthModalProps> = ({ isOpen, onClose }) => {


const [tab, setTab] = useState<'login' | 'signup'>('login');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [displayName, setDisplayName] = useState('');
const [isLoading, setIsLoading] = useState(false);
const [formError, setFormError] = useState('');

const { login, signup } = useAuth();

const emailSchema = z.string().email('Invalid email address');


const passwordSchema = z.string().min(6, 'Password must be at least 6
characters');
const displayNameSchema = z.string().min(2, 'Display name must be at least 2
characters');

const resetForm = () => {


setEmail('');
setPassword('');
setDisplayName('');
setFormError('');
};

const handleClose = () => {


resetForm();
onClose();
};

const validateLogin = () => {


setFormError('');
try {
emailSchema.parse(email);
passwordSchema.parse(password);
return true;
} catch (error) {
if (error instanceof z.ZodError) {
setFormError(error.errors[0].message);
toast.error(error.errors[0].message);
}
return false;
}
};
const validateSignup = () => {
setFormError('');
try {
emailSchema.parse(email);
passwordSchema.parse(password);
displayNameSchema.parse(displayName);
return true;
} catch (error) {
if (error instanceof z.ZodError) {
setFormError(error.errors[0].message);
toast.error(error.errors[0].message);
}
return false;
}
};

const handleLogin = async (e: React.FormEvent) => {


e.preventDefault();

if (!validateLogin()) return;

setIsLoading(true);
try {
console.log("Login form submitted with:", email);
await login(email, password);
console.log("Login successful in component");
handleClose();
} catch (error: any) {
console.error("Login error in component:", error);
if (error.message) {
setFormError(error.message);
}
} finally {
setIsLoading(false);
}
};

const handleSignup = async (e: React.FormEvent) => {


e.preventDefault();

if (!validateSignup()) return;

setIsLoading(true);
try {
console.log("Signup form submitted with:", email, displayName);
await signup(email, password, displayName);
console.log("Signup successful in component");
handleClose();
} catch (error: any) {
console.error("Signup error in component:", error);
if (error.message) {
setFormError(error.message);
}
} finally {
setIsLoading(false);
}
};
return (
<Dialog open={isOpen} onOpenChange={handleClose}>
<DialogContent className="sm:max-w-[425px] p-0 overflow-hidden animate-fade-
in">
<DialogHeader className="px-6 pt-6 pb-2">
<DialogTitle className="text-2xl font-medium text-center">
{tab === 'login' ? 'Welcome back' : 'Create account'}
</DialogTitle>
</DialogHeader>

<Tabs value={tab} onValueChange={(v) => setTab(v as 'login' | 'signup')}


className="w-full">
<div className="px-6">
<TabsList className="grid w-full grid-cols-2 mb-6">
<TabsTrigger value="login">Login</TabsTrigger>
<TabsTrigger value="signup">Sign Up</TabsTrigger>
</TabsList>
</div>

{formError && (
<div className="px-6 mb-4">
<p className="text-sm text-destructive">{formError}</p>
</div>
)}

<TabsContent value="login" className="m-0">


<form onSubmit={handleLogin} className="space-y-4 px-6 pb-6">
<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<Input
id="email"
type="email"
placeholder="you@example.com"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
className="input-animation"
/>
</div>
<div className="space-y-2">
<Label htmlFor="password">Password</Label>
<Input
id="password"
type="password"
placeholder="••••••••"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
className="input-animation"
/>
</div>
<Button
type="submit"
className="w-full"
disabled={isLoading}
>
{isLoading ? 'Signing in...' : 'Sign in'}
</Button>
</form>
</TabsContent>

<TabsContent value="signup" className="m-0">


<form onSubmit={handleSignup} className="space-y-4 px-6 pb-6">
<div className="space-y-2">
<Label htmlFor="display-name">Display Name</Label>
<Input
id="display-name"
placeholder="Your display name"
value={displayName}
onChange={(e) => setDisplayName(e.target.value)}
required
className="input-animation"
/>
</div>
<div className="space-y-2">
<Label htmlFor="signup-email">Email</Label>
<Input
id="signup-email"
type="email"
placeholder="you@example.com"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
className="input-animation"
/>
</div>
<div className="space-y-2">
<Label htmlFor="signup-password">Password</Label>
<Input
id="signup-password"
type="password"
placeholder="••••••••"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
className="input-animation"
/>
<p className="text-xs text-muted-foreground">
Password must be at least 6 characters
</p>
</div>
<Button
type="submit"
className="w-full"
disabled={isLoading}
>
{isLoading ? 'Creating account...' : 'Create account'}
</Button>
</form>
</TabsContent>
</Tabs>
</DialogContent>
</Dialog>
);
};

export default AuthModal;

You might also like