Surfaces the new GET /analytics/flowpilot/escalations endpoint as a card
above the EscalationQueue list. Closes the loop from yesterday's metric
endpoint commit — seniors and owners see the wedge stat the moment they
open the queue, which is the daily-reps version of the GTM ROI story.
Pieces:
- EscalationMetrics TS interface mirroring the backend Pydantic model
(incl. metric_definition disclaimer field)
- flowpilotAnalyticsApi.getEscalationMetrics(period) client method
- EscalationMetricCard component:
* loading skeleton, error state, zero-data empty state
* avg + median + n_with_action/n_claimed conversion rate
* humanized seconds → "Ns" / "N.N min" formatting
* inline disclaimer reminding callers this is in-product time-to-
first-action only, NOT the savings claim — pair with manual
baseline (per /codex review's two-metric correction)
- Wired into EscalationQueuePage above EscalationQueue
DS-aligned: card-flat, accent-dim usage held to interactive elements,
text-muted-foreground for secondary copy, font-heading on the headline
number, explicit transition properties (no `transition: all`). Respects
prefers-reduced-motion implicitly (only animation is the loading pulse,
which Tailwind's animate-pulse already gates).
tsc -b clean. No new tests in this commit — component is a thin
state-machine over an axios call; integration coverage comes from the
existing backend tests + the e2e Playwright work in the plan.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
56 lines
1.7 KiB
TypeScript
56 lines
1.7 KiB
TypeScript
import apiClient from './client'
|
|
import type {
|
|
FlowPilotDashboard,
|
|
KnowledgeGapReport,
|
|
CoverageResponse,
|
|
FlowQualityResponse,
|
|
EnhancedPsaMetrics,
|
|
EscalationMetrics,
|
|
} from '@/types/flowpilot-analytics'
|
|
|
|
export const flowpilotAnalyticsApi = {
|
|
async getDashboard(period: string = '30d'): Promise<FlowPilotDashboard> {
|
|
const response = await apiClient.get<FlowPilotDashboard>('/analytics/flowpilot', {
|
|
params: { period },
|
|
})
|
|
return response.data
|
|
},
|
|
|
|
async getKnowledgeGaps(period: string = '30d'): Promise<KnowledgeGapReport> {
|
|
const response = await apiClient.get<KnowledgeGapReport>('/analytics/flowpilot/knowledge-gaps', {
|
|
params: { period },
|
|
})
|
|
return response.data
|
|
},
|
|
|
|
async getCoverage(period: string = '30d'): Promise<CoverageResponse> {
|
|
const response = await apiClient.get<CoverageResponse>('/analytics/flowpilot/coverage', {
|
|
params: { period },
|
|
})
|
|
return response.data
|
|
},
|
|
|
|
async getFlowQuality(period: string = '30d', sort: string = 'quality'): Promise<FlowQualityResponse> {
|
|
const response = await apiClient.get<FlowQualityResponse>('/analytics/flowpilot/flow-quality', {
|
|
params: { period, sort },
|
|
})
|
|
return response.data
|
|
},
|
|
|
|
async getPsaMetrics(period: string = '30d'): Promise<EnhancedPsaMetrics> {
|
|
const response = await apiClient.get<EnhancedPsaMetrics>('/analytics/flowpilot/psa-metrics', {
|
|
params: { period },
|
|
})
|
|
return response.data
|
|
},
|
|
|
|
async getEscalationMetrics(period: string = '30d'): Promise<EscalationMetrics> {
|
|
const response = await apiClient.get<EscalationMetrics>('/analytics/flowpilot/escalations', {
|
|
params: { period },
|
|
})
|
|
return response.data
|
|
},
|
|
}
|
|
|
|
export default flowpilotAnalyticsApi
|