Skip to content
60 linesCodeBlameRaw
1import { Form, Link } from "react-router";
2
3import type { Route } from "./+types/forgot";
4import { page } from "../lib/meta";
5import { AuthCard } from "../components/auth-card";
6import { ErrorText, Field, Input, SubmitButton } from "../components/ui";
7import { Card } from "../components/ui/card";
8import { identity } from "../lib/services.server";
9import { assertSameOrigin, clientOf } from "../lib/session.server";
10
11export function meta(args: Route.MetaArgs) {
12 return page(args, { title: "Reset your password · g1t" });
13}
14
15export async function action({ request }: Route.ActionArgs) {
16 assertSameOrigin(request);
17 const form = await request.formData();
18 try {
19 await identity.requestPasswordReset(String(form.get("email") ?? ""), clientOf(request));
20 } catch (error) {
21 // Logged, never shown: what went wrong could say whether the address
22 // has an account. The person hears only that it did not go.
23 console.warn("forgot:", error);
24 return { sent: false, error: "We could not send a reset link just now. Try again in a few minutes." };
25 }
26 return { sent: true, error: null };
27}
28
29export default function Forgot({ actionData }: Route.ComponentProps) {
30 return (
31 <AuthCard
32 title="Forgot your password?"
33 subtitle="We will email you a link"
34 footer={
35 <Link to="/login" className="text-fg underline underline-offset-4">
36 Back to sign in
37 </Link>
38 }
39 >
40 {actionData?.sent ? (
41 <Card asChild radius="lg" className="p-4 text-sm leading-6">
42 <p>
43 If that address belongs to an account, a reset link is on its way to
44 it. It works for one hour.
45 </p>
46 </Card>
47 ) : (
48 <Form method="post" className="space-y-4">
49 <Field label="Email">
50 <Input name="email" type="email" autoComplete="email" required autoFocus />
51 </Field>
52 <ErrorText>{actionData?.error}</ErrorText>
53 <div className="pt-2 *:w-full">
54 <SubmitButton pending="Sending…">Send reset link</SubmitButton>
55 </div>
56 </Form>
57 )}
58 </AuthCard>
59 );
60}