mirror of
https://github.com/multica-ai/multica.git
synced 2026-07-27 21:33:41 +02:00
113 lines
3.8 KiB
TypeScript
113 lines
3.8 KiB
TypeScript
"use client";
|
|
|
|
import { useQuery } from "@tanstack/react-query";
|
|
import { useWorkspaceId } from "@multica/core/hooks";
|
|
import { notificationPreferenceOptions } from "@multica/core/notification-preferences/queries";
|
|
import { useUpdateNotificationPreferences } from "@multica/core/notification-preferences/mutations";
|
|
import type { NotificationGroupKey, NotificationPreferences } from "@multica/core/types";
|
|
import { Switch } from "@multica/ui/components/ui/switch";
|
|
import { toast } from "sonner";
|
|
import { useT } from "../../i18n";
|
|
import { BrowserNotificationSetting } from "./browser-notification-setting";
|
|
import {
|
|
SettingsCard,
|
|
SettingsRow,
|
|
SettingsSection,
|
|
SettingsTab,
|
|
} from "./settings-layout";
|
|
|
|
// Inbox event groups rendered in the per-event toggle list. `system_notifications`
|
|
// is a sibling preference key but lives in its own section below.
|
|
const INBOX_GROUP_KEYS = [
|
|
"assignments",
|
|
"status_changes",
|
|
"comments",
|
|
"updates",
|
|
"agent_activity",
|
|
] as const;
|
|
type InboxGroupKey = (typeof INBOX_GROUP_KEYS)[number];
|
|
|
|
export function NotificationsTab() {
|
|
const { t } = useT("settings");
|
|
const wsId = useWorkspaceId();
|
|
const { data } = useQuery(notificationPreferenceOptions(wsId));
|
|
const mutation = useUpdateNotificationPreferences();
|
|
|
|
const preferences = data?.preferences ?? {};
|
|
|
|
const handleToggle = (key: NotificationGroupKey, enabled: boolean) => {
|
|
const updated: NotificationPreferences = {
|
|
...preferences,
|
|
[key]: enabled ? "all" : "muted",
|
|
};
|
|
// Remove keys set to "all" (default) to keep the object clean
|
|
if (enabled) {
|
|
delete updated[key];
|
|
}
|
|
mutation.mutate(updated, {
|
|
onSuccess: () =>
|
|
toast.success(t(($) => $.auto_save.toast_saved), {
|
|
id: "settings-auto-save",
|
|
}),
|
|
onError: (err) =>
|
|
toast.error(
|
|
err instanceof Error && err.message
|
|
? err.message
|
|
: t(($) => $.notifications.toast_failed),
|
|
),
|
|
});
|
|
};
|
|
|
|
const systemEnabled = preferences.system_notifications !== "muted";
|
|
|
|
return (
|
|
<SettingsTab title={t(($) => $.page.tabs.notifications)}>
|
|
<SettingsSection
|
|
title={t(($) => $.notifications.title)}
|
|
description={t(($) => $.notifications.description)}
|
|
>
|
|
<SettingsCard>
|
|
{INBOX_GROUP_KEYS.map((key: InboxGroupKey) => {
|
|
const enabled = preferences[key] !== "muted";
|
|
return (
|
|
<SettingsRow
|
|
key={key}
|
|
label={t(($) => $.notifications.groups[key].label)}
|
|
description={t(($) => $.notifications.groups[key].description)}
|
|
>
|
|
<Switch
|
|
checked={enabled}
|
|
aria-label={t(($) => $.notifications.groups[key].label)}
|
|
onCheckedChange={(checked) => handleToggle(key, checked)}
|
|
/>
|
|
</SettingsRow>
|
|
);
|
|
})}
|
|
</SettingsCard>
|
|
</SettingsSection>
|
|
|
|
<SettingsSection
|
|
title={t(($) => $.notifications.system.title)}
|
|
description={t(($) => $.notifications.system.description)}
|
|
>
|
|
<SettingsCard>
|
|
<SettingsRow
|
|
label={t(($) => $.notifications.system.label)}
|
|
description={t(($) => $.notifications.system.hint)}
|
|
>
|
|
<Switch
|
|
checked={systemEnabled}
|
|
aria-label={t(($) => $.notifications.system.label)}
|
|
onCheckedChange={(checked) => handleToggle("system_notifications", checked)}
|
|
/>
|
|
</SettingsRow>
|
|
</SettingsCard>
|
|
|
|
{/* Web-only: the browser permission banners require. Renders nothing on
|
|
desktop (OS-native delivery) or where the Notification API is absent. */}
|
|
<BrowserNotificationSetting />
|
|
</SettingsSection>
|
|
</SettingsTab>
|
|
);
|
|
}
|