import { useState, useEffect } from 'react'; import { useParams } from 'react-router-dom'; import { fetchEvent, EventData, FetchEventError, FetchEventErrorCode, } from '../services/eventApi'; type EventDataStatus = 'loading' | 'ready' | 'error'; interface UseEventDataResult { event: EventData | null; status: EventDataStatus; loading: boolean; error: string | null; errorCode: FetchEventErrorCode | null; token: string | null; } const NO_TOKEN_ERROR_MESSAGE = 'Es wurde kein Einladungscode übergeben.'; const eventCache = new Map(); export function useEventData(): UseEventDataResult { const { token } = useParams<{ token: string }>(); const cachedEvent = token ? eventCache.get(token) ?? null : null; const [event, setEvent] = useState(cachedEvent); const [status, setStatus] = useState(token ? (cachedEvent ? 'ready' : 'loading') : 'error'); const [errorMessage, setErrorMessage] = useState(token ? null : NO_TOKEN_ERROR_MESSAGE); const [errorCode, setErrorCode] = useState(token ? null : 'invalid_token'); useEffect(() => { if (!token) { setEvent(null); setStatus('error'); setErrorCode('invalid_token'); setErrorMessage(NO_TOKEN_ERROR_MESSAGE); return; } let cancelled = false; const loadEvent = async () => { const cached = eventCache.get(token) ?? null; if (!cached) { setStatus('loading'); } setErrorCode(null); setErrorMessage(null); try { const eventData = await fetchEvent(token); if (cancelled) { return; } eventCache.set(token, eventData); setEvent(eventData); setStatus('ready'); } catch (err) { if (cancelled) { return; } if (cached) { setEvent(cached); setStatus('ready'); return; } setEvent(null); setStatus('error'); if (err instanceof FetchEventError) { setErrorCode(err.code); setErrorMessage(err.message); } else if (err instanceof Error) { setErrorCode('unknown'); setErrorMessage(err.message || 'Event konnte nicht geladen werden.'); } else { setErrorCode('unknown'); setErrorMessage('Event konnte nicht geladen werden.'); } } }; loadEvent(); return () => { cancelled = true; }; }, [token]); return { event, status, loading: status === 'loading', error: errorMessage, errorCode, token: token ?? null, }; }