supersam/src/components/notifications/NotificationSettings.jsx

104 lines
4.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React from "react";
import { useNotificationPreferences } from "../../hooks/useNotifications";
import { usePushNotifications } from "../../hooks/usePushNotifications";
import { Panel } from "../UI/Panel";
import { Bell, Settings } from "../UI/Icons";
const ALL_NOTIF_TYPES = [
{ key: "order_status_change", label: "Изменение статуса", description: "Статус заказа или доставки изменился", roles: ["manager", "logistician", "driver", "admin"] },
{ key: "driver_assigned", label: "Назначение на заказ", description: "Вам назначили заказ или доставку", roles: ["driver"] },
{ key: "driver_unassigned", label: "Снятие с заказа", description: "Вас сняли с заказа или доставки", roles: ["driver"] },
{ key: "delivery_problem", label: "Проблемы и отмены", description: "Отмена, проблема, невозможность дозвониться", roles: ["manager", "logistician", "admin"] },
{ key: "new_order", label: "Новый заказ", description: "Создан новый заказ в системе", roles: ["manager", "logistician", "admin"] },
{ key: "group_status_change", label: "Изменение группы доставки", description: "Статус группы доставки обновлён", roles: ["logistician", "manager", "admin"] },
];
export function NotificationSettings({ userId, userRole, onBack }) {
const { prefs, isLoading: prefsLoading, updatePref } = useNotificationPreferences(userId);
const { isSupported, isSubscribed, isLoading: pushLoading, subscribe, unsubscribe } = usePushNotifications(userId);
const role = userRole || "manager";
const visibleTypes = ALL_NOTIF_TYPES.filter((t) => t.roles.includes(role));
const loading = prefsLoading || pushLoading;
return (
<div className="space-y-4">
<div className="flex items-center gap-3">
{onBack && (
<button
className="rounded p-1 text-[var(--color-text-muted)] hover:bg-[var(--color-surface-strong)]"
onClick={onBack}
>
Назад
</button>
)}
<h2 className="text-lg font-semibold">Настройки уведомлений</h2>
</div>
{/* Push toggle */}
<Panel className="p-4">
<div className="flex items-center justify-between">
<div className="flex items-center gap-3">
<Bell className="h-5 w-5 text-[var(--color-accent)]" />
<div>
<p className="text-sm font-medium">Push-уведомления</p>
<p className="text-xs text-[var(--color-text-muted)]">
{isSupported
? isSubscribed
? "Включены — вы получаете уведомления на устройстве"
: "Выкл — нажмите чтобы включить"
: "Не поддерживаются в этом браузере"}
</p>
</div>
</div>
{isSupported && (
<button
className={`relative h-6 w-11 rounded-full transition-colors ${
isSubscribed ? "bg-[var(--color-accent)]" : "bg-[var(--color-border)]"
}`}
disabled={pushLoading}
onClick={isSubscribed ? unsubscribe : subscribe}
>
<span
className={`absolute top-0.5 left-0.5 h-5 w-5 rounded-full bg-white transition-transform ${
isSubscribed ? "translate-x-5" : "translate-x-0"
}`}
/>
</button>
)}
</div>
</Panel>
{/* Type preferences */}
<Panel className="p-4">
<h3 className="mb-3 flex items-center gap-2 text-sm font-semibold">
<Settings className="h-4 w-4" />
Что уведомлять
</h3>
<div className="space-y-3">
{visibleTypes.map(({ key, label, description }) => (
<label key={key} className="flex items-start justify-between gap-3">
<div>
<p className="text-sm font-medium">{label}</p>
<p className="text-xs text-[var(--color-text-muted)]">{description}</p>
</div>
<button
className={`relative mt-0.5 h-6 w-11 shrink-0 rounded-full transition-colors ${
prefs[key] ? "bg-[var(--color-accent)]" : "bg-[var(--color-border)]"
}`}
disabled={prefsLoading}
onClick={() => updatePref(key, !prefs[key])}
>
<span
className={`absolute top-0.5 left-0.5 h-5 w-5 rounded-full bg-white transition-transform ${
prefs[key] ? "translate-x-5" : "translate-x-0"
}`}
/>
</button>
</label>
))}
</div>
</Panel>
</div>
);
}