import { useEffect, useState } from "react"; import { Box, Flex, Skeleton, Text } from "@chakra-ui/react"; import { LuVideo, LuX } from "react-icons/lu"; import { useAuth } from "../../lib/AuthProvider"; import { API_URL } from "../../lib/apiClient"; type VideoPlayerProps = { transcriptId: string; duration: number | null; expanded: boolean; onClose: () => void; }; function formatDuration(seconds: number): string { const h = Math.floor(seconds / 3600); const m = Math.floor((seconds % 3600) / 60); const s = seconds % 60; if (h > 0) return `${h}:${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`; return `${m}:${String(s).padStart(2, "0")}`; } export default function VideoPlayer({ transcriptId, duration, expanded, onClose, }: VideoPlayerProps) { const [videoUrl, setVideoUrl] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const auth = useAuth(); const accessToken = auth.status === "authenticated" ? auth.accessToken : null; useEffect(() => { if (!expanded || !transcriptId || videoUrl) return; const fetchVideoUrl = async () => { setLoading(true); setError(null); try { const params = new URLSearchParams(); if (accessToken) { params.set("token", accessToken); } const url = `${API_URL}/v1/transcripts/${transcriptId}/video/url?${params}`; const headers: Record = {}; if (accessToken) { headers["Authorization"] = `Bearer ${accessToken}`; } const resp = await fetch(url, { headers }); if (!resp.ok) { throw new Error("Failed to load video"); } const data = await resp.json(); setVideoUrl(data.url); } catch (err) { setError(err instanceof Error ? err.message : "Failed to load video"); } finally { setLoading(false); } }; fetchVideoUrl(); }, [expanded, transcriptId, accessToken, videoUrl]); if (!expanded) return null; if (loading) { return ( ); } if (error || !videoUrl) { return ( Failed to load video recording ); } return ( {/* Header bar with title and close button */} Cloud recording {duration != null && ( {formatDuration(duration)} )} {/* Video element with visible controls */} ); }