import React, { useEffect, useState } from "react"; import { useNavigate } from "react-router-dom"; import { Box, Paper, Stack, Typography, Button, Chip, CircularProgress, Alert, alpha, IconButton, Tooltip, Dialog, DialogTitle, DialogContent, DialogActions, TextField, } from "@mui/material"; import { Mic as MicIcon, PlayArrow as PlayArrowIcon, Delete as DeleteIcon, Edit as EditIcon, Star as StarIcon, StarBorder as StarBorderIcon, Refresh as RefreshIcon, Search as SearchIcon, ArrowBack as ArrowBackIcon, } from "@mui/icons-material"; import { podcastApi } from "../../services/podcastApi"; import { GlassyCard, glassyCardSx, PrimaryButton, SecondaryButton } from "./ui"; interface Project { id: number; project_id: string; idea: string; duration: number; speakers: number; current_step: string | null; status: string; is_favorite: boolean; created_at: string; updated_at: string; } interface ProjectListProps { onSelectProject: (projectId: string) => void; onBack?: () => void; } export const ProjectList: React.FC = ({ onSelectProject, onBack }) => { const navigate = useNavigate(); const [projects, setProjects] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); const [projectToDelete, setProjectToDelete] = useState(null); const [searchQuery, setSearchQuery] = useState(""); const loadProjects = async () => { try { setLoading(true); setError(null); const response = await podcastApi.listProjects({ order_by: "updated_at", limit: 50, }); setProjects(response.projects); } catch (err) { setError(err instanceof Error ? err.message : "Failed to load projects"); } finally { setLoading(false); } }; useEffect(() => { loadProjects(); }, []); const handleDelete = async () => { if (!projectToDelete) return; try { await podcastApi.deleteProject(projectToDelete); await loadProjects(); setDeleteDialogOpen(false); setProjectToDelete(null); } catch (err) { setError(err instanceof Error ? err.message : "Failed to delete project"); } }; const handleToggleFavorite = async (projectId: string, currentFavorite: boolean) => { try { await podcastApi.toggleFavorite(projectId); await loadProjects(); } catch (err) { setError(err instanceof Error ? err.message : "Failed to update favorite"); } }; const getStepLabel = (step: string | null) => { switch (step) { case "analysis": return "Analysis"; case "research": return "Research"; case "script": return "Script"; case "render": return "Rendering"; default: return "Draft"; } }; const getStatusColor = (status: string) => { switch (status) { case "completed": return "success"; case "in_progress": return "info"; case "draft": return "default"; default: return "default"; } }; const filteredProjects = projects.filter((project) => project.idea.toLowerCase().includes(searchQuery.toLowerCase()) || project.project_id.toLowerCase().includes(searchQuery.toLowerCase()) ); return ( {/* Header */} My Podcast Projects Resume your work or start a new episode navigate(-1))} startIcon={}> Back } disabled={loading}> Refresh navigate("/podcast-maker")} startIcon={}> New Episode {/* Search */} setSearchQuery(e.target.value)} InputProps={{ startAdornment: , }} sx={{ "& .MuiOutlinedInput-root": { color: "white", "& fieldset": { borderColor: "rgba(255,255,255,0.2)" }, "&:hover fieldset": { borderColor: "rgba(255,255,255,0.3)" }, }, }} /> {/* Error */} {error && ( setError(null)}> {error} )} {/* Loading */} {loading && ( )} {/* Projects List */} {!loading && filteredProjects.length === 0 && ( {searchQuery ? "No projects match your search" : "No projects yet"} navigate("/podcast-maker")} startIcon={}> Create Your First Episode )} {!loading && filteredProjects.length > 0 && ( {filteredProjects.map((project) => ( onSelectProject(project.project_id)} > onSelectProject(project.project_id)} sx={{ cursor: "pointer" }}> {project.idea.length > 100 ? `${project.idea.substring(0, 100)}...` : project.idea} {project.speakers} {project.speakers === 1 ? "speaker" : "speakers"} {project.duration} min Updated {new Date(project.updated_at).toLocaleDateString()} { e.stopPropagation(); onSelectProject(project.project_id); }} sx={{ color: "#a78bfa" }} > { e.stopPropagation(); handleToggleFavorite(project.project_id, project.is_favorite); }} sx={{ color: project.is_favorite ? "#fbbf24" : "#a78bfa" }} > {project.is_favorite ? : } { e.stopPropagation(); setProjectToDelete(project.project_id); setDeleteDialogOpen(true); }} sx={{ color: "#ef4444" }} > ))} )} {/* Delete Confirmation Dialog */} { setDeleteDialogOpen(false); setProjectToDelete(null); }} PaperProps={{ sx: { background: alpha("#0f172a", 0.95), backdropFilter: "blur(20px)", border: "1px solid rgba(255,255,255,0.1)", }, }} > Delete Project? Are you sure you want to delete this project? This action cannot be undone. { setDeleteDialogOpen(false); setProjectToDelete(null); }}> Cancel }> Delete ); };