WFDASH-WEBAPP/docs/counter-pwa.md

110 lines
4.8 KiB
Markdown
Raw Normal View History

# Counter PWA — install + use
A standalone, installable web app on the office counter phones. One tap, no
login, and the order lands on the **New** tab of the order board.
## What it does
- Pick an existing customer (search by name, email, or phone) — or tap
**Add new** to create a customer inline (and a new company in the same
sheet if needed).
- Add any number of line items (description, qty, optional price).
- Snap photos with the phone camera (up to 10 per order).
- Tap **Submit Order** — the order appears on `/orders` under the **New** tab
immediately (via PocketBase realtime).
## Install on a counter phone
### iPhone (Safari)
1. Open `https://<your-coolify-host>/new-order` in Safari.
2. Tap **Share → Add to Home Screen**.
3. Confirm the name "Counter". The icon appears on the home screen.
4. Tap the icon — it opens full-screen, no address bar.
### Android (Chrome)
1. Open the URL in Chrome.
2. Tap the **⋮ menu → Install app** (or "Add to Home Screen").
3. Confirm. The icon appears in the launcher.
4. Tap the icon — it opens full-screen.
The same shortcut URL works: `https://<host>/counter` redirects to `/new-order`.
## What runs where
| Layer | What |
|---|---|
| Browser (phone) | `/new-order` — single-screen form, no login |
| Next.js route handlers | `/api/counter/*` — public, no Bearer token |
| `src/lib/server/counter-service.ts` | Thin service layer; calls existing `createOrder()`, `createCustomer()`, `createCompany()` |
| PocketBase | `orders` row + `order_items` rows with `item_status="pending"` (lands on **New** tab) + photos on `orders.order_attachements` |
The counter routes intentionally do **not** go through the same Bearer-token
gate as `/api/v1/*` — the counter phones are kiosk-mode and assumed to be on
office Wi-Fi.
## Smoke test after deploy
1. `npm run dev` → open `http://<host>:3000/new-order` from the dev machine.
2. Pick an existing customer, add one line item, hit Submit.
3. Open `/orders` in the main app — confirm the new order sits on the
**New** tab.
4. Submit again, this time with a photo. Confirm the photo opens from the
order detail page (`/orders/<id>`).
5. From an iPhone on the same Wi-Fi, open the same URL → Add to Home Screen
→ confirm the standalone icon works.
## Troubleshooting
- **Order doesn't appear on the board.** Check Coolify logs for
`/api/counter/orders` — PB admin SDK auth (`PB_ADMIN_EMAIL` /
`PB_ADMIN_PASSWORD`) must be set in `.env.local`.
- **Photos rejected with 413.** The phone uploaded a file > the cap.
Default `COUNTER_MAX_PHOTO_MB=8`. Drop it lower if your network is slow,
or compress on the client (not implemented yet).
- **Customer combobox empty.** The `/api/counter/customers` endpoint failed
on first load — see toast in the top-right and check the browser console.
- **"Photo upload failed" after submit.** The order was saved (it appears
on the board) but the photos didn't make it. Open the order in the main
CRM and re-attach from there.
- **Sheet won't open on iPhone 16+.** Some iOS versions need a user-tap to
fire `<input capture>`. The form provides two buttons (camera + gallery)
so the operator can fall back to gallery.
## Files added / changed
```
src/app/(counter)/layout.tsx new
src/app/(counter)/shell.tsx new
src/app/(counter)/page.tsx new (redirect)
src/app/(counter)/new-order/page.tsx new
src/app/(counter)/new-order/components/ new dir
header.tsx
counter-select.tsx
new-customer-sheet.tsx
items-list.tsx
photo-capture.tsx
success-screen.tsx
src/lib/server/counter-service.ts new
src/app/api/counter/customers/route.ts new
src/app/api/counter/companies/route.ts new
src/app/api/counter/orders/route.ts new
src/app/api/counter/orders/[id]/attachments/route.ts new
public/manifest-counter.json new
public/sw-counter.js new
src/components/service-worker-registration.tsx edited (dual SW)
src/app/layout.tsx edited (cleanup)
next.config.ts edited (/counter redirect)
.env.local edited (COUNTER_MAX_PHOTO_MB)
```
## Out of scope (intentionally)
- No login / PIN — phones are physically controlled by staff.
- No offline-queue — a flaky network at submit time means the order is
lost. The PWA caches the page chrome so navigation stays fast, but a
pending-submit queue would be a separate feature.
- No per-user audit (rep picker left blank — rep can be set later in the
main CRM process page).
- No quote linking — counter orders are standalone.