new status pages

This commit is contained in:
Alex Holliday committed 2026-02-02 19:20:59 +00:00
1 parent 57c3bf3240
commit 853e21623e
6 files changed
+230 -2

No files matched your search

@@ -0,0 +1,109 @@
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 { ExternalLink } from "lucide-react";
import { useTranslation } from "react-i18next";
import { useTheme } from "@mui/material/styles";
import { useNavigate } from "react-router-dom";
import type { StatusPage } from "@/Types/StatusPage";
interface StatusPagesTableProps {
data: StatusPage[];
}
export const StatusPagesTable = ({ data }: StatusPagesTableProps) => {
const { t } = useTranslation();
const theme = useTheme();
const navigate = useNavigate();
const handleUrlClick = (e: React.MouseEvent, row: StatusPage) => {
if (row.isPublished) {
e.stopPropagation();
const url = `/status/uptime/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")
}
/>
);
},
},
];
};
const handleRowClick = (statusPage: StatusPage) => {
navigate(`/status/uptime/${statusPage.url}`);
};
return (
<Box>
<Table
headers={getHeaders()}
data={data}
onRowClick={handleRowClick}
emptyViewText={t("common.table.empty")}
/>
</Box>
);
};
export default StatusPagesTable;
@@ -0,0 +1,33 @@
import { BasePageWithStates } from "@/Components/v2/design-elements";
import { StatusPagesTable } from "./Components/StatusPagesTable";
import { useGet } from "@/Hooks/UseApi";
import type { StatusPage } from "@/Types/StatusPage";
import { useTranslation } from "react-i18next";
const StatusPages = () => {
const { t } = useTranslation();
const {
data: statusPages,
isLoading,
error,
} = useGet<StatusPage[]>("/status-page/team");
return (
<BasePageWithStates
page={t("pages.statusPages.title")}
loading={isLoading}
bullets={
t("pages.statusPages.fallback.checks", { returnObjects: true }) as string[]
}
error={!!error}
items={statusPages ?? []}
actionButtonText={t("pages.statusPages.fallback.actionButton")}
actionLink="/status/uptime/create"
>
<StatusPagesTable data={statusPages ?? []} />
</BasePageWithStates>
);
};
export default StatusPages;
+8 -2
View File
@@ -37,7 +37,7 @@ import Incidents from "../Pages/Incidents/";
// Status pages
import CreateStatus from "../Pages/StatusPage/Create/index.jsx";
import StatusPages from "../Pages/StatusPage/StatusPages/index.jsx";
import StatusPages from "../Pages/StatusPage/StatusPages";
import Status from "../Pages/StatusPage/Status/index.jsx";
import Notifications from "../Pages/Notifications";
@@ -227,7 +227,13 @@ const Routes = () => {
<Route
path="status"
element={<StatusPages />}
element={
<>
<ThemeProvider theme={v2theme}>
<StatusPages />
</ThemeProvider>
</>
}
/>
<Route
+24
View File
@@ -0,0 +1,24 @@
export interface StatusPage {
id: string;
userId: string;
teamId: string;
type: string;
companyName: string;
url: string;
timezone?: string;
color: string;
monitors: string[];
subMonitors: string[];
originalMonitors?: string[];
logo?: {
data: string;
contentType: string;
} | null;
isPublished: boolean;
showCharts: boolean;
showUptimePercentage: boolean;
showAdminLoginLink: boolean;
customCSS: string;
createdAt: string;
updatedAt: string;
}
+56
View File
@@ -201,6 +201,10 @@
},
"uptime": {
"table": {
"headers": {
"name": "Status page name",
"url": "Public URL"
},
"headers": {
"responseTime": "Response time"
}
@@ -213,6 +217,10 @@
},
"checks": {
"table": {
"headers": {
"name": "Status page name",
"url": "Public URL"
},
"headers": {
"dateTime": "Date & time",
"statusCode": "Status code"
@@ -241,6 +249,10 @@
"actionButton": "Let's create your first PageSpeed monitor!"
},
"table": {
"headers": {
"name": "Status page name",
"url": "Public URL"
},
"headers": {
"pageSpeedScore": "PageSpeed score"
}
@@ -273,6 +285,10 @@
"actionButton": "Let's create your first infrastructure monitor!"
},
"table": {
"headers": {
"name": "Status page name",
"url": "Public URL"
},
"headers": {
"cpu": "CPU",
"disk": "Disk",
@@ -333,6 +349,10 @@
"title": "Notification channles are used to:"
},
"table": {
"headers": {
"name": "Status page name",
"url": "Public URL"
},
"headers": {
"destination": "Destination"
}
@@ -397,6 +417,10 @@
},
"table": {
"headers": {
"name": "Status page name",
"url": "Public URL"
},
"activeIncidents": "Active Incidents",
"resolvedIncidents": "Resolved Incidents",
"headers": {
@@ -452,6 +476,26 @@
}
}
}
},
"statusPages": {
"title": "Status Pages",
"table": {
"headers": {
"name": "Status page name",
"url": "Public URL"
},
"published": "Published",
"unpublished": "Unpublished"
},
"fallback": {
"actionButton": "Create a status page!",
"checks": [
"Monitor and display the health of your services in real time",
"Track multiple services and share their status",
"Keep users informed about outages and performance"
],
"title": "A status page is used to:"
}
}
},
"used": "Used",
@@ -589,6 +633,10 @@
"getToken": "Get token",
"emailToken": "E-mail token",
"table": {
"headers": {
"name": "Status page name",
"url": "Public URL"
},
"name": "Name",
"email": "Email",
"role": "Role",
@@ -793,6 +841,10 @@
}
},
"table": {
"headers": {
"name": "Status page name",
"url": "Public URL"
},
"timestamp": "Timestamp",
"level": "Level",
"service": "Service",
@@ -973,6 +1025,10 @@
"save": "Save"
},
"table": {
"headers": {
"name": "Status page name",
"url": "Public URL"
},
"actionHeader": "Action",
"roleHeader": "Role"
},