diff --git a/client/src/Components/design-elements/BasePage.tsx b/client/src/Components/design-elements/BasePage.tsx
index 845d20a4c..c955fb6b7 100644
--- a/client/src/Components/design-elements/BasePage.tsx
+++ b/client/src/Components/design-elements/BasePage.tsx
@@ -38,9 +38,9 @@ export const PageSpeedKeyPriorityFallback = () => {
diff --git a/client/src/Components/design-elements/MonitorStatus.tsx b/client/src/Components/design-elements/MonitorStatus.tsx
index dbeb5fa84..14f33d934 100644
--- a/client/src/Components/design-elements/MonitorStatus.tsx
+++ b/client/src/Components/design-elements/MonitorStatus.tsx
@@ -17,7 +17,7 @@ export const MonitorStatus = ({ monitor }: { monitor: Monitor }) => {
return (
= {
info: "ⓘ",
@@ -25,29 +27,26 @@ export const NoticeBanner = ({ severity = "info", children }: NoticeBannerProps)
direction="row"
alignItems="flex-start"
gap={theme.spacing(LAYOUT.SM)}
- sx={{
- width: "100%",
- p: theme.spacing(LAYOUT.MD),
- borderRadius: 1,
- border: `1px solid ${alpha(tone, 0.45)}`,
- backgroundColor: alpha(tone, 0.08),
- textAlign: "left",
- }}
+ width={"100%"}
+ p={theme.spacing(LAYOUT.MD)}
+ borderRadius={theme.shape.borderRadius}
+ border={`1px solid ${alpha(tone, 0.45)}`}
+ bgcolor={alpha(tone, 0.08)}
+ textAlign={"left"}
>
{SEVERITY_GLYPH[severity]}
{children}
diff --git a/client/src/Components/inputs/Button.tsx b/client/src/Components/inputs/Button.tsx
index 54f776075..4eae654b2 100644
--- a/client/src/Components/inputs/Button.tsx
+++ b/client/src/Components/inputs/Button.tsx
@@ -1,19 +1,43 @@
import Button from "@mui/material/Button";
import type { ButtonProps } from "@mui/material/Button";
-import { useTheme } from "@mui/material/styles";
+import { useTheme, darken } from "@mui/material/styles";
+import { HOVER } from "@/Utils/Theme/constants";
+
+const PALETTE_COLORS = [
+ "primary",
+ "secondary",
+ "error",
+ "warning",
+ "info",
+ "success",
+] as const;
+type PaletteColor = (typeof PALETTE_COLORS)[number];
export const ButtonInput = ({ sx, ...props }: ButtonProps) => {
const theme = useTheme();
- const outlinedSx =
+
+ const hoverOverrides: Record = { boxShadow: "none" };
+
+ if (props.variant === "outlined") {
+ hoverOverrides.borderColor = theme.palette.text.secondary;
+ }
+
+ if (props.variant === "contained") {
+ const colorKey = (props.color ?? "primary") as PaletteColor;
+ const palette = theme.palette[colorKey];
+ if (palette && typeof palette === "object" && "main" in palette) {
+ hoverOverrides.backgroundColor = darken(palette.main, HOVER.DARKEN);
+ }
+ }
+
+ const variantSx =
props.variant === "outlined"
? {
color: theme.palette.text.primary,
borderColor: theme.palette.divider,
- "&:hover": {
- borderColor: theme.palette.text.secondary,
- },
}
: {};
+
return (
}
>
-
+
{
+ const theme = useTheme();
+
+ return (
+
+ {children}
+
+ );
+};
+
+const Cell = ({ children }: { children: React.ReactNode }) => (
+ {children}
+);
+
export const CardDetails = ({ incident, monitor, sx }: CardDetailsProps) => {
const { t } = useTranslation();
const theme = useTheme();
@@ -33,22 +52,18 @@ export const CardDetails = ({ incident, monitor, sx }: CardDetailsProps) => {
gap={theme.spacing(LAYOUT.MD)}
sx={sx}
>
-
- {t("pages.incidents.dialog.details.title")}
-
+ {t("pages.incidents.dialog.details.title")}
-
- {t("pages.incidents.dialog.details.overview")}
-
-
-
+ {t("pages.incidents.dialog.details.overview")}
- {t("pages.incidents.dialog.details.status")}
+
+ | {t("pages.incidents.dialog.details.status")} |
+
{
{monitor && (
<>
- {t("pages.incidents.dialog.details.monitor")}
+
+ {t("pages.incidents.dialog.details.monitor")} |
+
- {monitor.name ?? "N/A"}
+ {monitor.name ?? "N/A"} |
- {t("pages.incidents.dialog.details.url")}
+ {t("pages.incidents.dialog.details.url")} |
- {monitor.url ?? "N/A"}
+ {monitor.url ?? "N/A"} |
>
)}
@@ -78,51 +95,48 @@ export const CardDetails = ({ incident, monitor, sx }: CardDetailsProps) => {
-
- {t("pages.incidents.dialog.details.analysis")}
-
-
+ {t("pages.incidents.dialog.details.analysis")}
- {t("pages.incidents.dialog.details.timeline")}
+ {t("pages.incidents.dialog.details.timeline")} |
- {t("pages.incidents.dialog.details.detailsLabel")}
+ {t("pages.incidents.dialog.details.detailsLabel")} |
-
+
-
+
- {t("pages.incidents.dialog.details.startedAt")}
+ {t("pages.incidents.dialog.details.startedAt")} |
-
+
{formatDateWithTz(incident.startTime, "D MMM YYYY, h:mm A", uiTimezone)}
- |
+
- {t("pages.incidents.dialog.details.statusCode")}
+ {t("pages.incidents.dialog.details.statusCode")} |
- {incident.statusCode ?? "N/A"}
+ {incident.statusCode ?? "N/A"} |
- {t("pages.incidents.dialog.details.downtime")}
+ {t("pages.incidents.dialog.details.downtime")} |
- {getIncidentsDuration(incident)}
+ {getIncidentsDuration(incident)} |
- {t("pages.incidents.dialog.details.message")}
+ {t("pages.incidents.dialog.details.message")} |
- {incident.message ?? "N/A"}
+ {incident.message ?? "N/A"} |
@@ -130,60 +144,53 @@ export const CardDetails = ({ incident, monitor, sx }: CardDetailsProps) => {
{!incident.status && (
-
+
{t("pages.incidents.dialog.details.resolutionDetails")}
-
-
+
- {t("pages.incidents.dialog.details.resolvedAt")}
+ {t("pages.incidents.dialog.details.resolvedAt")} |
-
+
{incident.endTime
? formatDateWithTz(incident.endTime, "D MMM YYYY, h:mm A", uiTimezone)
: "N/A"}
- |
+
-
- {t("pages.incidents.dialog.details.resolutionType")}
-
+ {t("pages.incidents.dialog.details.resolutionType")} |
-
+
{incident.resolutionType
? t(
`pages.incidents.dialog.details.resolutionTypes.${incident.resolutionType}`
)
: "N/A"}
- |
+
{incident.resolvedBy && (
<>
-
- {t("pages.incidents.dialog.details.resolvedBy")}
-
+ {t("pages.incidents.dialog.details.resolvedBy")} |
-
- {incident.resolvedByEmail ?? incident.resolvedBy}
-
+ {incident.resolvedByEmail ?? incident.resolvedBy} |
>
)}
{incident.comment && (
<>
- {t("pages.incidents.dialog.details.comment")}
+ {t("pages.incidents.dialog.details.comment")} |
- {incident.comment}
+ {incident.comment} |
>
)}
diff --git a/client/src/Pages/Incidents/Components/CardSummary.tsx b/client/src/Pages/Incidents/Components/CardSummary.tsx
index 938455808..60dadaa74 100644
--- a/client/src/Pages/Incidents/Components/CardSummary.tsx
+++ b/client/src/Pages/Incidents/Components/CardSummary.tsx
@@ -1,8 +1,7 @@
import Stack from "@mui/material/Stack";
import Typography from "@mui/material/Typography";
-import Divider from "@mui/material/Divider";
import Grid from "@mui/material/Grid";
-import { BaseBox, ValueLabel } from "@/Components/design-elements";
+import { BaseBox, Icon, ValueLabel } from "@/Components/design-elements";
import { CircleCheck, TriangleAlert, Bell, Wrench, Globe } from "lucide-react";
import Box from "@mui/material/Box";
@@ -25,6 +24,7 @@ const SummaryItem = ({ icon, label, value }: SummaryItemProps) => {
alignItems="center"
justifyContent="space-between"
gap={theme.spacing(2)}
+ minHeight={32}
>
{
gap={theme.spacing(2)}
>
{icon}
- {label}
+ {label}
{value}
@@ -67,15 +67,11 @@ export const SummaryCard = ({
>
{title}
-
{children}
@@ -97,10 +93,13 @@ export const SummaryCardActiveIncidents = ({
const activeCount = summary.totalActive;
const hasActive = activeCount > 0;
const color = hasActive ? theme.palette.error.main : theme.palette.success.main;
- const icon = hasActive ? (
-
- ) : (
-
+ const icon = (
+
+
+
);
const msg = t("pages.incidents.summaryCard.activeIncidents.active", {
count: activeCount,
@@ -133,10 +132,7 @@ const SummaryIncidentItem = ({ incident }: { incident: IncidentSummaryItem }) =>
container
alignItems="center"
spacing={2}
- sx={{
- width: "100%",
- py: theme.spacing(0.5),
- }}
+ sx={{ width: "100%", minHeight: 32 }}
>
gap: theme.spacing(2),
}}
>
-
+
size={{ xs: 12, md: 6, lg: 4 }}
sx={{
textAlign: { xs: "left", md: "right" },
- fontWeight: 500,
+ fontWeight: 600,
}}
>
{duration}
@@ -190,22 +184,17 @@ export const SummaryCardLatestIncidents = ({
summary,
}: SummaryCardLatestIncidentsProps) => {
const { t } = useTranslation();
- const theme = useTheme();
const latestIncidents = summary?.latestIncidents ?? [];
return (
-
- {latestIncidents.slice(0, 3).map((incident, index) => (
-
-
- {index < latestIncidents.length - 1 && (
-
- )}
-
- ))}
-
+ {latestIncidents.slice(0, 3).map((incident) => (
+
+ ))}
);
};
@@ -224,17 +213,17 @@ export const SummaryCardStats = ({ summary }: SummaryCardStatsProps) => {
return (
}
+ icon={}
label={t("pages.incidents.summaryCard.incidentStats.totalIncidents")}
value={summary?.total || 0}
/>
}
+ icon={}
label={t("pages.incidents.summaryCard.incidentStats.mostAffectedMonitor")}
value={mostAffected}
/>
}
+ icon={}
label={t("pages.incidents.summaryCard.incidentStats.avgResolutionTime")}
value={
summary.total > 0
diff --git a/client/src/Pages/Incidents/Components/ControlsIncidentFilter.tsx b/client/src/Pages/Incidents/Components/ControlsIncidentFilter.tsx
index a0f4eb15a..af7cba105 100644
--- a/client/src/Pages/Incidents/Components/ControlsIncidentFilter.tsx
+++ b/client/src/Pages/Incidents/Components/ControlsIncidentFilter.tsx
@@ -75,7 +75,7 @@ export const ControlsIncidentFilter = ({
variant="contained"
onClick={onClearFilters}
>
- {t("pages.incidents.filters.clearFilters")}
+ {t("common.buttons.clearFilters")}
)}
diff --git a/client/src/Pages/Incidents/index.tsx b/client/src/Pages/Incidents/index.tsx
index 84c414b26..63cd18889 100644
--- a/client/src/Pages/Incidents/index.tsx
+++ b/client/src/Pages/Incidents/index.tsx
@@ -15,6 +15,7 @@ import { HeaderTimeRange } from "@/Components/common";
import { ControlsIncidentFilter } from "@/Pages/Incidents/Components/ControlsIncidentFilter";
import { useGet } from "@/Hooks/UseApi";
+import { LAYOUT } from "@/Utils/Theme/constants";
import { useState, useEffect, useMemo } from "react";
import { useParams } from "react-router-dom";
import type { Incident, IncidentsResponse, IncidentSummary } from "@/Types/Incident";
@@ -186,8 +187,9 @@ const IncidentsPage = () => {
{activeIncidentsCount > 0 && (
<>
{t("pages.incidents.table.activeIncidents")}
@@ -208,8 +210,9 @@ const IncidentsPage = () => {
)}
{t("pages.incidents.table.resolvedIncidents")}
diff --git a/client/src/Utils/Theme/Palette.ts b/client/src/Utils/Theme/Palette.ts
index 0fe08583a..92c08cd2f 100644
--- a/client/src/Utils/Theme/Palette.ts
+++ b/client/src/Utils/Theme/Palette.ts
@@ -1,12 +1,13 @@
const typographyBase = 13;
export const typographyLevels = {
- base: typographyBase,
- xs: `${(typographyBase - 4) / 16}rem`,
- s: `${(typographyBase - 2) / 16}rem`,
- m: `${typographyBase / 16}rem`,
- l: `${(typographyBase + 2) / 16}rem`,
- xl: `${(typographyBase + 10) / 16}rem`,
+ base: typographyBase, // 13px
+ xs: `${(typographyBase - 4) / 16}rem`, // 9px
+ s: `${(typographyBase - 2) / 16}rem`, // 11px
+ m: `${typographyBase / 16}rem`, // 13px
+ l: `${(typographyBase + 2) / 16}rem`, // 15px
+ xl: `${(typographyBase + 5) / 16}rem`, // 18px
+ xxl: `${(typographyBase + 10) / 16}rem`, // 23px
};
export const colors = {
diff --git a/client/src/Utils/Theme/Theme.ts b/client/src/Utils/Theme/Theme.ts
index 19f864c6f..7c712d66d 100644
--- a/client/src/Utils/Theme/Theme.ts
+++ b/client/src/Utils/Theme/Theme.ts
@@ -58,7 +58,7 @@ export const theme = (mode: string, palette: any) =>
fontFamilyMonospace,
fontSize: typographyLevels.base,
h1: {
- fontSize: typographyLevels.xl,
+ fontSize: typographyLevels.xxl,
fontWeight: 500,
},
h2: {
diff --git a/client/src/Utils/Theme/constants.ts b/client/src/Utils/Theme/constants.ts
index 8b045f9f6..d718d61dc 100644
--- a/client/src/Utils/Theme/constants.ts
+++ b/client/src/Utils/Theme/constants.ts
@@ -8,6 +8,7 @@ export const SPACING = {
} as const;
export const LAYOUT = {
+ XXS: 2,
XS: 4,
SM: 6,
MD: 8,
@@ -15,3 +16,7 @@ export const LAYOUT = {
XL: 12,
XXL: 16,
} as const;
+
+export const HOVER = {
+ DARKEN: 0.06, // This is a coefficient for darkening function
+} as const;