- AddTeamMemberDialog: First name / Last name now share a row, and
Password / Confirm password share a row. Each field uses sx={flex:1}
so the row totals match the width of the email/role rows below.
- InviteTeamMemberDialog: drop the redundant mt={theme.spacing(...)}
workaround on the form Stack (the new Dialog component provides this
spacing).
- Constants conformance: spacing literals replaced with LAYOUT.XS.
- Replace duplicated page/rowsPerPage state in Team, Notifications and Status Pages tables with a shared useClientPagination hook
- Drop unused placeholderColor prop from Select; placeholder always uses secondary text
- Restore LAYOUT.MD constant for the account menu item gap
- New PageHeader component (variant D — grouped icon-pill toolbar):
big title + muted description on the left, Support / Docs /
Changelog as a 3-icon segmented pill on the right with tooltips.
External links open in a new tab.
- BasePage / BasePageWithStates / MonitorBasePageWithStates accept
a headerKey prop; when set, render PageHeader pulling
pages.<headerKey>.header.title and .description from i18n.
When unset, falls back to the existing breadcrumb (no behavior
change for not-yet-migrated pages).
- All top-level pages (uptime, infrastructure, pageSpeed,
notifications, maintenance, statusPages, incidents, logs, checks,
account, settings) now pass their headerKey.
- Sidebar: removed the bottom menu (Support / Discussions / Docs /
Changelog) since those links now live in the page header.
- New EmptyState + EmptyStateIllustration components: stacked-cards SVG
with grid background, theme-aware light/dark palette.
- Variants: default (centered with title + description), compact
(horizontal, in-section), fullscreen (vertically centers in viewport).
- Wired into Checks, Incidents, Logs (Logs+Queue tabs), Notifications,
Maintenance, Status pages, and Team tab — each with i18n title +
description and a fullscreen layout when truly empty.
- Table.EmptyView now wraps the EmptyState in a divider-bordered card
so short messages no longer look orphaned.
- Incidents Option-A short-circuit: when summary.total === 0, replace
the whole page chrome with EmptyState; otherwise keep filters + cards.
- Fallback.tsx (BaseFallback / EmptyFallback / EmptyMonitorFallback /
ErrorFallback) refactored to delegate to EmptyState.
- Merge duplicate react-router-dom imports into one
- Replace useIsAdmin + useIsSuperAdmin + useSelector with single useSelector
- Remove redundant !includes("superadmin") check from canDeleteUser
## Changes
- Add DELETE /api/v1/auth/users/:userId endpoint (admin + superadmin)
- Add deleteUserById service method with role hierarchy enforcement
- Superadmins can remove admins and regular users
- Admins can only remove regular users
- No one can remove superadmins, demo users, or themselves via this endpoint
- Add "Remove user" button with confirmation dialog on edit user page
- Allow admins to view user details and access the edit user page
- Add i18n strings for remove user button and confirmation dialog
## Access control
- superadmin -> can remove admin, user
- admin -> can remove user only
- admin cannot remove superadmin or other admins (enforced on both backend and frontend)
- Fix tooltip background using non-existent tertiary.background
property by switching to tertiary.main
- Fix Check component text color inheritance for noHighlightText
by adding color: inherit to inner Typography
- Add translation wrapper for validation error messages in PasswordPanel
- Add translation wrapper for validation error messages in ProfilePanel