Some checks failed
Deploy to Test Environment / deploy-to-test (push) Has been cancelled
- Removed individual context files for Auth, Flyers, MasterItems, Modal, UserData, and their respective hooks. - Introduced centralized provider files for each context, encapsulating logic and state management. - Updated imports across the application to reflect the new structure, ensuring all hooks and contexts are correctly referenced. - Enhanced the AppProviders component to streamline the wrapping of all context providers in the application. - Improved type definitions and context management for better type safety and clarity.
64 lines
2.4 KiB
TypeScript
64 lines
2.4 KiB
TypeScript
// src/hooks/useWatchedItems.tsx
|
|
import { useMemo, useCallback } from 'react';
|
|
import { useAuth } from '../hooks/useAuth';
|
|
import { useApi } from './useApi';
|
|
import { useUserData } from '../hooks/useUserData';
|
|
import * as apiClient from '../services/apiClient';
|
|
import type { MasterGroceryItem } from '../types';
|
|
|
|
/**
|
|
* A custom hook to manage all state and logic related to a user's watched items.
|
|
* It encapsulates API calls and state updates for adding and removing items.
|
|
*/
|
|
const useWatchedItemsHook = () => {
|
|
const { user } = useAuth();
|
|
// Get the watched items and the global setter from the DataContext.
|
|
const { watchedItems, setWatchedItems } = useUserData();
|
|
|
|
// API hooks for watched item operations
|
|
const { execute: addWatchedItemApi, error: addError } = useApi<MasterGroceryItem, [string, string]>(
|
|
(itemName, category) => apiClient.addWatchedItem(itemName, category)
|
|
);
|
|
const { execute: removeWatchedItemApi, error: removeError } = useApi<null, [number]>(
|
|
(masterItemId) => apiClient.removeWatchedItem(masterItemId)
|
|
);
|
|
|
|
// Consolidate errors into a single displayable error message.
|
|
const error = useMemo(() => (addError || removeError ? (addError?.message || removeError?.message) : null), [addError, removeError]);
|
|
|
|
const addWatchedItem = useCallback(async (itemName: string, category: string) => {
|
|
if (!user) return;
|
|
const updatedOrNewItem = await addWatchedItemApi(itemName, category);
|
|
|
|
if (updatedOrNewItem) {
|
|
|
|
// Update the global state in the DataContext.
|
|
setWatchedItems(currentItems => {
|
|
const itemExists = currentItems.some(item => item.master_grocery_item_id === updatedOrNewItem.master_grocery_item_id);
|
|
if (!itemExists) {
|
|
return [...currentItems, updatedOrNewItem].sort((a, b) => a.name.localeCompare(b.name));
|
|
}
|
|
return currentItems;
|
|
});
|
|
}
|
|
}, [user, setWatchedItems, addWatchedItemApi]);
|
|
|
|
const removeWatchedItem = useCallback(async (masterItemId: number) => {
|
|
if (!user) return;
|
|
const result = await removeWatchedItemApi(masterItemId);
|
|
if (result === null) {
|
|
|
|
// Update the global state in the DataContext.
|
|
setWatchedItems(currentItems => currentItems.filter(item => item.master_grocery_item_id !== masterItemId));
|
|
}
|
|
}, [user, setWatchedItems, removeWatchedItemApi]);
|
|
|
|
return {
|
|
watchedItems,
|
|
addWatchedItem,
|
|
removeWatchedItem,
|
|
error,
|
|
};
|
|
};
|
|
|
|
export { useWatchedItemsHook as useWatchedItems }; |