"use client"; import { useEffect, useMemo, useState } from "react"; import { useParams, useRouter } from "next/navigation"; import { useAuthContext } from "@/hooks/auth-context"; import useInviteLink from "@/features/groups/hooks/use-invite-link"; export default function InvitePage() { const params = useParams(); const router = useRouter(); const { checkSession } = useAuthContext(); const token = useMemo(() => { const raw = params?.token; if (typeof raw === "string") return raw; if (Array.isArray(raw)) return raw[0] || ""; return ""; }, [params]); const { link, loading, accepting, error, result, accept } = useInviteLink(token || null); const [checkingSession, setCheckingSession] = useState(true); const [hasSession, setHasSession] = useState(false); const [redirectOpen, setRedirectOpen] = useState(false); const [redirectMessage, setRedirectMessage] = useState(""); const [secondsLeft, setSecondsLeft] = useState(3); const viewerStatus = link?.viewerStatus || ""; const isAlreadyMember = viewerStatus === "ALREADY_MEMBER"; const isPendingViewer = viewerStatus === "PENDING"; const groupPolicy = link?.groupJoinPolicy || link?.policy || "NOT_ACCEPTING"; const isDisabled = groupPolicy === "NOT_ACCEPTING"; const isManual = groupPolicy === "APPROVAL_REQUIRED"; const isRevoked = Boolean(link?.revokedAt); const isExpired = link?.expiresAt ? new Date(link.expiresAt).getTime() < Date.now() : false; const isUsed = Boolean(link?.singleUse && link?.usedAt); const joinBlockedMessage = isAlreadyMember ? "You are already a member of this group." : isPendingViewer ? "You currently have a pending join request." : isDisabled ? "Invites are disabled for this group." : isRevoked ? "This invite link has been revoked." : isExpired ? "This invite link has expired." : isUsed ? "This invite link has already been used." : ""; useEffect(() => { let active = true; async function runCheck() { const user = await checkSession(); if (!active) return; setHasSession(Boolean(user)); setCheckingSession(false); } runCheck(); return () => { active = false; }; }, [checkSession]); useEffect(() => { if (!link || loading) return; if (isAlreadyMember) { setRedirectMessage("You are already a member of this group."); setRedirectOpen(true); return; } if (isPendingViewer) { setRedirectMessage("Your join request is pending approval."); setRedirectOpen(true); return; } if (isRevoked) { setRedirectMessage("This invite link has been revoked."); setRedirectOpen(true); } else if (isExpired) { setRedirectMessage("This invite link has expired."); setRedirectOpen(true); } else if (isUsed) { setRedirectMessage("This invite link has already been used."); setRedirectOpen(true); } }, [link, loading, isAlreadyMember, isPendingViewer, isRevoked, isExpired, isUsed]); useEffect(() => { if (!error) return; const lower = error.toLowerCase(); if (lower.includes("revoked")) { setRedirectMessage("This invite link has been revoked."); setRedirectOpen(true); return; } if (lower.includes("expired")) { setRedirectMessage("This invite link has expired."); setRedirectOpen(true); return; } if (lower.includes("used")) { setRedirectMessage("This invite link has already been used."); setRedirectOpen(true); return; } if (lower.includes("not found") || lower.includes("invalid invite")) { setRedirectMessage("This invite link no longer exists."); setRedirectOpen(true); } }, [error]); useEffect(() => { if (!result) return; if (result.status === "JOINED") setRedirectMessage("You have joined the group."); if (result.status === "PENDING") setRedirectMessage("Your join request is pending approval."); if (result.status === "ALREADY_MEMBER") setRedirectMessage("You are already a member of this group."); setRedirectOpen(true); }, [result]); useEffect(() => { if (!redirectOpen) return; setSecondsLeft(3); const timer = window.setInterval(() => { setSecondsLeft(prev => { if (prev <= 1) { window.clearInterval(timer); router.push("/"); return 0; } return prev - 1; }); }, 1000); return () => window.clearInterval(timer); }, [redirectOpen, router]); const actionLabel = result?.status === "JOINED" ? "Joined" : result?.status === "PENDING" ? "Request sent" : result?.status === "ALREADY_MEMBER" ? "Already a member" : "Join group"; return (
{redirectMessage}
Taking you to entries in {secondsLeft}s.