Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x 6x | import { zodResolver } from '@hookform/resolvers/zod';
import { createLazyFileRoute, useNavigate } from '@tanstack/react-router';
import { login } from '@web/api/v1/super-agents/auth';
import { AnimatedLogo } from '@web/components/side-bar/animated-logo';
import { Button } from '@web/components/ui/button';
import {
Card,
CardContent,
CardHeader,
CardTitle,
} from '@web/components/ui/card';
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@web/components/ui/form';
import { Input } from '@web/components/ui/input';
import { useState } from 'react';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
export const Route = createLazyFileRoute('/login')({
component: LoginPage,
});
const formSchema = z.object({
password: z.string().min(1),
});
function LoginPage(): React.ReactNode {
const navigate = useNavigate();
const [error, setError] = useState<string | null>(null);
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
password: '',
},
});
const isSubmitting = form.formState.isSubmitting;
async function handleLogin(data: z.infer<typeof formSchema>): Promise<void> {
const success = await login(data.password);
if (!success) {
setError('Invalid password');
return;
}
navigate({ to: '/agents' });
}
return (
<div className="flex h-screen w-screen items-center justify-center bg-background">
<Card className="w-96">
<CardHeader>
<CardTitle className="flex flex-col gap-2 mb-0">
<div className="flex flex-col gap-2">
<div className="w-full h-16">
<AnimatedLogo isCollapsed={false} />
</div>
<span className="text-2xl font-bold">
Enter password to continue
</span>
</div>
</CardTitle>
</CardHeader>
<CardContent className="flex flex-col gap-2">
<Form {...form}>
<form
onSubmit={form.handleSubmit(handleLogin)}
onChange={(): void => setError(null)}
className="flex flex-col w-full gap-4"
>
<FormField
control={form.control}
name="password"
render={({ field }): React.ReactElement => (
<FormItem>
<FormLabel>Password</FormLabel>
<FormControl>
<Input
type="password"
autoComplete="current-password"
placeholder="Enter your password"
disabled={isSubmitting}
{...field}
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
{error && (
<p className="text-red-600 leading-0 text-sm">{error}</p>
)}
<Button type="submit" disabled={isSubmitting}>
{isSubmitting ? 'Logging in…' : 'Login'}
</Button>
</form>
</Form>
</CardContent>
</Card>
</div>
);
}
|