import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; import { toast } from 'sonner'; import { api } from '../lib/api'; import type { ApiResponse } from '../lib/api'; // ── Types ──────────────────────────────────────────────────────────────────── export type InventoryStatus = 'in_stock' | 'low_stock' | 'out_of_stock'; export interface InventoryItem { uuid: string; name: string; consumable: string | null; unit: string; price: number; // Rial stock: number; alertThreshold: number; status: InventoryStatus; } export interface InventoryStats { total: number; low: number; inStock: number; outOfStock: number; } export interface PackageLine { itemUuid: string; name: string; unit: string; price: number; // Rial amount: number; } export interface InventoryPackage { uuid: string; title: string; items: PackageLine[]; total: number; // Rial available: boolean; } export interface ItemPayload { name: string; consumable?: string | null; unit?: string; price?: number; stock?: number; alertThreshold?: number; } export interface PackagePayload { title: string; items: { itemUuid: string; amount: number }[]; } const EMPTY_STATS: InventoryStats = { total: 0, low: 0, inStock: 0, outOfStock: 0 }; const EMPTY_ITEMS: InventoryItem[] = []; const EMPTY_PACKAGES: InventoryPackage[] = []; const EMPTY_CATS: string[] = []; // ── Hook ───────────────────────────────────────────────────────────────────── /** Per-tenant inventory: items (+stats), packages and category filter options. */ export function useInventory() { const qc = useQueryClient(); const itemsQuery = useQuery>({ queryKey: ['inventory-items'], queryFn: () => api.get('/api/v1/inventory-items'), }); const packagesQuery = useQuery>({ queryKey: ['inventory-packages'], queryFn: () => api.get('/api/v1/inventory-packages'), }); const categoriesQuery = useQuery>({ queryKey: ['inventory-categories'], queryFn: () => api.get('/api/v1/inventory-categories'), }); const invalidateItems = () => { qc.invalidateQueries({ queryKey: ['inventory-items'] }); qc.invalidateQueries({ queryKey: ['inventory-categories'] }); qc.invalidateQueries({ queryKey: ['inventory-packages'] }); }; const invalidatePackages = () => qc.invalidateQueries({ queryKey: ['inventory-packages'] }); const createItem = useMutation({ mutationFn: (d: ItemPayload) => api.post('/api/v1/inventory-item', d), onSuccess: () => { invalidateItems(); toast.success('کالا اضافه شد'); }, onError: (e: any) => toast.error(e.message), }); const updateItem = useMutation({ mutationFn: ({ uuid, d }: { uuid: string; d: ItemPayload }) => api.patch(`/api/v1/inventory-item/${uuid}`, d), onSuccess: () => { invalidateItems(); toast.success('کالا ویرایش شد'); }, onError: (e: any) => toast.error(e.message), }); const deleteItem = useMutation({ mutationFn: (uuid: string) => api.delete(`/api/v1/inventory-item/${uuid}`), onSuccess: () => { invalidateItems(); toast.success('کالا حذف شد'); }, onError: (e: any) => toast.error(e.message), }); const createPackage = useMutation({ mutationFn: (d: PackagePayload) => api.post('/api/v1/inventory-package', d), onSuccess: () => { invalidatePackages(); toast.success('پکیج اضافه شد'); }, onError: (e: any) => toast.error(e.message), }); const updatePackage = useMutation({ mutationFn: ({ uuid, d }: { uuid: string; d: PackagePayload }) => api.patch(`/api/v1/inventory-package/${uuid}`, d), onSuccess: () => { invalidatePackages(); toast.success('پکیج ویرایش شد'); }, onError: (e: any) => toast.error(e.message), }); const deletePackage = useMutation({ mutationFn: (uuid: string) => api.delete(`/api/v1/inventory-package/${uuid}`), onSuccess: () => { invalidatePackages(); toast.success('پکیج حذف شد'); }, onError: (e: any) => toast.error(e.message), }); return { items: itemsQuery.data?.data?.items ?? EMPTY_ITEMS, stats: itemsQuery.data?.data?.stats ?? EMPTY_STATS, packages: packagesQuery.data?.data ?? EMPTY_PACKAGES, categories: categoriesQuery.data?.data ?? EMPTY_CATS, itemsLoading: itemsQuery.isLoading, packagesLoading: packagesQuery.isLoading, createItem, updateItem, deleteItem, createPackage, updatePackage, deletePackage, }; }