@@ -268,8 +270,8 @@ export function ChatSessionsSidebar({ className={` group relative p-3 rounded-xl border cursor-pointer transition-all duration-200 pr-10 min-h-[64px] ${session.id === activeSessionId - ? 'bg-card border-[#FF6D20] shadow-md ring-1 ring-[#FF6D20]/20 z-10' - : 'bg-card border-border/60 shadow-md hover:border-primary/50 hover:bg-card/80' + ? 'bg-[var(--bg-card)] dark:bg-[#1F1F1F] border-[#FF6D20] shadow-[0_2px_4px_rgba(0,0,0,0.04),0_8px_16px_rgba(0,0,0,0.06)] dark:shadow-[0_2px_4px_rgba(0,0,0,0.3),0_8px_16px_rgba(0,0,0,0.2)] ring-1 ring-[#FF6D20]/20 z-10' + : 'bg-[var(--bg-card)] dark:bg-[#141414] border-[rgba(0,0,0,0.06)] dark:border-[rgba(255,255,255,0.08)] shadow-[0_2px_4px_rgba(0,0,0,0.04),0_8px_16px_rgba(0,0,0,0.04)] dark:shadow-[0_2px_4px_rgba(0,0,0,0.2),0_8px_16px_rgba(0,0,0,0.1)] hover:shadow-[0_4px_8px_rgba(0,0,0,0.06),0_12px_24px_rgba(0,0,0,0.06)] hover:-translate-y-0.5 hover:border-[var(--brand-solid)]/30' } `} > diff --git a/web/frontend/src/features/transcription/components/audio-detail/SummaryDialog.tsx b/web/frontend/src/features/transcription/components/audio-detail/SummaryDialog.tsx index 693a3de2..f2f3dffe 100644 --- a/web/frontend/src/features/transcription/components/audio-detail/SummaryDialog.tsx +++ b/web/frontend/src/features/transcription/components/audio-detail/SummaryDialog.tsx @@ -31,7 +31,7 @@ import { useSummaryTemplates, useSummarizer, useExistingSummary } from "@/featur import { useTranscript, useAudioDetail } from "@/features/transcription/hooks/useAudioDetail"; -import { Sparkles, Download, Copy, RefreshCw, ChevronDown } from "lucide-react"; +import { Sparkles, Download, Copy, RefreshCw, ChevronDown, FileText } from "lucide-react"; interface SummaryDialogProps { audioId: string; @@ -43,7 +43,7 @@ interface SummaryDialogProps { export function SummaryDialog({ audioId, isOpen, onClose, llmReady }: SummaryDialogProps) { const { toast } = useToast(); const { data: templates = [], isLoading: templatesLoading } = useSummaryTemplates(); - const { data: existingSummary } = useExistingSummary(audioId); + const { data: existingSummary, isLoading: summaryLoading } = useExistingSummary(audioId); const { data: transcript } = useTranscript(audioId, true); const { data: audioFile } = useAudioDetail(audioId); @@ -58,11 +58,20 @@ export function SummaryDialog({ audioId, isOpen, onClose, llmReady }: SummaryDia const selectedTemplate = templates.find(t => t.id === selectedTemplateId); // Auto-show existing summary if available and not streaming + // Wait for loading to complete to prevent blank display useEffect(() => { - if (isOpen && existingSummary && !isStreaming && !streamContent) { + if (isOpen && !summaryLoading && existingSummary?.content && !isStreaming && !streamContent) { setShowOutput(true); } - }, [isOpen, existingSummary, isStreaming, streamContent]); + }, [isOpen, existingSummary, summaryLoading, isStreaming, streamContent]); + + // Reset state when dialog closes + useEffect(() => { + if (!isOpen) { + setShowOutput(false); + setSelectedTemplateId(""); + } + }, [isOpen]); const handleStartSummary = () => { if (!selectedTemplate || !transcript) return; @@ -98,134 +107,193 @@ export function SummaryDialog({ audioId, isOpen, onClose, llmReady }: SummaryDia URL.revokeObjectURL(url); }; + // Handle close - prevent closing during streaming + const handleOpenChange = (open: boolean) => { + if (!open && isStreaming) { + // Don't allow closing during streaming + return; + } + onClose(open); + }; + if (showOutput) { - // Output View + // Output View - Redesigned with Scriberr Design System return ( -