Task #527: unify topbar into per-user Settings panel
Topbar right cluster collapses from 5–7 icons to exactly Bell -> Inbox
(conditional on canReceiveOrders) -> Settings (gear). Logout moved
inside the Settings panel; the second bell, globe, volume and clock
buttons are gone from the topbar.
New SettingsPanel renders as a Popover on md+ and a bottom Sheet on
<md (via new useMediaQuery hook). It composes existing controls
rather than re-implementing them:
- Language radio uses useUpdateLanguage + i18n.changeLanguage
- Notifications group renders extracted NotificationSettingsContent
- Sound group toggles notificationsMuted (same flag QuickMute used)
- Clock group renders extracted ClockStyleContent
All DB + localStorage persistence is preserved unchanged.
Refactors:
- notification-settings.tsx: extracted NotificationSettingsContent;
NotificationSettingsPicker now wraps it (kept for any future caller).
- clock-style-picker.tsx: extracted ClockStyleContent; ClockStylePicker
now wraps it; removed dead setOpen reference inside choose().
- home.tsx: removed Globe / QuickMute / NotificationSettingsPicker /
ClockStylePicker / standalone LogOut from the cluster, dropped
related imports + useUpdateLanguage, reordered to Bell -> Inbox ->
Settings, and passes onLogout to SettingsPanel.
i18n: added settingsPanel.{title, section.*, lang.*, sound.master}
keys to ar.json and en.json.
Code review: PASS.
This commit is contained in:
@@ -7,7 +7,6 @@ import {
|
||||
} from "@workspace/api-client-react";
|
||||
import {
|
||||
Settings as SettingsIcon,
|
||||
BellOff,
|
||||
Volume2,
|
||||
VolumeX,
|
||||
LogOut,
|
||||
@@ -235,7 +234,6 @@ export function SettingsPanel({ onLogout }: { onLogout: () => void }) {
|
||||
const { user } = useAuth();
|
||||
const isDesktop = useMediaQuery("(min-width: 768px)");
|
||||
if (!user) return null;
|
||||
const muted = user.notificationsMuted;
|
||||
|
||||
const trigger = (
|
||||
<button
|
||||
@@ -243,15 +241,9 @@ export function SettingsPanel({ onLogout }: { onLogout: () => void }) {
|
||||
aria-label={t("settingsPanel.title")}
|
||||
aria-haspopup="dialog"
|
||||
data-testid="topbar-settings-button"
|
||||
className="text-muted-foreground hover:text-foreground transition-colors p-1.5 md:p-2.5 rounded-lg md:rounded-xl hover:bg-foreground/5 relative"
|
||||
className="text-muted-foreground hover:text-foreground transition-colors p-1.5 md:p-2.5 rounded-lg md:rounded-xl hover:bg-foreground/5"
|
||||
>
|
||||
<SettingsIcon className="w-[18px] h-[18px] md:w-6 md:h-6" />
|
||||
{muted && (
|
||||
<BellOff
|
||||
aria-hidden="true"
|
||||
className="absolute -top-0.5 -right-0.5 w-3 h-3 text-destructive bg-background rounded-full p-px"
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
);
|
||||
|
||||
@@ -287,15 +279,9 @@ export function SettingsPanel({ onLogout }: { onLogout: () => void }) {
|
||||
aria-label={t("settingsPanel.title")}
|
||||
aria-haspopup="dialog"
|
||||
data-testid="topbar-settings-button"
|
||||
className="text-muted-foreground hover:text-foreground transition-colors p-1.5 rounded-lg hover:bg-foreground/5 relative"
|
||||
className="text-muted-foreground hover:text-foreground transition-colors p-1.5 rounded-lg hover:bg-foreground/5"
|
||||
>
|
||||
<SettingsIcon className="w-[18px] h-[18px]" />
|
||||
{muted && (
|
||||
<BellOff
|
||||
aria-hidden="true"
|
||||
className="absolute -top-0.5 -right-0.5 w-3 h-3 text-destructive bg-background rounded-full p-px"
|
||||
/>
|
||||
)}
|
||||
</button>
|
||||
<SheetContent
|
||||
side="bottom"
|
||||
|
||||
Reference in New Issue
Block a user