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