Drivers can now switch the header toggle to 'Invoice' to see stops
bucketed by PO within each supplier. Each PO sub-header is
collapsible and shows the PO number + item count + total qty.
Per-PO bulk actions (visible only when the supplier has more than
one invoice):
- Green 'All' button marks every item under that PO as collected
in one tap (no per-item modal flow, expectedQty is auto-stamped).
- Red flag button flags every item with a generic problem note.
Implementation:
- New 'po' groupMode in app/page.tsx with its own groupedByPO memo
and expandedPOs Set state (auto-expanded on load, controlled by
expandAll/collapseAll alongside supplier expansion).
- SupplierGroup now accepts optional poGroups + handlers and renders
PO sub-headers in compact mode. Each PO is rendered as a flat
list of CompactItemRow subcomponents (extracted to share the row
markup between flat-list and per-PO render paths).
- bulkCollect / bulkProblem helpers in lib/pocketbase.ts loop the
patch; per-row failures are logged and excluded from the count so
one bad row doesn't poison the batch.
Co-authored-by: Orca <help@stably.ai>
Two improvements to the collection flow:
1. Popover clipping under BottomNav (last item in list)
- Root cause: popovers were z-[60] *inside* a parent stacking
context at z-30, so their effective page z-index was 30 — below
BottomNav's z-50. Even if the z-index were right, the popover
extends below the trigger button and could fall below the
viewport on the last item in a long list.
- Add lib/hooks.ts with usePopoverPlacement: measures the
trigger's bottom edge and flips popover direction to "up" when
there isn't ~240px of room below (reserving 80px for BottomNav
+ safe-area inset).
- Bump the article/section/li stacking context from z-30 to z-[80]
when a popover is open so the popover paints above BottomNav
(z-50). Covers both compact-mode SupplierGroup rows and
detailed-mode CollectionItemCard via the existing
onPopoverChange callback.
- For SupplierGroup: hooks live at the top level (record keyed by
item.id) to avoid the Rules of Hooks trap of declaring hooks
inside items.map().
2. Partial collections must be justified
- In CollectModal, when received qty < expected, require EITHER a
reason (dropdown: out of stock / wrong item / quality issue /
damaged / wrong qty packed / other) OR a photo before Confirm
is enabled. Prevents silent partial submissions with no audit
trail.
- The picked reason flows into the auto-generated problem note
so the operator sees "[Reason] driver note" in PB.
Co-Authored-By: Claude <noreply@anthropic.com>
Co-authored-by: Orca <help@stably.ai>
- PO (FileText) and Notes (MessageSquare) inline buttons: w-7 h-7 / w-8 h-8
-> w-6 h-6 with size 11 icons and tighter radius, plus narrower right
column gap so the smaller buttons don't sit in stale spacing.
- Popover z-index vs next group: add onPopoverChange callback to
CollectionItemCard so SupplierGroup / AreaGroup can lift their
section from z-10 to z-30 when *any* popover inside is open. Covers
both compact (own popover) and detailed (card popover) modes. Active
<li> in compact mode also lifts to z-30 so popover paints above
sibling rows in the same list.
- Header categories on small screens: stats + toggle row now
flex-wraps so chips don't overflow; added xs (480px) breakpoint
and hid Supplier/Area labels below it to keep tiny phones clean.
Status filter chip row already scrolls horizontally.
Co-Authored-By: Claude <noreply@anthropic.com>
Co-authored-by: Orca <help@stably.ai>
- Add ItemDetailModal showing PO document (view/download/share/email) + buyer notes
- Add FileText (PO) and MessageSquare (notes) buttons to compact item list with popovers
- Fix photo upload: append to order_items.order_item_attachements (PB file field)
- Add colored left sidebar stripe per supplier group for visual distinction
- Fix popover z-index so they appear above following cards (overflow-visible + z-50)
- Extend PurchaseOrder type with documents, email_payload, supplier
- Add order_item_attachements and expand.purchase_order to OrderItem
- onShowDetails prop wired through SupplierGroup and AreaGroup
Co-authored-by: Orca <help@stably.ai>
- update dev server port to 4001 in package.json
- remove unused formatCurrency import from SupplierGroup component
- refactor cluster label generation for better multi-supplier display
- overhaul AreaGroup UI to use chip-style supplier tags with updated typography
- expand collapseAll handler to support both supplier and area group modes
- fix driver_locations schema mismatch: use `relation` instead of `driver` per live PB schema
- remove invalid `ready_for_collection` filter that caused silent 400 errors
- add order_item_attachments support for driver pickup photos with proper error handling:
* replace legacy collection_photo field with new collection for multiple per-item files
* upload photos after updating item status to avoid stranding assigned items
* show warning toast if upload fails instead of success confirmation
* update toast messages to reflect photo upload status
- add pre-build schema check script to catch invalid PB field references pre-deploy
- add corresponding npm scripts and prebuild hook for the schema check
- add e2e test scripts for collection and upload flows
- update type definitions and pocketbase SDK helpers for new schema and functionality
- add optional collection_photo field to OrderItem type and backend support for pickup photo uploads
- implement in-memory + localStorage cache for order items to eliminate tab-switch loading skeletons
- update service worker to use stale-while-revalidate for navigation requests to reduce perceived lag
- fix LocationTracker to only activate when logged in and hoist to root layout for persistent tracking
- adjust InstallPrompt positioning to avoid overlapping bottom navigation
- throttle map cluster recomputation to reduce unnecessary work during pan/zoom
- clear cached items on logout to prevent cross-driver data leakage
- Set up class-based dark mode in Tailwind config
- Add pre-hydration dark mode application to avoid theme flash on initial load
- Implement accessible dark mode toggle in settings page
- Update all UI surfaces (headers, bottom nav, maps) with dark mode color schemes
- Add comprehensive global CSS overrides for arbitrary Tailwind classes
- Add brand accent strips to header and bottom nav for consistent visual framing
- Refine map waypoint styling: reduce dot size, update label positioning and styling
- Add standardized item display helpers for consistent labeling across components
- Rework PocketBase data fetching into scoped assigned/pool/problem item queries
- Add proximity-based clustering and AreaGroup component for geographic list grouping
- Sync map page tab state with main collections list using localStorage
- Update all existing components to use new data and display patterns
- Add custom map marker, tooltip, and cluster styling
- rename `supplier` field to `suppliers` in OrderItem interface and PocketBase expand queries
- complete visual rebrand to warm cream (#f2f1ed) and dark brown (#26251e) color palette with custom CSS variables
- add accessibility improvements: skip-to-main content link, focus-visible styles, reduced motion support, and proper ARIA labels
- update all component styling to match new theme, including offline indicator, install prompt, login page, modals, map, bottom nav and global CSS
- standardize status colors: use green for success, red for errors, retain orange (#f54e00) as primary accent CTAs
Import global Leaflet CSS in the app layout, create a MapErrorBoundary in the map page to catch map load failures and show a retry UI, and wrap the dynamic CollectionMap with that boundary. Adjust CollectionMap by removing the local Leaflet CSS import, cleaning up unused imports/types, and changing the container to absolute/full-bleed styling so the map fills its parent. These changes improve robustness against map loading errors and ensure Leaflet styles are applied app-wide.
Introduce a new SupplierGroup component and group collections by supplier. Add supplier color palette, per-supplier expand/collapse state, compact/detailed view modes, and controls to toggle/expand/collapse groups. Pass supplierColor and compact props to CollectionItemCard to adjust visuals, use useMemo for grouping, and auto-expand suppliers on initial load. Minor UI tweaks: adjust skeleton count/spacing, update stats/controls bar, improve toast styling, and remove some console logs.
Add full PWA support (icons, manifest, service worker, pwa lib and bridge) and introduce install/offline UI. Generate app icons via a new scripts/generate-icons.js and include multiple icon sizes in public/icons; update manifest and layout head meta/preconnect. Revamp global styles (globals.css) with new utilities, animations, spacing for bottom nav, card shadows, skeletons and accessibility tweaks. Polish major screens (login, collections, map, settings) with improved headers, loading states, touch/press feedback, and layout adjustments; add new components (InstallPrompt, OfflineIndicator, PWABridge) and update various components to match new visual/UX patterns. Update Dockerfile to generate icons and use Next.js static export output (/out) for nginx, and bump package setup to support icon generation.
Render a driver's location trail on the map and add controls to toggle it. Changes include: component imports (Polyline, Route), new trail state and interval ref, fetchTrail logic (uses isAuthenticated/getCurrentUser/getDriverTrail) with periodic refresh (every minute), FitTrail component to fit map to the trail, Polyline and start marker rendering, and a Trail toggle button in the UI. Also cleaned up MapBounds (explicit return null), small popup/legend adjustments, and grouped supplier processing remains unchanged. Added getDriverTrail helper in lib/pocketbase.ts to fetch today's driver_locations for a given driver id.
Convert the app from using legacy Collection models to OrderItem-based data. Updated pages (app/page and app/map/page) and all related components (CollectionMap, CollectionItemCard, CollectModal, ProblemModal, LocationTracker) to use OrderItem and new field names (supplier, order, item_status, qty_collected/collected_date, problem_flag/notes, etc.). PocketBase client now queries/updates the order_items collection and maps status/field changes accordingly. Simplified location tracking logic and cleaned up map/navigation UI and Suspense fallbacks. Added import_suppliers.py script for migrating suppliers from NocoDB and included .DS_Store artifacts.
- Added package.json with dependencies for Next.js, React, and Tailwind CSS.
- Created postcss.config.js for Tailwind CSS and autoprefixer integration.
- Added SVG icon for the application in public/icons/icon.svg.
- Created manifest.json for PWA support with app details and icon.
- Configured Tailwind CSS in tailwind.config.js with custom colors and animations.
- Set up TypeScript configuration in tsconfig.json for strict type checking and module resolution.