Files
fotospiel-app/resources/js/guest-v2/context/EventDataContext.tsx
Codex Agent 83cf863548
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled
guest pwa: hide tasks when inactive and improve empty gallery state
2026-02-08 21:53:47 +01:00

143 lines
3.1 KiB
TypeScript

import React from 'react';
import { fetchEvent, type EventData, FetchEventError } from '../services/eventApi';
import { isTaskModeEnabled } from '@/shared/guest/lib/engagement';
import { fetchTasks } from '../services/tasksApi';
type EventDataStatus = 'idle' | 'loading' | 'ready' | 'error';
type EventDataContextValue = {
event: EventData | null;
status: EventDataStatus;
error: string | null;
token: string | null;
tasksEnabled: boolean;
hasActiveTasks: boolean;
};
const EventDataContext = React.createContext<EventDataContextValue>({
event: null,
status: 'idle',
error: null,
token: null,
tasksEnabled: true,
hasActiveTasks: true,
});
type EventDataProviderProps = {
token?: string | null;
tasksEnabledFallback?: boolean;
children: React.ReactNode;
};
export function EventDataProvider({
token,
tasksEnabledFallback = true,
children,
}: EventDataProviderProps) {
const [event, setEvent] = React.useState<EventData | null>(null);
const [status, setStatus] = React.useState<EventDataStatus>(token ? 'loading' : 'idle');
const [error, setError] = React.useState<string | null>(null);
React.useEffect(() => {
if (!token) {
setEvent(null);
setStatus('idle');
setError(null);
return;
}
let cancelled = false;
const loadEvent = async () => {
setStatus('loading');
setError(null);
try {
const eventData = await fetchEvent(token);
if (cancelled) {
return;
}
setEvent(eventData);
setStatus('ready');
} catch (err) {
if (cancelled) {
return;
}
setEvent(null);
setStatus('error');
if (err instanceof FetchEventError) {
setError(err.message);
} else if (err instanceof Error) {
setError(err.message || 'Event could not be loaded.');
} else {
setError('Event could not be loaded.');
}
}
};
loadEvent();
return () => {
cancelled = true;
};
}, [token]);
const tasksEnabled = event ? isTaskModeEnabled(event) : tasksEnabledFallback;
const [hasActiveTasks, setHasActiveTasks] = React.useState<boolean>(tasksEnabledFallback);
React.useEffect(() => {
if (!token) {
setHasActiveTasks(tasksEnabledFallback);
return;
}
if (!tasksEnabled) {
setHasActiveTasks(false);
return;
}
let cancelled = false;
fetchTasks(token, { page: 1, perPage: 1 })
.then((tasks) => {
if (cancelled) {
return;
}
setHasActiveTasks(tasks.length > 0);
})
.catch(() => {
if (cancelled) {
return;
}
setHasActiveTasks(true);
});
return () => {
cancelled = true;
};
}, [tasksEnabled, tasksEnabledFallback, token]);
return (
<EventDataContext.Provider
value={{
event,
status,
error,
token: token ?? null,
tasksEnabled,
hasActiveTasks,
}}
>
{children}
</EventDataContext.Provider>
);
}
export function useEventData() {
return React.useContext(EventDataContext);
}