182 lines
7.5 KiB
TypeScript
182 lines
7.5 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect } from "react";
|
|
import Location from "@components/Location/Location";
|
|
import { useLocationStore } from "@store/Location.Store";
|
|
import { useNotificationPreferencesStore } from "@store/NotificationPreferences.Store";
|
|
import { useSessionStore } from "@store/Sesion.Store";
|
|
import { useEventHandlerStore, EVENT_TYPES } from "@store/EventHandler.Store";
|
|
import { useAlert } from "@store/Alert.Store";
|
|
import { getClientPreferences, upsertClientPreferences } from "@services/Notifications.Service";
|
|
import { NotificationChannel } from "@models/NotificationPreferences.model";
|
|
import AccountCircleOutlinedIcon from "@mui/icons-material/AccountCircleOutlined";
|
|
import NotificationsIcon from "@mui/icons-material/NotificationsOutlined";
|
|
import MaterialAlert from "@mui/material/Alert";
|
|
import styles from "./NotificationsPreferencesPage.module.css";
|
|
|
|
const CHANNELS: { key: NotificationChannel; label: string }[] = [
|
|
{ key: "whatsapp", label: "WhatsApp" },
|
|
{ key: "email", label: "Email" },
|
|
{ key: "system", label: "Sistema" }
|
|
];
|
|
|
|
type ChannelPreference = "default" | "preferred" | "muted";
|
|
|
|
export default function NotificationsPreferencesPage() {
|
|
const location = useLocationStore();
|
|
const store = useNotificationPreferencesStore();
|
|
const SessionInfo = useSessionStore();
|
|
const eventHandler = useEventHandlerStore();
|
|
const alert = useAlert();
|
|
|
|
useEffect(() => {
|
|
location.clear();
|
|
|
|
location.add({
|
|
url: "/user/profile",
|
|
title: "Perfil de usuario",
|
|
icon: <AccountCircleOutlinedIcon sx={{ fontSize: "32px", mr: "10px" }} />
|
|
});
|
|
|
|
location.add({
|
|
url: "",
|
|
title: "Preferencias de notificación",
|
|
icon: <NotificationsIcon sx={{ fontSize: "32px", mr: "10px" }} />
|
|
});
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
if (!SessionInfo.userId) {
|
|
return;
|
|
}
|
|
|
|
store.setClientId(SessionInfo.userId);
|
|
store.setMode("client-preferences");
|
|
|
|
eventHandler.setEventType(EVENT_TYPES.LOADING);
|
|
getClientPreferences(SessionInfo.userId, SessionInfo.userId)
|
|
.then((preferences) => {
|
|
store.setClientPreferences(preferences);
|
|
store.updateFormData({
|
|
preferredChannels: preferences.preferredChannels || [],
|
|
mutedChannels: preferences.mutedChannels || []
|
|
});
|
|
store.setDirty(false);
|
|
})
|
|
.catch((error) => {
|
|
alert.showError(error.format());
|
|
})
|
|
.finally(() => {
|
|
eventHandler.setEventType(EVENT_TYPES.SLEEP);
|
|
});
|
|
}, [SessionInfo.userId]);
|
|
|
|
const getChannelPreference = (channel: NotificationChannel): ChannelPreference => {
|
|
if (store.formData.mutedChannels.includes(channel)) {
|
|
return "muted";
|
|
}
|
|
|
|
if (store.formData.preferredChannels.includes(channel)) {
|
|
return "preferred";
|
|
}
|
|
|
|
return "default";
|
|
};
|
|
|
|
const selectPreference = (channel: NotificationChannel, preference: ChannelPreference) => {
|
|
store.updateFormData({
|
|
preferredChannels:
|
|
preference === "preferred"
|
|
? [...store.formData.preferredChannels.filter((c) => c !== channel), channel]
|
|
: store.formData.preferredChannels.filter((c) => c !== channel),
|
|
mutedChannels:
|
|
preference === "muted"
|
|
? [...store.formData.mutedChannels.filter((c) => c !== channel), channel]
|
|
: store.formData.mutedChannels.filter((c) => c !== channel)
|
|
});
|
|
eventHandler.setEventType(EVENT_TYPES.NEED_SAVE);
|
|
};
|
|
|
|
const handleSave = () => {
|
|
eventHandler.setEventType(EVENT_TYPES.LOADING);
|
|
upsertClientPreferences(SessionInfo.userId, SessionInfo.userId, {
|
|
preferredChannels: store.formData.preferredChannels as NotificationChannel[],
|
|
mutedChannels: store.formData.mutedChannels as NotificationChannel[]
|
|
})
|
|
.then((preferences) => {
|
|
store.setClientPreferences(preferences);
|
|
store.setDirty(false);
|
|
})
|
|
.catch((error) => {
|
|
alert.showError(error.format());
|
|
})
|
|
.finally(() => {
|
|
eventHandler.setEventType(EVENT_TYPES.SLEEP);
|
|
});
|
|
};
|
|
|
|
useEffect(() => {
|
|
if (eventHandler.eventType === EVENT_TYPES.SAVE) {
|
|
handleSave();
|
|
}
|
|
}, [eventHandler.eventType]);
|
|
|
|
return (
|
|
<>
|
|
<Location />
|
|
|
|
<div className={styles.container}>
|
|
<MaterialAlert severity="info" sx={{ marginBottom: "0" }}>
|
|
<b>Preferencias globales:</b> Configure cómo prefiere recibir notificaciones. Si deja un canal en estándar, cada organización podrá usar su configuración general.
|
|
</MaterialAlert>
|
|
|
|
<div className={styles.channels}>
|
|
{CHANNELS.map((channel) => {
|
|
const selectedPreference = getChannelPreference(channel.key);
|
|
return (
|
|
<div key={channel.key} className={styles.card}>
|
|
<div>
|
|
<div className={styles.channelTitle}>{channel.label}</div>
|
|
<div className={styles.channelDescription}>
|
|
{selectedPreference === "preferred" && "Priorizar este canal para tus notificaciones."}
|
|
{selectedPreference === "muted" && "No recibir notificaciones por este canal."}
|
|
{selectedPreference === "default" && "Usar la configuración estándar de cada organización."}
|
|
</div>
|
|
</div>
|
|
|
|
<div className={styles.options}>
|
|
{[
|
|
{ key: "default" as ChannelPreference, label: "Estándar" },
|
|
{ key: "preferred" as ChannelPreference, label: "Preferido" },
|
|
{ key: "muted" as ChannelPreference, label: "Silenciado" }
|
|
].map((option) => {
|
|
const isSelected = selectedPreference === option.key;
|
|
return (
|
|
<button
|
|
key={option.key}
|
|
type="button"
|
|
onClick={() => selectPreference(channel.key, option.key)}
|
|
className={`${styles.optionButton} ${isSelected ? styles.optionButtonActive : ""}`}
|
|
>
|
|
{option.label}
|
|
</button>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
|
|
{store.isDirty && (
|
|
<button onClick={handleSave} className={styles.saveButton}>
|
|
Guardar preferencias
|
|
</button>
|
|
)}
|
|
</div>
|
|
|
|
<div style={{ marginBottom: "40px" }}> </div>
|
|
</>
|
|
);
|
|
}
|