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:
182
frontend/src/context/event-theme-context.tsx
Normal file
182
frontend/src/context/event-theme-context.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user