68 lines
2.3 KiB
TypeScript
68 lines
2.3 KiB
TypeScript
import { useEffect, useState } from "react";
|
|
import { useNavigate, useSearchParams } from "react-router-dom";
|
|
import { AuthShell } from "../components/auth/AuthShell";
|
|
import { setAttendeeSession, setGuestTokenForEvent } from "../lib/attendeeAuth";
|
|
import { postVisitorExchangeLink } from "../lib/api";
|
|
import { notifyRewardFromApiData } from "../lib/rewardCelebration";
|
|
import { buildPostAuthUrl, readStoredVisitorContext } from "../types/visitorContext";
|
|
|
|
export function AuthCallbackPage() {
|
|
const [searchParams] = useSearchParams();
|
|
const navigate = useNavigate();
|
|
const [err, setErr] = useState<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
const token = searchParams.get("token");
|
|
if (!token) {
|
|
setErr("Missing sign-in link. Open the link from your email again.");
|
|
return;
|
|
}
|
|
|
|
let cancelled = false;
|
|
(async () => {
|
|
try {
|
|
const data = await postVisitorExchangeLink(token);
|
|
if (cancelled) return;
|
|
setAttendeeSession(data.token, data.participant);
|
|
if (data.guestToken && data.participant.event) {
|
|
setGuestTokenForEvent(data.participant.event, data.guestToken);
|
|
}
|
|
notifyRewardFromApiData(data);
|
|
const ctx = readStoredVisitorContext();
|
|
if (data.pendingApproval) {
|
|
navigate("/pending-approval", { replace: true });
|
|
return;
|
|
}
|
|
if (data.needsProfile) {
|
|
navigate("/complete-profile", { replace: true });
|
|
return;
|
|
}
|
|
navigate(buildPostAuthUrl(ctx), { replace: true });
|
|
} catch (e) {
|
|
if (!cancelled) setErr(e instanceof Error ? e.message : "Sign-in failed.");
|
|
}
|
|
})();
|
|
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}, [searchParams, navigate]);
|
|
|
|
return (
|
|
<AuthShell>
|
|
<div className="flex w-full max-w-[354px] flex-col items-center gap-6 px-4 text-center">
|
|
<p className="font-inter text-base text-white/95">{err ? err : "Signing you in…"}</p>
|
|
{err ? (
|
|
<button
|
|
type="button"
|
|
onClick={() => navigate("/login", { replace: true })}
|
|
className="rounded-full bg-[#ef8d1d] px-6 py-2 text-sm font-semibold text-white"
|
|
>
|
|
Back to login
|
|
</button>
|
|
) : null}
|
|
</div>
|
|
</AuthShell>
|
|
);
|
|
}
|