'use client'; import { Suspense, useEffect, useState } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; interface TokenInfo { groupName: string; expiresAt: string; isConsumed: boolean; isExpired: boolean; } function ClaimGroupContent() { const router = useRouter(); const searchParams = useSearchParams(); const token = searchParams.get('token'); const [info, setInfo] = useState(null); const [error, setError] = useState(null); const [busy, setBusy] = useState(false); const [success, setSuccess] = useState(false); useEffect(() => { if (!token) { setError('No claim token provided'); return; } fetch(`/api/groups/claim-token-info?token=${encodeURIComponent(token)}`) .then((r) => r.json().catch(() => null)) .then((data) => { if (data?.groupName) setInfo(data); else setError('Invalid or expired claim link'); }) .catch(() => setError('Failed to load claim info')); }, [token]); async function handleClaim() { if (!token) return; setBusy(true); setError(null); try { const res = await fetch('/api/groups/claim-with-token', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ token }), }); if (res.status === 401) { router.push(`/signup?redirect=/claim-group?token=${encodeURIComponent(token)}`); return; } if (!res.ok) { const body = await res.json().catch(() => ({})); setError(body.message ?? 'Claim failed'); return; } setSuccess(true); } finally { setBusy(false); } } if (error && !info) { return (

Claim Group

{error}

); } if (success) { return (

Group Claimed!

{info?.groupName ?? 'Group'} has been added to your tenant.

Go to Groups
); } return (

Claim Group

{info && (

Group:{' '} {info.groupName}

Expires: {new Date(info.expiresAt).toLocaleDateString()}

{info.isConsumed && (

This link has already been used.

)} {info.isExpired && (

This link has expired.

)}
)} {error && (

{error}

)}
); } export default function ClaimGroupPage() { return (

Loading…

}>
); }