Insights Page
Insights Page
Overview
The /insights page is a map-first, interactive analytics hub inside the Pathfinder CRM. It visualizes resource coverage, community demand, and data quality across Oregon counties using real data from the shared Supabase database. It is visually distinct from the existing /reports page and sits as a top-level sidebar item above Reports.
Date implemented: March 2026
Features
Map Visualization
A full-width Mapbox GL JS map with three selectable modes:
| Mode | What it shows | Color scale |
|---|---|---|
| Coverage | Resource density per county (resources per 10k population) | Green gradient |
| Demand | Search volume and referral activity aggregated by county | Orange gradient |
| Quality | Data freshness (% verified in last 90 days) | Blue gradient |
Each county is rendered as a circle marker sized by population and colored by the active mode's metric. Clicking a county opens an intelligence panel with detailed breakdowns.
Intelligence Panel
A right-side panel that shows:
- County selected: Coverage breakdown by category, demand metrics, quality scores, key stats.
- No county selected: Statewide overview aggregated across all counties.
KPI Cards
Four headline metrics displayed above the map:
| KPI | Source |
|---|---|
| Total Public Resources | Count of resources where is_public = true and status = 'active' |
| Avg Coverage Index | Composite of resources-per-10k, verification rate, and completeness |
| No-Result Search Rate | Real percentage from search_events table (result_count = 0 / total) |
| Monthly Referrals | Count from referrals table |
Demand & Gaps Section
- Top Searched Needs: True search frequency from the
search_eventstable (one row per search). Per-query no-result percentage is shown alongside each need. Falls back to impression-based counting fromresource_eventsifsearch_eventshas no data yet. - High Demand / Low Supply Regions: Counties with the lowest coverage index, sorted by gap severity.
Data Quality Section
- Data Freshness Breakdown: Resources bucketed by last verification date (< 30d, 30–90d, 90–180d, 180+, never).
- Referral Outcomes: Referral counts grouped by status (completed, accepted, submitted, denied, draft).
Bottom CTA
A call-to-action strip linking to /reports for detailed reporting.
Data Pipeline
All data is fetched server-side in a Next.js Server Component and passed to the client:
page.tsx (Server Component)
│
▼
fetchInsightsData() ── lib/fetch-insights.ts
│
├── fetchAllResources() → resources table (paginated)
├── fetchAllReferrals() → referrals table
├── fetchEventCountsByResource() → resource_event_counts materialized view
├── getTopSearchQueries() → search_events table (fallback: resource_events)
└── getSearchNoResultRate() → search_events table
│
▼
InsightsClient.tsx (Client Component)
│
├── InsightsHeader
├── InsightsMap (Mapbox GL JS)
├── MapModeToggle / MapLegend
├── IntelligencePanel
├── KpiCards
├── DemandGapsSection
├── DataQualitySection
└── BottomCta
File Structure
app/(crm)/insights/
├── page.tsx # Server component — fetches data
├── InsightsClient.tsx # Client component — state + layout
├── lib/
│ └── fetch-insights.ts # Server-side data fetching & aggregation
├── data/
│ └── mock-data.ts # Type definitions, county seeds, toGeoJSON()
└── components/
├── InsightsHeader.tsx
├── InsightsMap.tsx
├── MapModeToggle.tsx
├── MapLegend.tsx
├── IntelligencePanel.tsx
├── KpiCards.tsx
├── DemandGapsSection.tsx
├── DataQualitySection.tsx
└── BottomCta.tsx
Access Control
The Insights page is gated by the reports module. Any organization with access to Reports also has access to Insights. The sidebar entry appears above Reports in the CRM navigation.
Admins and system-wide staff bypass module checks as usual.
Related Changes
Sidebar
CRMSidebar.tsx was updated to include an "Insights" nav item with a globe icon, using the existing reports module gate.
Global Styles
globals.css was updated with Mapbox popup overrides for dark/light theme consistency.
Dependencies
Uses existing installed packages: mapbox-gl for the map, Supabase client for data fetching. No new dependencies were added.
Environment Variables
| Variable | Required | Purpose |
|---|---|---|
NEXT_PUBLIC_MAPBOX_TOKEN | Yes | Mapbox GL JS map rendering |
This variable was already configured for other map features in the project.
Use links in each imported doc to open its source.