"use client"; import { useParams } from "next/navigation"; import { Suspense, useEffect, useState } from "react"; import { BarChart3, Search, Filter, PlayCircle, Calendar, Clock, ChevronRight, User, LayoutGrid } from "lucide-react"; import { PageHeader } from "~/components/ui/page-header"; import { useBreadcrumbsEffect } from "~/components/ui/breadcrumb-provider"; import { useStudyContext } from "~/lib/study-context"; import { useSelectedStudyDetails } from "~/hooks/useSelectedStudyDetails"; import { api } from "~/trpc/react"; import { TrialAnalysisView } from "~/components/trials/views/TrialAnalysisView"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "~/components/ui/select"; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "~/components/ui/card"; import { Button } from "~/components/ui/button"; import { ScrollArea } from "~/components/ui/scroll-area"; import { formatDistanceToNow } from "date-fns"; // -- Sub-Components -- function AnalyticsContent({ selectedTrialId, setSelectedTrialId, trialsList, isLoadingList }: { selectedTrialId: string | null; setSelectedTrialId: (id: string | null) => void; trialsList: any[]; isLoadingList: boolean; }) { // Fetch full details of selected trial const { data: selectedTrial, isLoading: isLoadingTrial, error: trialError } = api.trials.get.useQuery( { id: selectedTrialId! }, { enabled: !!selectedTrialId } ); // Transform trial data const trialData = selectedTrial ? { ...selectedTrial, startedAt: selectedTrial.startedAt ? new Date(selectedTrial.startedAt) : null, completedAt: selectedTrial.completedAt ? new Date(selectedTrial.completedAt) : null, eventCount: (selectedTrial as any).eventCount, mediaCount: (selectedTrial as any).mediaCount, } : null; return (
{selectedTrialId ? ( isLoadingTrial ? (
Loading trial data...
) : trialError ? (

Error Loading Trial

{trialError.message}

) : trialData ? ( ) : null ) : (
setSelectedTrialId(id)} />
)}
); } function StudyOverviewPlaceholder({ trials, onSelect }: { trials: any[], onSelect: (id: string) => void }) { const recentTrials = [...trials].sort((a, b) => new Date(b.startedAt || b.createdAt).getTime() - new Date(a.startedAt || a.createdAt).getTime() ).slice(0, 5); return (
{/* Left: Illustration / Prompt */}

Analytics & Playback

Select a session from the top right to review video recordings, event logs, and metrics.
Feature-rich playback
Synchronized timeline
{/* Right: Recent Sessions */} Recent Sessions
{recentTrials.map(trial => ( ))} {recentTrials.length === 0 && (
No sessions found.
)}
) } // -- Main Page -- export default function StudyAnalyticsPage() { const params = useParams(); const studyId: string = typeof params.id === "string" ? params.id : ""; const { setSelectedStudyId, selectedStudyId } = useStudyContext(); const { study } = useSelectedStudyDetails(); // State lifted up const [selectedTrialId, setSelectedTrialId] = useState(null); // Fetch list of trials for the selector const { data: trialsList, isLoading: isLoadingList } = api.trials.list.useQuery( { studyId, limit: 100 }, { enabled: !!studyId } ); // Set breadcrumbs useBreadcrumbsEffect([ { label: "Dashboard", href: "/dashboard" }, { label: "Studies", href: "/studies" }, { label: study?.name ?? "Study", href: `/studies/${studyId}` }, { label: "Analytics" }, ]); // Set the active study if it doesn't match the current route useEffect(() => { if (studyId && selectedStudyId !== studyId) { setSelectedStudyId(studyId); } }, [studyId, selectedStudyId, setSelectedStudyId]); return (
{/* Session Selector in Header */}
} />
Loading analytics...
}>
); }