Mobile-first web app for browsing and reporting DPWH infrastructure projects on an interactive map.
Built with vanilla JavaScript, Leaflet.js, and a brutalist design system. Uses Next.js as a minimal server wrapper for static file serving.
- Interactive Map — Browse DPWH projects on a Leaflet map with automatic geolocation
- Smart Filtering — Filter by distance (500m–50km), project status, and infrastructure type
- Marker Interactions — Click markers to get directions or view project details
- Animated Routing — Visualize routes from your location to any project
- Issue Reporting — Report concerns on specific projects
- Cover Page — Animated landing page with Philippines map background
- Brutalist Design — Bold typography, thick borders, hard shadows, no gradients
| Layer | Technology |
|---|---|
| Server | Next.js 16 (API proxy + static serving) |
| Frontend | Vanilla JavaScript (ES6 modules) |
| Mapping | Leaflet.js 1.9.4, Leaflet Routing Machine, OpenStreetMap |
| Styling | Modular CSS with custom properties |
| Data | DPWH Transparency API |
| Geocoding | Nominatim (OpenStreetMap) |
| Routing | OSRM |
| Fonts | Darker Grotesque, Inter, JetBrains Mono |
- Node.js 18+
- npm
- Modern browser with geolocation support
npm installnpm run devnpm run build
npm start├── pages/
│ ├── _app.js # Minimal Next.js app shell
│ ├── index.js # Redirects to static frontend
│ └── api/
│ └── projects.js # DPWH API proxy route
├── public/
│ ├── index.html # Main application HTML
│ ├── favicon.svg
│ └── src/
│ ├── css/
│ │ ├── main.css # CSS entry (import order matters)
│ │ ├── base/ # Variables, reset, typography
│ │ ├── layout/ # Map, header, panels, bottom sheet
│ │ ├── components/ # Buttons, cards, modals, markers
│ │ ├── utilities/ # Animations, responsive, loading
│ │ └── vendor/ # Leaflet overrides
│ └── js/
│ ├── main.js # JS entry point
│ ├── api/ # DPWH, geocoding, report APIs
│ ├── config/ # Constants, province mappings
│ ├── events/ # Event handlers, global handlers
│ ├── services/ # Filtering, location, routing
│ ├── state/ # AppState singleton
│ ├── ui/ # Map, markers, panels, modals, bottom sheet
│ └── utils/ # Formatters, helpers, validators
├── package.json
├── next.config.js
└── .gitignore
Next.js serves two purposes only:
- Static file serving — Serves the vanilla JS frontend from
public/ - API proxy — Server-side proxy for DPWH API requests
The frontend is entirely vanilla JavaScript with no React rendering.
Layered modular design with strict dependency direction:
Entry Point (main.js)
→ Events (user interactions)
→ UI (DOM, rendering)
→ Services (business logic)
→ API / State / Utils
→ Config (constants)
appStatesingleton manages all application state- Display logic uses
appState.filteredProjects(never modify.projectsdirectly) - Distance filter defaults to 1km for performance
- Browser requests geolocation
- Coordinates are reverse-geocoded via Nominatim
- City/province used to query DPWH Transparency API
- Projects filtered by distance, then status/type
- Markers rendered on Leaflet map
Brutalist aesthetic defined in public/src/css/base/variables.css:
| Element | Value |
|---|---|
| Primary | #DD614C (Coral Red) |
| Secondary | #DAA144 (Golden Yellow) |
| Borders | 2–4px, #111827 (Near Black) |
| Shadows | Hard offset, no blur |
| Corners | Square (no border-radius) |
| Display Font | Darker Grotesque (900, uppercase) |
| Body Font | Inter |
| Mono Font | JetBrains Mono |
| Easing | cubic-bezier(0.16, 1, 0.3, 1) |
- Chrome / Edge (latest)
- Firefox (latest)
- Safari iOS 12+
- Chrome Mobile (Android)
Requirements: ES6 modules, Geolocation API, Fetch API. Geolocation requires HTTPS in production (localhost exempt).
- DPWH API may return invalid coordinates (lat/lng = 0) — these are skipped
- DPWH API is behind Cloudflare; production uses pre-cached data per city
- On localhost, the app calls the DPWH API directly (browser solves Cloudflare challenge)
- Maximum dataset size limited by upstream DPWH API
- NEXTJS_MIGRATION.md — Migration notes from plain Node.js to Next.js
- TESTING.md — Comprehensive testing guide
- AGENTS.md — Developer patterns and gotchas
- OpenStreetMap — Map tiles and geocoding
- Leaflet.js — Interactive mapping
- DPWH Transparency Portal — Project data
- Material Icons — Icon set
This project is intended for demonstration and development purposes around publicly available DPWH infrastructure data.