diff --git a/src/screens/ManageProductsScreen.test.tsx b/src/screens/ManageProductsScreen.test.tsx index 575dde9..468b903 100644 --- a/src/screens/ManageProductsScreen.test.tsx +++ b/src/screens/ManageProductsScreen.test.tsx @@ -308,3 +308,41 @@ describe('ManageProductsScreen deletion safeguards', () => { }); }); +describe('ManageProductsScreen filtering feedback', () => { + it('informs the user when no products match the search and category filter', async () => { + mockUseProducts.mockReturnValue([ + { + id: 'prod-1', + name: 'Chips', + category: 'Snacks', + unit_type: 'unit', + bulk_name: 'pack', + archived: false, + created_at: 0, + updated_at: 0, + }, + ]); + mockUseCategories.mockReturnValue([ + { id: 'cat-1', name: 'Snacks', created_at: 0, updated_at: 0 }, + { id: 'cat-2', name: 'Drinks', created_at: 0, updated_at: 0 }, + ]); + + const user = userEvent.setup(); + render( + + + , + ); + + await user.type(screen.getByPlaceholderText(/search/i), 'Soda'); + + const [filterSelect] = screen.getAllByLabelText(/category/i); + await user.click(filterSelect); + await user.click(screen.getByRole('option', { name: /drinks/i })); + + expect( + await screen.findByText(/no products match your search and category filter\./i), + ).toBeVisible(); + }); +}); + diff --git a/src/screens/ManageProductsScreen.tsx b/src/screens/ManageProductsScreen.tsx index a781b3d..fd52c9b 100644 --- a/src/screens/ManageProductsScreen.tsx +++ b/src/screens/ManageProductsScreen.tsx @@ -352,15 +352,21 @@ export const ManageProductsScreen = () => { Save Product - {sortedFiltered.map((product) => ( - - ))} + {sortedFiltered.length === 0 ? ( + + No products match your search and category filter. + + ) : ( + sortedFiltered.map((product) => ( + + )) + )} setScannerOpen(false)} fullWidth> Scan Barcode