"use client";
import * as React from "react";
import { useParams, useRouter } from "next/navigation";
import Link from "next/link";
import { signIn, useSession } from "next-auth/react";
import { CheckCircle2, Loader2, Mail, ShieldAlert } from "lucide-react";
import { Button } from "@/components/ui/button";
import { api } from "@/lib/trpc";
/**
* Public-by-token invite redeem page. Three phases:
*
* 1. Not signed in -> bounce to /sign-in with callbackUrl that brings us
* back here. We don't surface the invite contents pre-auth; the only
* thing the operator needs to see is "you need to sign in first."
*
* 2. Signed in, calling invites.accept(). On success: route to the
* workspace landing page.
*
* 3. Signed in but identity mismatch (FORBIDDEN with cause.reason ===
* "email_not_owned"). Render the explainer with a deep link to the
* profile's Linked Emails section. The user can either:
* - Sign out and sign in via the matching email's provider.
* - Add the missing email to their profile (manual verification
* is a follow-up task; in v1 the link points at the read-only
* Linked Emails page).
*/
export default function InviteAcceptPage() {
const params = useParams();
const router = useRouter();
const { data: session, status } = useSession();
const rawToken = params?.token;
const token = typeof rawToken === "string" ? rawToken : undefined;
const acceptMut = api.invites.accept.useMutation({
onSuccess: (result) => {
router.replace(`/${result.workspace.slug}`);
},
});
const triedRef = React.useRef(false);
React.useEffect(() => {
if (!token) return;
if (status !== "authenticated") return;
if (triedRef.current) return;
triedRef.current = true;
acceptMut.mutate({ token });
}, [token, status]); // eslint-disable-line react-hooks/exhaustive-deps
if (!token) {
return
You need to be signed in for us to know which account to add to the
workspace.
Joined {acceptMut.data.workspace.name} as{" "}
{acceptMut.data.role}. Redirecting…
The invite was for{" "}
{cause.invitedEmail}, but
you're signed in as{" "}
{session?.user?.email}.
To accept, link the invited email to your account from your
profile (e.g. sign in via that email's OAuth provider), then
return to this page. Or sign out and sign back in with the
invited email directly.
{acceptMut.error.message}