Pathfinder Docs

Documentation Preview

Insights Page

Source: `docs/product/features/INSIGHTS_PAGE.md`View on GitHub

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:

ModeWhat it showsColor scale
CoverageResource density per county (resources per 10k population)Green gradient
DemandSearch volume and referral activity aggregated by countyOrange gradient
QualityData 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:

KPISource
Total Public ResourcesCount of resources where is_public = true and status = 'active'
Avg Coverage IndexComposite of resources-per-10k, verification rate, and completeness
No-Result Search RateReal percentage from search_events table (result_count = 0 / total)
Monthly ReferralsCount from referrals table

Demand & Gaps Section

  • Top Searched Needs: True search frequency from the search_events table (one row per search). Per-query no-result percentage is shown alongside each need. Falls back to impression-based counting from resource_events if search_events has 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

VariableRequiredPurpose
NEXT_PUBLIC_MAPBOX_TOKENYesMapbox 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.