Added a new pagination system for the "Plant log entries" table in PlantView, allowing for separate page management from the main plant data. Introduced constants for log page size and updated the rendering logic to accommodate paginated logs, enhancing user experience when navigating through log entries. |
||
|---|---|---|
| .freebuff | ||
| .opencode/openwork/inbox/chat-attachments | ||
| .playwright-mcp | ||
| docs | ||
| public | ||
| RAW_DOCS | ||
| scripts | ||
| src | ||
| .dockerignore | ||
| .env.coolify | ||
| .env.local.example | ||
| .gitignore | ||
| AGENTS.md | ||
| CLAUDE.md | ||
| cooler.env | ||
| COOLIFY.md | ||
| Copy of THE HILLS WAGES HRS AUGUST 2026.xlsx | ||
| deployment-vptid1uo0jnz2q4t1mcbqjj9-all-logs-2026-08-19-00-23-06.txt | ||
| docker-compose.yml | ||
| Dockerfile | ||
| next.config.js | ||
| package-lock.json | ||
| package.json | ||
| postcss.config.mjs | ||
| README.md | ||
| tsconfig.json | ||
| vitest.config.ts | ||
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-pwauses the Webpack plugin, sonext devandnext buildmust run with--webpack. Next 16 ships Turbopack by default; thepackage.jsonscripts 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)