Add EventThemesContext for managing event theme state

Introduced a new React context, EventThemesContext, to handle event theme state and CRUD operations. It includes support for creating, updating, deleting, and fetching themes with React Query integration. This provides a centralized solution for managing event theme-related data in the application.
This commit is contained in:
2025-03-12 15:55:28 +01:00
parent e2265573eb
commit 99ec4ebfa1

View File

@@ -0,0 +1,182 @@
"use client";
import React, {
createContext,
ReactNode,
useCallback,
useContext,
useState,
} from "react";
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import {
getEventThemeOptions,
listEventThemesOptions,
} from "@/client/@tanstack/react-query.gen";
import {
EventThemeCreate,
EventThemeResponse,
EventThemeUpdate,
} from "@/client/types.gen";
import { createEventTheme, deleteEventTheme, updateEventTheme } from "@/client";
// Event Theme context state
interface EventThemesContextState {
theme: EventThemeResponse | undefined;
themes: EventThemeResponse[] | undefined;
isLoadingThemes: boolean;
isLoadingTheme: boolean;
createTheme: (
data: EventThemeCreate,
) => Promise<EventThemeResponse | undefined>;
updateTheme: (
id: string,
data: EventThemeUpdate,
) => Promise<EventThemeResponse | undefined>;
deleteTheme: (id: string) => Promise<any>;
fetchThemeById: (id: string) => void;
error: Error | null;
currentThemeId: string | null;
setCurrentThemeId: (id: string | null) => void;
}
// Default state
const defaultEventThemesState: EventThemesContextState = {
theme: undefined,
themes: undefined,
isLoadingThemes: false,
isLoadingTheme: false,
createTheme: async () => {
throw new Error("EventThemesProvider not initialized");
},
updateTheme: async () => {
throw new Error("EventThemesProvider not initialized");
},
deleteTheme: async () => {
throw new Error("EventThemesProvider not initialized");
},
fetchThemeById: () => {},
error: null,
currentThemeId: null,
setCurrentThemeId: () => {},
};
// Create context
const EventThemesContext = createContext<EventThemesContextState>(
defaultEventThemesState,
);
// Hook to use the context
export const useEventThemes = () => {
const context = useContext(EventThemesContext);
if (!context) {
throw new Error("useEventThemes must be used within EventThemesProvider");
}
return context;
};
// Provider Props
interface EventThemesProviderProps {
children: ReactNode;
}
// Provider Component
export const EventThemesProvider: React.FC<EventThemesProviderProps> = ({
children,
}) => {
const queryClient = useQueryClient();
const [currentThemeId, setCurrentThemeId] = useState<string | null>(null);
// Fetch all themes
const {
data: themes,
isLoading: isLoadingThemes,
error,
} = useQuery({
...listEventThemesOptions(),
});
// Fetch specific theme
const { data: theme, isLoading: isLoadingTheme } = useQuery({
...getEventThemeOptions({ path: { theme_id: currentThemeId || "" } }),
enabled: !!currentThemeId,
});
// Fetch a single theme explicitly by ID
const fetchThemeById = useCallback((id: string) => {
setCurrentThemeId(id);
}, []);
// Mutations
const createMutation = useMutation({
mutationFn: (data: EventThemeCreate) =>
createEventTheme({ body: data }).then((result) => result.data),
onSuccess: () =>
queryClient.invalidateQueries({
queryKey: listEventThemesOptions().queryKey,
}),
});
const updateMutation = useMutation({
mutationFn: ({ id, data }: { id: string; data: EventThemeUpdate }) =>
updateEventTheme({ path: { theme_id: id }, body: data }).then(
(result) => result.data,
),
onSuccess: () =>
queryClient.invalidateQueries({
queryKey: listEventThemesOptions().queryKey,
}),
});
const deleteMutation = useMutation({
mutationFn: (id: string) =>
deleteEventTheme({ path: { theme_id: id } }).then(
(result) => result.data,
),
onSuccess: () =>
queryClient.invalidateQueries({
queryKey: listEventThemesOptions().queryKey,
}),
});
// CRUD methods exposed to context consumers
const createTheme = async (data: EventThemeCreate) => {
return createMutation.mutateAsync(data);
};
const updateTheme = async (id: string, data: EventThemeUpdate) => {
return updateMutation.mutateAsync({ id, data });
};
const deleteTheme = async (id: string) => {
return deleteMutation.mutateAsync(id);
};
const contextValue: EventThemesContextState = {
theme,
themes,
isLoadingThemes,
isLoadingTheme,
createTheme,
updateTheme,
deleteTheme,
fetchThemeById,
error: error as Error | null,
currentThemeId,
setCurrentThemeId,
};
return (
<EventThemesContext.Provider value={contextValue}>
{children}
</EventThemesContext.Provider>
);
};