53 lines · 1.8 KB
import { createFileRoute } from "@tanstack/react-router";
import { useState } from "react";
import { z } from "zod";
import { verifyEmail } from "~/fns/login";
import { useAction } from "~/hooks/use-action";
import { AuthCard } from "~/components/AuthCard";
import { Button } from "~/ui/Button";
import { ErrorBanner } from "~/ui/Callout";
import { TextLink } from "~/ui/TextLink";

export const Route = createFileRoute("/verify-email")({
  validateSearch: z.object({ token: z.string().optional() }),
  head: () => ({ meta: [{ title: "Verify email · gitfor" }] }),
  component: VerifyEmailPage,
});

/** Verification needs an explicit click so link scanners in mail clients can't consume the token. */
function VerifyEmailPage() {
  const { token } = Route.useSearch();
  const action = useAction(verifyEmail);
  const [verified, setVerified] = useState<string | null>(null);

  return (
    <AuthCard title="Verify your email" subtitle="Confirm this address belongs to you.">
      {verified ? (
        <div className="space-y-3 text-sm text-kumo-default">
          <p>
            <span className="font-medium text-white">{verified}</span> is verified.
          </p>
          <TextLink to="/settings">Go to settings</TextLink>
        </div>
      ) : (
        <div className="space-y-4">
          <ErrorBanner message={token ? action.error : "This verification link is missing its token."} />
          <Button
            variant="primary"
            className="w-full"
            disabled={!token}
            pending={action.pending}
            onClick={async () => {