32 lines
1.5 KiB
TypeScript
32 lines
1.5 KiB
TypeScript
import type { ActionFunctionArgs, LoaderFunctionArgs } from "react-router";
|
|
import { Form, useActionData, useLoaderData } from "react-router";
|
|
import { LoginErrorType } from "@shopify/shopify-app-react-router/server";
|
|
import { login } from "../shopify.server";
|
|
|
|
function message(errors: Awaited<ReturnType<typeof login>> | undefined) {
|
|
if (!errors || errors instanceof Response) return null;
|
|
if (errors.shop === LoginErrorType.MissingShop) return "Enter your shop domain to log in";
|
|
if (errors.shop === LoginErrorType.InvalidShop) return "Enter a valid shop domain, like your-store.myshopify.com";
|
|
return null;
|
|
}
|
|
|
|
export const loader = async ({ request }: LoaderFunctionArgs) => ({ error: message(await login(request)) });
|
|
export const action = async ({ request }: ActionFunctionArgs) => ({ error: message(await login(request)) });
|
|
|
|
export default function Login() {
|
|
const loaderData = useLoaderData<typeof loader>();
|
|
const actionData = useActionData<typeof action>();
|
|
const error = actionData?.error ?? loaderData.error;
|
|
return (
|
|
<main style={{ maxWidth: 420, margin: "10vh auto", padding: 16, fontFamily: "system-ui, sans-serif" }}>
|
|
<h1>Log in to Datewise</h1>
|
|
<Form method="post" style={{ display: "grid", gap: 8 }}>
|
|
<label htmlFor="shop">Shop domain</label>
|
|
<input id="shop" name="shop" placeholder="your-store.myshopify.com" autoComplete="on" />
|
|
{error && <p role="alert">{error}</p>}
|
|
<button type="submit">Log in</button>
|
|
</Form>
|
|
</main>
|
|
);
|
|
}
|