104 lines
3.6 KiB
TypeScript
104 lines
3.6 KiB
TypeScript
'use client';
|
|
|
|
import { Button } from '@/components/ui/button';
|
|
import { Input } from '@/components/ui/input';
|
|
import { Label } from '@/components/ui/label';
|
|
import { useLoginForm } from '@/hooks/useLoginForm';
|
|
import { Loader2 } from 'lucide-react';
|
|
import Image from 'next/image';
|
|
|
|
export default function LoginPage() {
|
|
const { register, handleSubmit, errors, isLoading } = useLoginForm();
|
|
|
|
return (
|
|
<main className="grid min-h-screen bg-background text-foreground lg:grid-cols-[1.05fr_0.95fr]">
|
|
<section className="relative hidden overflow-hidden border-r border-border/60 lg:block">
|
|
<Image
|
|
src="/background.png"
|
|
alt=""
|
|
fill
|
|
priority
|
|
className="object-cover"
|
|
sizes="55vw"
|
|
/>
|
|
<div className="absolute inset-0 bg-background/35" />
|
|
<div className="absolute inset-x-0 bottom-0 p-10">
|
|
<div className="max-w-lg space-y-3">
|
|
<p className="text-sm font-medium uppercase tracking-[0.18em] text-primary">
|
|
VisionRoad
|
|
</p>
|
|
<h1 className="text-4xl font-semibold tracking-normal text-foreground">
|
|
Road intelligence for faster inspection decisions
|
|
</h1>
|
|
<p className="text-sm leading-6 text-muted-foreground">
|
|
Review projects, uploads, detections, and chainage insights from one secure
|
|
workspace.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section className="flex min-h-screen items-center justify-center px-6 py-10">
|
|
<div className="w-full max-w-sm space-y-7">
|
|
<header className="space-y-2">
|
|
<p className="text-sm font-medium text-muted-foreground">VisionRoad</p>
|
|
<h2 className="text-2xl font-semibold tracking-normal">Sign in</h2>
|
|
<p className="text-sm text-muted-foreground">
|
|
Use your email and password to continue.
|
|
</p>
|
|
</header>
|
|
|
|
<form className="space-y-5" onSubmit={handleSubmit}>
|
|
<div className="space-y-2">
|
|
<Label htmlFor="email">Email</Label>
|
|
<Input
|
|
id="email"
|
|
type="email"
|
|
placeholder="admin@visionroad.ai"
|
|
autoComplete="email"
|
|
disabled={isLoading}
|
|
aria-invalid={!!errors.email}
|
|
{...register('email', {
|
|
required: 'Email is required',
|
|
})}
|
|
/>
|
|
{errors.email && (
|
|
<p className="text-sm text-destructive">{errors.email.message}</p>
|
|
)}
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="password">Password</Label>
|
|
<Input
|
|
id="password"
|
|
type="password"
|
|
placeholder="Enter password"
|
|
autoComplete="current-password"
|
|
disabled={isLoading}
|
|
aria-invalid={!!errors.password}
|
|
{...register('password', {
|
|
required: 'Password is required',
|
|
})}
|
|
/>
|
|
{errors.password && (
|
|
<p className="text-sm text-destructive">{errors.password.message}</p>
|
|
)}
|
|
</div>
|
|
|
|
<Button type="submit" className="w-full" disabled={isLoading}>
|
|
{isLoading ? (
|
|
<>
|
|
<Loader2 className="size-4 animate-spin" />
|
|
Signing in
|
|
</>
|
|
) : (
|
|
'Sign in'
|
|
)}
|
|
</Button>
|
|
</form>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
);
|
|
}
|