"use client"; import { useTranslations } from "next-intl"; import { useEffect, useState, useCallback } from "react"; import { useParams } from "next/navigation"; import { PACKAGE_CATALOG, type PackageDef } from "@/lib/packages"; import { PhaseBadge } from "@/components/dashboard/InstanceStatus"; import PackageCard from "@/components/packages/PackageCard"; import WorkspaceEditor from "@/components/packages/WorkspaceEditor"; interface TenantCR { metadata: { name: string; creationTimestamp: string; resourceVersion: string; }; spec: { agentName?: string; displayName?: string; packages?: string[]; workspaceFiles?: { name: string; content: string }[]; litellmTeamId?: string; }; status?: { phase: string; conditions?: { type: string; status: string; message?: string; reason?: string; }[]; }; } export default function TenantDetailClient() { const t = useTranslations("tenantDetail"); const { name } = useParams<{ name: string }>(); const [tenant, setTenant] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const fetchTenant = useCallback(async () => { try { const res = await fetch(`/api/tenants/${name}`); if (!res.ok) throw new Error(`${res.status}`); setTenant(await res.json()); } catch (err: any) { setError(err.message); } finally { setLoading(false); } }, [name]); useEffect(() => { fetchTenant(); }, [fetchTenant]); async function handlePackageToggle( packageId: string, enable: boolean ) { if (!tenant) return; const currentPackages = tenant.spec.packages || []; const newPackages = enable ? [...currentPackages, packageId] : currentPackages.filter((p) => p !== packageId); const res = await fetch(`/api/tenants/${name}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ packages: newPackages }), }); if (!res.ok) { const err = await res.json(); throw new Error(err.error || "Failed to update packages"); } // Refetch tenant state await fetchTenant(); } async function handleWorkspaceSave( files: { name: string; content: string }[] ) { const res = await fetch(`/api/tenants/${name}`, { method: "PATCH", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ workspaceFiles: files }), }); if (!res.ok) { const err = await res.json(); throw new Error(err.error || "Failed to update workspace files"); } await fetchTenant(); } function getPackageStatus( pkgId: string ): "pending" | "active" | "error" | undefined { if (!tenant?.status?.conditions) return undefined; const cond = tenant.status.conditions.find( (c) => c.type === `Package/${pkgId}` ); if (!cond) return "pending"; if (cond.status === "True") return "active"; if (cond.status === "False") return "error"; return "pending"; } if (loading) { return (
{[1, 2, 3].map((i) => (
))}
); } if (error || !tenant) { return (
{error || t("notFound")}
); } const enabledPackages = tenant.spec.packages || []; const workspaceFiles = tenant.spec.workspaceFiles || [ { name: "SOUL.md", content: "" }, { name: "AGENTS.md", content: "" }, { name: "TOOLS.md", content: "" }, ]; return (
{/* Header */}

{tenant.spec.displayName || name}

{tenant.spec.agentName && (

{t("agent")}: {tenant.spec.agentName}

)}
{/* Packages */}

{t("packages")}

{PACKAGE_CATALOG.map((pkg) => ( ))}
{/* Workspace files */}

{t("workspaceFiles")}

); }