All the UI fixes for now

This commit is contained in:
2026-04-11 17:21:52 +02:00
parent 1bd51ecb5d
commit c67259ebe0
15 changed files with 565 additions and 112 deletions

View File

@@ -1,40 +1,66 @@
"use client";
import { useTranslations } from "next-intl";
import { useRouter } from "next/navigation";
import { PACKAGE_CATALOG } from "@/lib/packages";
import { PackageCard } from "./package-card";
import type { PiecedTenantStatus } from "@/types";
interface Props {
tenantName: string;
enabledPackages: string[];
conditions?: PiecedTenantStatus["conditions"];
conditions?: Array<{ type: string; status: string; reason?: string }>;
onRefresh?: () => void;
}
export function PackageList({ tenantName, enabledPackages, conditions }: Props) {
const router = useRouter();
const CATEGORIES = [
{ key: "channel" as const, labelKey: "categories.channels" },
{ key: "skill" as const, labelKey: "categories.skills" },
] as const;
function getStatus(pkgId: string): "pending" | "active" | "error" | undefined {
if (!conditions) return enabledPackages.includes(pkgId) ? "pending" : undefined;
const cond = conditions.find((c) => c.type === `Package/${pkgId}`);
if (!cond) return enabledPackages.includes(pkgId) ? "pending" : undefined;
if (cond.status === "True") return "active";
if (cond.status === "False") return "error";
return "pending";
}
function getPackageStatus(
pkgId: string,
enabled: boolean,
conditions?: Props["conditions"]
): "pending" | "active" | "error" | undefined {
if (!enabled) return undefined;
const cond = conditions?.find((c) => c.type === `Package/${pkgId}`);
if (!cond) return "pending";
if (cond.status === "True") return "active";
if (cond.reason === "SecretReady") return "active";
return "error";
}
export function PackageList({ tenantName, enabledPackages, conditions, onRefresh }: Props) {
const t = useTranslations("packages");
const router = useRouter();
const handleRefresh = onRefresh || (() => router.refresh());
return (
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
{PACKAGE_CATALOG.map((pkg) => (
<PackageCard
key={pkg.id}
pkg={pkg}
enabled={enabledPackages.includes(pkg.id)}
status={enabledPackages.includes(pkg.id) ? getStatus(pkg.id) : undefined}
tenantName={tenantName}
onToggled={() => router.refresh()}
/>
))}
<div className="space-y-6">
{CATEGORIES.map(({ key, labelKey }) => {
const packages = PACKAGE_CATALOG.filter((p) => p.category === key);
if (packages.length === 0) return null;
return (
<div key={key}>
<h3 className="text-[10px] font-semibold uppercase tracking-wider text-text-muted mb-3">
{t(labelKey)}
</h3>
<div className="grid gap-3 sm:grid-cols-2">
{packages.map((pkg) => (
<PackageCard
key={pkg.id}
pkg={pkg}
enabled={enabledPackages.includes(pkg.id)}
status={getPackageStatus(pkg.id, enabledPackages.includes(pkg.id), conditions)}
tenantName={tenantName}
onToggled={handleRefresh}
/>
))}
</div>
</div>
);
})}
</div>
);
}