SafeCommute helps walkers and cyclists pick safer routes by blending travel time with lighting, patrol, and incident data. The current build ships with rich demo data so you can evaluate the experience before a backend is connected.
- React 19 + ReactDOM 19 rendered with Vite and React Bootstrap for a clean, accessible UI.
- GitHub Pages workflow (
.github/workflows/deploy.yml) builds frommainand publishes the production bundle fromdist/. - Environment-driven configuration via
.envand.env.local, usingVITE_*(orREACT_APP_*for legacy keys) to surface secrets to the browser.
- Duplicate
.env(or.env.exampleif you received a blank template) to.env.localand plug in your own keys. The Google Maps key is required to render the interactive map, while other fields help you wire in live APIs later. AddVITE_PUBLIC_BASE=/p24/(or your repository slug) if you plan to build locally and push thedist/folder to GitHub Pages. - Install dependencies with
npm install. - Run the dev server with
npm run dev. Your app is available at the Vite preview URL (typicallyhttp://localhost:5173). - Build for production with
npm run build, or preview the static build locally withnpm run preview.
The Google Maps SDK loads on demand. Without a valid
VITE_GOOGLE_MAPS_API_KEY, the map pane gracefully falls back to a helper message.
SafeCommute reads the following keys from .env/.env.local (prefix with VITE_ so Vite exposes them to the client):
VITE_GOOGLE_MAPS_API_KEY– required for the live map preview.VITE_BACKEND_BASE_URL– base URL for the/routesand/feedbackendpoints.VITE_FIREBASE_API_KEY,VITE_FIREBASE_AUTH_DOMAIN,VITE_FIREBASE_PROJECT_ID,VITE_FIREBASE_STORAGE_BUCKET,VITE_FIREBASE_MESSAGING_SENDER_ID,VITE_FIREBASE_APP_ID– client credentials for Firebase Authentication + Firestore (used for login and records sync).VITE_CRIME_DATA_API_URLandVITE_CRIME_DATA_API_TOKEN– optional future integrations for municipal crime feeds.VITE_WEATHER_API_KEY– reserved for weather-aware routing.VITE_PUBLIC_BASE– optional override for the built asset base path. Set this to/p24/(or equivalent) when deploying manually to GitHub Pages from a nested route.MONGODB_URI,MONGODB_DB_NAME,MONGODB_ROUTES_COLLECTION,MONGODB_FEEDBACK_COLLECTION– reference values for an Express + MongoDB backend.JWT_SECRET– seed value for planned auth/session features.
All VITE_* variables (and any REACT_APP_* values you keep around) are exposed to the browser via import.meta.env.
The Node backend (see server/) expects its own .env file with:
PORT– defaults to8787locally; set by your host in production.GOOGLE_MAPS_API_KEY– server-side Directions API key (can differ from the frontend key/restrictions).FIREBASE_SERVICE_ACCOUNT_BASE64orFIREBASE_SERVICE_ACCOUNT_PATH– credentials for Firestore writes.FEEDBACK_WINDOW_HOURS– rolling window (in hours) used when blending community feedback into route scores.WEATHER_USER_AGENT– required contact string for weather.gov (e.g.,SafeCommute/1.0 (tanush.shrivastava@gmail.com)).WEATHER_CACHE_TTL_MS– cache duration (ms) for weather/grid lookups to keep the NWS API happy.WEATHER_SAMPLE_MILES/WEATHER_MAX_POINTS– spacing (in miles) and cap for weather checkpoints calculated along each route.
Set these as environment variables when deploying (Render, Fly, Cloud Run, etc.) so the backend can access Google Maps, Firestore, and weather.gov safely.
src/App.jsxwires the global providers (Firebase Auth context + React Router) and registers every page in the experience (planner, login, records, about, and contact).src/layout/AppLayout.jsxandsrc/components/AppNavbar.jsxrender the shared chrome + navigation links so the user can bounce between planner, contact, and records screens.src/pages/PlannerPage.jsxhosts the original routing workflow: it seeds demo routes, calls/routeswhen configured, lets the user prioritize metrics, and now exposes a “Save to records” action tied to the authenticated user.src/pages/LoginPage.jsxhandles email/password auth via Firebase;src/pages/RecordsPage.jsxlistens to Firestore for per-user route/comment history;src/pages/AboutPage.jsxandsrc/pages/ContactPage.jsxround out the brochure content.src/components/RoutePlannerForm.jsxcollects origin, destination, and travel mode. It swaps fields client side and prevents submission until both fields are filled.src/components/RouteCard.jsxrenders metrics, confidence levels, and recent incidents for each route. Toggle buttons reorder the same routes by priority.src/components/FeedbackForm.jsxcaptures community notes, submitting to/feedbackwhen configured—or quietly storing the result client-side while you remain in demo mode.src/components/MapView.jsxpairs withsrc/hooks/useGoogleMaps.jsto load the Maps SDK, render polylines for each candidate route, and provide a fallback message when the script fails to load.
src/data/mockRoutes.jsholds the three illustrative route options plus feedback categories that seed the UI.src/services/api.jsexposesfetchRoutesandsubmitFeedback, calling your configured backend but gracefully returning the bundled mock data or noop responses when unavailable.src/services/firebaseClient.jscentralizes Firebase app/Auth/Firestore initialization, whilesrc/services/records.jswraps Firestore calls that save and stream per-user route records.src/components/SaveRecordPanel.jsxprovides the UI hook for persisting the active route + optional note for the logged-in rider.
- Layout relies on React Bootstrap components with a white surface, soft blue accents, and pill-shaped buttons.
- Component-level CSS modules (
RoutePlannerForm.module.css,RouteCard.module.css, etc.) add gradient cards and shadows to achieve the dashboard look. - Global typography lives in
src/index.css; page layout styles live insrc/App.css.
Automated tests are not wired up yet. Add Jest or Vitest coverage for route filtering, API fallbacks, and feedback submission when you begin wiring in production data.
- Stand up real
/routesand/feedbackendpoints, then updateVITE_BACKEND_BASE_URLto remove the mock data dependency. - Replace the placeholder test with meaningful unit coverage.
- Integrate live data feeds (crime, weather, protected lanes) and expand the map markers accordingly.
- Harden authentication by plumbing the provided JWT scaffold through your backend of choice.