319 lines
8.8 KiB
Markdown
319 lines
8.8 KiB
Markdown
# Pantry Management Frontend
|
|
|
|
React + Vite frontend for the ASP.NET Core pantry manager API.
|
|
|
|
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.
|
|
|
|
## What Changed
|
|
|
|
- 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 site-admin user creation form on the Admin page backed by `POST /api/auth/register`.
|
|
- 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.
|
|
|
|
## Routes
|
|
|
|
| Route | Purpose |
|
|
| --- | --- |
|
|
| `/` | Dashboard. Shows login when signed out, or inventory summary, chart, and nearest expiry data when signed in. |
|
|
| `/admin` | Site-admin page for household administration and user creation. |
|
|
| `/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. |
|
|
|
|
Routing is defined in `src/App.jsx`.
|
|
|
|
## API Endpoint Map
|
|
|
|
### Dashboard (`src/pages/HomePage/HomePage.jsx`)
|
|
|
|
When signed out:
|
|
|
|
- `POST /api/auth/login`
|
|
|
|
When signed in:
|
|
|
|
- `GET /api/locations`
|
|
- `GET /api/inventoryitems`
|
|
|
|
### Inventory (`src/pages/InventoryPage/InventoryPage.jsx`)
|
|
|
|
Locations:
|
|
|
|
- `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`
|
|
|
|
Users:
|
|
|
|
- `POST /api/auth/register`
|
|
|
|
Notes:
|
|
|
|
- The `/admin` route is only visible and accessible for users with the backend `Admin` role.
|
|
- User creation on this page uses the register contract: `email`, `password`, `confirmPassword`, `firstName`, and `lastName`.
|
|
- The register endpoint does not assign roles, so new users are created without admin access by default.
|
|
|
|
### 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 exposed in the Admin page for site admins and does not replace the current signed-in session.
|
|
|
|
## 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(/\/$/, '')
|
|
```
|
|
|
|
That means:
|
|
|
|
- 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`.
|
|
|
|
### Recommended Override
|
|
|
|
Create a `.env.local` file in the project root:
|
|
|
|
```env
|
|
VITE_API_BASE_URL=http://localhost:5000
|
|
```
|
|
|
|
Example for a different backend host:
|
|
|
|
```env
|
|
VITE_API_BASE_URL=https://your-api-host.example.com
|
|
```
|
|
|
|
After changing the env file, restart the Vite dev server.
|
|
|
|
## Auth and Session Behavior
|
|
|
|
Auth/session logic lives in:
|
|
|
|
- `src/api/client.js`
|
|
- `src/context/AuthContext.jsx`
|
|
|
|
Behavior:
|
|
|
|
- Access token and refresh token are stored in `localStorage`.
|
|
- Storage key: `pantry-management-session`
|
|
- Authenticated requests automatically send `Authorization: Bearer <token>`.
|
|
- 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
|
|
npm install
|
|
```
|
|
|
|
### 2. Make sure the backend API is running
|
|
|
|
Default expected API URL:
|
|
|
|
```text
|
|
http://localhost:5000
|
|
```
|
|
|
|
If you use a different URL, set `VITE_API_BASE_URL` in `.env.local`.
|
|
|
|
### 3. Start the frontend
|
|
|
|
```bash
|
|
npm run dev
|
|
```
|
|
|
|
### 4. Build for production
|
|
|
|
```bash
|
|
npm run build
|
|
```
|
|
|
|
### 5. Preview the production build
|
|
|
|
```bash
|
|
npm run preview
|
|
```
|
|
|
|
## Using the App
|
|
|
|
### Login
|
|
|
|
1. Open `/`
|
|
2. Enter an existing user email and password
|
|
3. Sign in to unlock the protected routes and API-backed data
|
|
|
|
There is no public registration form in the signed-out UI. Site admins can create accounts from `/admin`.
|
|
|
|
### Inventory Page
|
|
|
|
Use `/inventory` to:
|
|
|
|
- Create, edit, and delete locations
|
|
- Create, edit, and delete inventory items
|
|
- Load a single inventory item before editing
|
|
|
|
Important update behavior:
|
|
|
|
- Blank text fields on item update are sent as empty strings.
|
|
- Blank amount, date, and location fields are omitted from the update payload because the backend only updates fields that are provided.
|
|
|
|
### Admin Page
|
|
|
|
Use `/admin` to:
|
|
|
|
- Review household data as a site admin
|
|
- Create a new household
|
|
- Invite members by email to the selected household
|
|
- Leave a household from the same page
|
|
- Create a new user account through the register endpoint
|
|
|
|
### Search Page
|
|
|
|
Use `/search` to:
|
|
|
|
- Search items with the backend `items` search endpoint
|
|
- Search locations with the backend `locations` search endpoint
|
|
- Narrow item results further by location, amount, and expiry date in the frontend
|
|
- Page through large result sets
|
|
|
|
### Barcode Page
|
|
|
|
Use `/barcode` to:
|
|
|
|
- Scan via keyboard input
|
|
- Scan via device camera
|
|
- Automatically search inventory after a scan
|
|
- Re-run search for the last scanned barcode
|
|
|
|
Camera scanning works best on HTTPS or localhost with a trusted dev certificate.
|
|
|
|
### Users Page
|
|
|
|
Use `/users` to:
|
|
|
|
- Refresh the users dataset from the backend once `GET /api/users` exists
|
|
- Verify a future users endpoint without adding UI complexity first
|
|
|
|
## Key Files
|
|
|
|
| File | Purpose |
|
|
| --- | --- |
|
|
| `src/api/client.js` | API base URL, fetch wrapper, auth headers, token refresh, endpoint helpers |
|
|
| `src/context/AuthContext.jsx` | Shared auth/session state for the React app |
|
|
| `src/App.jsx` | Route definitions |
|
|
| `src/pages/AdminPage/AdminPage.jsx` | Household administration UI |
|
|
| `src/pages/HomePage/HomePage.jsx` | Dashboard and login UI |
|
|
| `src/pages/InventoryPage/InventoryPage.jsx` | Location and inventory CRUD UI |
|
|
| `src/pages/SearchPage/SearchPage.jsx` | API-backed search UI |
|
|
| `src/pages/BarcodePage/BarcodePage.jsx` | Barcode scanning and API lookup UI |
|
|
| `src/pages/UsersPage/UsersPage.jsx` | Users endpoint scaffold and list view |
|
|
|
|
## Troubleshooting
|
|
|
|
### The frontend cannot reach the API
|
|
|
|
Check:
|
|
|
|
- The backend is running
|
|
- `VITE_API_BASE_URL` is correct
|
|
- The backend HTTPS certificate is trusted
|
|
- CORS is enabled on the API
|
|
|
|
### Login works but protected pages fail later
|
|
|
|
Check:
|
|
|
|
- The backend refresh token flow is working
|
|
- The stored session in browser `localStorage` is valid
|
|
- The API still matches the endpoint shapes described in the backend README
|
|
|
|
### The users page shows a placeholder instead of data
|
|
|
|
This is expected until the backend adds a users endpoint.
|
|
|
|
- The page assumes `GET /api/users`
|
|
- The current C# repo does not expose that route yet
|
|
- Once the backend endpoint exists, the page will start rendering results without additional routing work
|
|
|
|
### Search filters do not match backend behavior exactly
|
|
|
|
This is expected for some filters.
|
|
|
|
- The backend only exposes `q` search for items and locations.
|
|
- Additional amount, location, and expiry filters are applied in the frontend after the API returns results.
|
|
|
|
## Notes
|
|
|
|
- The barcode page uses `@ericblade/quagga2` for camera scanning.
|
|
- The frontend was verified with `npm run build` after these API integration changes.
|