more integration tests added
All checks were successful
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Successful in 2m43s
All checks were successful
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Successful in 2m43s
This commit is contained in:
@@ -368,12 +368,12 @@ export const countFlyerItemsForFlyers = async (flyerIds: number[]): Promise<numb
|
||||
* @param logoImage The logo image file.
|
||||
* @returns A promise that resolves with the new logo URL.
|
||||
*/
|
||||
export const uploadLogoAndUpdateStore = async (storeId: number, logoImage: File): Promise<{ logoUrl: string }> => {
|
||||
export const uploadLogoAndUpdateStore = async (storeId: number, logoImage: File, tokenOverride?: string): Promise<{ logoUrl: string }> => {
|
||||
const formData = new FormData();
|
||||
formData.append('logoImage', logoImage);
|
||||
|
||||
// Use apiFetch to ensure the user is authenticated to perform this action.
|
||||
const response = await apiFetch(`${API_BASE_URL}/stores/${storeId}/logo`, {
|
||||
const response = await apiFetch(`/stores/${storeId}/logo`, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
// Do not set Content-Type for FormData, browser handles it.
|
||||
@@ -388,12 +388,12 @@ export const uploadLogoAndUpdateStore = async (storeId: number, logoImage: File)
|
||||
* @param logoImage The logo image file.
|
||||
* @returns A promise that resolves with the new logo URL.
|
||||
*/
|
||||
export const uploadBrandLogo = async (brandId: number, logoImage: File): Promise<{ logoUrl: string }> => {
|
||||
export const uploadBrandLogo = async (brandId: number, logoImage: File, tokenOverride?: string): Promise<{ logoUrl: string }> => {
|
||||
const formData = new FormData();
|
||||
formData.append('logoImage', logoImage);
|
||||
|
||||
// Use apiFetch to ensure the user is an authenticated admin.
|
||||
const response = await apiFetch(`${API_BASE_URL}/admin/brands/${brandId}/logo`, {
|
||||
const response = await apiFetch(`/admin/brands/${brandId}/logo`, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
// Do not set Content-Type for FormData, browser handles it.
|
||||
@@ -408,12 +408,12 @@ export const uploadBrandLogo = async (brandId: number, logoImage: File): Promise
|
||||
* @param masterItemIds An array of master grocery item IDs.
|
||||
* @returns A promise that resolves to an array of historical price records.
|
||||
*/
|
||||
export const fetchHistoricalPriceData = async (masterItemIds: number[]): Promise<{ master_item_id: number; summary_date: string; avg_price_in_cents: number | null; }[]> => {
|
||||
export const fetchHistoricalPriceData = async (masterItemIds: number[], tokenOverride?: string): Promise<{ master_item_id: number; summary_date: string; avg_price_in_cents: number | null; }[]> => {
|
||||
if (masterItemIds.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const response = await apiFetch(`${API_BASE_URL}/price-history`, {
|
||||
const response = await apiFetch(`/price-history`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ masterItemIds }),
|
||||
@@ -429,8 +429,8 @@ export const fetchHistoricalPriceData = async (masterItemIds: number[]): Promise
|
||||
|
||||
// --- Watched Items API Functions ---
|
||||
|
||||
export const fetchWatchedItems = async (): Promise<MasterGroceryItem[]> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/watched-items`);
|
||||
export const fetchWatchedItems = async (tokenOverride?: string): Promise<MasterGroceryItem[]> => {
|
||||
const response = await apiFetch(`/watched-items`, {}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to fetch watched items.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -438,12 +438,12 @@ export const fetchWatchedItems = async (): Promise<MasterGroceryItem[]> => {
|
||||
return response.json();
|
||||
};
|
||||
|
||||
export const addWatchedItem = async (itemName: string, category: string): Promise<MasterGroceryItem> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/watched-items`, {
|
||||
export const addWatchedItem = async (itemName: string, category: string, tokenOverride?: string): Promise<MasterGroceryItem> => {
|
||||
const response = await apiFetch(`/watched-items`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ itemName, category }),
|
||||
});
|
||||
}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to add watched item.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -451,10 +451,10 @@ export const addWatchedItem = async (itemName: string, category: string): Promis
|
||||
return response.json();
|
||||
};
|
||||
|
||||
export const removeWatchedItem = async (masterItemId: number): Promise<void> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/watched-items/${masterItemId}`, {
|
||||
export const removeWatchedItem = async (masterItemId: number, tokenOverride?: string): Promise<void> => {
|
||||
const response = await apiFetch(`/watched-items/${masterItemId}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to remove watched item.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -463,8 +463,8 @@ export const removeWatchedItem = async (masterItemId: number): Promise<void> =>
|
||||
|
||||
// --- Shopping List API Functions ---
|
||||
|
||||
export const fetchShoppingLists = async (): Promise<ShoppingList[]> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/shopping-lists`);
|
||||
export const fetchShoppingLists = async (tokenOverride?: string): Promise<ShoppingList[]> => {
|
||||
const response = await apiFetch(`/shopping-lists`, {}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to fetch shopping lists.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -472,12 +472,12 @@ export const fetchShoppingLists = async (): Promise<ShoppingList[]> => {
|
||||
return response.json();
|
||||
};
|
||||
|
||||
export const createShoppingList = async (name: string): Promise<ShoppingList> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/shopping-lists`, {
|
||||
export const createShoppingList = async (name: string, tokenOverride?: string): Promise<ShoppingList> => {
|
||||
const response = await apiFetch(`/shopping-lists`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ name }),
|
||||
});
|
||||
}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to create shopping list.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -485,22 +485,22 @@ export const createShoppingList = async (name: string): Promise<ShoppingList> =>
|
||||
return response.json();
|
||||
};
|
||||
|
||||
export const deleteShoppingList = async (listId: number): Promise<void> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/shopping-lists/${listId}`, {
|
||||
export const deleteShoppingList = async (listId: number, tokenOverride?: string): Promise<void> => {
|
||||
const response = await apiFetch(`/shopping-lists/${listId}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to delete shopping list.' }));
|
||||
throw new Error(errorData.message);
|
||||
}
|
||||
};
|
||||
|
||||
export const addShoppingListItem = async (listId: number, item: { masterItemId?: number, customItemName?: string }): Promise<ShoppingListItem> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/shopping-lists/${listId}/items`, {
|
||||
export const addShoppingListItem = async (listId: number, item: { masterItemId?: number, customItemName?: string }, tokenOverride?: string): Promise<ShoppingListItem> => {
|
||||
const response = await apiFetch(`/shopping-lists/${listId}/items`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(item),
|
||||
});
|
||||
}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to add item to list.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -508,12 +508,12 @@ export const addShoppingListItem = async (listId: number, item: { masterItemId?:
|
||||
return response.json();
|
||||
};
|
||||
|
||||
export const updateShoppingListItem = async (itemId: number, updates: Partial<ShoppingListItem>): Promise<ShoppingListItem> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/shopping-lists/items/${itemId}`, {
|
||||
export const updateShoppingListItem = async (itemId: number, updates: Partial<ShoppingListItem>, tokenOverride?: string): Promise<ShoppingListItem> => {
|
||||
const response = await apiFetch(`/shopping-lists/items/${itemId}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(updates),
|
||||
});
|
||||
}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to update list item.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -521,10 +521,10 @@ export const updateShoppingListItem = async (itemId: number, updates: Partial<Sh
|
||||
return response.json();
|
||||
};
|
||||
|
||||
export const removeShoppingListItem = async (itemId: number): Promise<void> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/shopping-lists/items/${itemId}`, {
|
||||
export const removeShoppingListItem = async (itemId: number, tokenOverride?: string): Promise<void> => {
|
||||
const response = await apiFetch(`/shopping-lists/items/${itemId}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to remove list item.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -581,13 +581,13 @@ export async function loginUser(email: string, password: string, rememberMe: boo
|
||||
* @param receiptImage The image file of the receipt.
|
||||
* @returns A promise that resolves with the backend's response, including the newly created receipt record.
|
||||
*/
|
||||
export const uploadReceipt = async (receiptImage: File): Promise<{ message: string; receipt: Receipt }> => {
|
||||
export const uploadReceipt = async (receiptImage: File, tokenOverride?: string): Promise<{ message: string; receipt: Receipt }> => {
|
||||
const formData = new FormData();
|
||||
formData.append('receiptImage', receiptImage);
|
||||
|
||||
// Use apiFetch to ensure the user is authenticated for this action.
|
||||
// The browser will automatically set the correct 'Content-Type' for FormData.
|
||||
const response = await apiFetch(`${API_BASE_URL}/receipts/upload`, {
|
||||
const response = await apiFetch(`/receipts/upload`, {
|
||||
method: 'POST',
|
||||
body: formData,
|
||||
});
|
||||
@@ -604,8 +604,8 @@ export const uploadReceipt = async (receiptImage: File): Promise<{ message: stri
|
||||
* @param receiptId The ID of the processed receipt.
|
||||
* @returns A promise that resolves to an array of ReceiptDeal objects.
|
||||
*/
|
||||
export const getDealsForReceipt = async (receiptId: number): Promise<ReceiptDeal[]> => {
|
||||
const response = await apiFetch(`/receipts/${receiptId}/deals`);
|
||||
export const getDealsForReceipt = async (receiptId: number, tokenOverride?: string): Promise<ReceiptDeal[]> => {
|
||||
const response = await apiFetch(`/receipts/${receiptId}/deals`, {}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to fetch deals for receipt.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -641,9 +641,9 @@ export const trackFlyerItemInteraction = async (itemId: number, type: 'view' | '
|
||||
* This is a "fire-and-forget" call.
|
||||
* @param query The search query data to log.
|
||||
*/
|
||||
export const logSearchQuery = async (query: Omit<SearchQuery, 'id' | 'created_at' | 'user_id'>): Promise<void> => {
|
||||
export const logSearchQuery = async (query: Omit<SearchQuery, 'id' | 'created_at' | 'user_id'>, tokenOverride?: string): Promise<void> => {
|
||||
try {
|
||||
apiFetch(`${API_BASE_URL}/search/log`, {
|
||||
apiFetch(`/search/log`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(query),
|
||||
@@ -658,8 +658,8 @@ export const logSearchQuery = async (query: Omit<SearchQuery, 'id' | 'created_at
|
||||
* Fetches all pantry locations for the current user.
|
||||
* @returns A promise that resolves to an array of PantryLocation objects.
|
||||
*/
|
||||
export const getPantryLocations = async (): Promise<PantryLocation[]> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/pantry/locations`);
|
||||
export const getPantryLocations = async (tokenOverride?: string): Promise<PantryLocation[]> => {
|
||||
const response = await apiFetch(`/pantry/locations`, {}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to fetch pantry locations.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -672,12 +672,12 @@ export const getPantryLocations = async (): Promise<PantryLocation[]> => {
|
||||
* @param name The name of the new location (e.g., "Fridge").
|
||||
* @returns A promise that resolves to the newly created PantryLocation object.
|
||||
*/
|
||||
export const createPantryLocation = async (name: string): Promise<PantryLocation> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/pantry/locations`, {
|
||||
export const createPantryLocation = async (name: string, tokenOverride?: string): Promise<PantryLocation> => {
|
||||
const response = await apiFetch(`/pantry/locations`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ name }),
|
||||
});
|
||||
}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to create pantry location.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -691,12 +691,12 @@ export const createPantryLocation = async (name: string): Promise<PantryLocation
|
||||
* @param totalSpentCents Optional total amount spent on the trip.
|
||||
* @returns A promise that resolves to an object containing the new shopping trip ID.
|
||||
*/
|
||||
export const completeShoppingList = async (shoppingListId: number, totalSpentCents?: number): Promise<{ newTripId: number }> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/shopping-lists/${shoppingListId}/complete`, {
|
||||
export const completeShoppingList = async (shoppingListId: number, totalSpentCents?: number, tokenOverride?: string): Promise<{ newTripId: number }> => {
|
||||
const response = await apiFetch(`/shopping-lists/${shoppingListId}/complete`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ totalSpentCents }),
|
||||
});
|
||||
}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to complete shopping list.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -708,8 +708,8 @@ export const completeShoppingList = async (shoppingListId: number, totalSpentCen
|
||||
* Fetches the historical shopping trips for the current user.
|
||||
* @returns A promise that resolves to an array of ShoppingTrip objects.
|
||||
*/
|
||||
export const getShoppingTripHistory = async (): Promise<ShoppingTrip[]> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/shopping-history`);
|
||||
export const getShoppingTripHistory = async (tokenOverride?: string): Promise<ShoppingTrip[]> => {
|
||||
const response = await apiFetch(`/shopping-history`, {}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to fetch shopping trip history.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -749,8 +749,8 @@ export const getAppliances = async (): Promise<Appliance[]> => {
|
||||
* Fetches the dietary restrictions for the currently authenticated user.
|
||||
* @returns A promise that resolves to an array of the user's DietaryRestriction objects.
|
||||
*/
|
||||
export const getUserDietaryRestrictions = async (): Promise<DietaryRestriction[]> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/users/me/dietary-restrictions`);
|
||||
export const getUserDietaryRestrictions = async (tokenOverride?: string): Promise<DietaryRestriction[]> => {
|
||||
const response = await apiFetch(`/users/me/dietary-restrictions`, {}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to fetch user dietary restrictions.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -763,12 +763,12 @@ export const getUserDietaryRestrictions = async (): Promise<DietaryRestriction[]
|
||||
* This will replace all existing restrictions with the new set.
|
||||
* @param restrictionIds An array of numbers representing the IDs of the selected restrictions.
|
||||
*/
|
||||
export const setUserDietaryRestrictions = async (restrictionIds: number[]): Promise<void> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/users/me/dietary-restrictions`, {
|
||||
export const setUserDietaryRestrictions = async (restrictionIds: number[], tokenOverride?: string): Promise<void> => {
|
||||
const response = await apiFetch(`/users/me/dietary-restrictions`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ restrictionIds }),
|
||||
});
|
||||
}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to set user dietary restrictions.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -779,8 +779,8 @@ export const setUserDietaryRestrictions = async (restrictionIds: number[]): Prom
|
||||
* Fetches recipes that are compatible with the user's dietary restrictions.
|
||||
* @returns A promise that resolves to an array of compatible Recipe objects.
|
||||
*/
|
||||
export const getCompatibleRecipes = async (): Promise<Recipe[]> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/users/me/compatible-recipes`);
|
||||
export const getCompatibleRecipes = async (tokenOverride?: string): Promise<Recipe[]> => {
|
||||
const response = await apiFetch(`/users/me/compatible-recipes`, {}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to fetch compatible recipes.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -794,8 +794,8 @@ export const getCompatibleRecipes = async (): Promise<Recipe[]> => {
|
||||
* @param offset The starting offset for pagination.
|
||||
* @returns A promise that resolves to an array of ActivityLogItem objects.
|
||||
*/
|
||||
export const getUserFeed = async (limit: number = 20, offset: number = 0): Promise<ActivityLogItem[]> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/users/me/feed?limit=${limit}&offset=${offset}`);
|
||||
export const getUserFeed = async (limit: number = 20, offset: number = 0, tokenOverride?: string): Promise<ActivityLogItem[]> => {
|
||||
const response = await apiFetch(`/users/me/feed?limit=${limit}&offset=${offset}`, {}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to fetch user feed.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -808,10 +808,10 @@ export const getUserFeed = async (limit: number = 20, offset: number = 0): Promi
|
||||
* @param originalRecipeId The ID of the recipe to fork.
|
||||
* @returns A promise that resolves to the newly created Recipe object.
|
||||
*/
|
||||
export const forkRecipe = async (originalRecipeId: number): Promise<Recipe> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/recipes/${originalRecipeId}/fork`, {
|
||||
export const forkRecipe = async (originalRecipeId: number, tokenOverride?: string): Promise<Recipe> => {
|
||||
const response = await apiFetch(`/recipes/${originalRecipeId}/fork`, {
|
||||
method: 'POST',
|
||||
});
|
||||
}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to fork recipe.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -823,10 +823,10 @@ export const forkRecipe = async (originalRecipeId: number): Promise<Recipe> => {
|
||||
* Follows another user.
|
||||
* @param userIdToFollow The UUID of the user to follow.
|
||||
*/
|
||||
export const followUser = async (userIdToFollow: string): Promise<void> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/users/${userIdToFollow}/follow`, {
|
||||
export const followUser = async (userIdToFollow: string, tokenOverride?: string): Promise<void> => {
|
||||
const response = await apiFetch(`/users/${userIdToFollow}/follow`, {
|
||||
method: 'POST',
|
||||
});
|
||||
}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to follow user.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -837,10 +837,10 @@ export const followUser = async (userIdToFollow: string): Promise<void> => {
|
||||
* Unfollows another user.
|
||||
* @param userIdToUnfollow The UUID of the user to unfollow.
|
||||
*/
|
||||
export const unfollowUser = async (userIdToUnfollow: string): Promise<void> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/users/${userIdToUnfollow}/follow`, {
|
||||
export const unfollowUser = async (userIdToUnfollow: string, tokenOverride?: string): Promise<void> => {
|
||||
const response = await apiFetch(`/users/${userIdToUnfollow}/follow`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to unfollow user.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -855,8 +855,8 @@ export const unfollowUser = async (userIdToUnfollow: string): Promise<void> => {
|
||||
* @param offset The starting offset for pagination.
|
||||
* @returns A promise that resolves to an array of ActivityLogItem objects.
|
||||
*/
|
||||
export const fetchActivityLog = async (limit: number = 20, offset: number = 0): Promise<ActivityLogItem[]> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/activity-log?limit=${limit}&offset=${offset}`);
|
||||
export const fetchActivityLog = async (limit: number = 20, offset: number = 0, tokenOverride?: string): Promise<ActivityLogItem[]> => {
|
||||
const response = await apiFetch(`/activity-log?limit=${limit}&offset=${offset}`, {}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to fetch activity log.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -866,8 +866,8 @@ export const fetchActivityLog = async (limit: number = 20, offset: number = 0):
|
||||
|
||||
// --- Favorite Recipes API Functions ---
|
||||
|
||||
export const getUserFavoriteRecipes = async (): Promise<Recipe[]> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/users/favorite-recipes`);
|
||||
export const getUserFavoriteRecipes = async (tokenOverride?: string): Promise<Recipe[]> => {
|
||||
const response = await apiFetch(`/users/favorite-recipes`, {}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to fetch favorite recipes.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -875,12 +875,12 @@ export const getUserFavoriteRecipes = async (): Promise<Recipe[]> => {
|
||||
return response.json();
|
||||
};
|
||||
|
||||
export const addFavoriteRecipe = async (recipeId: number): Promise<FavoriteRecipe> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/users/favorite-recipes`, {
|
||||
export const addFavoriteRecipe = async (recipeId: number, tokenOverride?: string): Promise<FavoriteRecipe> => {
|
||||
const response = await apiFetch(`/users/favorite-recipes`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ recipeId }),
|
||||
});
|
||||
}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to add favorite recipe.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -888,10 +888,10 @@ export const addFavoriteRecipe = async (recipeId: number): Promise<FavoriteRecip
|
||||
return response.json();
|
||||
};
|
||||
|
||||
export const removeFavoriteRecipe = async (recipeId: number): Promise<void> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/users/favorite-recipes/${recipeId}`, {
|
||||
export const removeFavoriteRecipe = async (recipeId: number, tokenOverride?: string): Promise<void> => {
|
||||
const response = await apiFetch(`/users/favorite-recipes/${recipeId}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to remove favorite recipe.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -910,12 +910,12 @@ export const getRecipeComments = async (recipeId: number): Promise<RecipeComment
|
||||
return response.json();
|
||||
};
|
||||
|
||||
export const addRecipeComment = async (recipeId: number, content: string, parentCommentId?: number): Promise<RecipeComment> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/recipes/${recipeId}/comments`, {
|
||||
export const addRecipeComment = async (recipeId: number, content: string, parentCommentId?: number, tokenOverride?: string): Promise<RecipeComment> => {
|
||||
const response = await apiFetch(`/recipes/${recipeId}/comments`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ content, parentCommentId }),
|
||||
});
|
||||
}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to add recipe comment.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -946,12 +946,12 @@ export const getUnmatchedFlyerItems = async (): Promise<UnmatchedFlyerItem[]> =>
|
||||
* @param status The new status for the recipe.
|
||||
* @returns A promise that resolves to the updated Recipe object.
|
||||
*/
|
||||
export const updateRecipeStatus = async (recipeId: number, status: 'private' | 'pending_review' | 'public' | 'rejected'): Promise<Recipe> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/admin/recipes/${recipeId}/status`, {
|
||||
export const updateRecipeStatus = async (recipeId: number, status: 'private' | 'pending_review' | 'public' | 'rejected', tokenOverride?: string): Promise<Recipe> => {
|
||||
const response = await apiFetch(`/admin/recipes/${recipeId}/status`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ status }),
|
||||
});
|
||||
}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to update recipe status.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -966,12 +966,12 @@ export const updateRecipeStatus = async (recipeId: number, status: 'private' | '
|
||||
* @param status The new status for the comment.
|
||||
* @returns A promise that resolves to the updated RecipeComment object.
|
||||
*/
|
||||
export const updateRecipeCommentStatus = async (commentId: number, status: 'visible' | 'hidden' | 'reported'): Promise<RecipeComment> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/admin/comments/${commentId}/status`, {
|
||||
export const updateRecipeCommentStatus = async (commentId: number, status: 'visible' | 'hidden' | 'reported', tokenOverride?: string): Promise<RecipeComment> => {
|
||||
const response = await apiFetch(`/admin/comments/${commentId}/status`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ status }),
|
||||
});
|
||||
}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to update recipe comment status.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -983,8 +983,8 @@ export const updateRecipeCommentStatus = async (commentId: number, status: 'visi
|
||||
* Fetches all brands from the backend. Requires admin privileges.
|
||||
* @returns A promise that resolves to an array of Brand objects.
|
||||
*/
|
||||
export const fetchAllBrands = async (): Promise<Brand[]> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/admin/brands`);
|
||||
export const fetchAllBrands = async (tokenOverride?: string): Promise<Brand[]> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/admin/brands`, {}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to fetch brands.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -1009,8 +1009,8 @@ export interface DailyStat {
|
||||
* Fetches daily user registration and flyer upload stats for the last 30 days.
|
||||
* @returns A promise that resolves to an array of daily stat objects.
|
||||
*/
|
||||
export const getDailyStats = async (): Promise<DailyStat[]> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/admin/stats/daily`);
|
||||
export const getDailyStats = async (tokenOverride?: string): Promise<DailyStat[]> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/admin/stats/daily`, {}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to fetch daily statistics.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -1021,8 +1021,8 @@ export const getDailyStats = async (): Promise<DailyStat[]> => {
|
||||
* Fetches application-wide statistics. Requires admin privileges.
|
||||
* @returns A promise that resolves to an object containing app stats.
|
||||
*/
|
||||
export const getApplicationStats = async (): Promise<AppStats> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/admin/stats`);
|
||||
export const getApplicationStats = async (tokenOverride?: string): Promise<AppStats> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/admin/stats`, {}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to fetch application statistics.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -1036,8 +1036,8 @@ export const getApplicationStats = async (): Promise<AppStats> => {
|
||||
* Fetches all pending suggested corrections. Requires admin privileges.
|
||||
* @returns A promise that resolves to an array of SuggestedCorrection objects.
|
||||
*/
|
||||
export const getSuggestedCorrections = async (): Promise<SuggestedCorrection[]> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/admin/corrections`);
|
||||
export const getSuggestedCorrections = async (tokenOverride?: string): Promise<SuggestedCorrection[]> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/admin/corrections`, {}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to fetch suggested corrections.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -1050,10 +1050,10 @@ export const getSuggestedCorrections = async (): Promise<SuggestedCorrection[]>
|
||||
* @param correctionId The ID of the correction to approve.
|
||||
* @returns A promise that resolves with the success message.
|
||||
*/
|
||||
export const approveCorrection = async (correctionId: number): Promise<{ message: string }> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/admin/corrections/${correctionId}/approve`, {
|
||||
export const approveCorrection = async (correctionId: number, tokenOverride?: string): Promise<{ message: string }> => {
|
||||
const response = await apiFetch(`/admin/corrections/${correctionId}/approve`, {
|
||||
method: 'POST',
|
||||
});
|
||||
}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to approve correction.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -1065,10 +1065,10 @@ export const approveCorrection = async (correctionId: number): Promise<{ message
|
||||
* Rejects a suggested correction. Requires admin privileges.
|
||||
* @param correctionId The ID of the correction to reject.
|
||||
*/
|
||||
export const rejectCorrection = async (correctionId: number): Promise<{ message: string }> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/admin/corrections/${correctionId}/reject`, {
|
||||
export const rejectCorrection = async (correctionId: number, tokenOverride?: string): Promise<{ message: string }> => {
|
||||
const response = await apiFetch(`/admin/corrections/${correctionId}/reject`, {
|
||||
method: 'POST',
|
||||
});
|
||||
}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to reject correction.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -1082,12 +1082,12 @@ export const rejectCorrection = async (correctionId: number): Promise<{ message:
|
||||
* @param newSuggestedValue The new value for the suggestion.
|
||||
* @returns A promise that resolves to the updated SuggestedCorrection object.
|
||||
*/
|
||||
export const updateSuggestedCorrection = async (correctionId: number, newSuggestedValue: string): Promise<SuggestedCorrection> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/admin/corrections/${correctionId}`, {
|
||||
export const updateSuggestedCorrection = async (correctionId: number, newSuggestedValue: string, tokenOverride?: string): Promise<SuggestedCorrection> => {
|
||||
const response = await apiFetch(`/admin/corrections/${correctionId}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ suggested_value: newSuggestedValue }),
|
||||
});
|
||||
}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to update suggested correction.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -1226,8 +1226,8 @@ export async function exportUserData(tokenOverride?: string): Promise<UserDataEx
|
||||
* Fetches the kitchen appliances for the currently authenticated user.
|
||||
* @returns A promise that resolves to an array of the user's Appliance objects.
|
||||
*/
|
||||
export const getUserAppliances = async (): Promise<Appliance[]> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/users/me/appliances`);
|
||||
export const getUserAppliances = async (tokenOverride?: string): Promise<Appliance[]> => {
|
||||
const response = await apiFetch(`/users/me/appliances`, {}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to fetch user appliances.' }));
|
||||
throw new Error(errorData.message);
|
||||
@@ -1240,12 +1240,12 @@ export const getUserAppliances = async (): Promise<Appliance[]> => {
|
||||
* This will replace all existing appliances with the new set.
|
||||
* @param applianceIds An array of numbers representing the IDs of the selected appliances.
|
||||
*/
|
||||
export const setUserAppliances = async (applianceIds: number[]): Promise<void> => {
|
||||
const response = await apiFetch(`${API_BASE_URL}/users/me/appliances`, {
|
||||
export const setUserAppliances = async (applianceIds: number[], tokenOverride?: string): Promise<void> => {
|
||||
const response = await apiFetch(`/users/me/appliances`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ applianceIds }),
|
||||
});
|
||||
}, tokenOverride);
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({ message: 'Failed to set user appliances.' }));
|
||||
throw new Error(errorData.message);
|
||||
|
||||
Reference in New Issue
Block a user