Add initial implementation of gift context in frontend
This commit is contained in:
780
frontend/src/context/gift-context.tsx
Normal file
780
frontend/src/context/gift-context.tsx
Normal file
@@ -0,0 +1,780 @@
|
||||
"use client";
|
||||
|
||||
import React, { createContext, ReactNode, useContext } from "react";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import {
|
||||
createGiftCategory,
|
||||
readGiftCategories,
|
||||
deleteGiftCategory,
|
||||
readGiftCategory,
|
||||
updateGiftCategory,
|
||||
associateCategoryWithEvent,
|
||||
updateCategoryEventSettings,
|
||||
getEventsForCategory,
|
||||
reorderGiftsInCategory,
|
||||
createGiftItem,
|
||||
readGiftItems,
|
||||
deleteGiftItem,
|
||||
readGiftItem,
|
||||
updateGiftItem,
|
||||
updateGiftItemStatus,
|
||||
reserveGiftItem,
|
||||
cancelGiftReservation,
|
||||
createGiftPurchase,
|
||||
readGiftPurchase,
|
||||
readGiftPurchasesByGift,
|
||||
readGiftPurchasesByGuest,
|
||||
} from "@/client/sdk.gen";
|
||||
import {
|
||||
GiftCategory,
|
||||
GiftCategoryCreate,
|
||||
GiftCategoryUpdate,
|
||||
GiftItem,
|
||||
GiftItemCreate,
|
||||
GiftItemUpdate,
|
||||
GiftStatus,
|
||||
GiftPriority,
|
||||
GiftPurchase,
|
||||
GiftPurchaseCreate,
|
||||
} from "@/client/types.gen";
|
||||
|
||||
// Gift context state
|
||||
interface GiftContextState {
|
||||
// Gift Categories
|
||||
categories: GiftCategory[] | undefined;
|
||||
category: GiftCategory | undefined;
|
||||
isLoadingCategories: boolean;
|
||||
isLoadingCategory: boolean;
|
||||
refetchCategories: (eventId: string) => Promise<any>;
|
||||
|
||||
fetchCategoryById: (id: string, eventId?: string) => void;
|
||||
createCategory: (data: GiftCategoryCreate) => Promise<GiftCategory | undefined>;
|
||||
updateCategory: (
|
||||
id: string,
|
||||
data: GiftCategoryUpdate,
|
||||
eventId?: string
|
||||
) => Promise<GiftCategory | undefined>;
|
||||
deleteCategory: (id: string, eventId?: string) => Promise<GiftCategory | undefined>;
|
||||
associateCategoryWithEvent: (
|
||||
categoryId: string,
|
||||
eventId: string,
|
||||
displayOrder?: number,
|
||||
isVisible?: boolean
|
||||
) => Promise<GiftCategory | undefined>;
|
||||
updateCategoryEventSettings: (
|
||||
categoryId: string,
|
||||
eventId: string,
|
||||
displayOrder?: number,
|
||||
isVisible?: boolean
|
||||
) => Promise<GiftCategory | undefined>;
|
||||
getEventsForCategory: (categoryId: string) => Promise<any>;
|
||||
reorderGiftsInCategory: (
|
||||
categoryId: string,
|
||||
giftIds: string[]
|
||||
) => Promise<GiftCategory | undefined>;
|
||||
|
||||
// Gift Items
|
||||
items: GiftItem[] | undefined;
|
||||
item: GiftItem | undefined;
|
||||
isLoadingItems: boolean;
|
||||
isLoadingItem: boolean;
|
||||
refetchItems: (categoryId?: string, eventId?: string) => Promise<any>;
|
||||
|
||||
fetchItemById: (id: string) => void;
|
||||
createItem: (data: GiftItemCreate) => Promise<GiftItem | undefined>;
|
||||
updateItem: (
|
||||
id: string,
|
||||
data: GiftItemUpdate
|
||||
) => Promise<GiftItem | undefined>;
|
||||
deleteItem: (id: string) => Promise<GiftItem | undefined>;
|
||||
updateItemStatus: (
|
||||
id: string,
|
||||
status: GiftStatus
|
||||
) => Promise<GiftItem | undefined>;
|
||||
reserveItem: (
|
||||
id: string,
|
||||
guestId: string,
|
||||
quantity?: number
|
||||
) => Promise<GiftItem | undefined>;
|
||||
cancelReservation: (
|
||||
id: string,
|
||||
guestId: string
|
||||
) => Promise<GiftItem | undefined>;
|
||||
|
||||
// Gift Purchases
|
||||
purchases: GiftPurchase[] | undefined;
|
||||
purchase: GiftPurchase | undefined;
|
||||
isLoadingPurchases: boolean;
|
||||
isLoadingPurchase: boolean;
|
||||
refetchPurchases: (giftId?: string, guestId?: string) => Promise<any>;
|
||||
|
||||
fetchPurchaseById: (id: string) => void;
|
||||
createPurchase: (data: GiftPurchaseCreate) => Promise<GiftPurchase | undefined>;
|
||||
fetchPurchasesByGift: (giftId: string) => Promise<GiftPurchase[] | undefined>;
|
||||
fetchPurchasesByGuest: (guestId: string) => Promise<GiftPurchase[] | undefined>;
|
||||
|
||||
// Current selections
|
||||
currentCategoryId: string | null;
|
||||
setCurrentCategoryId: (id: string | null) => void;
|
||||
currentItemId: string | null;
|
||||
setCurrentItemId: (id: string | null) => void;
|
||||
currentPurchaseId: string | null;
|
||||
setCurrentPurchaseId: (id: string | null) => void;
|
||||
currentEventId: string | null;
|
||||
setCurrentEventId: (id: string | null) => void;
|
||||
|
||||
error: Error | null;
|
||||
}
|
||||
|
||||
// Default context state
|
||||
const defaultGiftContextState: GiftContextState = {
|
||||
// Gift Categories
|
||||
categories: undefined,
|
||||
category: undefined,
|
||||
isLoadingCategories: false,
|
||||
isLoadingCategory: false,
|
||||
refetchCategories: async () => {
|
||||
throw new Error("GiftContext not initialized");
|
||||
},
|
||||
|
||||
fetchCategoryById: () => {},
|
||||
createCategory: async () => {
|
||||
throw new Error("GiftContext not initialized");
|
||||
},
|
||||
updateCategory: async () => {
|
||||
throw new Error("GiftContext not initialized");
|
||||
},
|
||||
deleteCategory: async () => {
|
||||
throw new Error("GiftContext not initialized");
|
||||
},
|
||||
associateCategoryWithEvent: async () => {
|
||||
throw new Error("GiftContext not initialized");
|
||||
},
|
||||
updateCategoryEventSettings: async () => {
|
||||
throw new Error("GiftContext not initialized");
|
||||
},
|
||||
getEventsForCategory: async () => {
|
||||
throw new Error("GiftContext not initialized");
|
||||
},
|
||||
reorderGiftsInCategory: async () => {
|
||||
throw new Error("GiftContext not initialized");
|
||||
},
|
||||
|
||||
// Gift Items
|
||||
items: undefined,
|
||||
item: undefined,
|
||||
isLoadingItems: false,
|
||||
isLoadingItem: false,
|
||||
refetchItems: async () => {
|
||||
throw new Error("GiftContext not initialized");
|
||||
},
|
||||
|
||||
fetchItemById: () => {},
|
||||
createItem: async () => {
|
||||
throw new Error("GiftContext not initialized");
|
||||
},
|
||||
updateItem: async () => {
|
||||
throw new Error("GiftContext not initialized");
|
||||
},
|
||||
deleteItem: async () => {
|
||||
throw new Error("GiftContext not initialized");
|
||||
},
|
||||
updateItemStatus: async () => {
|
||||
throw new Error("GiftContext not initialized");
|
||||
},
|
||||
reserveItem: async () => {
|
||||
throw new Error("GiftContext not initialized");
|
||||
},
|
||||
cancelReservation: async () => {
|
||||
throw new Error("GiftContext not initialized");
|
||||
},
|
||||
|
||||
// Gift Purchases
|
||||
purchases: undefined,
|
||||
purchase: undefined,
|
||||
isLoadingPurchases: false,
|
||||
isLoadingPurchase: false,
|
||||
refetchPurchases: async () => {
|
||||
throw new Error("GiftContext not initialized");
|
||||
},
|
||||
|
||||
fetchPurchaseById: () => {},
|
||||
createPurchase: async () => {
|
||||
throw new Error("GiftContext not initialized");
|
||||
},
|
||||
fetchPurchasesByGift: async () => {
|
||||
throw new Error("GiftContext not initialized");
|
||||
},
|
||||
fetchPurchasesByGuest: async () => {
|
||||
throw new Error("GiftContext not initialized");
|
||||
},
|
||||
|
||||
// Current selections
|
||||
currentCategoryId: null,
|
||||
setCurrentCategoryId: () => {},
|
||||
currentItemId: null,
|
||||
setCurrentItemId: () => {},
|
||||
currentPurchaseId: null,
|
||||
setCurrentPurchaseId: () => {},
|
||||
currentEventId: null,
|
||||
setCurrentEventId: () => {},
|
||||
|
||||
error: null,
|
||||
};
|
||||
|
||||
// Create context
|
||||
const GiftContext = createContext<GiftContextState>(defaultGiftContextState);
|
||||
|
||||
// Hook to use context
|
||||
export const useGifts = () => {
|
||||
const context = useContext(GiftContext);
|
||||
if (!context) {
|
||||
throw new Error("useGifts must be used within a GiftProvider");
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
||||
// Gift Provider Props
|
||||
interface GiftProviderProps {
|
||||
children: ReactNode;
|
||||
}
|
||||
|
||||
// Gift Provider Component
|
||||
export const GiftProvider: React.FC<GiftProviderProps> = ({ children }) => {
|
||||
const queryClient = useQueryClient();
|
||||
const [currentCategoryId, setCurrentCategoryId] = React.useState<string | null>(null);
|
||||
const [currentItemId, setCurrentItemId] = React.useState<string | null>(null);
|
||||
const [currentPurchaseId, setCurrentPurchaseId] = React.useState<string | null>(null);
|
||||
const [currentEventId, setCurrentEventId] = React.useState<string | null>(null);
|
||||
|
||||
// Fetch all categories for an event
|
||||
const {
|
||||
data: categories,
|
||||
isLoading: isLoadingCategories,
|
||||
error: categoriesError,
|
||||
refetch: refetchCategoriesInternal,
|
||||
} = useQuery({
|
||||
queryKey: ["giftCategories", currentEventId],
|
||||
queryFn: () =>
|
||||
currentEventId
|
||||
? readGiftCategories({
|
||||
path: { event_id: currentEventId }
|
||||
}).then((res) => res.data)
|
||||
: Promise.resolve(undefined),
|
||||
enabled: !!currentEventId,
|
||||
});
|
||||
|
||||
const refetchCategories = async (eventId: string) => {
|
||||
setCurrentEventId(eventId);
|
||||
return refetchCategoriesInternal();
|
||||
};
|
||||
|
||||
// Fetch specific category
|
||||
const {
|
||||
data: category,
|
||||
isLoading: isLoadingCategory,
|
||||
error: categoryError,
|
||||
} = useQuery({
|
||||
queryKey: ["giftCategory", currentCategoryId, currentEventId],
|
||||
queryFn: () =>
|
||||
currentCategoryId
|
||||
? readGiftCategory({
|
||||
path: {
|
||||
category_id: currentCategoryId
|
||||
},
|
||||
query: currentEventId ? { event_id: currentEventId } : undefined
|
||||
}).then((res) => res.data)
|
||||
: Promise.resolve(undefined),
|
||||
enabled: !!currentCategoryId,
|
||||
});
|
||||
|
||||
const fetchCategoryById = (id: string, eventId?: string) => {
|
||||
setCurrentCategoryId(id);
|
||||
if (eventId) {
|
||||
setCurrentEventId(eventId);
|
||||
}
|
||||
};
|
||||
|
||||
// Create Category Mutation
|
||||
const createCategoryMutation = useMutation({
|
||||
mutationFn: (data: GiftCategoryCreate) =>
|
||||
createGiftCategory({ body: data }).then((res) => res.data),
|
||||
onSuccess: () => {
|
||||
if (currentEventId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftCategories", currentEventId] });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Update Category Mutation
|
||||
const updateCategoryMutation = useMutation({
|
||||
mutationFn: ({
|
||||
id,
|
||||
data,
|
||||
eventId
|
||||
}: {
|
||||
id: string;
|
||||
data: GiftCategoryUpdate;
|
||||
eventId?: string;
|
||||
}) =>
|
||||
updateGiftCategory({
|
||||
path: { category_id: id },
|
||||
body: data,
|
||||
query: eventId ? { event_id: eventId } : undefined
|
||||
}).then((res) => res.data),
|
||||
onSuccess: () => {
|
||||
if (currentEventId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftCategories", currentEventId] });
|
||||
}
|
||||
if (currentCategoryId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftCategory", currentCategoryId] });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Delete Category Mutation
|
||||
const deleteCategoryMutation = useMutation({
|
||||
mutationFn: ({ id, eventId }: { id: string; eventId?: string }) =>
|
||||
deleteGiftCategory({
|
||||
path: { category_id: id },
|
||||
query: eventId ? { event_id: eventId } : undefined
|
||||
}).then((res) => res.data),
|
||||
onSuccess: () => {
|
||||
if (currentEventId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftCategories", currentEventId] });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Fetch all items for a category or event
|
||||
const {
|
||||
data: items,
|
||||
isLoading: isLoadingItems,
|
||||
error: itemsError,
|
||||
refetch: refetchItemsInternal,
|
||||
} = useQuery({
|
||||
queryKey: ["giftItems", currentCategoryId, currentEventId],
|
||||
queryFn: () => {
|
||||
const query: Record<string, string> = {};
|
||||
if (currentCategoryId) {
|
||||
query.category_id = currentCategoryId;
|
||||
}
|
||||
if (currentEventId) {
|
||||
query.event_id = currentEventId;
|
||||
}
|
||||
|
||||
return Object.keys(query).length > 0
|
||||
? readGiftItems({ query }).then((res) => res.data)
|
||||
: Promise.resolve(undefined);
|
||||
},
|
||||
enabled: !!(currentCategoryId || currentEventId),
|
||||
});
|
||||
|
||||
const refetchItems = async (categoryId?: string, eventId?: string) => {
|
||||
if (categoryId) {
|
||||
setCurrentCategoryId(categoryId);
|
||||
}
|
||||
if (eventId) {
|
||||
setCurrentEventId(eventId);
|
||||
}
|
||||
return refetchItemsInternal();
|
||||
};
|
||||
|
||||
// Fetch specific item
|
||||
const {
|
||||
data: item,
|
||||
isLoading: isLoadingItem,
|
||||
error: itemError,
|
||||
} = useQuery({
|
||||
queryKey: ["giftItem", currentItemId],
|
||||
queryFn: () =>
|
||||
currentItemId
|
||||
? readGiftItem({
|
||||
path: {
|
||||
gift_id: currentItemId
|
||||
}
|
||||
}).then((res) => res.data)
|
||||
: Promise.resolve(undefined),
|
||||
enabled: !!currentItemId,
|
||||
});
|
||||
|
||||
const fetchItemById = (id: string) => {
|
||||
setCurrentItemId(id);
|
||||
};
|
||||
|
||||
// Create Item Mutation
|
||||
const createItemMutation = useMutation({
|
||||
mutationFn: (data: GiftItemCreate) =>
|
||||
createGiftItem({ body: data }).then((res) => res.data),
|
||||
onSuccess: () => {
|
||||
if (currentCategoryId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftItems", currentCategoryId] });
|
||||
}
|
||||
if (currentEventId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftItems", null, currentEventId] });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Update Item Mutation
|
||||
const updateItemMutation = useMutation({
|
||||
mutationFn: ({
|
||||
id,
|
||||
data
|
||||
}: {
|
||||
id: string;
|
||||
data: GiftItemUpdate;
|
||||
}) =>
|
||||
updateGiftItem({
|
||||
path: { gift_id: id },
|
||||
body: data
|
||||
}).then((res) => res.data),
|
||||
onSuccess: () => {
|
||||
if (currentCategoryId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftItems", currentCategoryId] });
|
||||
}
|
||||
if (currentEventId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftItems", null, currentEventId] });
|
||||
}
|
||||
if (currentItemId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftItem", currentItemId] });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Delete Item Mutation
|
||||
const deleteItemMutation = useMutation({
|
||||
mutationFn: (id: string) =>
|
||||
deleteGiftItem({
|
||||
path: { gift_id: id }
|
||||
}).then((res) => res.data),
|
||||
onSuccess: () => {
|
||||
if (currentCategoryId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftItems", currentCategoryId] });
|
||||
}
|
||||
if (currentEventId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftItems", null, currentEventId] });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Update Item Status Mutation
|
||||
const updateItemStatusMutation = useMutation({
|
||||
mutationFn: ({
|
||||
id,
|
||||
status
|
||||
}: {
|
||||
id: string;
|
||||
status: GiftStatus;
|
||||
}) =>
|
||||
updateGiftItemStatus({
|
||||
path: { gift_id: id },
|
||||
body: { status }
|
||||
}).then((res) => res.data),
|
||||
onSuccess: () => {
|
||||
if (currentCategoryId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftItems", currentCategoryId] });
|
||||
}
|
||||
if (currentEventId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftItems", null, currentEventId] });
|
||||
}
|
||||
if (currentItemId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftItem", currentItemId] });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Reserve Item Mutation
|
||||
const reserveItemMutation = useMutation({
|
||||
mutationFn: ({
|
||||
id,
|
||||
guestId,
|
||||
quantity
|
||||
}: {
|
||||
id: string;
|
||||
guestId: string;
|
||||
quantity?: number;
|
||||
}) =>
|
||||
reserveGiftItem({
|
||||
path: { gift_id: id },
|
||||
body: {
|
||||
guest_id: guestId,
|
||||
quantity
|
||||
}
|
||||
}).then((res) => res.data),
|
||||
onSuccess: () => {
|
||||
if (currentCategoryId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftItems", currentCategoryId] });
|
||||
}
|
||||
if (currentEventId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftItems", null, currentEventId] });
|
||||
}
|
||||
if (currentItemId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftItem", currentItemId] });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Cancel Reservation Mutation
|
||||
const cancelReservationMutation = useMutation({
|
||||
mutationFn: ({
|
||||
id,
|
||||
guestId
|
||||
}: {
|
||||
id: string;
|
||||
guestId: string;
|
||||
}) =>
|
||||
cancelGiftReservation({
|
||||
path: {
|
||||
gift_id: id,
|
||||
guest_id: guestId
|
||||
}
|
||||
}).then((res) => res.data),
|
||||
onSuccess: () => {
|
||||
if (currentCategoryId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftItems", currentCategoryId] });
|
||||
}
|
||||
if (currentEventId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftItems", null, currentEventId] });
|
||||
}
|
||||
if (currentItemId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftItem", currentItemId] });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Associate Category With Event Mutation
|
||||
const associateCategoryWithEventMutation = useMutation({
|
||||
mutationFn: ({
|
||||
categoryId,
|
||||
eventId,
|
||||
displayOrder,
|
||||
isVisible
|
||||
}: {
|
||||
categoryId: string;
|
||||
eventId: string;
|
||||
displayOrder?: number;
|
||||
isVisible?: boolean;
|
||||
}) =>
|
||||
associateCategoryWithEvent({
|
||||
path: {
|
||||
category_id: categoryId,
|
||||
event_id: eventId
|
||||
},
|
||||
body: {
|
||||
display_order: displayOrder,
|
||||
is_visible: isVisible
|
||||
}
|
||||
}).then((res) => res.data),
|
||||
onSuccess: () => {
|
||||
if (currentEventId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftCategories", currentEventId] });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Update Category Event Settings Mutation
|
||||
const updateCategoryEventSettingsMutation = useMutation({
|
||||
mutationFn: ({
|
||||
categoryId,
|
||||
eventId,
|
||||
displayOrder,
|
||||
isVisible
|
||||
}: {
|
||||
categoryId: string;
|
||||
eventId: string;
|
||||
displayOrder?: number;
|
||||
isVisible?: boolean;
|
||||
}) =>
|
||||
updateCategoryEventSettings({
|
||||
path: {
|
||||
category_id: categoryId,
|
||||
event_id: eventId
|
||||
},
|
||||
body: {
|
||||
display_order: displayOrder,
|
||||
is_visible: isVisible
|
||||
}
|
||||
}).then((res) => res.data),
|
||||
onSuccess: () => {
|
||||
if (currentEventId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftCategories", currentEventId] });
|
||||
}
|
||||
if (currentCategoryId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftCategory", currentCategoryId] });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Get Events For Category Query
|
||||
const getEventsForCategoryQuery = async (categoryId: string) => {
|
||||
return getEventsForCategory({
|
||||
path: { category_id: categoryId }
|
||||
}).then((res) => res.data);
|
||||
};
|
||||
|
||||
// Reorder Gifts In Category Mutation
|
||||
const reorderGiftsInCategoryMutation = useMutation({
|
||||
mutationFn: ({
|
||||
categoryId,
|
||||
giftIds
|
||||
}: {
|
||||
categoryId: string;
|
||||
giftIds: string[];
|
||||
}) =>
|
||||
reorderGiftsInCategory({
|
||||
path: { category_id: categoryId },
|
||||
body: { gift_ids: giftIds }
|
||||
}).then((res) => res.data),
|
||||
onSuccess: () => {
|
||||
if (currentCategoryId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftCategory", currentCategoryId] });
|
||||
}
|
||||
if (currentEventId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftCategories", currentEventId] });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Fetch all purchases for a gift or guest
|
||||
const {
|
||||
data: purchases,
|
||||
isLoading: isLoadingPurchases,
|
||||
error: purchasesError,
|
||||
refetch: refetchPurchasesInternal,
|
||||
} = useQuery({
|
||||
queryKey: ["giftPurchases", currentItemId, null],
|
||||
queryFn: () =>
|
||||
currentItemId
|
||||
? readGiftPurchasesByGift({
|
||||
path: { gift_id: currentItemId }
|
||||
}).then((res) => res.data)
|
||||
: Promise.resolve(undefined),
|
||||
enabled: !!currentItemId,
|
||||
});
|
||||
|
||||
const refetchPurchases = async (giftId?: string, guestId?: string) => {
|
||||
if (giftId) {
|
||||
setCurrentItemId(giftId);
|
||||
}
|
||||
return refetchPurchasesInternal();
|
||||
};
|
||||
|
||||
// Fetch specific purchase
|
||||
const {
|
||||
data: purchase,
|
||||
isLoading: isLoadingPurchase,
|
||||
error: purchaseError,
|
||||
} = useQuery({
|
||||
queryKey: ["giftPurchase", currentPurchaseId],
|
||||
queryFn: () =>
|
||||
currentPurchaseId
|
||||
? readGiftPurchase({
|
||||
path: { purchase_id: currentPurchaseId }
|
||||
}).then((res) => res.data)
|
||||
: Promise.resolve(undefined),
|
||||
enabled: !!currentPurchaseId,
|
||||
});
|
||||
|
||||
const fetchPurchaseById = (id: string) => {
|
||||
setCurrentPurchaseId(id);
|
||||
};
|
||||
|
||||
// Create Purchase Mutation
|
||||
const createPurchaseMutation = useMutation({
|
||||
mutationFn: (data: GiftPurchaseCreate) =>
|
||||
createGiftPurchase({ body: data }).then((res) => res.data),
|
||||
onSuccess: () => {
|
||||
if (currentItemId) {
|
||||
queryClient.invalidateQueries({ queryKey: ["giftPurchases", currentItemId] });
|
||||
queryClient.invalidateQueries({ queryKey: ["giftItem", currentItemId] });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// Fetch Purchases By Gift
|
||||
const fetchPurchasesByGiftQuery = async (giftId: string) => {
|
||||
return readGiftPurchasesByGift({
|
||||
path: { gift_id: giftId }
|
||||
}).then((res) => res.data);
|
||||
};
|
||||
|
||||
// Fetch Purchases By Guest
|
||||
const fetchPurchasesByGuestQuery = async (guestId: string) => {
|
||||
return readGiftPurchasesByGuest({
|
||||
path: { guest_id: guestId }
|
||||
}).then((res) => res.data);
|
||||
};
|
||||
|
||||
const contextValue: GiftContextState = {
|
||||
// Gift Categories
|
||||
categories,
|
||||
category,
|
||||
isLoadingCategories,
|
||||
isLoadingCategory,
|
||||
refetchCategories,
|
||||
|
||||
fetchCategoryById,
|
||||
createCategory: createCategoryMutation.mutateAsync,
|
||||
updateCategory: (id, data, eventId) =>
|
||||
updateCategoryMutation.mutateAsync({ id, data, eventId }),
|
||||
deleteCategory: (id, eventId) =>
|
||||
deleteCategoryMutation.mutateAsync({ id, eventId }),
|
||||
|
||||
// Gift Items
|
||||
items,
|
||||
item,
|
||||
isLoadingItems,
|
||||
isLoadingItem,
|
||||
refetchItems,
|
||||
|
||||
fetchItemById,
|
||||
createItem: createItemMutation.mutateAsync,
|
||||
updateItem: (id, data) =>
|
||||
updateItemMutation.mutateAsync({ id, data }),
|
||||
deleteItem: deleteItemMutation.mutateAsync,
|
||||
updateItemStatus: (id, status) =>
|
||||
updateItemStatusMutation.mutateAsync({ id, status }),
|
||||
reserveItem: (id, guestId, quantity) =>
|
||||
reserveItemMutation.mutateAsync({ id, guestId, quantity }),
|
||||
cancelReservation: (id, guestId) =>
|
||||
cancelReservationMutation.mutateAsync({ id, guestId }),
|
||||
|
||||
// Gift Categories additional methods
|
||||
associateCategoryWithEvent: (categoryId, eventId, displayOrder, isVisible) =>
|
||||
associateCategoryWithEventMutation.mutateAsync({ categoryId, eventId, displayOrder, isVisible }),
|
||||
updateCategoryEventSettings: (categoryId, eventId, displayOrder, isVisible) =>
|
||||
updateCategoryEventSettingsMutation.mutateAsync({ categoryId, eventId, displayOrder, isVisible }),
|
||||
getEventsForCategory: getEventsForCategoryQuery,
|
||||
reorderGiftsInCategory: (categoryId, giftIds) =>
|
||||
reorderGiftsInCategoryMutation.mutateAsync({ categoryId, giftIds }),
|
||||
|
||||
// Gift Purchases
|
||||
purchases,
|
||||
purchase,
|
||||
isLoadingPurchases,
|
||||
isLoadingPurchase,
|
||||
refetchPurchases,
|
||||
|
||||
fetchPurchaseById,
|
||||
createPurchase: createPurchaseMutation.mutateAsync,
|
||||
fetchPurchasesByGift: fetchPurchasesByGiftQuery,
|
||||
fetchPurchasesByGuest: fetchPurchasesByGuestQuery,
|
||||
|
||||
// Current selections
|
||||
currentCategoryId,
|
||||
setCurrentCategoryId,
|
||||
currentItemId,
|
||||
setCurrentItemId,
|
||||
currentPurchaseId,
|
||||
setCurrentPurchaseId,
|
||||
currentEventId,
|
||||
setCurrentEventId,
|
||||
|
||||
error: (categoriesError || categoryError || itemsError || itemError || purchasesError || purchaseError) as Error | null,
|
||||
};
|
||||
|
||||
return (
|
||||
<GiftContext.Provider value={contextValue}>{children}</GiftContext.Provider>
|
||||
);
|
||||
};
|
||||
@@ -3,13 +3,16 @@ import { EventsProvider } from "@/context/event-context";
|
||||
import { EventThemesProvider } from "@/context/event-theme-context";
|
||||
import { RSVPProvider } from "@/context/rsvp-context";
|
||||
import { GuestsProvider } from "@/context/guest-context";
|
||||
import { GiftProvider } from "@/context/gift-context";
|
||||
|
||||
export function DataProviders({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<EventThemesProvider>
|
||||
<EventsProvider>
|
||||
<GuestsProvider>
|
||||
<RSVPProvider>{children}</RSVPProvider>
|
||||
<GiftProvider>
|
||||
<RSVPProvider>{children}</RSVPProvider>
|
||||
</GiftProvider>
|
||||
</GuestsProvider>
|
||||
</EventsProvider>
|
||||
</EventThemesProvider>
|
||||
|
||||
Reference in New Issue
Block a user