Files
Checkmate/client/src/Pages/StatusPage/StatusPages/Components/StatusPagesTable.tsx
T
2026-02-03 21:40:17 +00:00

181 lines
4.5 KiB
TypeScript

import Box from "@mui/material/Box";
import Stack from "@mui/material/Stack";
import Typography from "@mui/material/Typography";
import { Table, type Header, ValueLabel } from "@/Components/v2/design-elements";
import { ActionsMenu, type ActionMenuItem } from "@/Components/v2/actions-menu";
import { Dialog } from "@/Components/v2/inputs";
import { ExternalLink } from "lucide-react";
import { useTranslation } from "react-i18next";
import { useTheme } from "@mui/material/styles";
import { useNavigate } from "react-router-dom";
import { useDelete } from "@/Hooks/UseApi";
import { useState } from "react";
import { createToast } from "@/Utils/toastUtils";
import type { StatusPage } from "@/Types/StatusPage";
interface StatusPagesTableProps {
data: StatusPage[];
refetch: () => void;
}
export const StatusPagesTable = ({ data, refetch }: StatusPagesTableProps) => {
const { t } = useTranslation();
const theme = useTheme();
const navigate = useNavigate();
const { deleteFn, loading: isDeleting } = useDelete();
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false);
const [selectedStatusPage, setSelectedStatusPage] = useState<StatusPage | null>(null);
const handleDeleteClick = (statusPage: StatusPage) => {
setSelectedStatusPage(statusPage);
setIsDeleteDialogOpen(true);
};
const handleDeleteConfirm = async () => {
if (!selectedStatusPage) return;
const result = await deleteFn(`/status-page/${selectedStatusPage.id}`);
if (result) {
createToast({ body: t("pages.statusPages.deleteSuccess") });
refetch();
}
setIsDeleteDialogOpen(false);
setSelectedStatusPage(null);
};
const handleDeleteCancel = () => {
setIsDeleteDialogOpen(false);
setSelectedStatusPage(null);
};
const getActions = (row: StatusPage): ActionMenuItem[] => {
return [
{
id: 1,
label: t("common.buttons.configure"),
action: () => {
navigate(`/status/configure/${row.url}`);
},
closeMenu: true,
},
{
id: 2,
label: (
<Typography color={theme.palette.error.main}>
{t("common.buttons.delete")}
</Typography>
),
action: () => {
handleDeleteClick(row);
},
closeMenu: true,
},
];
};
const handleUrlClick = (e: React.MouseEvent, row: StatusPage) => {
if (row.isPublished) {
e.stopPropagation();
const url = `/status/public/${row.url}`;
window.open(url, "_blank", "noopener,noreferrer");
}
};
const getHeaders = (): Header<StatusPage>[] => {
return [
{
id: "name",
content: t("pages.statusPages.table.headers.name"),
render: (row) => row.companyName,
},
{
id: "url",
content: t("pages.statusPages.table.headers.url"),
render: (row) => {
const content = row.isPublished
? `/${row.url}`
: t("pages.statusPages.table.unpublished");
return (
<Stack
direction="row"
alignItems="center"
justifyContent="center"
gap={theme.spacing(2)}
paddingLeft={theme.spacing(2)}
paddingRight={theme.spacing(2)}
onClick={(e) => handleUrlClick(e, row)}
sx={{
...(row.isPublished && {
display: "inline-flex",
":hover": {
cursor: "pointer",
borderBottom: 1,
},
}),
}}
>
<Typography>{content}</Typography>
{row.isPublished && <ExternalLink size={18} />}
</Stack>
);
},
},
{
id: "type",
content: t("common.table.headers.type"),
render: (row) => row.type,
},
{
id: "status",
content: t("common.table.headers.status"),
render: (row) => {
return (
<ValueLabel
value={row.isPublished ? "positive" : "neutral"}
text={
row.isPublished
? t("pages.statusPages.table.published")
: t("pages.statusPages.table.unpublished")
}
/>
);
},
},
{
id: "actions",
content: t("common.table.headers.actions"),
render: (row) => {
return <ActionsMenu items={getActions(row)} />;
},
},
];
};
const handleRowClick = (statusPage: StatusPage) => {
navigate(`/status/${statusPage.url}`);
};
return (
<Box>
<Table
headers={getHeaders()}
data={data}
onRowClick={handleRowClick}
emptyViewText={t("common.table.empty")}
/>
<Dialog
open={isDeleteDialogOpen}
title={t("common.dialogs.delete.title")}
content={t("common.dialogs.delete.description")}
onConfirm={handleDeleteConfirm}
onCancel={handleDeleteCancel}
loading={isDeleting}
/>
</Box>
);
};
export default StatusPagesTable;