Commit Graph

68 Commits

Author SHA1 Message Date
Developer
3beafa3ac2 feat(admin/trips): surface dumpsite release records in trip detail panel
- Eager-load dumpsiteReleases.dumpsite + dumpsiteReleases.releasedByDriver
  in AdminTripController::show()
- Add releases[] array to TripResource via whenLoaded('dumpsiteReleases')
  - Fields: weight_kg, released_at, dumpsite_name, driver_name,
    gate_pass_number, dumpsite_attendant, notes
- Admin Trips detail panel now shows a 'Dumpsite Releases' section
  below the timeline with per-release cards
- Load row updated to show release count e.g. '450 kg (2 releases)'
2026-07-02 15:01:23 +08:00
Developer
6b39cf645a fix: restore Endroid Builder::create() fix in StorePortalController 2026-07-02 13:57:40 +08:00
Developer
ba30a5fcdf fix: QrCode relation bug and Endroid create() error 2026-07-02 13:57:39 +08:00
Developer
d9495be0e0 feat: Implement segmented toggle for Resident/Household sales, Cash Only badge, and user_id in StoreSale 2026-07-02 13:57:39 +08:00
Developer
f517b77377 style: fix linting issues with Laravel Pint 2026-07-02 13:55:34 +08:00
Developer
c4cbdb42c7 feat(store): complete partner store overhaul with mapping, household search, financial analytics, and resident notification system 2026-07-02 13:55:08 +08:00
ramram1515
7ced07b323 feat: Relax barangay_id requirement for resident registration 2026-07-02 13:22:33 +08:00
ramram1515
ec6b9e61a3 feat: implement Live Truck Radar caching 2026-07-02 13:02:29 +08:00
Developer
a1470eb85e feat: implement team standby status, helper persistence, and store portal foundations 2026-07-02 12:03:50 +08:00
ramram1515
a9a1df93bd feat(driver): Add assigned truck details to profile screen 2026-07-02 11:44:31 +08:00
Developer
4a4b88ffe4 feat: partner store financial settlements, qr replacements, and tenant resolution fix 2026-07-01 16:38:49 +08:00
Developer
62bcf68bdb feat: add partner store analytics, history logs, and global SRP validation 2026-07-01 15:02:43 +08:00
Developer
cc4fd8ba17 feat: early dumping detour mode backend logic 2026-07-01 13:23:39 +08:00
Developer
70741a3c24 feat: live tracking setup and map parsing fixes 2026-07-01 13:04:51 +08:00
Developer
7a63d2c680 Merge branch 'main' of https://gitea-qzlf.srv1050180.hstgr.cloud/admin/Verde-Web 2026-06-30 16:10:43 +08:00
ramram1515
2467633b1b Config 2026-06-30 16:10:19 +08:00
Developer
d66d6e3396 fix: resolve tenant_id scoping issue on QR code batch generation 2026-06-30 15:59:03 +08:00
Developer
6c83d99fd7 Merge branch 'main' of https://gitea-qzlf.srv1050180.hstgr.cloud/admin/Verde-Web 2026-06-30 15:33:50 +08:00
Developer
5959f74746 chore: clean up 2026-06-30 15:32:01 +08:00
Developer
cfb09fd5fb feat: add void and delete endpoints for qr batches, fix batch list status counts 2026-06-30 15:03:25 +08:00
Developer
7452848cf9 fix: resolve duplicate entry error when adding a soft-deleted member back to a household 2026-06-30 14:48:23 +08:00
Developer
bb9825a86b feat: add batch activation endpoint and fix batch generation sequence bug 2026-06-30 14:27:17 +08:00
ramram1515
b8c56585bc UI enhancements and Actionable Notifications 2026-06-30 14:06:21 +08:00
Developer
a4e0fd3408 Merge branch 'main' of https://gitea-qzlf.srv1050180.hstgr.cloud/admin/Verde-Web 2026-06-30 13:35:28 +08:00
Developer
92f8ee95fc feat: Add Geofence Leaflet drawing tool for DOPs and Dumpsites 2026-06-30 13:31:36 +08:00
ramram1515
88caf14aa1 fix(api): force Manila timezone for upcoming pickups evaluation 2026-06-30 13:21:56 +08:00
Developer
7601d721d2 feat(api): add active-trip endpoint for helper and enable Vite dev server CORS 2026-06-30 11:25:31 +08:00
Developer
64d442ec2e feat: add proof of residency upload option during admin household creation 2026-06-30 10:27:49 +08:00
Super Admin
cfd7166a24 feat: implement drop-off points & dumpsites edit/delete and status transition logic 2026-06-29 23:15:55 +08:00
Super Admin
f2c1573f00 feat: Implement Truck edit, delete, and automatic trip cancellation when moved to maintenance/retired status 2026-06-29 22:59:47 +08:00
Super Admin
7a8fe3e7c3 feat: Add mapping, boundaries, and tabbed slide-over management to Partner Stores 2026-06-29 22:32:59 +08:00
Super Admin
31b9bbb026 feat: Implement tabbed slide-over edit modal for households 2026-06-29 19:42:16 +08:00
Developer
7dc074e3c3 Implement household, QR sale, team helpers assignment, and helper endpoints 2026-06-29 16:56:33 +08:00
Developer
b85fc255cf feat: implement barangay and household management with associated tests 2026-06-29 15:02:52 +08:00
ramram1515
9ac2ea7bda chore: apply code review checklist and web design guidelines fixes 2026-06-29 13:54:14 +08:00
Developer
2c7c3528e4 feat: implement interactive Barangay polygon map selector in Service Areas 2026-06-29 13:22:45 +08:00
Developer
4d8ccd3cd4 Merge branch 'main' of https://gitea-qzlf.srv1050180.hstgr.cloud/admin/Verde-Web 2026-06-29 12:45:13 +08:00
Developer
8dbc87b44f feat: add super admin LGU management and global user creator dashboard screens 2026-06-29 12:45:07 +08:00
ramram1515
91df4d05f0 fix: increase per_page validation limit to 500 across all remaining admin endpoints 2026-06-29 12:26:37 +08:00
ramram1515
e76eec1fbd Merge branch 'main' of https://gitea-qzlf.srv1050180.hstgr.cloud/admin/Verde-Web 2026-06-29 12:21:48 +08:00
ramram1515
4b483c093b fix: increase per_page validation limit to 500 on admin endpoints to allow drop-down populating 2026-06-29 12:17:34 +08:00
Developer
82dc044e1a merge: resolve conflicts in EnsureUserHasRole.php and echo.js 2026-06-29 12:05:52 +08:00
ramram1515
8638a80067 feat: implement interactive map location picker and address search with autocomplete suggestions 2026-06-29 11:54:39 +08:00
Developer
167abdc6ad fix: resolve super_admin login, echo crash and GD extension test failures 2026-06-29 11:43:40 +08:00
b1bc73b100 feat(mobile-driver): Phase 2 — trip lifecycle + foreground GPS
Backend:
- Driver trip endpoints now eager-load 'truck' on both index and
  show. The mobile app needs the truck UUID to target the GPS
  endpoint (POST /driver/trucks/{truck}/location); without this it
  would have to re-query.

Mobile (mobile-driver/):
- TripModel + TripStopModel + DropOffSummary + DumpsiteSummary +
  TruckSummary — typed Dart models that mirror the backend's
  TripResource shape exactly.
- TripsRepository covers all 11 driver endpoints: index, show,
  start, arrive, depart, skip, arrive-dumpsite, release-load,
  complete, report-incident, post-location.
- myTripsProvider + tripDetailProvider (FutureProvider.family)
  for declarative re-fetching after every action.
- Home screen replaces the placeholder cards with a real trip list:
  status pill (scheduled / in_progress / at_dumpsite / completed /
  cancelled), today badge, route name + trip number, scheduled
  time, truck plate, and a per-trip progress bar showing
  done/total stops. Pull-to-refresh + empty/loading/error states.
- Trip detail screen with a verde gradient header (route, trip
  number, truck plate, dumpsite), a context-aware primary action
  (Start / Arrive at dumpsite / Release load + Complete), and a
  list of stops with active-stop highlighting + per-stop Arrive /
  Depart / Skip buttons. Skip prompts for a reason. Release load
  is a bottom-sheet with a numeric weight input.
- LocationBroadcaster service: 15-second foreground GPS pump that
  posts to the truck-location endpoint, with permission cascade,
  immediate first-pulse on start, and graceful network-failure
  swallowing (Phase 3 will add a local buffer).
- activeTripWatcherProvider: listens to myTripsProvider and
  auto-starts/stops the broadcaster when a trip transitions in or
  out of the running state. Mounted from the home screen.
- Router gains /trip/:uuid.

Limitations carried forward:
- Foreground only. iOS will throttle the timer within ~30s of
  backgrounding. Phase 3 swaps in a native background-locator.
- No offline buffer — if the server is unreachable a GPS pulse is
  dropped silently.
- No incident-reporting UI yet (the repository method is in place).

Tests:
- Widget test now renders the TenantScreen in isolation. The
  full-app test was flagging timers from Dio + secure_storage that
  are tricky to flush deterministically. Phase 3 will add a
  fakeAsync harness.
- flutter analyze: 8 style infos, no warnings, no errors.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 23:36:43 +08:00
fcf2f9d0bf feat: multi-LGU tenancy — Phase A (foundation + customer-web)
Backend:
- New tenants table with PSGC-derived code, links to
  cities_municipalities, optional boundary_polygon override, theme
  color, contact info, timezone.
- Adds nullable tenant_id to users / households / drop_off_points /
  dumpsites / partner_stores. Foreign-keyed, indexed.
- Tenant model with deriveCode() helper + effectiveBoundary()
  fallback chain.
- App\Tenancy\Tenancy — process-level current-tenant register with
  withTenant() / withoutScope() helpers for jobs + super-admin.
- App\Tenancy\TenantScope — global Eloquent scope, no-op when no
  tenant is set (so seeders + super-admin reads still work).
- App\Tenancy\HasTenant trait — applied to Household, DropOffPoint,
  Dumpsite, PartnerStore. Auto-fills tenant_id on create from
  Tenancy::current().
- ResolveTenant middleware — reads X-Tenant-Code (or X-Tenant-Id),
  validates tenant exists + active, sets Tenancy::current(). Falls
  back to authenticated user's tenant_id when header missing.
  Registered globally on the api group.
- Login + register now require an active tenant (super-admin
  bypasses). Cross-tenant credential reuse is rejected with a
  403 + clear message.
- super_admin role added to RoleSeeder + users.role enum.
- Public GET /api/v1/tenants/lookup?code= — no auth, returns tenant
  details for the pre-login screen.

Seeders:
- SuperAdminSeeder seeds super@verde.local (tenant_id = null).
- SanPascualTenantSeeder seeds Region IV-A → Batangas → San Pascual
  municipality → sample Poblacion barangay → Tenant row with code
  SAN-PASCUAL-BAT, then backfills every existing tenant-aware row
  (13 users / 2 households / 5 DOPs / 1 dumpsite / 3 stores) so
  the dev environment keeps working end-to-end.
- Wired into DatabaseSeeder so migrate:fresh --seed bootstraps
  cleanly.

Customer-web:
- New /tenant page — text input, calls public lookup, confirms with
  resolved tenant card, stores code + name in cookies (1 year).
  "Pilot users: SAN-PASCUAL-BAT" hint as a clickable shortcut.
- /login + /register now redirect to /tenant?next= when no cookie,
  show a verde "signing in to <LGU>" pill with a Switch link,
  delegate the actual form to client components.
- /api/tenant route — POST sets cookie, DELETE clears.
- apiServer auto-attaches X-Tenant-Code on every API call when the
  cookie is present.
- Tenant cookies are non-httpOnly so the client can echo them; the
  session token stays httpOnly.

Build: 23 routes (added /tenant), 196 backend tests still pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 22:38:35 +08:00
f552bccd1a feat(customer-web): Phase 3 — codes / pickups / history / live tracker
Backend:
- New GET /api/v1/me/live/trucks. Returns active trucks whose
  in-progress trip serves the resident's assigned drop-off point,
  with the same shape as the admin endpoint. Empty when household
  has no DOP yet.

Frontend (customer-web/):
- /codes — paginated list with status filter pills (all / active /
  allocated / used / expired), one-click activate for allocated
  codes (in-place state update), inline balance summary + low-balance
  warning banner with link to partner stores.
- /pickups — upcoming-trip cards with status pill, route, scheduled
  date/time, my stop sequence, driver, truck plate, link to live
  tracker. Friendly empty states for "no DOP assigned" and
  "no trips scheduled".
- /collections — date-range filtered scan history table (when /
  serial / drop-off / weight / waste type), shows total scan count.
- /tracker — Leaflet map polling /me/live/trucks every 10s. Drop-off
  pin (verde dot) + truck markers (rotating SVG arrow by heading
  degrees, 400ms transition between updates). Diff-update logic:
  reuses markers across polls and removes trucks that vanish.
  Side list of active trucks with plate, team, speed, last update.
  Falls back to NCR center when no DOP coords. Leaflet loaded from
  CDN (kept out of bundle) — no SSR concerns.
- Resident nav adds /collections (label "History").
- API client: types LiveTruck + LiveTrucksResponse; me.liveTrucks().

Build: 16 routes, all type-check + lint clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 19:49:04 +08:00
1bc1ea7282 feat(customer-web): Phase 2 — onboarding wizard + household management
Backend:
- New GET /api/v1/me/household endpoint. Returns the resident's
  household (with members + barangay + assigned DOP) or { household:
  null }. Used by the wizard to gate-keep the onboarding flow.

Frontend (customer-web/):
- /onboarding — 5-step wizard (Address+map, Size, Proof, Members,
  Review). Submits POST /households then uploads proof + adds
  members in sequence. Server-side guard redirects to /household
  when one already exists.
- /household — full status view:
  - Pending: live polling every 30s, "Refresh" button, status pill
  - Approved: success state, link back to dashboard
  - Rejected: shows reviewer's reason, ResubmitCard re-uploads
    proof and flips status back to pending automatically
  - Members card with add/remove (head is protected)
- /home now checks household state server-side:
  - No household → redirect /onboarding
  - Pending/rejected → status banner + link
  - Approved → full dashboard with QR balance + next pickup +
    quick-action grid
- New components:
  - MapPicker — click-to-place pin via Leaflet (CDN-loaded), drag
    to fine-tune, returns {lat, lng}
  - ProofUpload — drag-and-drop with image preview, jpg/png/pdf,
    8MB cap, file size + type validation
- API client adds me.household() and reuses existing household.*
  + uploadProof multipart helpers

Build: 12 routes compile clean, biggest first-load JS 122 kB
(/register), Wizard + Household views 5–7 kB each.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 18:55:38 +08:00
306f8fb4e8 feat(backend): customer-site API gaps + CORS
- GET /partner-stores/nearby — public, residents browse active stores
  ranked by distance via ST_Distance_Sphere; PublicPartnerStoreResource
  excludes commission rate / owner / permit (only what a buyer needs).
- GET /partner-stores/{uuid} — public details, 404 if not active.
- GET /me/collections — paginated resident QR scan history with
  optional from/to date filters.
- GET /me/upcoming-pickups — finds scheduled/in-progress trips whose
  route includes the resident's assigned drop-off point. Returns
  household_assigned: false when no household yet.
- GET /me/notifications — paginated database notifications inbox
  with unread_only filter + unread_count in meta.
- POST /me/notifications/{id}/read, POST .../mark-all-read,
  GET .../unread-count.
- config/cors.php — allow CUSTOMER_APP_URL and any EXTRA_CORS_ORIGINS
  to call the API with credentials. Same-origin admin web is
  unaffected.

202 feature tests passing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 17:55:10 +08:00
968ced302c feat(live): god's-eye view — heading, route, breadcrumb, click-to-detail, push
Live Tracking page upgrades:

- **Heading rotation** on each truck marker via CSS transform driven by
  the heading_degrees broadcast field.
- **Click-to-detail** opens a slide-over showing trip number, status,
  route, started-at, current load, an ordered stop list color-coded by
  status, and the last 20 timeline events.
- **Route overlay** draws planned-route polyline (stops in order →
  dumpsite, dashed), stop markers (pending/arrived/completed/skipped
  colors), a diamond marker for the dumpsite, and a translucent
  geofence polygon when the dumpsite has one configured.
- **Breadcrumb trail** of the last 60 minutes of GPS pings rendered
  as a polyline; new pings tack on incrementally while the panel is
  open.
- **Real-time push via Reverb** with polling fallback. Subscribes to
  private-admin.live, listens for `.truck.location`, and updates
  marker position + the trucks-online list immediately. When Reverb
  isn't configured or fails, falls back to 10s polling. Status pill
  shows live (push) / polling / offline.

Backend additions:
- GET /admin/live/trucks/{uuid}/trail — recent location pings
- GET /admin/live/trucks/{uuid}/active-trip — full trip + stops +
  dumpsite + boundary + recent timeline
- Broadcasting auth route now accepts Sanctum bearer tokens (admin
  web posts them via Echo's authorizer callback)

Frontend wiring:
- npm: laravel-echo + pusher-js
- window.Verde.getEcho() lazily inits Echo with bearer-token authorizer
- Layout exposes window.VERDE_BROADCAST with reverb config

196 tests passing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 17:44:13 +08:00