Commit Graph

125 Commits

Author SHA1 Message Date
shawn f4cbe00f7f feat: scan existing asset redirects to detail view instead of scan result card
When a user scans a barcode that matches an existing asset:
- Redirect directly to the asset detail view (Assets tab)
- Auto-checkin still runs in background if GPS available
- Show a toast notification with the asset name

When scanning a barcode not in database:
- Switch back to Add Asset tab and show the create form
- Deferred status update survives async startScanning

No backend changes needed.

Closes #39
2026-05-24 17:17:13 -04:00
shawn b896a5680d feat: enlarge asset list cards — bigger icons, padding, prominent floor/building/room display 2026-05-23 20:31:48 -04:00
shawn 9fe615c76b clean up asset names: strip addresses/floors/parks/building prefixes from names (353/1848 cleaned) 2026-05-23 20:24:51 -04:00
shawn 76e28614ae feat: tag Disney assets with park/resort codes and display names
- Script: scripts/tag_disney_properties.py (supports dry-run + --apply)
- Maps 112 Disney location IDs to park/resort/office/other codes
- Updated 994 assets: disney_park column + appended display name with emoji
- Added disney_park column to locations table, populated 112 rows
- Covers all 364 locations via case-insensitive substring matching
2026-05-23 19:50:16 -04:00
shawn a5708623cc feat: show address, floor, building, room in asset list items
- Add .ai-address and .ai-location CSS classes
- Increase .asset-item padding to 14px, align-items to flex-start
- Reduce .ai-name font to 14px, allow wrapping
- Render address line (📍 icon) when present
- Render floor · building · room location line when any field present
- Keep existing icon and meta line unchanged
2026-05-23 19:46:25 -04:00
shawn 13bf61d856 feat: extract floor/building/room/trailer from asset names
Adds scripts/extract_asset_location_data.py which:
- Extracts floor, building_number, room, trailer_number, building_name from names
- Detects and removes duplicated name segments
- Updates both assets (1848) and locations (364) tables
- Dry-run mode by default, --apply to write changes
2026-05-23 19:41:55 -04:00
shawn a305766d65 fix: show '— No report yet' for assets without dex_report_date 2026-05-23 18:46:58 -04:00
shawn 6016f6a5e6 feat: add No DEX (5d) filter toggle to asset list filter panel
- Add .filter-toggle.warn CSS styles (amber border/text with active bg)
- Add Data Health row with toggle button in filter panel HTML
- Add noDexFilterActive state variable and toggleNoDexFilter() function
- Wire no_dex_days=5 into API URL builder when toggle active
- Integrate into getActiveFilterCount, renderActiveFilterTags, removeFilter, clearAllFilters
2026-05-23 17:41:04 -04:00
shawn 9d9e50834c feat(import_machines): add dex_report_date, deployed, pulled_date extraction
- Extract from row[7] (Col 8), row[34] (Col 35), row[35] (Col 36)
- Handle datetime -> ISO conversion for date columns
- Include in UPDATE and INSERT statements

Kanban: t_3bef3c9c
2026-05-23 17:30:10 -04:00
shawn 4ebe3a5076 feat: add dex_report_date to AssetCreate model + test for no_dex_days filter
- Add dex_report_date field to AssetCreate Pydantic model
- Include dex_report_date in _build_asset_insert columns/values
- Add test_list_assets_filter_no_dex_days test (11/11 pass)
2026-05-23 17:29:37 -04:00
shawn 900f912147 v5 migration: add dex_report_date and install_date columns to assets table 2026-05-23 17:26:11 -04:00
shawn c9c6317900 fix: larger park/resort labels (13px bold), allow 2-line wrap, center-aligned 2026-05-23 00:41:35 -04:00
shawn 0be50e7957 fix: revert chips to emoji, Snack pins use 🍿 fallback (img→emoji), bigger markers 28px 2026-05-23 00:37:10 -04:00
shawn 1bb03eb964 feat: SVG icons for map toolbar chips — flame/crosshair/outline, 13px, with label spans 2026-05-23 00:34:54 -04:00
shawn 384a0b842b fix: simple colored circle pins, no transforms — 22px dot with emoji and white border 2026-05-23 00:33:53 -04:00
shawn 71de462040 fix: teardrop pin markers (smaller, 24px) with category emoji on white dot 2026-05-23 00:31:46 -04:00
shawn 26311e7fe6 feat: text labels on Leaflet.draw toolbar — Area/Box/Circle/Edit/Delete instead of bare icons; revert chip changes 2026-05-23 00:29:56 -04:00
shawn 0401e45ea4 feat: category-based icon pins on map — 🥤🍔🔧 etc instead of blue dots 2026-05-23 00:27:54 -04:00
shawn 796914b089 feat: clearer map control icons with SVG + label spans, replace emoji chips 2026-05-23 00:25:43 -04:00
shawn 4ac930f2bf feat: 15 named Disney resort outlines with individual labels on map 2026-05-23 00:18:47 -04:00
shawn 0f2ead4b5b feat: bolder park outline styling — thicker lines (5px), full opacity, stronger fill, saturated colors 2026-05-23 00:15:08 -04:00
shawn 39b8669b21 Fix park outline coordinates + visibility
- Magic Kingdom: accurate 60-point polygon from OSM way 297428432
- All parks: adjusted boundaries for better alignment
- Increased stroke weight (3px) and opacity for visibility
- Higher fill opacity (0.15)
2026-05-23 00:04:27 -04:00
shawn 5380bf7256 Add Disney park outlines to map
- Polygons for Magic Kingdom, Epcot, Hollywood Studios, Animal Kingdom, Disney Springs
- Resort area outline (dashed) for Pop Century / Art of Animation
- Color-coded to match existing park badge colors
- Labels with park icons at polygon centers
- Toggle chip (🏰 Parks) in map controls to show/hide
- Outlines visible by default on map load
2026-05-22 23:53:09 -04:00
shawn a0e6f627f4 Revert "Add clear GPS endpoint + frontend button"
This reverts commit ca77a29d7d.
2026-05-22 23:32:51 -04:00
shawn ca77a29d7d Add clear GPS endpoint + frontend button
- DELETE /api/assets/{id}/gps sets lat/lng to NULL
- Detail view shows 'Clear GPS' button when asset has GPS coords
- Confirmation modal before clearing
- Tests: 204 success + 404 not found
2026-05-22 23:30:07 -04:00
shawn 95b02a1ecc fix: dynamic VALID_CATEGORIES from DB + populate categories table
- server.py: VALID_CATEGORIES now loaded from categories table at startup
  (was hardcoded to {Furniture, Appliances, Utensils, Equipment, Other})
- categories table now includes: Bev, Snack, GF Bev, GF Food,
  Snack/bev, Snack/food, Food
- Cleared GPS for MID 60006 per user request
2026-05-22 19:43:50 -04:00
shawn d91c1f0861 fix: normalize GF Bev/GF Food category casing throughout
- import_machines.py: add GF Bev/GF Food/Bev to category_map
- static/index.html: CATEGORY_MAP keys Gf bev→GF Bev, Gf food→GF Food
- DB: migrated 236 Gf bev→GF Bev, 173 Gf food→GF Food
2026-05-22 19:15:57 -04:00
shawn c64baf2c45 classify_makes: add short 8-digit DN + 76/77 prefix rules
Covers 3 additional edge cases found in unmatched:
- 8-digit 114xxxx / 241xxxx → DN (short serial format)
- 10-digit 76xxxx / 77xxxx → DN (no alpha suffix variant)

Unknown make: 130 → 6 (95.4% classified)
6 remaining: garbage serials (00, 520, a×3) + RY01023590 (low-conf Royal)
2026-05-22 19:10:42 -04:00
shawn 4f33afb445 classify_makes.py: serial number → make/model/class classification
Classifies Unknown-make assets by serial number prefix patterns,
cross-referenced against Cantaloupe Excel export data.

Handles:
- Character substitution errors (S→5, I→1, O→0)
- Double-strike/extra character cleanup (I5SS → 155)
- 8 rule sets: Vendo, Crane (167/168/186/187/222/221/47x),
  DN/Dixie Narco, Royal (20xx/BA/CA/PA), USI, AMS, VE
- Confidence levels: high/medium/low
- Dry-run + --apply modes
- --stats for post-classification summary

Result: 121/130 unknown machines classified (93%)
  76 Vendo, 14 DN, 12 Crane, 8 Royal, 6 USI, 1 AMS
  9 remaining: garbage serials (a, 00, 520) + one-offs
2026-05-22 19:02:04 -04:00
shawn db6859a0f5 fix: Add Cache-Control: no-cache to static files to prevent stale HTML/image caching 2026-05-22 18:44:36 -04:00
shawn 71a0c9936a chore: Update chips icon to transparent-background PNG with 'REAL POTATO CRISPS' 2026-05-22 18:42:39 -04:00
shawn 8c828000bb feat: Swap snack icon from popcorn 🍿 to bag of chips image
Replaced the Snack category emoji with an actual chips illustration
served from static/icons/chips.png. The icon renders in the asset
list category badges as a 28x28 object-fit:contain image within
the 42x42 circular badge.
2026-05-22 18:40:26 -04:00
shawn e8a918fc7b feat: add is_disney column for reliable Disney/Non-Disney filtering
- Added is_disney INTEGER DEFAULT 0 column to assets table
- Backfilled 996 Disney assets based on D- customer prefix
- Server: is_disney in AssetCreate/AssetUpdate models, INSERT/UPDATE
- Server: disney_filter query param now uses is_disney column (no JOIN needed)
- import_cantaloupe.py: sets is_disney=1 when customer starts with D-
- import_machines.py: sets is_disney=1 when customer starts with D-
- disney_classify.py: sets is_disney=1 when classifying
- Frontend: new Location Type dropdown with Disney/Non-Disney toggle
  (replaces the __disney__/__non_disney__ park dropdown pseudo-options)
2026-05-22 18:34:13 -04:00
shawn 60dfd3434a feat: add Disney/Non-Disney quick filter to dropdown panel
Backend:
- disney_filter query param on /api/assets (values: 'disney' | 'non_disney')
- Detects Disney by checking disney_park IS NOT NULL OR customer name LIKE 'D-%'
- Catches ESPN, Wide World of Sports, all Disney resorts, etc.
- Adds LEFT JOIN to customers table when disney_filter is active

Frontend:
- '🏰 Disney only' and '🏢 Non-Disney' options in Disney Park dropdown
- Active filter tag shows which is selected
- Works together with other dropdown filters
2026-05-22 18:25:54 -04:00
shawn 11628898ff chore: remove orphaned renderFilterPills function 2026-05-22 18:21:32 -04:00
shawn c19295f1a2 fix: remove inline filter pills, keep only Filters button + dropdown panel 2026-05-22 18:21:07 -04:00
shawn e0412acbe3 feat: add Category, Make, Disney Park to filter panel dropdowns with backend endpoints 2026-05-22 18:19:32 -04:00
shawn d98a791c96 feat: improved asset filter UX - collapsible filter panel, customer/location cascade, status dropdown, assigned_to filter, active filter tags, result count
Backend:
- GET /api/customers — lists all customers for filter dropdown
- GET /api/locations?customer_id=X — cascading locations per customer
- GET /api/users — lists users for assigned_to filter

Frontend:
- Collapsible 'Filters' panel with Customer→Location cascade, Status, Assigned To
- Active filter tags showing what's currently filtering, removable individually
- 'Clear all filters' button to reset all at once
- Result count display ('X assets found')
- Better search placeholder showing searchable fields
- Filter count badge on the toggle button
2026-05-22 18:15:35 -04:00
shawn 35ccebb0f0 Add serial_number to search bar query 2026-05-22 18:07:42 -04:00
shawn dec6a90409 Add proper category icons for all 10 types, remove stale CSS 2026-05-22 18:02:41 -04:00
shawn 7394d44caf Load all assets at once (no pagination), add server-side disney_park filter 2026-05-22 17:59:33 -04:00
shawn 95b5bd26eb Add pagination (Prev/Next with counter) and X-Total-Count header 2026-05-22 17:57:24 -04:00
shawn cce5cf2b5f Add Disney park badges, filter pills, editable classification, and service entrances to asset detail view 2026-05-22 17:53:32 -04:00
shawn bb0f6b81e7 Add Excel import script for Cantaloupe machine list 2026-05-22 17:53:29 -04:00
shawn 27f372ed49 DB schema: add disney_park column to assets, create service_entrances table
- Added disney_park TEXT DEFAULT NULL to assets table in _create_v2_tables
- Created service_entrances table with id, location_id, name, latitude,
  longitude, notes, created_at, updated_at; location_id FK to locations
  with ON DELETE CASCADE; name/lat/lon are NOT NULL
- Added v4 migration in init_db: ALTER TABLE for disney_park on existing
  DBs, schema-aware recreation of service_entrances if name column lacks
  NOT NULL constraint
- 44/45 tests pass (1 pre-existing 404 failure on stats endpoint)
2026-05-22 17:45:47 -04:00
shawn 6aa5d3d35c Add Disney park classification + service entrance API
- Auto-classifies 1,155 Disney assets into parks/resorts/offices
- New columns/table: assets.disney_park, service_entrances
- API: /api/disney/stats, /api/disney/classify, /api/assets/{id}/disney-park
- API: /api/service-entrances CRUD, /api/locations/{id}/service-entrances
- OCR strategy: ConnectID last-5, resort keyword detection, address patterns
2026-05-22 17:41:11 -04:00
shawn 2e2fd50f70 fix: retake admin screenshots in portrait with working emoji icons
- All admin screenshots retaken at 412×892 @2.625x (pixel 9a portrait)
- Fixed emoji rendering — ni-icon emojis now show colored icons (📈⚙️👥🏢📋📤📥)
- Fixed ADMIN_GUIDE.md TOC: 'Cantaloupe Data Sync' → 'Excel Import'
- Fixed sidebar nav list: '🔄 Sync' → '📥 Import'
2026-05-22 16:38:37 -04:00
shawn d92f2a0b2c docs: portrait admin screenshots + user guide admin section
- Retake all admin screenshots in portrait (412px narrow column)
- Add Admin Panel section (Section 9) to USER_GUIDE.md
- Update ADMIN_GUIDE.md references for portrait screenshots
2026-05-22 16:24:58 -04:00
shawn 1ef86ebfe0 docs(admin): retake all admin page screenshots for visual clarity
- Retake full set of p9a_admin_*.png screenshots (login, dashboard, settings, users, customers, activity, export, import, sidebar)
- Each screenshot inspected for layout errors
- Proper 1280px desktop viewport for all pages, clean empty states
- Save to docs/images directory
2026-05-22 16:17:57 -04:00
shawn d139abf923 docs(admin): new screenshots for Import page and hamburger sidebar
- Replace p9a_admin_sync.png with p9a_admin_import.png (new Import page)
- Add p9a_admin_sidebar.png (mobile sidebar with hamburger open)
- Update ADMIN_GUIDE.md with mobile navigation section
- Add screenshot reference in Import section
2026-05-22 16:12:15 -04:00