feat: Add base routes for Map View, Admin Dashboard, and Workflow page#5
feat: Add base routes for Map View, Admin Dashboard, and Workflow page#5echelonnought wants to merge 1 commit into
Conversation
Implements Issue #191 — Create base routes for Map View, Admin Dashboard, and Workflow page. Changes: - Install react-router-dom for client-side routing - Wrap App with BrowserRouter in main.tsx - Add React.lazy + Suspense for code-splitting all page components - Create MapPage: extracts existing map logic from App.tsx (MapContainer + LayerControls) - Create AdminPage: styled placeholder with 'Coming Soon' badge - Create WorkflowPage: styled placeholder with 'Coming Soon' badge - Create NotFoundPage: 404 page with 'Back to Map' link - Configure routes: /map, /admin, /workflow, / → redirect to /map, * → 404 - Update Header with NavLink navigation (Map, Admin, Workflow) with active state - Add pages.css for placeholder page styles and nav link styles All routes lazy-loaded, TypeScript compiles cleanly (tsc --noEmit exit 0).
📝 WalkthroughWalkthroughThis PR adds React Router to the application, converting it from a single-page map view to a multi-route application with lazy-loaded pages. Routes for ChangesRouting Architecture & Multi-Page Setup
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 0/1 reviews remaining, refill in 60 minutes.Comment |
Detailed Implementation NotesWhat was doneThis PR addresses Issue #191 — setting up the base routing structure for the Map Dashboard application. Here's a breakdown of every change and the reasoning behind it. Architecture Decisions1. React.lazy() + Suspense for code splitting 2. Page extraction pattern 3. NavLink with active state 4. 404 handling Files Changed (10 files, +368 / -38 lines)
Verification
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/pages/MapPage.tsx`:
- Around line 19-29: The effect calling FixtureReader.collections() lacks error
handling and an unmount guard: catch promise rejections from
FixtureReader.collections() and handle errors (e.g., log or show fallback)
before attempting to setLayers or setLayerVisibility, and add a cleanup guard
(e.g., isMounted flag or AbortController) inside the useEffect so you only call
setLayers and setLayerVisibility (and construct the LayerVisibilityMap) when the
component is still mounted; ensure the promise chain uses .catch(...) and the
cleanup toggles the guard to prevent state updates after unmount.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ef30d0ff-1d7e-4aca-ad9f-ceaf5bb5238e
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (9)
package.jsonsrc/App.tsxsrc/components/Layout/Header.tsxsrc/main.tsxsrc/pages/AdminPage.tsxsrc/pages/MapPage.tsxsrc/pages/NotFoundPage.tsxsrc/pages/WorkflowPage.tsxsrc/styles/pages.css
| useEffect(() => { | ||
| FixtureReader.collections() | ||
| .then(collections => { | ||
| setLayers([...collections]); | ||
|
|
||
| // Take the name property of each collection and set it's initial visibility to true | ||
| const layerNames = collections.map((fc) => fc.name); | ||
| const visibilityMap = layerNames.reduce((map, name) => { map[name] = true; return map; }, {} as LayerVisibilityMap); | ||
| setLayerVisibility({ ...visibilityMap }); | ||
| }); | ||
| }, []); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
rg -n --type ts 'FixtureReader\.collections\(|useEffect\(' src/pages src/dataRepository: OpenSourceFellows/map_dashboard_hackathon
Length of output: 187
🏁 Script executed:
cat -n src/pages/MapPage.tsx | head -50Repository: OpenSourceFellows/map_dashboard_hackathon
Length of output: 1940
🏁 Script executed:
rg -n 'FixtureReader' src/ -A 5 -B 2Repository: OpenSourceFellows/map_dashboard_hackathon
Length of output: 2305
🏁 Script executed:
fd -t ts -name 'FixtureReader*'Repository: OpenSourceFellows/map_dashboard_hackathon
Length of output: 316
🏁 Script executed:
cat -n src/data/fixture-reader.tsRepository: OpenSourceFellows/map_dashboard_hackathon
Length of output: 909
Handle fixture loading failures and unmounts.
FixtureReader.collections() is fire-and-forget here: a rejected fetch (line 13 of fixture-reader.ts throws on failed response) will surface as an unhandled promise rejection, and state updates can still run after the user navigates away from the map. Add a cleanup guard and .catch() handler before setting layers and layerVisibility.
♻️ Suggested fix
useEffect(() => {
- FixtureReader.collections()
- .then(collections => {
- setLayers([...collections]);
-
- // Take the name property of each collection and set it's initial visibility to true
- const layerNames = collections.map((fc) => fc.name);
- const visibilityMap = layerNames.reduce((map, name) => { map[name] = true; return map; }, {} as LayerVisibilityMap);
- setLayerVisibility({ ...visibilityMap });
- });
+ let cancelled = false;
+
+ FixtureReader.collections()
+ .then((collections) => {
+ if (cancelled) return;
+
+ setLayers(collections);
+ const visibilityMap = collections.reduce((map, fc) => {
+ map[fc.name] = true;
+ return map;
+ }, {} as LayerVisibilityMap);
+ setLayerVisibility(visibilityMap);
+ })
+ .catch((error) => {
+ console.error('Failed to load map layers', error);
+ });
+
+ return () => {
+ cancelled = true;
+ };
}, []);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| useEffect(() => { | |
| FixtureReader.collections() | |
| .then(collections => { | |
| setLayers([...collections]); | |
| // Take the name property of each collection and set it's initial visibility to true | |
| const layerNames = collections.map((fc) => fc.name); | |
| const visibilityMap = layerNames.reduce((map, name) => { map[name] = true; return map; }, {} as LayerVisibilityMap); | |
| setLayerVisibility({ ...visibilityMap }); | |
| }); | |
| }, []); | |
| useEffect(() => { | |
| let cancelled = false; | |
| FixtureReader.collections() | |
| .then((collections) => { | |
| if (cancelled) return; | |
| setLayers(collections); | |
| const visibilityMap = collections.reduce((map, fc) => { | |
| map[fc.name] = true; | |
| return map; | |
| }, {} as LayerVisibilityMap); | |
| setLayerVisibility(visibilityMap); | |
| }) | |
| .catch((error) => { | |
| console.error('Failed to load map layers', error); | |
| }); | |
| return () => { | |
| cancelled = true; | |
| }; | |
| }, []); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/pages/MapPage.tsx` around lines 19 - 29, The effect calling
FixtureReader.collections() lacks error handling and an unmount guard: catch
promise rejections from FixtureReader.collections() and handle errors (e.g., log
or show fallback) before attempting to setLayers or setLayerVisibility, and add
a cleanup guard (e.g., isMounted flag or AbortController) inside the useEffect
so you only call setLayers and setLayerVisibility (and construct the
LayerVisibilityMap) when the component is still mounted; ensure the promise
chain uses .catch(...) and the cleanup toggles the guard to prevent state
updates after unmount.
Summary
Implements the routing foundation for the Map Dashboard application as described in Issue #191.
Changes
New Files
src/pages/MapPage.tsx— Extracts existing map logic (MapContainer + LayerControls + layer state) from App.tsx into a dedicated page componentsrc/pages/AdminPage.tsx— Styled placeholder page for future admin dashboard functionalitysrc/pages/WorkflowPage.tsx— Styled placeholder page for future workflow managementsrc/pages/NotFoundPage.tsx— 404 page with a Back to Map navigation linksrc/styles/pages.css— Styles for placeholder pages (floating animation, badges, dark mode support) and header navigation linksModified Files
src/App.tsx— Replaced monolithic component with React Router setup using Routes, React.lazy(), and Suspense for code-splittingsrc/main.tsx— Wrapped App with BrowserRouter to enable client-side routingsrc/components/Layout/Header.tsx— Added NavLink navigation for Map, Admin, and Workflow routes with active state highlightingpackage.json/pnpm-lock.yaml— Added react-router-dom dependencyRoutes Configured
Technical Details
Testing
Summary by CodeRabbit