LoginPage.tsx 4.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import { Form, Head } from '@inertiajs/react';
  2. import { LoaderCircle } from 'lucide-react';
  3. import AuthenticatedSessionController from '@/actions/App/Http/Controllers/Auth/AuthenticatedSessionController';
  4. import { InputError } from '@/common/InputError';
  5. import { TextLink } from '@/common/TextLink';
  6. import AuthLayout from '@/pages/layouts/AuthLayout';
  7. import { register } from '@/routes';
  8. import { request } from '@/routes/password';
  9. import { Button } from '@/shadcn/button';
  10. import { Checkbox } from '@/shadcn/checkbox';
  11. import { Input } from '@/shadcn/input';
  12. import { Label } from '@/shadcn/label';
  13. interface LoginProps {
  14. status?: string;
  15. canResetPassword: boolean;
  16. }
  17. export default function LoginPage({ status, canResetPassword }: LoginProps) {
  18. return (
  19. <AuthLayout title="Log in to your account" description="Enter your email and password below to log in">
  20. <Head title="Log in" />
  21. <Form {...AuthenticatedSessionController.store.form()} resetOnSuccess={['password']} className="flex flex-col gap-6">
  22. {({ processing, errors }) => (
  23. <>
  24. <div className="grid gap-6">
  25. <div className="grid gap-2">
  26. <Label htmlFor="email">Email address</Label>
  27. <Input
  28. id="email"
  29. type="email"
  30. name="email"
  31. required
  32. autoFocus
  33. tabIndex={1}
  34. autoComplete="email"
  35. placeholder="email@example.com"
  36. />
  37. <InputError message={errors.email} />
  38. </div>
  39. <div className="grid gap-2">
  40. <div className="flex items-center">
  41. <Label htmlFor="password">Password</Label>
  42. {canResetPassword && (
  43. <TextLink href={request()} className="ml-auto text-sm" tabIndex={5}>
  44. Forgot password?
  45. </TextLink>
  46. )}
  47. </div>
  48. <Input
  49. id="password"
  50. type="password"
  51. name="password"
  52. required
  53. tabIndex={2}
  54. autoComplete="current-password"
  55. placeholder="Password"
  56. />
  57. <InputError message={errors.password} />
  58. </div>
  59. <div className="flex items-center space-x-3">
  60. <Checkbox id="remember" name="remember" tabIndex={3} />
  61. <Label htmlFor="remember">Remember me</Label>
  62. </div>
  63. <Button type="submit" className="mt-4 w-full" tabIndex={4} disabled={processing}>
  64. {processing && <LoaderCircle className="h-4 w-4 animate-spin" />}
  65. Log in
  66. </Button>
  67. </div>
  68. <div className="text-center text-sm text-muted-foreground">
  69. Don't have an account?{' '}
  70. <TextLink href={register()} tabIndex={5}>
  71. Sign up
  72. </TextLink>
  73. </div>
  74. </>
  75. )}
  76. </Form>
  77. {status && <div className="mb-4 text-center text-sm font-medium text-green-600">{status}</div>}
  78. </AuthLayout>
  79. );
  80. }