No description
Find a file
DEls fa5611cb38 Drop in real data for The Hills ext 12 (C26/09) + Burn panel
Data wired from the site cost sheet, fuel log, wage schedule and two
PO PDFs the user shared:

  - src/lib/types.ts            VehicleType expanded (Roller, TLB,
                                Pickup, Water Truck, Compressor,
                                Mixer) so plant types map cleanly to
                                the source data. Vehicle gains
                                optional kmPerL and expectedLPerHour
                                fields for the mixed L/h + km/L
                                allowance model.
  - src/lib/mock-data.ts       SITES_DATA[0] = The Hills ext 12,
                                contract value R24,988,663, contract
                                code C26/09, 8-month duration.
                                SITES, SUPPLIERS updated.
                                VEHICLES populated with 47 entries
                                covering rollers, TLBs, excavators,
                                graders, loaders, tipper trucks,
                                water trucks, pickups, mixers and
                                auxiliary equipment (compressors,
                                crushing machine).
                                EMPLOYEES populated with 15 permanent
                                + 53 casuals, all at the project's
                                45h/week standard.
                                PLANT_HIRE_RATES populated with 32
                                entries matching the cost sheet
                                (R185–R680/h depending on equipment).
                                PG_EXPENSES populated with all 6 P&G
                                monthly lines (container, security,
                                salaries, overheads, insurance,
                                site facilities = R567,403.50/m).
                                ORDERS populated with MEGCPO9199
                                (PPE, Delivered) and MEGCPO9165
                                (aggregates, Partial).
                                FUEL_READINGS starts empty — drop
                                CSV-imported rows in once the depot
                                system is wired.
  - src/lib/uploads.ts          UPLOAD_HISTORY seeded with the GRN
                                attached to MEGCPO9199.
  - src/lib/burn.ts             New helper. burnBreakdown() joins
                                plant hire rates with the vehicles
                                list, multiplies each hire rate by
                                the standard 45h/week, adds weekly
                                P&G share, and surfaces both weekly
                                and monthly totals.
  - src/lib/sites.ts            summarizeSite + summarizeAllSites
                                now take PlantHireRate[] and
                                PgExpense[] so the site summary
                                exposes weeklyBurn / monthlyBurn /
                                weeklyPlantHire / monthlyPg etc.
  - src/app/dashboard/page.tsx  New 'Burn rate — weekly vs monthly'
                                panel. Two side-by-side cards show
                                weekly + monthly totals with plant
                                hire vs P&G breakdown, plus a
                                'Cost breakdown' card on the right.
  - src/app/dashboard/sites/*  Pass the new hireRates + pgExpenses
                                arrays through to the summary helpers.

Notes:
  - The 'Spent to date' KPI on the Sites list / detail now sums PO
    value (since there are no fuel readings yet). Once depot data is
    ingested, it will pick up the actual R25.65/L burn automatically.
  - Tank capacities + odometer start values are sensible estimates
    for the equipment types — adjust per-unit when you have real
    fleet specs.
  - Weekly hours per employee default to 45h so the workforce
    trends look populated; replace with timesheet imports as soon as
    those land.
2026-08-18 12:35:34 +02:00
.opencode/openwork/inbox/chat-attachments/ses_01cf7df27ffeyy367S81LZdRJG Initial commit: MEGA INFRASTRUCTURE dashboard + Coolify Dockerfile 2026-08-09 01:37:40 +02:00
public Add Open Graph image + social link preview metadata 2026-08-09 20:01:13 +02:00
scripts Add Open Graph image + social link preview metadata 2026-08-09 20:01:13 +02:00
src Drop in real data for The Hills ext 12 (C26/09) + Burn panel 2026-08-18 12:35:34 +02:00
.dockerignore Fix Coolify build: include scripts/ in Docker context 2026-08-09 20:30:29 +02:00
.env.local.example Initial commit: MEGA INFRASTRUCTURE dashboard + Coolify Dockerfile 2026-08-09 01:37:40 +02:00
.gitignore Remove Active Sites card from sidebar 2026-08-09 03:02:59 +02:00
COOLIFY.md Fix Coolify build: skip postinstall in deps stage 2026-08-09 02:29:48 +02:00
docker-compose.yml Initial commit: MEGA INFRASTRUCTURE dashboard + Coolify Dockerfile 2026-08-09 01:37:40 +02:00
Dockerfile Fix Coolify build: skip postinstall in deps stage 2026-08-09 02:29:48 +02:00
next.config.js Initial commit: MEGA INFRASTRUCTURE dashboard + Coolify Dockerfile 2026-08-09 01:37:40 +02:00
package-lock.json Initial commit: MEGA INFRASTRUCTURE dashboard + Coolify Dockerfile 2026-08-09 01:37:40 +02:00
package.json Add Open Graph image + social link preview metadata 2026-08-09 20:01:13 +02:00
postcss.config.mjs Initial commit: MEGA INFRASTRUCTURE dashboard + Coolify Dockerfile 2026-08-09 01:37:40 +02:00
README.md Initial commit: MEGA INFRASTRUCTURE dashboard + Coolify Dockerfile 2026-08-09 01:37:40 +02:00
tsconfig.json Initial commit: MEGA INFRASTRUCTURE dashboard + Coolify Dockerfile 2026-08-09 01:37:40 +02:00

MEGA INFRASTRUCTURE — Operations Dashboard

A Next.js 16 + TypeScript + Tailwind v4 dashboard for a construction company. Tracks fuel consumption per hour/day/week, delivery notes & outstanding items per purchase order, and weekly workforce hours with attendance flags.

The project is frontend-first with mock data, ready to be wired up to PocketBase (or any backend) for live data.


Modules

Path What it does
/login Numeric PIN gate. PIN lives in NEXT_PUBLIC_APP_PIN. Append ?demo=1 to any URL to skip the PIN during development.
/dashboard Operations overview — KPI cards, fuel chart, order status donut, "needs attention" rail, top suppliers.
/dashboard/fuel Per-vehicle consumption, theft detection, CSV ingest (papaparse), anomaly log.
/dashboard/orders Purchase-order table with filters, pagination, sort. Click any PO to see line items, delivery notes, outstanding items.
/dashboard/employees Weekly hours per employee with progress bar, overtime flag, role/site/attendance filters, mini daily-hours chart.

APIs

  • GET /api/health — counts and site list.
  • GET /api/mcp?module=all|fuel|orders|employees — compact JSON for an AI agent / MCP server / n8n workflow.
  • POST /api/upload — multipart upload of PDF / image / CSV (delivery notes, fuel attachments). 20 MB limit per file.

PWA

The app is installable on phone and desktop. Service worker is generated by @ducanh2912/next-pwa at build time (public/sw.js), manifest at public/manifest.json, icons at public/icons/.

Note: @ducanh2912/next-pwa uses the Webpack plugin, so next dev and next build must run with --webpack. Next 16 ships Turbopack by default; the package.json scripts already pass --webpack.


Run

cp .env.local.example .env.local       # change NEXT_PUBLIC_APP_PIN
npm install
npm run dev                            # http://localhost:3000

Default PIN is 2468.

Production

npm run build
npm run start

How the theft detection works

src/lib/fuel.ts defines EXPECTED_LITRES_TOLERANCE_PCT = 12. For every reading we compute:

expectedLitres = hoursWorked * expectedConsumptionPerHour
deltaPct       = (litresFilled - expectedLitres) / expectedLitres * 100

Severity buckets:

Over expected Severity
≤ 12 % ok
12 – 24 % watch
24 – 48 % alert
> 48 % critical

Adjust EXPECTED_LITRES_TOLERANCE_PCT to suit on-site practice.


CSV format for fuel upload

Required columns:

vehicleRegistration,date,hoursWorked,odometer,litresFilled,unitPrice,expectedConsumptionPerHour
MI-EX-01,2026-08-01,9.5,12480,90,24.50,9

The "Template" button on the Fuel page downloads a populated example.


Wiring a backend

Replace the imports in src/app/dashboard/*/page.tsx and src/app/api/mcp/route.ts with calls into PocketBase / your API. The shape of every type is in src/lib/types.ts.

Recommended PocketBase collections:

  • vehicles (registration, type, model, tankCapacityL, assignedSite)
  • fuel_readings (vehicleId, date, hoursWorked, odometer, litresFilled, unitPrice, expectedConsumptionPerHour, attachment?)
  • orders (reference, supplier, site, status, priority, placedAt, expectedAt, totalValue, notes)
  • order_lines (orderId, description, quantityOrdered, quantityDelivered, unit, unitPrice)
  • delivery_notes (orderId, scannedBy, file, mimeType, receivedAt)
  • employees (fullName, role, site, status, phone, hourlyRate, weeklyTargetHours)
  • daily_hours (employeeId, date, hours)