From c4cf6a92fe9e1b3b99229658f0bfd76a65ebecc0 Mon Sep 17 00:00:00 2001 From: Luke Betteridge Date: Wed, 15 Apr 2026 14:08:16 +0100 Subject: [PATCH] Refactored Barcode Page and made fixes to logic --- README.md | 556 +++++------ src/App.css | 314 +++++- src/App.jsx | 68 +- src/api/client.js | 401 ++++++++ src/components/ItemCard/ItemCard.css | 20 +- src/components/Navbar/Navbar.css | 88 +- src/components/Navbar/Navbar.jsx | 59 +- src/components/PieChart/PieChart.css | 5 +- src/components/PieChart/PieChart.jsx | 2 +- src/context/AuthContext.jsx | 81 ++ src/main.jsx | 9 +- src/pages/AdminPage/AdminPage.css | 86 ++ src/pages/AdminPage/AdminPage.jsx | 427 +++++++++ src/pages/BarcodePage/BarcodePage.css | 483 ++++++---- src/pages/BarcodePage/BarcodePage.jsx | 1048 +++++++++++++++------ src/pages/HomePage/HomePage.css | 74 +- src/pages/HomePage/HomePage.jsx | 237 ++++- src/pages/InventoryPage/InventoryPage.css | 89 ++ src/pages/InventoryPage/InventoryPage.jsx | 527 +++++++++++ src/pages/SearchPage/SearchPage.css | 76 +- src/pages/SearchPage/SearchPage.jsx | 461 ++++++--- src/pages/UsersPage/UsersPage.css | 47 + src/pages/UsersPage/UsersPage.jsx | 126 +++ src/utils/inventoryItemUtils.js | 63 ++ src/utils/searchUtils.js | 68 +- 25 files changed, 4387 insertions(+), 1028 deletions(-) create mode 100644 src/api/client.js create mode 100644 src/context/AuthContext.jsx create mode 100644 src/pages/AdminPage/AdminPage.css create mode 100644 src/pages/AdminPage/AdminPage.jsx create mode 100644 src/pages/InventoryPage/InventoryPage.css create mode 100644 src/pages/InventoryPage/InventoryPage.jsx create mode 100644 src/pages/UsersPage/UsersPage.css create mode 100644 src/pages/UsersPage/UsersPage.jsx create mode 100644 src/utils/inventoryItemUtils.js diff --git a/README.md b/README.md index 89f72e1..b958804 100644 --- a/README.md +++ b/README.md @@ -1,353 +1,313 @@ -# Webpage Playground +# Pantry Management Frontend -A modern inventory management demo app featuring multiple pages for browsing, searching, and scanning barcodes. Built with vanilla HTML, CSS, and JavaScript. +React + Vite frontend for the ASP.NET Core pantry manager API. -## Overview +This app is no longer a static demo. It now uses the backend API for authentication, profile data, inventory items, locations, search, and barcode-based item lookup. -Webpage Playground is a lightweight, responsive web application for managing and tracking inventory across multiple storage locations (Pantry, Fridge, Freezer). The app includes: +## What Changed -- **Dynamic Navigation** — Easy page switching with a responsive navbar -- **Inventory Demo** — Display items using reusable item components -- **Advanced Search** — Filter inventory by name, location, quantity range, and expiry date -- **Barcode Scanner** — Scan barcodes using camera or keyboard (hardware scanner support) -- **Data Visualization** — Pie chart showing inventory distribution -- **Responsive Design** — Works on desktop, tablet, and mobile devices +- Replaced local demo inventory data with live API calls. +- Added a shared API client with JWT handling, refresh-token retry, and normalized error messages. +- Added shared auth/session state with `localStorage` persistence. +- Updated the dashboard to support login and live inventory summary data. +- Added a dedicated inventory management page for CRUD operations. +- Updated search to call the backend search endpoints. +- Updated barcode scanning so scans look up matching inventory items through the API. +- Removed the register panel and the old `Connected API` section from the login view. -## Project Structure +## Routes -### Pages -- `index.html` — Homepage with item component demo and inventory pie chart -- `search.html` — Search and filter inventory by name, location, quantity, and expiry date -- `barcode.html` — Barcode scanner with camera and keyboard input modes -- `pantry.html` — Pantry inventory container -- `fridge.html` — Fridge inventory container -- `freezer.html` — Freezer inventory container +| Route | Purpose | +| --- | --- | +| `/` | Dashboard. Shows login when signed out, or inventory summary, chart, and nearest expiry data when signed in. | +| `/admin` | Household administration page for listing, creating, editing, inviting, and leaving households. | +| `/inventory` | Manage locations and inventory items. | +| `/search` | Search items and locations, then filter results further in the UI. | +| `/barcode` | Scan a barcode and search the inventory API for matches. | +| `/users` | Site-admin users page scaffold for loading all users once the backend endpoint is available. | -### Core Modules -- `navbar.js` — Dynamic navigation bar system loaded by all pages -- `main.css` — Global styles and responsive design -- `item-component.js` — Reusable ES6 module for displaying inventory items in a grid -- `search.js` — Search and filtering logic with 20 sample inventory items including expiry dates -- `barcode-scanner.js` — Barcode capture and console logging module -- `piechart.js` — Inventory distribution pie chart visualization +Routing is defined in `src/App.jsx`. -### Documentation -- `ITEM_COMPONENT.md` — Detailed documentation for the item component factory -- `README.md` — This file +## API Endpoint Map -## Features Overview +### Dashboard (`src/pages/HomePage/HomePage.jsx`) -### 🏠 Homepage (`index.html`) -The landing page showcasing the project with: -- Interactive item component grid (3 sample items) -- Inventory breakdown pie chart showing distribution across storage locations -- Responsive grid layout that adapts to screen size +When signed out: -**Sample Data:** -- Pantry: 104 items -- Fridge: 30 items -- Freezer: 87 items +- `POST /api/auth/login` -### 🔍 Search Page (`search.html`) -Advanced inventory search and filtering interface. +When signed in: -**Features:** -- Search by item name (case-insensitive) -- Filter by storage location (All, Pantry, Fridge, Freezer) -- Filter by quantity range (min/max values) -- Filter by expiry date range (start date and end date) -- Real-time result display with item cards -- Visual expiry status indicators (Fresh, Expiring Soon, Expired) -- **Pagination** — Results displayed with configurable items per page (15, 30, or 60) -- Reset button to clear all filters -- Keyboard support (press Enter to search) -- Date range validation (start date ≤ end date) +- `GET /api/locations` +- `GET /api/inventoryitems` -**Pagination Features:** -- **Items Per Page Dropdown** — Choose between 15, 30, or 60 items per page -- **Previous/Next Navigation** — Browse through pages of results -- **Page Information** — Shows current page and total pages (e.g., "Page 2 of 5") -- **Result Summary** — Displays showing item count (e.g., "Found 47 items (16-30)") -- **Smart Boundaries** — Previous button disabled on page 1, Next disabled on last page -- **Auto-Reset** — Returns to page 1 when search filters change -- **Dynamic Page Count** — Automatically updates total pages when page size changes +### Inventory (`src/pages/InventoryPage/InventoryPage.jsx`) -**Expiry Date Features:** -- Each inventory item includes an expiry date -- Visual badges show expiry status: - - 🟢 **Fresh** — Items expiring in more than 7 days - - 🟠 **Expiring Soon** — Items expiring within 7 days - - 🔴 **Expired** — Items past expiry date -- Formatted expiry dates displayed on item cards -- Filter by start and end date to find items expiring in a specific timeframe +Locations: -**Sample Usage:** -``` -Search for items expiring between March 15 and April 15 -Results show all items with expiry dates in that range -Items display formatted dates and expiry status badges +- `GET /api/locations` +- `POST /api/locations` +- `PUT /api/locations/{id}` +- `DELETE /api/locations/{id}` + +Inventory items: + +- `GET /api/inventoryitems` +- `GET /api/inventoryitems/{id}` +- `POST /api/inventoryitems` +- `PUT /api/inventoryitems/{id}` +- `DELETE /api/inventoryitems/{id}` + +### Admin (`src/pages/AdminPage/AdminPage.jsx`) + +Households: + +- `GET /api/households` +- `POST /api/households` +- `PUT /api/households/{id}` +- `POST /api/households/{id}/invite` +- `DELETE /api/households/{id}/leave` + +Notes: + +- Household creation is limited to users with the backend `Admin` role. +- Household editing and member invites are available when the current user is a household admin or site admin. + +### Search (`src/pages/SearchPage/SearchPage.jsx`) + +Initial page data: + +- `GET /api/locations` +- `GET /api/inventoryitems` + +Search actions: + +- `GET /api/search/items?q={query}` +- `GET /api/search/locations?q={query}` + +Note: + +- The backend search API only supports the `q` query parameter. +- Location, amount, expiry-date filtering, and pagination are applied client-side after the API search returns. + +### Barcode (`src/pages/BarcodePage/BarcodePage.jsx`) + +- `GET /api/search/items?q={barcode}` + +The barcode page scans via Quagga2, then searches the backend for inventory items whose barcode or other searchable fields match the scanned value. + +### Users (`src/pages/UsersPage/UsersPage.jsx`) + +- `GET /api/users` + +Notes: + +- The users page is intentionally minimal and is ready to consume a future users endpoint. +- The current C# repo does not expose `GET /api/users` yet, so the page shows a placeholder when that endpoint returns `404`. + +### Shared Auth Support (`src/api/client.js`) + +The shared API client also supports: + +- `POST /api/auth/register` +- `POST /api/auth/refresh-token` + +Notes: + +- `register` is still implemented in the client helper, but there is currently no registration form in the UI. +- If you need to create a user, use the backend Swagger UI or another client to call `POST /api/auth/register`. + +## API Configuration + +The API base URL is configured in `src/api/client.js`. + +Current setup: + +```js +const API_BASE_URL = (import.meta.env.VITE_API_BASE_URL ?? 'http://localhost:5000').trim().replace(/\/$/, '') ``` -### 📱 Barcode Scanner (`barcode.html`) -Dual-mode barcode scanning interface with keyboard input and camera scanning. +That means: -**Features:** +- If `VITE_API_BASE_URL` is set, the frontend uses that value. +- Otherwise it defaults to `http://localhost:5000` to match the C# API repo's `appsettings.json`. -#### Keyboard Input Mode -- Type or paste barcode values -- Hardware barcode scanner device support -- Real-time console logging -- Auto-focus field for seamless entry -- Enter key to scan +### Recommended Override -#### Camera Scanning Mode (**NEW**) -- **Real-time barcode detection** using device camera -- **Supported formats:** UPC-A, UPC-E, EAN-13, EAN-8, Code-128, Code-39, and more -- **Browser-based detection** (uses Quagga2 library - local version) -- **Mode toggle** between keyboard and camera input -- **Camera controls** with start/stop buttons -- **Real-time feedback** showing detected barcodes -- **Error handling** with user-friendly messages -- **Mobile support** — Works on iOS and Android devices with camera access -- **Console logging** of all detections with metadata +Create a `.env.local` file in the project root: -**Camera Usage:** -1. Switch to "Camera Scan" mode by clicking the button -2. Click "Start Camera" to begin -3. Browser will request camera permission (grant access) -4. Position barcode in front of camera -5. Barcode is detected automatically in real-time -6. Detected barcodes logged to console (press F12) -7. Click "Stop Camera" to end scanning - -**Keyboard Usage:** -1. Stay in "Keyboard Input" mode -2. Type barcode value or paste from clipboard -3. Press Enter to complete scan -4. Barcode logged to console - -**Console Output Format:** -``` -[Barcode Scanned] 14:07:32.456 | Barcode: 5901234123457 | Input: keyboard -[Barcode Scanned] 14:07:45.123 | Barcode: 123456789012 | Input: camera +```env +VITE_API_BASE_URL=http://localhost:5000 ``` -**Browser Support:** -- Chrome 53+, Firefox 55+, Safari 11+, Edge 79+ -- Camera access requires HTTPS or localhost -- Mobile browsers support camera scanning +Example for a different backend host: -**Testing Instructions:** -1. Navigate to the Barcode Scanner page via navbar -2. Try keyboard input mode: Type a barcode and press Enter -3. Try camera mode: Switch to "Camera Scan" and point at a barcode -4. Press F12 to open DevTools Console -5. View logged barcodes with timestamps and input type +```env +VITE_API_BASE_URL=https://your-api-host.example.com +``` -### 📦 Storage Location Pages -- `pantry.html` — Pantry inventory (expandable for displaying specific items) -- `fridge.html` — Fridge inventory -- `freezer.html` — Freezer inventory +After changing the env file, restart the Vite dev server. -These pages are currently placeholder containers ready for future development (e.g., displaying items specific to each location). +## Auth and Session Behavior -## Quick Start +Auth/session logic lives in: -The project is a static site. For best results, serve it over HTTP (ES module imports can be blocked when opened via the `file://` protocol in some browsers). +- `src/api/client.js` +- `src/context/AuthContext.jsx` -### Python 3 (Recommended) +Behavior: + +- Access token and refresh token are stored in `localStorage`. +- Storage key: `pantry-management-session` +- Authenticated requests automatically send `Authorization: Bearer `. +- If a request returns `401`, the client attempts `POST /api/auth/refresh-token` once and retries the original request. +- Logout clears local session state even if the API logout request fails. + +## Local Development + +### 1. Install dependencies ```bash -# From the project root -python -m http.server 8000 - -# Then open http://localhost:8000 in your browser +npm install ``` -### Alternative Options +### 2. Make sure the backend API is running -- **VS Code Live Server Extension** — Right-click `index.html` → "Open with Live Server" -- **Node.js http-server** — `npx http-server` -- **Any static file server** +Default expected API URL: -## Usage - -### Navigation -The navbar appears at the top of every page and provides links to: -- Homepage — Main demo page with pie chart -- Search — Advanced inventory search and filtering with expiry date support -- Barcode Scanner — Barcode capture with camera and keyboard modes -- Pantry, Fridge, Freezer — Individual storage location pages - -### Using the Search Page -1. Open the Search page from the navbar -2. Enter search criteria: - - Item name (optional) - - Storage location (optional, defaults to "All") - - Quantity range (optional, defaults to 0-999) - - Expiry date range (optional) — Leave blank to ignore -3. Click "Search" or press Enter -4. Results display as item cards using the item component with expiry status badges -5. Click "Reset" to clear all filters - -**Expiry Date Search Examples:** -- Find items expiring soon: Set start date to today, end date to 7 days from today -- Find expired items: Set start date to 100 days ago, end date to today -- Find fresh items: Set start date to tomorrow, end date to 90 days from today - -### Using the Barcode Scanner - -#### Keyboard Mode -1. Open the Barcode Scanner page from the navbar -2. Make sure "Keyboard Input" mode is selected -3. Click in the input field (auto-focused) -4. Enter a barcode: - - Type manually and press Enter - - Scan with a barcode scanner device - - Paste a value (Ctrl/Cmd+V) -5. Press F12 to open Developer Tools Console -6. View scanned barcodes in the Console tab with metadata - -#### Camera Mode -1. Open the Barcode Scanner page from the navbar -2. Click "Camera Scan" to switch to camera mode -3. Click "Start Camera" -4. Browser will request camera permission (grant access) -5. Position barcode in front of camera lens -6. Barcode is detected automatically and displayed -7. Press F12 to view console logs -8. Click "Stop Camera" to end - -**Tips:** -- Ensure good lighting for better barcode detection -- Hold barcode steady and clearly in frame -- Device must have a working camera -- Camera mode requires HTTPS or localhost - -### The Item Component -The `item-component` is a reusable UI building block used throughout the app. See `ITEM_COMPONENT.md` for detailed documentation on using it in your own pages. - -**Quick Example:** -```html - +```text +http://localhost:5000 ``` -## Customizing and Extending +If you use a different URL, set `VITE_API_BASE_URL` in `.env.local`. -### Adding New Items to Search -Edit `search.js` and add items to the `inventoryData` array: -```javascript -export const inventoryData = [ - { - id: 21, - name: 'Coffee', - location: 'Pantry', - quantity: 2, - unit: 'bags', - expiryDate: '2026-06-15', - img: 'https://picsum.photos/seed/coffee/200/200' - }, - // ... more items -]; +### 3. Start the frontend + +```bash +npm run dev ``` -**Date Format:** Use ISO 8601 format (YYYY-MM-DD) for expiry dates. +### 4. Build for production -### Styling -- Override styles in `main.css` for global changes -- Page-specific styles are included in `