Usage Gap Analysis Feature Design
Overview
Add a new "Usage Gap Analysis" section to the Flow Meter page that visualizes which days have no Dustloc usage logs. This helps with operational monitoring - identifying equipment downtime or issues.
Requirements
- Primary Use Case: Operational monitoring - identify when equipment might be down or there are issues
- Scope: Selected site only (matches existing chart behavior)
- Date Range: Uses the same DateRangeSelector as the main charts
- Placement: New collapsible section below the existing "Recent Dispensing Events" table
Components
1. UsageCalendarHeatmap
A month-view calendar showing usage status for each day.
Visual Design:
- Grid layout: 7 columns (Mon-Sun), rows for each week
- Each day cell shows:
- Day number
- Color coding:
- Green (
bg-green-500) - Has usage data - Red/Orange (
bg-red-400) - No usage data (gap) - Gray (
bg-slate-200) - Outside date range or future dates
- Green (
- Hover tooltip shows: date, litres used (if any), number of events
Layout:
- If date range spans multiple months, show each month as a separate mini-calendar side by side (horizontally scrollable if needed)
- Month/year header above each calendar grid
2. UsageGapChart
A horizontal timeline highlighting consecutive no-data periods.
Visual Design:
- Horizontal bar/timeline spanning the date range
- Green segments - Days with usage data
- Red/orange segments - Consecutive days without data (gaps)
- X-axis shows dates (same format as existing charts)
Gap Blocks:
- Each gap block shows the duration (e.g., "3 days") as a label
- Hover tooltip shows: start date, end date, gap duration
Summary Stats (top-right corner):
- Total days in range
- Days with data
- Days without data (gaps)
- Longest gap duration
3. NoDataDaysTable
A simple table listing all days without usage data.
Columns:
| Date | Day of Week | Gap Duration | Notes |
|---|---|---|---|
| 09 Jan 2026 | Thursday | Start of 3-day gap | - |
| 10 Jan 2026 | Friday | - | - |
| 11 Jan 2026 | Saturday | End of gap | Weekend |
Features:
- Sorted by date (newest first by default)
- "Day of Week" column helps identify if gaps correlate with weekends
- "Gap Duration" indicates if day is start/middle/end of a consecutive gap
- Pagination if many days (reuse existing pagination pattern)
- Shows message "No gaps found - all days have usage data" if no gaps exist
- Weekends (Sat/Sun) marked differently since no usage may be expected
File Structure
src/features/flow-meter/components/
├── UsageGapAnalysis/
│ ├── index.tsx # Main collapsible section wrapper
│ ├── UsageCalendarHeatmap.tsx # Calendar heatmap component
│ ├── UsageGapChart.tsx # Timeline gap indicator
│ └── NoDataDaysTable.tsx # Summary tableData Model
typescript
interface GapData {
allDays: Date[]; // All days in the date range
daysWithData: Set<string>; // YYYY-MM-DD format
daysWithoutData: Date[]; // Days with no usage
gaps: Gap[]; // Consecutive gap periods
}
interface Gap {
startDate: Date;
endDate: Date;
duration: number; // Number of days
}
interface DayStatus {
date: Date;
hasData: boolean;
litresUsed?: number;
eventCount?: number;
isWeekend: boolean;
gapInfo?: {
position: 'start' | 'middle' | 'end' | 'single';
gapDuration: number;
};
}Utility Function
typescript
function calculateGapData(
dateRange: { start: Date; end: Date },
dailySummaries: DailySummary[]
): GapData {
// 1. Generate all days in the date range
// 2. Create set of days that have data from dailySummaries
// 3. Find days without data
// 4. Group consecutive no-data days into gaps
// Returns: { allDays, daysWithData, daysWithoutData, gaps }
}Integration
In src/app/(admin)/(pages)/flow-meter/index.tsx:
tsx
import { UsageGapAnalysis } from "@/features/flow-meter/components/UsageGapAnalysis";
// ... inside the component, after the Records Table section:
{selectedSiteSummary && (
<UsageGapAnalysis
dateRange={dateRange}
dailySummaries={selectedSiteSummary.dailySummaries}
siteName={selectedSite}
/>
)}UI Layout
┌─────────────────────────────────────────────────────────────┐
│ ▼ Usage Gap Analysis [Collapse]│
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────┐ ┌──────────────────────────────┐ │
│ │ Calendar Heatmap │ │ Gap Indicator Chart │ │
│ │ (Month view) │ │ (Timeline view) │ │
│ └─────────────────────┘ └──────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ No-Data Days Summary Table │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘Dependencies
- Recharts (already used) for the gap timeline chart
- date-fns (already used) for date manipulation
- No new dependencies needed
Acceptance Criteria
- New collapsible "Usage Gap Analysis" section appears below Records Table
- Calendar heatmap shows all days in range with color coding for data/no-data
- Gap indicator chart shows timeline with green (data) and red (gap) segments
- Summary table lists all no-data days with day of week and gap duration info
- All components respond to the same date range selector as existing charts
- All components filter by selected site
- Section is collapsible and remembers state in localStorage
- Hover tooltips provide detailed information
- "No gaps found" message when all days have data