Files
whyrating-engine-legacy/web/components/reviewiq/DashboardSkeleton.tsx
Alejandro Gutiérrez c8ecb4b98f feat(reviewiq): Add AI synthesis support to dashboard components
Frontend:
- Add Synthesis type with action plan, insights, annotations
- ExecutiveSummary: Accept synthesis prop for AI narrative
- SentimentPie: Accept insight prop for contextual explanation
- IntensityHeatmap: Accept insight + highlightDomain props
- TimelineChart: Accept insight + annotations props
- All components gracefully degrade when synthesis is null

Backend:
- Add Stage 4: Synthesize for generating AI narratives
- Gathers context from classified spans
- Generates executive narrative, section insights, action plan
- Produces timeline annotations and marketing angles
- Stores synthesis in pipeline.executions table

Components show AI insights with purple gradient styling when available,
fall back to existing behavior when synthesis is not yet generated.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-29 02:59:47 +00:00

75 lines
2.1 KiB
TypeScript

'use client';
/**
* Loading skeleton for the ReviewIQ Dashboard.
*/
export function DashboardSkeleton() {
return (
<div className="space-y-6 animate-pulse">
{/* KPI Cards Skeleton */}
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
{Array.from({ length: 8 }).map((_, i) => (
<div
key={i}
className="bg-gray-200 rounded-xl h-28"
/>
))}
</div>
{/* Charts Grid Skeleton */}
<div className="grid md:grid-cols-3 gap-6">
<div className="bg-gray-200 rounded-xl h-80" />
<div className="bg-gray-200 rounded-xl h-80" />
<div className="bg-gray-200 rounded-xl h-80" />
</div>
{/* Timeline Skeleton */}
<div className="bg-gray-200 rounded-xl h-96" />
{/* Tables Skeleton */}
<div className="grid md:grid-cols-2 gap-6">
<div className="bg-gray-200 rounded-xl h-80" />
<div className="bg-gray-200 rounded-xl h-80" />
</div>
</div>
);
}
/**
* Error state component.
*/
export function DashboardError({ message, onRetry }: { message: string; onRetry?: () => void }) {
return (
<div className="flex flex-col items-center justify-center h-96 bg-red-50 rounded-xl border-2 border-red-200">
<div className="text-red-600 text-lg font-semibold mb-2">
Failed to load dashboard
</div>
<p className="text-red-500 text-sm mb-4">{message}</p>
{onRetry && (
<button
onClick={onRetry}
className="px-4 py-2 bg-red-600 text-white rounded-lg font-semibold hover:bg-red-700 transition-colors"
>
Try Again
</button>
)}
</div>
);
}
/**
* Empty state when no job is selected.
*/
export function DashboardEmpty() {
return (
<div className="flex flex-col items-center justify-center h-96 bg-gray-50 rounded-xl border-2 border-gray-200">
<div className="text-gray-600 text-lg font-semibold mb-2">
No Job Selected
</div>
<p className="text-gray-500 text-sm">
Select a job to view analytics or run the ReviewIQ pipeline first.
</p>
</div>
);
}