import { useState } from "react"; import { useNavigate } from "react-router-dom"; import { useTranslation } from "react-i18next"; import { useRequest } from "ahooks"; import { Card, Col, Divider, notification, Row, Space, Statistic, theme, Typography } from "antd"; import { PageHeader } from "@ant-design/pro-components"; import { CalendarClock as CalendarClockIcon, CalendarX2 as CalendarX2Icon, FolderCheck as FolderCheckIcon, SquareSigma as SquareSigmaIcon, Workflow as WorkflowIcon, } from "lucide-react"; import { ClientResponseError } from "pocketbase"; import { type Statistics } from "@/domain/statistics"; import { get as getStatistics } from "@/api/statistics"; import { getErrMsg } from "@/utils/error"; const Dashboard = () => { const navigate = useNavigate(); const { t } = useTranslation(); const { token: themeToken } = theme.useToken(); const [notificationApi, NotificationContextHolder] = notification.useNotification(); const statisticsGridSpans = { xs: { flex: "50%" }, md: { flex: "50%" }, lg: { flex: "33.3333%" }, xl: { flex: "33.3333%" }, xxl: { flex: "20%" }, }; const [statistics, setStatistics] = useState(); const { loading } = useRequest( () => { return getStatistics(); }, { onSuccess: (data) => { setStatistics(data); }, onError: (err) => { if (err instanceof ClientResponseError && err.isAbort) { return; } console.error(err); notificationApi.error({ message: t("common.text.request_error"), description: <>{getErrMsg(err)} }); }, } ); return ( <> {NotificationContextHolder} } label={t("dashboard.statistics.all_certificates")} loading={loading} value={statistics?.certificateTotal ?? "-"} suffix={t("dashboard.statistics.unit")} onClick={() => navigate("/certificates")} /> } label={t("dashboard.statistics.expire_soon_certificates")} loading={loading} value={statistics?.certificateExpireSoon ?? "-"} suffix={t("dashboard.statistics.unit")} onClick={() => navigate("/certificates?state=expireSoon")} /> } label={t("dashboard.statistics.expired_certificates")} loading={loading} value={statistics?.certificateExpired ?? "-"} suffix={t("dashboard.statistics.unit")} onClick={() => navigate("/certificates?state=expired")} /> } label={t("dashboard.statistics.all_workflows")} loading={loading} value={statistics?.workflowTotal ?? "-"} suffix={t("dashboard.statistics.unit")} onClick={() => navigate("/workflows")} /> } label={t("dashboard.statistics.enabled_workflows")} loading={loading} value={statistics?.workflowEnabled ?? "-"} suffix={t("dashboard.statistics.unit")} onClick={() => navigate("/workflows?state=enabled")} />
TODO: {t("dashboard.latest_workflow_run")}
); }; const StatisticCard = ({ label, loading, icon, value, suffix, onClick, }: { label: React.ReactNode; loading?: boolean; icon: React.ReactNode; value?: string | number | React.ReactNode; suffix?: React.ReactNode; onClick?: () => void; }) => { return ( {icon} { return {value}; }} suffix={{suffix}} /> ); }; export default Dashboard;