{{ theme.skipToContentLabel || 'Skip to content' }}

Tank Alert Management Page Design

Overview

A dedicated admin page for monitoring and managing tank level alerts. This page provides visibility into the entire alert lifecycle: detection → queue → email sending.

Route: /settings/tank-alertsAccess: Admin only Navigation: Settings menu, below Email Schedules

Problem Statement

The tank level email schedule process is complex and invisible to users:

  1. Detect low water level tanks
  2. Create alerts and add to send queue
  3. Send aggregated email at 8:00 AM next day

Users cannot monitor the status and progress of this workflow. This page solves that by providing a management interface for all tank alerts.

Page Structure

┌─────────────────────────────────────────────────┐
│  Tank Alert Management                    [立即发送] │
├─────────────────────────────────────────────────┤
│  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│  │ 待发送   │ │ 已发送   │ │ 已解决   │ │ 总告警   │ │
│  │   5     │ │   12    │ │   8     │ │   25    │ │
│  └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
├─────────────────────────────────────────────────┤
│  [待发送]  [已发送]  [已解决]                       │
├─────────────────────────────────────────────────┤
│  ☑ 全选    站点筛选: [全部 ▼]    [批量发送] [批量删除] │
├─────────────────────────────────────────────────┤
│  告警列表...                                      │
└─────────────────────────────────────────────────┘

Features

Display Features

  • Pending alerts list - Alerts with notified=false and resolved_at=null
  • Sent alerts list - Alerts with notified=true
  • Resolved alerts list - Alerts with resolved_at not null
  • Statistics overview - Counts for pending, sent, resolved, and total alerts

Management Operations

  • Mark as sent - Skip email, mark alert as notified=true
  • Mark as resolved - Set resolved_at timestamp
  • Modify send date - Change scheduled_send_date
  • Send immediately - Trigger email send now (single or batch)
  • Delete alert - Remove alert record permanently

Data Model

Alert Status Definition

typescript
type AlertStatus = 'pending' | 'sent' | 'resolved';

// pending: resolved_at = null AND notified = false
// sent: notified = true AND resolved_at = null
// resolved: resolved_at != null

List Item Data Structure

typescript
type TankAlertListItem = {
  // Alert basic info
  id: string;
  assetId: string;
  triggeredAt: Date;
  scheduledSendDate: Date;
  notified: boolean;
  resolvedAt?: Date;

  // Tank info (joined)
  assetDisplayId: string;
  siteName: string;

  // Real-time water level (calculated)
  currentLitres?: number;
  capacityLitres?: number;
  percentRemaining?: number;

  // Computed status
  status: AlertStatus;
};

Service Methods

typescript
// tankAlertManagementService.ts

// Get all alerts with filtering
getAllAlerts(filters: { status?: AlertStatus; siteId?: string }): Promise<TankAlertListItem[]>

// Get statistics
getAlertStats(): Promise<{ pending: number; sent: number; resolved: number; total: number }>

// Update scheduled send date
updateScheduledDate(alertId: string, newDate: Date): Promise<void>

// Mark as sent (without sending email)
markAsSent(alertIds: string[]): Promise<void>

// Mark as resolved
markAsResolved(alertIds: string[]): Promise<void>

// Delete alerts
deleteAlerts(alertIds: string[]): Promise<void>

// Send alert email immediately (calls Edge Function)
sendAlertEmailNow(alertIds: string[]): Promise<void>

File Structure

src/features/tank-alerts/
├── components/
│   ├── TankAlertManagement.tsx    # Main page component
│   ├── TankAlertStats.tsx         # Statistics overview cards
│   ├── TankAlertTabs.tsx          # Tab switching component
│   ├── TankAlertTable.tsx         # Alert list table
│   ├── TankAlertRow.tsx           # Single alert row display
│   ├── MiniTankIndicator.tsx      # Mini tank icon visualization
│   └── TankAlertActions.tsx       # Action buttons group
├── hooks/
│   └── useTankAlerts.ts           # Data fetching and operations hook
├── services/
│   └── tankAlertManagementService.ts  # Extends existing tankAlertService
└── types.ts                       # Type definitions

UI Component Details

Statistics Cards (TankAlertStats)

Four cards in horizontal layout, clickable to switch to corresponding tab:

  • Pending (orange) - pending count
  • Sent (green) - sent count
  • Resolved (gray) - resolved count
  • Total (blue) - total count

Alert Table Columns (TankAlertTable)

ColumnWidthContent
40pxCheckbox (pending tab only)
Tank60pxMiniTankIndicator mini tank icon
Tank150pxasset_display_id
Site120pxsite_name
Level140px12,500L / 50,000L (25%)
Triggered150pxtriggered_at formatted
Scheduled120pxscheduled_send_date (pending tab)
Sent At120pxsent time (sent tab)
Resolved At120pxresolved_at (resolved tab)
Actions150pxAction buttons

Action Buttons by Tab

Pending Tab:

  • 📤 Send Now - Single immediate send
  • 📅 Change Date - Modal to modify scheduled_send_date
  • ✅ Mark Sent - Skip sending, mark as sent
  • ✓ Mark Resolved - Mark as resolved
  • 🗑️ Delete

Sent Tab:

  • ✓ Mark Resolved
  • 🗑️ Delete

Resolved Tab:

  • 🗑️ Delete

Bulk Actions Bar

When multiple records selected, show bulk action bar at top:

Selected 3 items  [Bulk Send] [Bulk Mark Sent] [Bulk Mark Resolved] [Bulk Delete]  [Cancel]

Interaction Flows

Send Immediately Flow

  1. User clicks "Send Now" (single or batch)
  2. Confirmation dialog: "Send X alert email(s) now?"
  3. Call Edge Function send-tank-level-alert
  4. On success, refresh list, alerts move to "Sent" tab
  5. Show Toast: "Successfully sent X alert email(s)"

Modify Send Date Flow

  1. Click "Change Date" button
  2. Date picker modal opens (default: current scheduled_send_date)
  3. Select new date and confirm
  4. Update database, refresh list
  5. Show Toast: "Send date updated"

Delete Confirmation

  • Single delete: "Delete this alert record? This action cannot be undone."
  • Bulk delete: "Delete X selected alert records? This action cannot be undone."

Edge Cases

CaseHandling
Water level cannot be calculatedShow -- or N/A, mini tank shows gray
Alert's tank has been deletedShow asset_id, label "Tank deleted"
Email send failsShow error Toast, alert stays in pending
Empty listShow empty state: "No [pending/sent/resolved] alerts"
Network errorShow error message with retry button

Auto Refresh

  • Load data on page open
  • Auto refresh statistics every 60 seconds
  • Refresh current list after any operation

Route Configuration

typescript
// In Routes.tsx
{
  path: 'tank-alerts',
  element: (
    <ProtectedRoute adminOnly>
      <TankAlertManagement />
    </ProtectedRoute>
  ),
}

Add to Settings menu in sidebar, below Email Schedules:

typescript
{
  label: 'Tank Alerts',
  path: '/settings/tank-alerts',
  icon: AlertTriangle, // or similar icon
  adminOnly: true,
}