98 lines
2.6 KiB
TypeScript
98 lines
2.6 KiB
TypeScript
import { useState, useEffect, useCallback } from 'react';
|
|
import { shoppingService } from '../services';
|
|
import { ShoppingItem, CreateShoppingItemRequest } from '../types';
|
|
import { showToast } from '../utils/toast';
|
|
import { showErrorToast } from '../utils/errorHandler';
|
|
|
|
export function useShoppingList(familyId: number) {
|
|
const [items, setItems] = useState<ShoppingItem[]>([]);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState<Error | null>(null);
|
|
|
|
const loadItems = useCallback(async () => {
|
|
if (!familyId) return;
|
|
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
const data = await shoppingService.getAllByFamily(familyId);
|
|
setItems(data);
|
|
} catch (err) {
|
|
setError(err as Error);
|
|
showErrorToast(err);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}, [familyId]);
|
|
|
|
useEffect(() => {
|
|
loadItems();
|
|
}, [loadItems]);
|
|
|
|
const createItem = useCallback(async (data: CreateShoppingItemRequest) => {
|
|
try {
|
|
await shoppingService.create(familyId, data);
|
|
showToast.success('Item added successfully');
|
|
await loadItems();
|
|
} catch (err) {
|
|
showErrorToast(err);
|
|
throw err;
|
|
}
|
|
}, [familyId, loadItems]);
|
|
|
|
const deleteItem = useCallback(async (itemId: number) => {
|
|
try {
|
|
await shoppingService.delete(familyId, itemId);
|
|
showToast.success('Item deleted successfully');
|
|
await loadItems();
|
|
} catch (err) {
|
|
showErrorToast(err);
|
|
throw err;
|
|
}
|
|
}, [familyId, loadItems]);
|
|
|
|
const togglePurchased = useCallback(async (itemId: number, isPurchased: boolean) => {
|
|
try {
|
|
await shoppingService.markAsPurchased(familyId, itemId, isPurchased);
|
|
await loadItems();
|
|
} catch (err) {
|
|
showErrorToast(err);
|
|
throw err;
|
|
}
|
|
}, [familyId, loadItems]);
|
|
|
|
const markAllAsPurchased = useCallback(async () => {
|
|
try {
|
|
const affected = await shoppingService.markAllAsPurchased(familyId);
|
|
showToast.success(`Marked ${affected} items as purchased`);
|
|
await loadItems();
|
|
} catch (err) {
|
|
showErrorToast(err);
|
|
throw err;
|
|
}
|
|
}, [familyId, loadItems]);
|
|
|
|
const clearAll = useCallback(async () => {
|
|
try {
|
|
const affected = await shoppingService.clearAll(familyId);
|
|
showToast.success(`Cleared ${affected} items`);
|
|
await loadItems();
|
|
} catch (err) {
|
|
showErrorToast(err);
|
|
throw err;
|
|
}
|
|
}, [familyId, loadItems]);
|
|
|
|
return {
|
|
items,
|
|
loading,
|
|
error,
|
|
loadItems,
|
|
createItem,
|
|
deleteItem,
|
|
togglePurchased,
|
|
markAllAsPurchased,
|
|
clearAll,
|
|
};
|
|
}
|