'use client'; import { useState } from 'react'; import { RefreshCw } from 'lucide-react'; import { ReviewIQFilterProvider, useReviewIQFilters } from '@/contexts/ReviewIQFilterContext'; import { useReviewIQAnalytics } from '@/hooks/useReviewIQAnalytics'; import { DashboardSkeleton, DashboardError, DashboardEmpty } from './DashboardSkeleton'; import { FilterBar } from './FilterBar'; import { SentimentPie } from './charts/SentimentPie'; import { IntensityHeatmap } from './charts/IntensityHeatmap'; import { TimelineChart } from './charts/TimelineChart'; import { IssuesTable } from './tables/IssuesTable'; import { SpansTable } from './tables/SpansTable'; import { OpportunityMatrix } from './insights/OpportunityMatrix'; import { ExplorerView } from './ExplorerView'; import type { URTDomain, Synthesis, LegacySynthesis } from './types'; import { isSynthesisV2 } from './types'; // Helper to extract legacy fields from either synthesis format function getLegacyInsight(synthesis: Synthesis | null | undefined, field: keyof LegacySynthesis): string | undefined { if (!synthesis) return undefined; if (isSynthesisV2(synthesis)) { // V2 doesn't have these fields, return undefined return undefined; } return (synthesis as LegacySynthesis)[field] as string | undefined; } interface ReviewIQDashboardProps { jobId?: string | null; businessId?: string | null; } /** * Inner dashboard component that uses the filter context. * Shows data exploration view with charts, tables, and trend explorer. */ function ReviewIQDashboardInner({ jobId, businessId }: ReviewIQDashboardProps) { const { filters, setURTDomain } = useReviewIQFilters(); const [issuesPage, setIssuesPage] = useState(1); const [spansPage, setSpansPage] = useState(1); const { data, loading, error, refetch } = useReviewIQAnalytics({ jobId, businessId, filters, issuesPage, issuesPageSize: 10, spansPage, spansPageSize: 10, }); // No job selected if (!jobId && !businessId) { return ; } // Loading state if (loading && !data) { return ; } // Error state if (error) { return ; } // No data if (!data) { return ; } return (
{/* Header */}

Data Explorer

{data.overview.total_reviews.toLocaleString()} reviews ยท {data.overview.total_spans.toLocaleString()} insights

{/* Data View */}
); } /** * Data view - the detailed charts and tables */ function DataView({ data, filters, setURTDomain, issuesPage, spansPage, setIssuesPage, setSpansPage, jobId, businessId, }: { data: NonNullable['data']>; filters: ReturnType['filters']; setURTDomain: ReturnType['setURTDomain']; issuesPage: number; spansPage: number; setIssuesPage: (page: number) => void; setSpansPage: (page: number) => void; jobId?: string; businessId?: string; }) { const handleDomainClick = (domain: URTDomain) => { setURTDomain(filters.urtDomain === domain ? null : domain); }; return ( <> {/* Filters */} {/* Sentiment + Categories */}
{/* Opportunity Matrix */} {/* Timeline */} {/* Tables */}
{/* Trend Explorer */}

Trend Explorer

); } /** * Main ReviewIQ Dashboard with filter context provider. */ export function ReviewIQDashboard({ jobId, businessId }: ReviewIQDashboardProps) { return ( ); }