import { useMemo, useState } from "react"; import { ArrowRight, Film, Image, Search, SlidersHorizontal, Video } from "lucide-react"; import { JobCard } from "./JobCard"; import { MediaTile } from "./MediaTile"; import type { JobItem, MediaItem } from "../types"; type Filter = "all" | "images" | "videos"; interface StudioViewProps { items: MediaItem[]; jobs: JobItem[]; loading: boolean; error: string | null; onOpen: (url: string) => void; onDelete: (item: MediaItem) => Promise | void; onOpenProjects?: () => void; } function isVideo(item: MediaItem) { return item.type === "video" || item.url.endsWith(".mp4") || item.url.endsWith(".webm"); } export function StudioView({ items, jobs, loading, error, onOpen, onDelete, onOpenProjects }: StudioViewProps) { const [filter, setFilter] = useState("all"); const [query, setQuery] = useState(""); const imageCount = items.filter((item) => !isVideo(item)).length; const videoCount = items.length - imageCount; const visibleItems = useMemo(() => { const q = query.trim().toLowerCase(); return items.filter((item) => { if (filter === "images" && isVideo(item)) return false; if (filter === "videos" && !isVideo(item)) return false; if (!q) return true; return [item.name, item.filename, item.prompt].some((value) => String(value || "").toLowerCase().includes(q)); }); }, [filter, items, query]); return (

Workspace

Studio

Your gallery for quick image and video generation — freeform, no structure. Generate, browse, iterate.

Total

{items.length}

Images

{imageCount}

Videos

{videoCount}

{[ ["all", "All", SlidersHorizontal], ["images", "Images", Image], ["videos", "Videos", Video], ].map(([id, label, Icon]) => ( ))}
{loading && items.length === 0 && jobs.length === 0 ? (

Loading...

) : error ? (
{error}
) : jobs.length === 0 && visibleItems.length === 0 ? (

No media found.

) : (
{jobs.map((job) => )} {visibleItems.map((item) => ( onOpen(item.url)} onDelete={onDelete} /> ))}
)}
); }