import { useState, useEffect, useRef } from 'react'; import { useNavigate, useSearchParams } from 'react-router-dom'; import axios from 'axios'; export default function InviteResponse() { const [searchParams] = useSearchParams(); const navigate = useNavigate(); const [loading, setLoading] = useState(true); const [tokenData, setTokenData] = useState(null); const [error, setError] = useState(null); const [processing, setProcessing] = useState(false); const shouldAutoLink = useRef(false); const handleLinkAccount = async () => { setProcessing(true); setError(null); try { // Try to link the account directly - if not authenticated, backend will return 401 await axios.post('/api/link-account', { token: tokenData.token }, { withCredentials: true }); // Force a page reload to refresh user profile and trigger privacy settings check window.location.href = '/signin-landing'; } catch (err) { // If not authenticated, redirect to signin if (err.response?.status === 401 || err.response?.status === 403) { const returnUrl = encodeURIComponent(`/invite-response?token=${tokenData.token}&autolink=true`); navigate(`/signin?redirect=${returnUrl}`); return; } setError(err.response?.data?.error || 'Failed to link account. Please try again.'); setProcessing(false); } }; useEffect(() => { validateToken(); }, []); // Auto-link when tokenData is set and autolink flag is true useEffect(() => { if (tokenData && shouldAutoLink.current && !processing) { shouldAutoLink.current = false; // Prevent double-trigger handleLinkAccount(); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [tokenData]); const validateToken = async () => { const token = searchParams.get('token'); const autoLink = searchParams.get('autolink'); // Check if we should auto-link after signin if (!token) { setError('No invitation token provided'); setLoading(false); return; } try { // Decode token to check if it's for existing user const base64Url = token.split('.')[1]; const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/'); const payload = JSON.parse(window.atob(base64)); if (payload.prp !== 'student_invite') { setError('Invalid invitation token'); setLoading(false); return; } if (payload.isNewUser !== false) { // This is for a new user, redirect to signup navigate(`/signup?invite=${token}`, { replace: true }); return; } // Token is valid for existing user setTokenData({ token, organizationId: payload.organizationId, email: payload.email }); setLoading(false); // If autolink param is present, set flag to trigger auto-link if (autoLink === 'true') { shouldAutoLink.current = true; } } catch (err) { setError('Invalid invitation token'); setLoading(false); } }; const handleCreateSeparateAccount = () => { // User needs to contact admin for a new invitation with different email navigate('/', { replace: true }); }; if (loading) { return (
Validating invitation...
{error}
Choose how you'd like to proceed
We noticed you already have an AptivaAI account. You can either link your existing account or create a separate one for your organization.
{error}
Questions? Contact your administrator for help.