feat: produce worker deployment + web producer/collective/branding UI + mobile CSS (wave-2c)
Deployment (t4g2): media-worker gains font-dejavu (drawtext lower-thirds) and a dedicated produce-worker compose service running src/produce.ts — claims video_processing_jobs compose|mix by lane, renders assembled/ overlaid/voiced cuts, registers derived library assets. Deliberately its own process so a remote-lane box needs only Postgres + S3 + ffmpeg. Web: compose media attachments UI (t2), Producer panel in the video drawer (t5), collective creation + branding settings + shell branding (brandweb), mobile CSS (mcss: touch targets, icon sizing, safe areas).
This commit is contained in:
parent
1183d69849
commit
d9e8cdf789
18 changed files with 2384 additions and 20 deletions
|
|
@ -3,6 +3,7 @@
|
|||
import Link from "next/link";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { useAuth } from "../../lib/auth-store";
|
||||
import { useBranding } from "../../lib/branding";
|
||||
import { useApiResource } from "../../lib/use-api";
|
||||
import type { DraftRecord } from "../../lib/api-types";
|
||||
import { LogoMark } from "../brand/logo";
|
||||
|
|
@ -22,7 +23,7 @@ const NAV: { href: string; label: string; icon: string; external?: boolean }[] =
|
|||
{ href: "/analytics", label: "Analytics", icon: "analytics" },
|
||||
{ href: "/connections", label: "Channels", icon: "connections" },
|
||||
{ href: "/team", label: "Team", icon: "team" },
|
||||
{ href: "/audit", label: "Audit", icon: "audit" },
|
||||
{ href: "/audit", label: "Audit log", icon: "audit" },
|
||||
{ href: "/onboarding", label: "Onboarding", icon: "home" },
|
||||
{ href: "/settings", label: "Settings", icon: "settings" },
|
||||
];
|
||||
|
|
@ -33,19 +34,41 @@ const emptyDrafts: DraftRecord[] = [];
|
|||
export function Sidebar(): React.ReactElement {
|
||||
const pathname = usePathname();
|
||||
const { session, can } = useAuth();
|
||||
const branding = useBranding();
|
||||
const drafts = useApiResource<DraftRecord[], DraftRecord[]>("/publishing/drafts", identity, emptyDrafts, { state: "in_review", limit: 100 });
|
||||
// Real in-review count from the API; hidden while loading/offline and for non-approvers.
|
||||
const approvals = can("approval.grant") && drafts.source === "live" ? drafts.data.length : 0;
|
||||
const workspaceName = session?.workspace.name ?? "Studio";
|
||||
// Branding is per collective; the session's workspace is the source of truth
|
||||
// for the name, branding only decorates it (and may be loading/unavailable).
|
||||
const workspaceName = session?.workspace.name ?? branding.workspaceName ?? "Studio";
|
||||
const showTagline = branding.source === "live" && branding.tagline !== null;
|
||||
return (
|
||||
<aside className="hidden h-screen w-52 shrink-0 flex-col border-r border-border-subtle bg-surface lg:flex">
|
||||
<div className="flex items-center gap-2.5 border-b border-border-subtle px-4 py-4">
|
||||
<LogoMark size={30} title="Tactical Media Broadcast Hub" />
|
||||
<div className="min-w-0">
|
||||
<div className="text-xs font-semibold leading-tight tracking-tight">Tactical Media Broadcast Hub</div>
|
||||
<div className="truncate text-2xs text-text-faint" title={workspaceName}>
|
||||
{workspaceName} ▾
|
||||
<div className="flex items-start gap-2.5 border-b border-border-subtle px-4 py-4">
|
||||
{branding.logoUrl !== null ? (
|
||||
<img
|
||||
src={branding.logoUrl}
|
||||
alt={`${workspaceName} logo`}
|
||||
width={30}
|
||||
height={30}
|
||||
className="mt-0.5 h-[30px] w-[30px] shrink-0 rounded object-contain"
|
||||
/>
|
||||
) : (
|
||||
<LogoMark size={30} title="Tactical Media Broadcast Hub" />
|
||||
)}
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="text-xs font-semibold leading-tight tracking-tight" title={workspaceName}>
|
||||
{workspaceName}
|
||||
</div>
|
||||
{showTagline ? (
|
||||
<div className="mt-0.5 truncate text-2xs leading-snug text-text-faint" title={branding.tagline ?? undefined}>
|
||||
{branding.tagline}
|
||||
</div>
|
||||
) : (
|
||||
<div className="truncate text-2xs text-text-faint" title={workspaceName}>
|
||||
Tactical Media Broadcast Hub
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<nav className="flex-1 overflow-y-auto scrollbar-thin p-2">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue