# Phase 4: Frontend - Research
**Researched:** 2026-02-24
**Domain:** React + TypeScript frontend integration with admin monitoring APIs
**Confidence:** HIGH
## Summary
Phase 4 wires the existing React/TypeScript/Tailwind frontend to the three admin API endpoints delivered in Phase 3: `GET /admin/health`, `GET /admin/analytics`, and `GET /admin/alerts` + `POST /admin/alerts/:id/acknowledge`. The frontend already has a complete admin-detection pattern, tab-based navigation, an axios-backed `adminService.ts`, and a `ProtectedRoute` component. The work is pure frontend integration — no new infrastructure, no new libraries, no new backend routes.
The stack is locked: React 18 + TypeScript + Tailwind CSS + lucide-react icons + react-router-dom v6 + axios (via `adminService.ts`). The project uses `clsx` and `tailwind-merge` (via `cn()`) for conditional class composition. No charting library is installed. The existing `Analytics.tsx` component shows the styling and layout patterns to follow. The existing `UploadMonitoringDashboard.tsx` shows the health indicator pattern with colored circles.
The primary implementation risk is the alert acknowledgement UX: after calling `POST /admin/alerts/:id/acknowledge`, the local state must update immediately (optimistic update or re-fetch) so the banner disappears without waiting for a full page refresh. The alert banner must render above the tab navigation because it is a global signal, not scoped to a specific tab.
**Primary recommendation:** Add new components to the existing `monitoring` tab in App.tsx, extend `adminService.ts` with the three monitoring API methods, add an `AdminMonitoringDashboard` component, add an `AlertBanner` component that renders above the nav inside `Dashboard`, and add an `AdminRoute` wrapper that shows access-denied for non-admins who somehow hit the monitoring tab directly.
---
## Phase Requirements
| ID | Description | Research Support |
|----|-------------|-----------------|
| ALRT-03 | Admin sees in-app alert banner for active critical issues; banner disappears after acknowledgement | alertBanner component using GET /admin/alerts + POST /admin/alerts/:id/acknowledge; optimistic state update on acknowledge |
| ANLY-02 (UI) | Admin dashboard shows processing summary: upload counts, success/failure rates, avg processing time | AdminMonitoringDashboard section consuming GET /admin/analytics response shape (AnalyticsSummary interface) |
| HLTH-01 (UI) | Admin dashboard shows health status indicators (green/yellow/red) for all four services with last-checked timestamp | ServiceHealthPanel component consuming GET /admin/health; status → color mapping green=healthy, yellow=degraded, red=down/unknown |
*Note: ANLY-02 and HLTH-01 were marked Complete in Phase 3 (backend side). Phase 4 completes their UI delivery.*
---
## Standard Stack
### Core (already installed — no new packages needed)
| Library | Version | Purpose | Why Standard |
|---------|---------|---------|--------------|
| react | ^18.2.0 | Component rendering | Project standard |
| typescript | ^5.2.2 | Type safety | Project standard |
| tailwindcss | ^3.3.5 | Utility CSS | Project standard |
| lucide-react | ^0.294.0 | Icons (AlertTriangle, CheckCircle, Activity, Clock, etc.) | Already used throughout |
| axios | ^1.6.2 | HTTP client (via adminService) | Already used in adminService.ts |
| clsx + tailwind-merge | ^2.0.0 / ^2.0.0 | Conditional class composition via `cn()` | Already used in Analytics.tsx |
| react-router-dom | ^6.20.1 | Routing, Navigate | Already used |
### No New Libraries Required
All required UI capabilities exist in the current stack:
- Status indicators: plain `div` with Tailwind bg-green-500 / bg-yellow-500 / bg-red-500
- Alert banner: fixed/sticky div above nav, standard Tailwind layout
- Timestamps: `new Date(ts).toLocaleString()` or `toRelative()` — no date library needed
- Loading state: existing spinner pattern (`animate-spin rounded-full border-b-2`)
**Installation:** None required.
---
## Architecture Patterns
### Recommended File Changes
```
frontend/src/
├── components/
│ ├── AlertBanner.tsx # NEW — global alert banner above nav
│ ├── AdminMonitoringDashboard.tsx # NEW — health + analytics panel
│ └── (existing files unchanged)
├── services/
│ └── adminService.ts # EXTEND — add getHealth(), getAnalytics(), getAlerts(), acknowledgeAlert()
└── App.tsx # MODIFY — render AlertBanner, wire monitoring tab to new component
```
### Pattern 1: Alert Banner — global, above nav, conditional render
**What:** A dismissible/acknowledgeable banner rendered inside `Dashboard` ABOVE the `