App.tsx refactor + even more unit tests
All checks were successful
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Successful in 8m28s
All checks were successful
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Successful in 8m28s
This commit is contained in:
61
src/hooks/useWatchedItems.tsx
Normal file
61
src/hooks/useWatchedItems.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
// src/hooks/useWatchedItems.tsx
|
||||
import { useState, useCallback } from 'react';
|
||||
import { useAuth } from './useAuth';
|
||||
import { useData } from './useData';
|
||||
import * as apiClient from '../services/apiClient';
|
||||
import type { MasterGroceryItem } from '../types';
|
||||
import { logger } from '../services/logger';
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
export const useWatchedItems = () => {
|
||||
const { user } = useAuth();
|
||||
// Get the watched items and the global setter from the DataContext.
|
||||
const { watchedItems, setWatchedItems } = useData();
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
const addWatchedItem = useCallback(async (itemName: string, category: string) => {
|
||||
if (!user) return;
|
||||
try {
|
||||
setError(null);
|
||||
const updatedOrNewItem: MasterGroceryItem = await (await apiClient.addWatchedItem(itemName, category)).json();
|
||||
|
||||
// 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;
|
||||
});
|
||||
} catch (e) {
|
||||
const errorMessage = e instanceof Error ? e.message : String(e);
|
||||
logger.error('Could not add watched item', { error: errorMessage });
|
||||
setError(`Could not add watched item: ${errorMessage}`);
|
||||
}
|
||||
}, [user, setWatchedItems]);
|
||||
|
||||
const removeWatchedItem = useCallback(async (masterItemId: number) => {
|
||||
if (!user) return;
|
||||
try {
|
||||
setError(null);
|
||||
await apiClient.removeWatchedItem(masterItemId);
|
||||
|
||||
// Update the global state in the DataContext.
|
||||
setWatchedItems(currentItems => currentItems.filter(item => item.master_grocery_item_id !== masterItemId));
|
||||
} catch (e) {
|
||||
const errorMessage = e instanceof Error ? e.message : String(e);
|
||||
logger.error('Could not remove watched item', { error: errorMessage });
|
||||
setError(`Could not remove watched item: ${errorMessage}`);
|
||||
}
|
||||
}, [user, setWatchedItems]);
|
||||
|
||||
return {
|
||||
watchedItems,
|
||||
addWatchedItem,
|
||||
removeWatchedItem,
|
||||
error,
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user