2026-10-08 14:43:34 +00:00
|
|
|
import {
|
|
|
|
|
BoxIcon,
|
|
|
|
|
ChevronRightIcon,
|
|
|
|
|
FileKeyIcon,
|
|
|
|
|
TriangleAlertIcon,
|
|
|
|
|
UserRoundXIcon,
|
|
|
|
|
UsersIcon,
|
2026-10-09 16:00:41 +00:00
|
|
|
} from "@repo/rdx-ui/lib/icons";
|
2026-10-08 14:43:34 +00:00
|
|
|
import { useQuery } from "@tanstack/react-query";
|
|
|
|
|
import { useTranslation } from "react-i18next";
|
|
|
|
|
|
2026-10-08 17:25:02 +00:00
|
|
|
import type { DashboardIssue } from "../../../../common/dashboard";
|
2026-10-08 22:27:19 +00:00
|
|
|
import { BlockState, DashboardPanel } from "../../shared";
|
|
|
|
|
import { dashboardApi, dashboardKeys } from "../../shared/api";
|
2026-10-08 14:43:34 +00:00
|
|
|
|
|
|
|
|
const ISSUE_ICONS = {
|
|
|
|
|
certificate: FileKeyIcon,
|
|
|
|
|
license: FileKeyIcon,
|
|
|
|
|
profile: UsersIcon,
|
|
|
|
|
missing_site: BoxIcon,
|
|
|
|
|
inactive_person: UserRoundXIcon,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export function DashboardAttentionPanel({
|
|
|
|
|
companyId,
|
|
|
|
|
onDetails,
|
|
|
|
|
}: {
|
|
|
|
|
companyId: string | undefined;
|
|
|
|
|
onDetails: (issue: DashboardIssue) => void;
|
|
|
|
|
}) {
|
|
|
|
|
const { t } = useTranslation("companies");
|
|
|
|
|
const attention = useQuery({
|
|
|
|
|
queryKey: dashboardKeys.block("attention", companyId),
|
|
|
|
|
queryFn: ({ signal }) => dashboardApi.attention(signal, companyId),
|
|
|
|
|
staleTime: 0,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<DashboardPanel
|
|
|
|
|
icon={<TriangleAlertIcon className="text-destructive" />}
|
|
|
|
|
title={t("dashboard.attention")}
|
|
|
|
|
>
|
|
|
|
|
<BlockState
|
|
|
|
|
empty={!attention.data?.items.length}
|
|
|
|
|
emptyText={t("dashboard.noAttention")}
|
|
|
|
|
query={attention}
|
|
|
|
|
>
|
|
|
|
|
<ul className="divide-y">
|
|
|
|
|
{attention.data?.items.map((item) => {
|
|
|
|
|
const Icon = ISSUE_ICONS[item.kind];
|
2026-10-10 10:01:58 +00:00
|
|
|
|
2026-10-08 14:43:34 +00:00
|
|
|
return (
|
|
|
|
|
<li key={item.kind}>
|
|
|
|
|
<button
|
2026-10-08 16:31:46 +00:00
|
|
|
className="flex w-full items-center gap-4 py-4 text-left text-sm leading-[1.5] focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-3 focus-visible:outline-ring"
|
2026-10-08 14:43:34 +00:00
|
|
|
onClick={() => onDetails(item.kind)}
|
|
|
|
|
type="button"
|
|
|
|
|
>
|
|
|
|
|
<Icon aria-hidden="true" className="size-5" />
|
|
|
|
|
<strong
|
|
|
|
|
className={
|
2026-10-08 16:31:46 +00:00
|
|
|
item.count
|
|
|
|
|
? "text-xl leading-[1.5] text-amber-600 dark:text-amber-400"
|
|
|
|
|
: "text-xl leading-[1.5] text-muted-foreground"
|
2026-10-08 14:43:34 +00:00
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
{item.count}
|
|
|
|
|
</strong>
|
2026-10-08 16:31:46 +00:00
|
|
|
<span className="flex-1">{t(`dashboard.issues.${item.kind}`)}</span>
|
2026-10-08 14:43:34 +00:00
|
|
|
<ChevronRightIcon aria-hidden="true" className="size-4 shrink-0" />
|
|
|
|
|
</button>
|
|
|
|
|
</li>
|
|
|
|
|
);
|
|
|
|
|
})}
|
|
|
|
|
</ul>
|
|
|
|
|
</BlockState>
|
|
|
|
|
</DashboardPanel>
|
|
|
|
|
);
|
|
|
|
|
}
|