"use client"; import { useState } from "react"; import ReactMarkdown from "react-markdown"; import rehypeRaw from "rehype-raw"; // Import rehype-raw interface TranscriptViewerProps { transcriptContent: string; transcriptUrl?: string | null; } /** * Renders a message bubble with proper styling */ function renderMessageBubble( speaker: string, messages: string[], key: string ): React.ReactNode { return (
{messages.map((msg, i) => ( ( ), }} > {msg} ))}
); } /** * Checks if a line indicates a new speaker */ function isNewSpeakerLine(line: string): boolean { return line.startsWith("User:") || line.startsWith("Assistant:"); } /** * Extracts speaker and message content from a speaker line */ function extractSpeakerInfo(line: string): { speaker: string; content: string; } { const speaker = line.startsWith("User:") ? "User" : "Assistant"; const content = line.substring(line.indexOf(":") + 1).trim(); return { speaker, content }; } /** * Processes accumulated messages for a speaker */ function processAccumulatedMessages( currentSpeaker: string | null, currentMessages: string[], elements: React.ReactNode[] ): void { if (currentSpeaker && currentMessages.length > 0) { elements.push( renderMessageBubble( currentSpeaker, currentMessages, `message-${elements.length}` ) ); } } /** * Format the transcript content into a more readable format with styling */ function formatTranscript(content: string): React.ReactNode[] { if (!content.trim()) { return [

No transcript content available.

]; } const lines = content.split("\n"); const elements: React.ReactNode[] = []; let currentSpeaker: string | null = null; let currentMessages: string[] = []; // Process each line for (const line of lines) { const trimmedLine = line.trim(); if (!trimmedLine) { continue; // Skip empty lines } if (isNewSpeakerLine(line)) { // Process any accumulated messages from previous speaker processAccumulatedMessages(currentSpeaker, currentMessages, elements); currentMessages = []; // Set new speaker and add initial content const { speaker, content } = extractSpeakerInfo(trimmedLine); currentSpeaker = speaker; if (content) { currentMessages.push(content); } } else if (currentSpeaker) { // Continuation of current speaker's message currentMessages.push(trimmedLine); } } // Process any remaining messages processAccumulatedMessages(currentSpeaker, currentMessages, elements); return elements; } /** * Component to display a chat transcript */ export default function TranscriptViewer({ transcriptContent, transcriptUrl, }: TranscriptViewerProps) { const [showRaw, setShowRaw] = useState(false); const formattedElements = formatTranscript(transcriptContent); return (

Session Transcript

{transcriptUrl && ( View Full Raw )}
{showRaw ? (
          {transcriptContent}
        
) : (
{formattedElements.length > 0 ? ( formattedElements ) : (

No transcript content available.

)}
)}
); }