134 lines
4.0 KiB
TypeScript
134 lines
4.0 KiB
TypeScript
'use client'
|
|
|
|
import { useState } from 'react'
|
|
import { useRouter, useSearchParams } from 'next/navigation'
|
|
import { signIn } from 'next-auth/react'
|
|
import { Button } from '@/components/ui/button'
|
|
import { Input } from '@/components/ui/input'
|
|
import { Label } from '@/components/ui/label'
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardFooter,
|
|
CardHeader,
|
|
CardTitle,
|
|
} from '@/components/ui/card'
|
|
|
|
export default function LoginPage() {
|
|
const router = useRouter()
|
|
const searchParams = useSearchParams()
|
|
const callbackUrl = searchParams.get('callbackUrl') || '/'
|
|
const error = searchParams.get('error')
|
|
|
|
const [email, setEmail] = useState('')
|
|
const [password, setPassword] = useState('')
|
|
const [userType, setUserType] = useState<'customer' | 'staff'>('staff')
|
|
const [isLoading, setIsLoading] = useState(false)
|
|
const [loginError, setLoginError] = useState<string | null>(null)
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
e.preventDefault()
|
|
setIsLoading(true)
|
|
setLoginError(null)
|
|
|
|
try {
|
|
const result = await signIn('credentials', {
|
|
email,
|
|
password,
|
|
userType,
|
|
redirect: false,
|
|
callbackUrl,
|
|
})
|
|
|
|
if (result?.error) {
|
|
setLoginError(result.error)
|
|
} else if (result?.ok) {
|
|
router.push(userType === 'staff' ? '/admin' : '/')
|
|
router.refresh()
|
|
}
|
|
} catch {
|
|
setLoginError('An unexpected error occurred')
|
|
} finally {
|
|
setIsLoading(false)
|
|
}
|
|
}
|
|
|
|
return (
|
|
<div className="min-h-screen flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
|
|
<Card className="w-full max-w-md">
|
|
<CardHeader className="space-y-1">
|
|
<CardTitle className="text-2xl font-bold text-center">
|
|
LetsBe Hub
|
|
</CardTitle>
|
|
<CardDescription className="text-center">
|
|
Sign in to your account
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<form onSubmit={handleSubmit}>
|
|
<CardContent className="space-y-4">
|
|
{(error || loginError) && (
|
|
<div className="p-3 text-sm text-red-500 bg-red-50 rounded-md">
|
|
{error === 'CredentialsSignin'
|
|
? 'Invalid email or password'
|
|
: loginError || error}
|
|
</div>
|
|
)}
|
|
|
|
<div className="flex gap-2">
|
|
<Button
|
|
type="button"
|
|
variant={userType === 'staff' ? 'default' : 'outline'}
|
|
className="flex-1"
|
|
onClick={() => setUserType('staff')}
|
|
>
|
|
Staff Login
|
|
</Button>
|
|
<Button
|
|
type="button"
|
|
variant={userType === 'customer' ? 'default' : 'outline'}
|
|
className="flex-1"
|
|
onClick={() => setUserType('customer')}
|
|
>
|
|
Customer Login
|
|
</Button>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="email">Email</Label>
|
|
<Input
|
|
id="email"
|
|
type="email"
|
|
placeholder="Enter your email"
|
|
value={email}
|
|
onChange={(e) => setEmail(e.target.value)}
|
|
required
|
|
autoComplete="email"
|
|
/>
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="password">Password</Label>
|
|
<Input
|
|
id="password"
|
|
type="password"
|
|
placeholder="Enter your password"
|
|
value={password}
|
|
onChange={(e) => setPassword(e.target.value)}
|
|
required
|
|
autoComplete="current-password"
|
|
/>
|
|
</div>
|
|
</CardContent>
|
|
|
|
<CardFooter>
|
|
<Button type="submit" className="w-full" disabled={isLoading}>
|
|
{isLoading ? 'Signing in...' : 'Sign In'}
|
|
</Button>
|
|
</CardFooter>
|
|
</form>
|
|
</Card>
|
|
</div>
|
|
)
|
|
}
|