| import { useState } from 'react' |
| import { Link, useNavigate } from 'react-router-dom' |
| import { useAuthStore } from '@/store/authStore' |
| 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 { Alert, AlertDescription } from '@/components/ui/alert' |
| import LoadingSpinner from '@/components/LoadingSpinner' |
| import { MessageCircle } from 'lucide-react' |
|
|
| export default function RegisterPage() { |
| const [formData, setFormData] = useState({ |
| email: '', |
| username: '', |
| displayName: '', |
| password: '', |
| confirmPassword: '' |
| }) |
| const [validationError, setValidationError] = useState('') |
| const { register, loading, error, clearError } = useAuthStore() |
| const navigate = useNavigate() |
|
|
| const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => { |
| const { name, value } = e.target |
| setFormData(prev => ({ |
| ...prev, |
| [name]: value |
| })) |
| setValidationError('') |
| } |
|
|
| const validateForm = () => { |
| if (formData.password !== formData.confirmPassword) { |
| setValidationError('Passwords do not match') |
| return false |
| } |
| |
| if (formData.password.length < 6) { |
| setValidationError('Password must be at least 6 characters long') |
| return false |
| } |
| |
| if (formData.username.length < 3) { |
| setValidationError('Username must be at least 3 characters long') |
| return false |
| } |
| |
| if (!/^[a-zA-Z0-9_]+$/.test(formData.username)) { |
| setValidationError('Username can only contain letters, numbers, and underscores') |
| return false |
| } |
| |
| return true |
| } |
|
|
| const handleSubmit = async (e: React.FormEvent) => { |
| e.preventDefault() |
| clearError() |
| setValidationError('') |
| |
| if (!validateForm()) { |
| return |
| } |
| |
| try { |
| await register({ |
| email: formData.email, |
| username: formData.username, |
| displayName: formData.displayName, |
| password: formData.password |
| }) |
| navigate('/chat') |
| } catch (error) { |
| |
| } |
| } |
|
|
| const displayError = validationError || error |
|
|
| return ( |
| <div className="min-h-screen flex items-center justify-center bg-gradient-to-br from-blue-50 to-indigo-100 p-4"> |
| <Card className="w-full max-w-md"> |
| <CardHeader className="text-center"> |
| <div className="flex justify-center mb-4"> |
| <div className="p-3 bg-blue-600 rounded-full"> |
| <MessageCircle className="w-8 h-8 text-white" /> |
| </div> |
| </div> |
| <CardTitle className="text-2xl font-bold">Create Account</CardTitle> |
| <CardDescription> |
| Join ChatApp and start messaging |
| </CardDescription> |
| </CardHeader> |
| <CardContent> |
| <form onSubmit={handleSubmit} className="space-y-4"> |
| {displayError && ( |
| <Alert variant="destructive"> |
| <AlertDescription>{displayError}</AlertDescription> |
| </Alert> |
| )} |
| |
| <div className="space-y-2"> |
| <Label htmlFor="email">Email</Label> |
| <Input |
| id="email" |
| name="email" |
| type="email" |
| placeholder="Enter your email" |
| value={formData.email} |
| onChange={handleChange} |
| required |
| disabled={loading} |
| /> |
| </div> |
| |
| <div className="space-y-2"> |
| <Label htmlFor="username">Username</Label> |
| <Input |
| id="username" |
| name="username" |
| type="text" |
| placeholder="Choose a username" |
| value={formData.username} |
| onChange={handleChange} |
| required |
| disabled={loading} |
| /> |
| </div> |
| |
| <div className="space-y-2"> |
| <Label htmlFor="displayName">Display Name</Label> |
| <Input |
| id="displayName" |
| name="displayName" |
| type="text" |
| placeholder="Your display name" |
| value={formData.displayName} |
| onChange={handleChange} |
| required |
| disabled={loading} |
| /> |
| </div> |
| |
| <div className="space-y-2"> |
| <Label htmlFor="password">Password</Label> |
| <Input |
| id="password" |
| name="password" |
| type="password" |
| placeholder="Create a password" |
| value={formData.password} |
| onChange={handleChange} |
| required |
| disabled={loading} |
| /> |
| </div> |
| |
| <div className="space-y-2"> |
| <Label htmlFor="confirmPassword">Confirm Password</Label> |
| <Input |
| id="confirmPassword" |
| name="confirmPassword" |
| type="password" |
| placeholder="Confirm your password" |
| value={formData.confirmPassword} |
| onChange={handleChange} |
| required |
| disabled={loading} |
| /> |
| </div> |
| |
| <Button |
| type="submit" |
| className="w-full" |
| disabled={loading} |
| > |
| {loading ? ( |
| <> |
| <LoadingSpinner size="sm" className="mr-2" /> |
| Creating account... |
| </> |
| ) : ( |
| 'Create Account' |
| )} |
| </Button> |
| </form> |
| |
| <div className="mt-6 text-center"> |
| <p className="text-sm text-gray-600"> |
| Already have an account?{' '} |
| <Link |
| to="/login" |
| className="text-blue-600 hover:text-blue-500 font-medium" |
| > |
| Sign in |
| </Link> |
| </p> |
| </div> |
| </CardContent> |
| </Card> |
| </div> |
| ) |
| } |
|
|