feat(client): group sidebar navigation into four labelled sections

The sidebar listed twelve items in a flat column ordered roughly by when each
feature was added, so nothing signalled that Uptime, Pagespeed and
Infrastructure are the same kind of thing, or that Tags and Proxies are
configuration rather than views. Adding a new monitor type made this worse:
the natural place for a new entry is the end of the list, three rows below the
item it most resembles.

Groups the menu into Monitoring, Alerting, Reporting and Configuration.
`getMenu` now returns groups of items rather than a flat array; the sidebar
renders an eyebrow label per group.

When collapsed to 64px there is no room for a label, so the labels are
replaced by dividers between groups — the grouping survives as rhythm.

Settings moves from the middle of the list to the end of Configuration.

Adds four `components.sidebar.menu.groups.*` keys across all 19 locales.

Also corrects the i18n note in CLAUDE.md, which claimed translations are
managed through PoEditor.

Claude-Session: https://claude.ai/code/session_01AbYLvwpEaZFXktHVcqrFRd
This commit is contained in:
gorkem-bwl committed 2026-08-28 19:25:38 -04:00
1 parent 80073af80a
commit ebbf1a8b1e
22 files changed
+248 -83

No files matched your search

+1 -1
View File
@@ -109,7 +109,7 @@ client/src/
- **Data Fetching**: SWR + Axios
- **Database**: MongoDB with Mongoose ODM
- **Queue/Cache**: Redis + BullMQ + Pulse (cron scheduling)
- **i18n**: i18next + react-i18next (translations via PoEditor)
- **i18n**: i18next + react-i18next (non-English locales are machine translated, not managed through a translation service)
---
+72 -52
View File
@@ -23,64 +23,84 @@ import {
export const getMenu = (t: Function) => {
return [
{
name: t("components.sidebar.menu.uptime"),
path: "uptime",
icon: <Icon icon={Globe} />,
group: t("components.sidebar.menu.groups.monitoring"),
items: [
{
name: t("components.sidebar.menu.uptime"),
path: "uptime",
icon: <Icon icon={Globe} />,
},
{
name: t("components.sidebar.menu.pagespeed"),
path: "pagespeed",
icon: <Icon icon={Gauge} />,
},
{
name: t("components.sidebar.menu.infrastructure"),
path: "infrastructure",
icon: <Icon icon={Link} />,
},
],
},
{
name: t("components.sidebar.menu.pagespeed"),
path: "pagespeed",
icon: <Icon icon={Gauge} />,
group: t("components.sidebar.menu.groups.alerting"),
items: [
{
name: t("components.sidebar.menu.incidents"),
path: "incidents",
icon: <Icon icon={AlertTriangle} />,
},
{
name: t("components.sidebar.menu.notifications"),
path: "notifications",
icon: <Icon icon={Bell} />,
},
{
name: t("components.sidebar.menu.maintenance"),
path: "maintenance",
icon: <Icon icon={Wrench} />,
},
],
},
{
name: t("components.sidebar.menu.infrastructure"),
path: "infrastructure",
icon: <Icon icon={Link} />,
group: t("components.sidebar.menu.groups.reporting"),
items: [
{
name: t("components.sidebar.menu.statusPages"),
path: "status",
icon: <Icon icon={Wifi} />,
},
{
name: t("components.sidebar.menu.checks"),
path: "checks",
icon: <Icon icon={FileText} />,
},
{
name: t("components.sidebar.menu.logs"),
path: "logs",
icon: <Icon icon={ScrollText} />,
},
],
},
{
name: t("components.sidebar.menu.notifications"),
path: "notifications",
icon: <Icon icon={Bell} />,
},
{
name: t("components.sidebar.menu.tags"),
path: "tags",
icon: <Icon icon={Tag} />,
},
{
name: t("components.sidebar.menu.proxies"),
path: "proxies",
icon: <Icon icon={Waypoints} />,
},
{
name: t("components.sidebar.menu.checks"),
path: "checks",
icon: <Icon icon={FileText} />,
},
{
name: t("components.sidebar.menu.incidents"),
path: "incidents",
icon: <Icon icon={AlertTriangle} />,
},
{
name: t("components.sidebar.menu.statusPages"),
path: "status",
icon: <Icon icon={Wifi} />,
},
{
name: t("components.sidebar.menu.maintenance"),
path: "maintenance",
icon: <Icon icon={Wrench} />,
},
{
name: t("components.sidebar.menu.logs"),
path: "logs",
icon: <Icon icon={ScrollText} />,
},
{
name: t("components.sidebar.menu.settings"),
icon: <Icon icon={Settings} />,
path: "settings",
group: t("components.sidebar.menu.groups.configuration"),
items: [
{
name: t("components.sidebar.menu.tags"),
path: "tags",
icon: <Icon icon={Tag} />,
},
{
name: t("components.sidebar.menu.proxies"),
path: "proxies",
icon: <Icon icon={Waypoints} />,
},
{
name: t("components.sidebar.menu.settings"),
path: "settings",
icon: <Icon icon={Settings} />,
},
],
},
];
};
+42 -11
View File
@@ -1,6 +1,8 @@
import { useEffect } from "react";
import Backdrop from "@mui/material/Backdrop";
import Stack from "@mui/material/Stack";
import Box from "@mui/material/Box";
import Typography from "@mui/material/Typography";
import List from "@mui/material/List";
import Divider from "@mui/material/Divider";
import { LAYOUT } from "@/Utils/Theme/constants";
@@ -89,17 +91,46 @@ export const Sidebar = () => {
pt={theme.spacing(LAYOUT.MD)}
pb={theme.spacing(LAYOUT.MD)}
/>
{menu.map((item) => {
const selected = location.pathname.startsWith(`/${item.path}`);
return (
<NavItem
key={item.path}
item={item}
selected={selected}
onClick={() => handleNavClick(item.path)}
/>
);
})}
{menu.map((group, groupIndex) => (
<Box
component="li"
key={group.group}
sx={{ listStyle: "none" }}
>
{collapsed ? (
groupIndex > 0 && (
<Divider
sx={{
borderColor: theme.palette.divider,
marginY: theme.spacing(LAYOUT.XS),
}}
/>
)
) : (
<Typography
variant="eyebrow"
component="div"
color={theme.palette.text.disabled}
paddingLeft={theme.spacing(LAYOUT.LG)}
paddingTop={theme.spacing(LAYOUT.XS)}
paddingBottom={theme.spacing(LAYOUT.XXS)}
>
{group.group}
</Typography>
)}
{group.items.map((item) => {
const selected = location.pathname.startsWith(`/${item.path}`);
return (
<NavItem
key={item.path}
item={item}
selected={selected}
onClick={() => handleNavClick(item.path)}
/>
);
})}
</Box>
))}
</List>
<StarPrompt />
+7 -1
View File
@@ -181,7 +181,13 @@
"statusPages": "صفحات الحالة",
"maintenance": "الصيانة",
"logs": "السجلات",
"settings": "الإعدادات"
"settings": "الإعدادات",
"groups": {
"monitoring": "المراقبة",
"alerting": "التنبيهات",
"reporting": "التقارير",
"configuration": "الإعدادات العامة"
}
},
"bottomMenu": {
"support": "الدعم",
+7 -1
View File
@@ -189,7 +189,13 @@
"statusPages": "Pàgines d'estat",
"maintenance": "Manteniment",
"logs": "Registres",
"settings": "Configuració"
"settings": "Configuració",
"groups": {
"monitoring": "Monitoratge",
"alerting": "Alertes",
"reporting": "Informes",
"configuration": "Configuració"
}
},
"bottomMenu": {
"support": "Suport",
+7 -1
View File
@@ -181,7 +181,13 @@
"statusPages": "Stavové stránky",
"maintenance": "Údržba",
"logs": "Záznamy",
"settings": "Nastavení"
"settings": "Nastavení",
"groups": {
"monitoring": "Monitorování",
"alerting": "Upozornění",
"reporting": "Přehledy",
"configuration": "Konfigurace"
}
},
"bottomMenu": {
"support": "Podpora",
+7 -1
View File
@@ -181,7 +181,13 @@
"statusPages": "Statusseite",
"maintenance": "Wartung",
"logs": "Protokolle",
"settings": "Einstellungen"
"settings": "Einstellungen",
"groups": {
"monitoring": "Überwachung",
"alerting": "Benachrichtigungen",
"reporting": "Berichte",
"configuration": "Konfiguration"
}
},
"bottomMenu": {
"support": "Support",
+7 -1
View File
@@ -211,7 +211,13 @@
"statusPages": "Status pages",
"maintenance": "Maintenance",
"logs": "Logs",
"settings": "Settings"
"settings": "Settings",
"groups": {
"monitoring": "Monitoring",
"alerting": "Alerting",
"reporting": "Reporting",
"configuration": "Configuration"
}
},
"bottomMenu": {
"support": "Support",
+7 -1
View File
@@ -181,7 +181,13 @@
"statusPages": "Páginas de estado",
"maintenance": "Mantenimiento",
"logs": "Registros",
"settings": "Configuración"
"settings": "Configuración",
"groups": {
"monitoring": "Monitorización",
"alerting": "Alertas",
"reporting": "Informes",
"configuration": "Configuración"
}
},
"bottomMenu": {
"support": "Soporte",
+7 -1
View File
@@ -181,7 +181,13 @@
"statusPages": "Tilasivut",
"maintenance": "Huolto",
"logs": "Lokit",
"settings": "Asetukset"
"settings": "Asetukset",
"groups": {
"monitoring": "Valvonta",
"alerting": "Hälytykset",
"reporting": "Raportointi",
"configuration": "Määritykset"
}
},
"bottomMenu": {
"support": "Tuki",
+7 -1
View File
@@ -181,7 +181,13 @@
"statusPages": "Pages de statut",
"maintenance": "Maintenance",
"logs": "Journaux",
"settings": "Paramètres"
"settings": "Paramètres",
"groups": {
"monitoring": "Surveillance",
"alerting": "Alertes",
"reporting": "Rapports",
"configuration": "Configuration"
}
},
"bottomMenu": {
"support": "Support",
+7 -1
View File
@@ -193,7 +193,13 @@
"statusPages": "Pagine di stato",
"maintenance": "Manutenzione",
"logs": "Log",
"settings": "Impostazioni"
"settings": "Impostazioni",
"groups": {
"monitoring": "Monitoraggio",
"alerting": "Avvisi",
"reporting": "Report",
"configuration": "Configurazione"
}
},
"bottomMenu": {
"support": "Supporto",
+7 -1
View File
@@ -181,7 +181,13 @@
"statusPages": "ステータスページ",
"maintenance": "メンテナンス",
"logs": "ログ",
"settings": "設定"
"settings": "設定",
"groups": {
"monitoring": "監視",
"alerting": "アラート",
"reporting": "レポート",
"configuration": "設定"
}
},
"bottomMenu": {
"support": "サポート",
+7 -1
View File
@@ -214,7 +214,13 @@
"settings": "Ustawienia",
"statusPages": "Strony statusu",
"tags": "Tagi",
"uptime": "Czas działania"
"uptime": "Czas działania",
"groups": {
"monitoring": "Monitorowanie",
"alerting": "Alerty",
"reporting": "Raporty",
"configuration": "Konfiguracja"
}
},
"starPrompt": {
"description": "Zobacz najnowsze wydania i pomóż rozwijać społeczność na GitHub",
+7 -1
View File
@@ -181,7 +181,13 @@
"statusPages": "Pagina de status",
"maintenance": "Manutenção",
"logs": "Registros",
"settings": "Configurações"
"settings": "Configurações",
"groups": {
"monitoring": "Monitoramento",
"alerting": "Alertas",
"reporting": "Relatórios",
"configuration": "Configuração"
}
},
"bottomMenu": {
"support": "Suporte",
+7 -1
View File
@@ -181,7 +181,13 @@
"statusPages": "Страницы статуса",
"maintenance": "Обслуживание",
"logs": "Логи",
"settings": "Настройки"
"settings": "Настройки",
"groups": {
"monitoring": "Мониторинг",
"alerting": "Оповещения",
"reporting": "Отчёты",
"configuration": "Конфигурация"
}
},
"bottomMenu": {
"support": "Поддержка",
+7 -1
View File
@@ -181,7 +181,13 @@
"statusPages": "หน้าสถานะ",
"maintenance": "การบำรุงรักษา",
"logs": "บันทึก",
"settings": "การตั้งค่า"
"settings": "การตั้งค่า",
"groups": {
"monitoring": "การตรวจสอบ",
"alerting": "การแจ้งเตือน",
"reporting": "รายงาน",
"configuration": "การกำหนดค่า"
}
},
"bottomMenu": {
"support": "การสนับสนุน",
+7 -1
View File
@@ -181,7 +181,13 @@
"statusPages": "Durum sayfaları",
"maintenance": "Bakım",
"logs": "Günlükler",
"settings": "Ayarlar"
"settings": "Ayarlar",
"groups": {
"monitoring": "İzleme",
"alerting": "Uyarılar",
"reporting": "Raporlama",
"configuration": "Yapılandırma"
}
},
"bottomMenu": {
"support": "Destek",
+7 -1
View File
@@ -181,7 +181,13 @@
"statusPages": "Сторінки статусу",
"maintenance": "Обслуговування",
"logs": "Журнали",
"settings": "Налаштування"
"settings": "Налаштування",
"groups": {
"monitoring": "Моніторинг",
"alerting": "Сповіщення",
"reporting": "Звіти",
"configuration": "Конфігурація"
}
},
"bottomMenu": {
"support": "Підтримка",
+7 -1
View File
@@ -181,7 +181,13 @@
"statusPages": "Trang trạng thái",
"maintenance": "Bảo trì",
"logs": "Nhật ký",
"settings": "Cài đặt"
"settings": "Cài đặt",
"groups": {
"monitoring": "Giám sát",
"alerting": "Cảnh báo",
"reporting": "Báo cáo",
"configuration": "Cấu hình"
}
},
"bottomMenu": {
"support": "Hỗ trợ",
+7 -1
View File
@@ -181,7 +181,13 @@
"statusPages": "状态页",
"maintenance": "维护",
"logs": "日志",
"settings": "设置"
"settings": "设置",
"groups": {
"monitoring": "监控",
"alerting": "告警",
"reporting": "报表",
"configuration": "配置"
}
},
"bottomMenu": {
"support": "支持",
+7 -1
View File
@@ -181,7 +181,13 @@
"statusPages": "狀態頁面",
"maintenance": "維護",
"logs": "日誌",
"settings": "設定"
"settings": "設定",
"groups": {
"monitoring": "監控",
"alerting": "警示",
"reporting": "報表",
"configuration": "設定"
}
},
"bottomMenu": {
"support": "支援",