All files / web/src/routes login.lazy.tsx

75% Statements 63/84
33.33% Branches 1/3
25% Functions 1/4
75% Lines 63/84

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 1091x 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>
  );
}