metis-desk/modules/companies/src/web/components/dashboard-companies-panel.tsx

129 lines
4.5 KiB
TypeScript
Raw Normal View History

2026-10-08 14:43:34 +00:00
import { Building2Icon } from "@repo/shadcn-ui/lib/icons";
import { useQuery } from "@tanstack/react-query";
import { useTranslation } from "react-i18next";
import type { DashboardNavigation } from "./dashboard-api";
import { dashboardApi, dashboardKeys } from "./dashboard-api";
import { BlockState } from "./dashboard-block";
import { DashboardPanel } from "./dashboard-panel";
export function DashboardCompaniesPanel({
companyId,
onDetails,
onNavigate,
}: {
companyId: string | undefined;
onDetails: () => void;
onNavigate: (destination: DashboardNavigation) => void;
}) {
const { t } = useTranslation("companies");
const totals = useQuery({
queryKey: dashboardKeys.block("companies", companyId),
queryFn: ({ signal }) => dashboardApi.companies(signal, companyId),
staleTime: 0,
});
return (
<DashboardPanel
action={onDetails}
icon={<Building2Icon />}
title={t("dashboard.companySummary")}
>
<BlockState empty={!totals.data?.items.length} emptyText={t("noCompanies")} query={totals}>
<div className="overflow-x-auto">
<table>
<caption className="sr-only">{t("dashboard.companySummary")}</caption>
<thead>
<tr>
{[
t("tickets.company"),
t("dashboard.openTickets"),
t("dashboard.pendingInterventions"),
t("dashboard.registeredAssets"),
t("people"),
].map((label) => (
<th key={label} scope="col">
{label}
</th>
))}
</tr>
</thead>
<tbody>
{totals.data?.items.slice(0, 5).map((item) => (
<tr key={item.id}>
<td>
<button
className="dashboard-link"
onClick={() =>
onNavigate({ area: "company", id: item.id, section: "inventory" })
}
type="button"
>
{item.name}
</button>
</td>
<td>
<button
aria-label={`${t("dashboard.openTickets")} · ${item.name}: ${item.tickets}`}
className="dashboard-link text-destructive"
onClick={() =>
onNavigate({ area: "tickets", companyId: item.id, pendingOnly: true })
}
type="button"
>
{item.tickets}
</button>
</td>
<td>
<button
aria-label={`${t("dashboard.pendingInterventions")} · ${item.name}: ${item.interventions}`}
className="dashboard-link text-amber-600 dark:text-amber-400"
onClick={() =>
onNavigate({
area: "interventions",
companyId: item.id,
pendingOnly: true,
})
}
type="button"
>
{item.interventions}
</button>
</td>
<td>
<button
className="dashboard-link"
onClick={() =>
onNavigate({ area: "company", id: item.id, section: "inventory" })
}
type="button"
>
<span className="sr-only">
{t("dashboard.registeredAssets")} · {item.name}:{" "}
</span>
{item.assets}
</button>
</td>
<td>
<button
className="dashboard-link"
onClick={() =>
onNavigate({ area: "company", id: item.id, section: "people" })
}
type="button"
>
<span className="sr-only">
{t("people")} · {item.name}:{" "}
</span>
{item.people}
</button>
</td>
</tr>
))}
</tbody>
</table>
</div>
</BlockState>
</DashboardPanel>
);
}