import { Trans, useLingui } from "@lingui/react/macro"; import type { MediaProject } from "@rakazo/contracts"; import { Button, Dialog, DialogClose, DialogContent, DialogTitle, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, Tabs, TabsList, TabsTrigger, } from "@rakazo/ui-web"; import { ChevronDown, ChevronLeft, X } from "lucide-react"; import { useCallback, useEffect, useMemo, useState } from "react"; import { MediaStudioContext, useMediaCapabilities } from "../../lib/media-studio"; import { rpc } from "../../lib/rpc"; import { BrandKitView } from "./BrandKitView"; import { CollectionView } from "./CollectionView"; import { EditorView } from "./EditorView"; import { LibraryView } from "./LibraryView"; import type { MediaSection, MediaView } from "./nav"; import { pushView, sectionOf } from "./nav"; import { PeopleView } from "./PeopleView"; import { ProjectView } from "./ProjectView"; import { ResultsView } from "./ResultsView"; import { ReviewView } from "./ReviewView"; function ViewSwitch({ view, navigate, onClose, }: { view: MediaView; navigate: (view: MediaView) => void; onClose: () => void; }) { const props = { navigate, onClose }; switch (view.name) { case "library": return ; case "collection": return ; case "people": return ; case "results": return ; case "project": return ; case "editor": return ; case "review": return ; case "brandKit": return ; } } function ProjectsMenu({ navigate, refreshKey, }: { navigate: (view: MediaView) => void; refreshKey: unknown; }) { const [projects, setProjects] = useState([]); useEffect(() => { void refreshKey; let active = true; rpc.media.projects .list({ cursor: null, limit: 20 }) .then((page) => { if (active) setProjects(page.items.filter((project) => project.status !== "archived")); }) .catch(() => undefined); return () => { active = false; }; }, [refreshKey]); if (projects.length === 0) return null; return ( } > Projects {projects.map((project) => ( navigate({ name: "project", projectId: project.id })} > {project.title} ))} ); } /** Media Studio surface: a full-window layer with its own back stack. */ export function MediaStudio({ onClose, canLinkFolder = false, }: { onClose: () => void; /** Deployment owner only: folder sources live on the host. */ canLinkFolder?: boolean; }) { const { t } = useLingui(); const capabilities = useMediaCapabilities(); const [stack, setStack] = useState([{ name: "library" }]); const view = stack.at(-1) ?? { name: "library" }; const section = sectionOf(view); const navigate = useCallback( (next: MediaView) => setStack((current) => pushView(current, next)), [], ); const back = useCallback( () => setStack((current) => (current.length > 1 ? current.slice(0, -1) : current)), [], ); const env = useMemo(() => ({ capabilities, canLinkFolder }), [capabilities, canLinkFolder]); const notConfigured = capabilities !== null && !capabilities.configured; return ( { if (!open) onClose(); }} >
{stack.length > 1 ? ( ) : null} Media
navigate({ name: value as MediaSection })} > Library Results Brand kit
}>
{notConfigured ? (
Media Studio is not set up on this server.
) : ( )}
); }