import React, { useState, useEffect, useRef } from 'react'; import { FaMicrophone, FaPlay, FaPause, FaVolumeUp, FaTrash } from 'react-icons/fa'; import { BiPodcast } from 'react-icons/bi'; import { MdDateRange } from 'react-icons/md'; import DeleteModal from '../components/DeleteModal'; import Toast from '../components/Toast'; import './Podcasts.css'; const AudioPlayer = ({ audioUrl }) => { const [isPlaying, setIsPlaying] = useState(false); const [progress, setProgress] = useState(0); const [currentTime, setCurrentTime] = useState(0); const [audioDuration, setAudioDuration] = useState(0); const audioRef = useRef(null); // Check if we have a valid URL const validUrl = audioUrl && audioUrl.trim() !== ''; useEffect(() => { const audio = audioRef.current; if (audio && validUrl) { // Add loadedmetadata event to get duration const handleLoadedMetadata = () => { setAudioDuration(audio.duration); }; const updateProgress = () => { if (audio.duration) { setProgress((audio.currentTime / audio.duration) * 100); setCurrentTime(audio.currentTime); } }; audio.addEventListener('loadedmetadata', handleLoadedMetadata); audio.addEventListener('timeupdate', updateProgress); audio.addEventListener('ended', () => setIsPlaying(false)); return () => { audio.removeEventListener('loadedmetadata', handleLoadedMetadata); audio.removeEventListener('timeupdate', updateProgress); audio.removeEventListener('ended', () => setIsPlaying(false)); }; } }, [audioUrl, validUrl]); const togglePlay = () => { if (audioRef.current && validUrl) { setIsPlaying((prevIsPlaying) => { if (prevIsPlaying) { audioRef.current.pause(); } else { audioRef.current.play().catch(err => { console.error("Error playing audio:", err); setIsPlaying(false); }); } return !prevIsPlaying; }); } }; const formatTime = (time) => { if (isNaN(time) || time < 0) return '0:00'; const minutes = Math.floor(time / 60); const seconds = Math.floor(time % 60); return `${minutes}:${seconds.toString().padStart(2, '0')}`; }; const seekAudio = (event) => { if (!audioRef.current || !validUrl) return; const progressBar = event.currentTarget; const clickX = event.nativeEvent.offsetX; const progressBarWidth = progressBar.clientWidth; // Calculate the new time based on click position const newTime = (clickX / progressBarWidth) * audioRef.current.duration; audioRef.current.currentTime = newTime; // Seek to new time setProgress((newTime / audioRef.current.duration) * 100); }; return (
{formatTime(currentTime)} / {formatTime(audioDuration)}
{validUrl ? (
); }; const Podcasts = () => { const [podcasts, setPodcasts] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [deleteModal, setDeleteModal] = useState({ isOpen: false, podcast: null }); const [toast, setToast] = useState(null); useEffect(() => { fetchPodcasts(); }, []); const fetchPodcasts = async () => { try { const token = localStorage.getItem('token'); const response = await fetch('http://localhost:8000/podcasts', { headers: { 'Authorization': `Bearer ${token}` } }); if (!response.ok) { throw new Error('Failed to fetch podcasts'); } if (response.status === 401) { throw new Error('Unauthorized access. Please log in again.'); } const data = await response.json(); setPodcasts(data); } catch (err) { setError(err.message); } finally { setLoading(false); } }; const handleDelete = async () => { if (!deleteModal.podcast?._id) return; try { const token = localStorage.getItem('token'); const response = await fetch(`http://localhost:8000/podcast/${deleteModal.podcast._id}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${token}` } }); if (!response.ok) { throw new Error('Failed to delete podcast'); } // Remove the podcast from the state setPodcasts(podcasts.filter(p => p._id !== deleteModal.podcast._id)); setDeleteModal({ isOpen: false, podcast: null }); // Show success toast setToast({ message: 'Podcast deleted successfully', type: 'success' }); // Clear toast after 3 seconds setTimeout(() => { setToast(null); }, 3000); } catch (err) { setError(err.message); // Show error toast setToast({ message: 'Failed to delete podcast', type: 'error' }); // Clear toast after 3 seconds setTimeout(() => { setToast(null); }, 3000); } }; if (loading) { return (
Loading your podcasts...
); } if (error) { return (
Error: {error}
); } return (

Your Generated Podcasts

{podcasts.length === 0 ? (

You haven't generated any podcasts yet. Head over to the Home page to create your first podcast!

) : ( podcasts.map((podcast) => (

{podcast.topic}

{podcast.research ? podcast.research.substring(0, 150) + '...' : 'No description available'}

{new Date(podcast.created_at).toLocaleDateString()}
)) )}
setDeleteModal({ isOpen: false, podcast: null })} onConfirm={handleDelete} podcastName={deleteModal.podcast?.topic} /> {toast && (
setToast(null)} />
)}
); }; export default Podcasts;