import { Play, Pause, Volume2, MoreVertical, Clock, ChevronDown, ChevronUp, Download } from 'lucide-react' import { useState, useRef, useEffect } from 'react' import { api } from '../api' export default function AudioPostCard({ post }) { const [isPlaying, setIsPlaying] = useState(false) const [currentTime, setCurrentTime] = useState(0) const [duration, setDuration] = useState(0) const [volume, setVolume] = useState(1) const [transcript, setTranscript] = useState(null) const [loadingTranscript, setLoadingTranscript] = useState(false) const [transcriptExpanded, setTranscriptExpanded] = useState(false) const [downloading, setDownloading] = useState(false) const audioRef = useRef(null) // DEBUG: Log post data to console useEffect(() => { console.log('Post data:', post) console.log('Audio URL:', post.audio_url) console.log('Status:', post.status) }, [post]) const formatDate = (dateString) => { const date = new Date(dateString) const now = new Date() const diffMs = now - date const diffMins = Math.floor(diffMs / 60000) if (diffMins < 60) return `${diffMins}m ago` if (diffMins < 1440) return `${Math.floor(diffMins / 60)}h ago` return `${Math.floor(diffMins / 1440)}d ago` } const formatTime = (seconds) => { if (!seconds || isNaN(seconds)) return '0:00' const mins = Math.floor(seconds / 60) const secs = Math.floor(seconds % 60) return `${mins}:${secs.toString().padStart(2, '0')}` } // Load transcript on mount if post is ready useEffect(() => { if (post.status === 'ready' && !transcript && !loadingTranscript) { loadTranscript() } // Set audio source if available if (post.audio_url && audioRef.current) { console.log('Setting audio src to:', post.audio_url) audioRef.current.src = post.audio_url audioRef.current.load() // Force reload } }, [post.post_id, post.status, post.audio_url]) const loadTranscript = async () => { setLoadingTranscript(true) try { const metadata = await api.getPostMetadata(post.post_id) if (metadata && metadata.metadata) { const metadataObj = JSON.parse(metadata.metadata) const promptText = metadataObj.prompt || '' const transcriptMatch = promptText.match(/Transcript:\n([\s\S]*?)\n\nAnswer user questions/) if (transcriptMatch) { setTranscript(transcriptMatch[1].trim()) } else { setTranscript('Transcript not available') } } } catch (err) { console.error('Failed to load transcript:', err) setTranscript('Failed to load transcript') } finally { setLoadingTranscript(false) } } const handleDownload = async () => { if (downloading) return setDownloading(true) try { const zipBlob = await api.exportPost(post.post_id) const url = window.URL.createObjectURL(zipBlob) const a = document.createElement("a") a.href = url a.download = `${post.title.replace(/[^a-zA-Z0-9]/g, "_")}_${post.post_id}.zip` document.body.appendChild(a) a.click() a.remove() window.URL.revokeObjectURL(url) } catch (err) { console.error("Failed to download post:", err) alert(`Download failed: ${err.message}`) } finally { setDownloading(false) } } const togglePlay = () => { if (!audioRef.current) return if (isPlaying) { audioRef.current.pause() } else { audioRef.current.play() } setIsPlaying(!isPlaying) } const handleTimeUpdate = () => { if (audioRef.current) { setCurrentTime(audioRef.current.currentTime) } } const handleLoadedMetadata = () => { if (audioRef.current) { console.log('Audio metadata loaded, duration:', audioRef.current.duration) setDuration(audioRef.current.duration) } } const handleAudioError = (e) => { console.error('Audio error:', e) console.error('Audio element error:', audioRef.current?.error) } const handleSeek = (e) => { const rect = e.currentTarget.getBoundingClientRect() const x = e.clientX - rect.left const percentage = x / rect.width const newTime = percentage * duration if (audioRef.current) { audioRef.current.currentTime = newTime setCurrentTime(newTime) } } const handleVolumeChange = (e) => { const newVolume = parseFloat(e.target.value) setVolume(newVolume) if (audioRef.current) { audioRef.current.volume = newVolume } } const handleEnded = () => { setIsPlaying(false) setCurrentTime(0) } const progress = duration > 0 ? (currentTime / duration) * 100 : 0 return (
{/* Post Header */}

{post.title}

{post.visibility === 'private' && ( Private )}
{formatDate(post.created_at)} {post.status} {post.language && ( {post.language.toUpperCase()} )}
{post.status === 'ready' && ( )}
{/* Description */} {post.description && (

{post.description}

)} {/* Audio Player - Only show if ready */} {post.status === 'ready' && ( <>
{/* Hidden audio element */}
{/* Transcript Section - Always shown */}
{transcript && (

{transcript}

)} {!transcript && !loadingTranscript && (

No transcript available

)} {loadingTranscript && (

Loading transcript...

)}
)} {/* Processing Status */} {post.status === 'processing' && (

Processing audio and generating transcript...

)} {/* Failed Status */} {post.status === 'failed' && (

Failed to process this recording. Please try uploading again.

)}
) }