Skip to content

Commit d6b44d1

Browse files
committed
Show magic link errors in the UI, switch to useNavigation hook, and return using the authenticator
1 parent c6784ba commit d6b44d1

File tree

1 file changed

+28
-10
lines changed

1 file changed

+28
-10
lines changed

apps/webapp/app/routes/login.magic/route.tsx

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { ActionArgs, LoaderArgs } from "@remix-run/node";
22
import { redirect } from "@remix-run/node";
3-
import { Form, useTransition } from "@remix-run/react";
3+
import { Form, useNavigation, useTransition } from "@remix-run/react";
44
import { TypedMetaFunction, typedjson, useTypedLoaderData } from "remix-typedjson";
55
import { z } from "zod";
66
import { LogoIcon } from "~/components/LogoIcon";
@@ -20,6 +20,7 @@ import magicLinkIcon from "./login.magic.svg";
2020
import type { LoaderType as RootLoader } from "~/root";
2121
import { appEnvTitleTag } from "~/utils";
2222
import { TextLink } from "~/components/primitives/TextLink";
23+
import { FormError } from "~/components/primitives/FormError";
2324

2425
export const meta: TypedMetaFunction<typeof loader, { root: RootLoader }> = ({ parentsData }) => ({
2526
title: `Login to Trigger.dev${appEnvTitleTag(parentsData?.root.appEnv)}`,
@@ -31,10 +32,26 @@ export async function loader({ request }: LoaderArgs) {
3132
});
3233

3334
const session = await getUserSession(request);
35+
const error = session.get("auth:error");
3436

35-
return typedjson({
36-
magicLinkSent: session.has("triggerdotdev:magiclink"),
37-
});
37+
let magicLinkError: string | undefined;
38+
if (error) {
39+
if ("message" in error) {
40+
magicLinkError = error.message;
41+
} else {
42+
magicLinkError = JSON.stringify(error, null, 2);
43+
}
44+
}
45+
46+
return typedjson(
47+
{
48+
magicLinkSent: session.has("triggerdotdev:magiclink"),
49+
magicLinkError,
50+
},
51+
{
52+
headers: { "Set-Cookie": await commitSession(session) },
53+
}
54+
);
3855
}
3956

4057
export async function action({ request }: ActionArgs) {
@@ -49,7 +66,7 @@ export async function action({ request }: ActionArgs) {
4966
.parse(payload);
5067

5168
if (action === "send") {
52-
await authenticator.authenticate("email-link", request, {
69+
return authenticator.authenticate("email-link", request, {
5370
successRedirect: "/login/magic",
5471
failureRedirect: "/login/magic",
5572
});
@@ -66,13 +83,13 @@ export async function action({ request }: ActionArgs) {
6683
}
6784

6885
export default function LoginMagicLinkPage() {
69-
const { magicLinkSent } = useTypedLoaderData<typeof loader>();
70-
const transition = useTransition();
86+
const { magicLinkSent, magicLinkError } = useTypedLoaderData<typeof loader>();
87+
const navigate = useNavigation();
7188

7289
const isLoading =
73-
(transition.state === "loading" || transition.state === "submitting") &&
74-
transition.type === "actionSubmission" &&
75-
transition.submission.formData.get("action") === "send";
90+
(navigate.state === "loading" || navigate.state === "submitting") &&
91+
navigate.formAction !== undefined &&
92+
navigate.formData?.get("action") === "send";
7693

7794
return (
7895
<AppContainer showBackgroundGradient={true}>
@@ -152,6 +169,7 @@ export default function LoginMagicLinkPage() {
152169
/>
153170
{isLoading ? "Sending…" : "Send a magic link"}
154171
</Button>
172+
{magicLinkError && <FormError>{magicLinkError}</FormError>}
155173
</Fieldset>
156174
<Paragraph variant="extra-small" className="my-4 text-center">
157175
By logging in with your email you agree to our{" "}

0 commit comments

Comments
 (0)