- {subscriptions.map((subscription, index) => (
+ {notifications.map((subscription, index) => (
- {subscription.type === "mobile" ? (
-
- ) : (
-
- )}
+
- {subscription.name}
+ {subscription.device}
- {subscription.status === "revoked" && (
+ {subscription.enabled ? (
+
+ Active
+
+ ) : (
)}
- {subscription.status === "active" && (
-
- Active
-
- )}
-
- Last seen {subscription.lastSeen}
-
{
+ testNotification(subscription.id)
+ .then(() => {
+ toast.success(
+ "Vous allez recevoir une notification de test sur votre appareil..."
+ );
+ })
+ .catch((error) => {
+ console.error(
+ "Failed to send test notification:",
+ error
+ );
+ toast.error(
+ "Échec de l'envoi de la notification de test."
+ );
+ });
+ }}
className="flex items-center gap-1 bg-transparent text-xs sm:text-sm px-2 sm:px-3"
>
@@ -280,26 +338,41 @@ export default function NotificationSettings() {
variant="outline"
size="sm"
className="flex items-center gap-1 text-destructive hover:text-destructive bg-transparent text-xs sm:text-sm px-2 sm:px-3"
+ onClick={() => {
+ unsubscribe(subscription.id)
+ .then(() => {
+ toast.success(
+ "L'appareil a été désabonné des notifications."
+ );
+ })
+ .catch((error) => {
+ console.error("Failed to unsubscribe:", error);
+ toast.error(
+ "Échec de la désinscription de l'appareil."
+ );
+ });
+ }}
>
Delete
- {index < subscriptions.length - 1 && (
+ {index < notifications.length - 1 && (
)}
))}
- {subscriptions.length === 0 && (
+ {notifications.length === 0 && (
- No subscribed devices found
+ Aucun appareil n'est actuellement abonné aux notifications.
- Enable push notifications to add this device
+ Vous pouvez activer les notifications pour recevoir des
+ alertes sur vos appareils.
)}
diff --git a/app/lib/api.ts b/app/lib/api.ts
index 7e0d599..3a34fa3 100644
--- a/app/lib/api.ts
+++ b/app/lib/api.ts
@@ -320,16 +320,68 @@ export const useSubjects = () => {
*/
export const subscribe = async (data: any) => {
return makePostRequest(
- "/notifications/subscribe",
+ "/notifications",
data,
"Échec de l'abonnement aux notifications"
);
-}
+};
-export const unsubscribe = async (data: any) => {
+export const unsubscribe = async (id: string) => {
return makePostRequest(
- "/notifications/unsubscribe",
- data,
+ `/notifications/${id}/unsubscribe`,
+ {},
"Échec de la désinscription des notifications"
);
};
+
+export const updateSubscription = async (id: string, events: string[]) => {
+ return makePostRequest(
+ `/notifications/${id}`,
+ { events },
+ "Échec de la mise à jour de l'abonnement aux notifications"
+ );
+};
+
+export const getNotifications = async () => {
+ return makeRequest(
+ "/notifications",
+ "Échec de la récupération des notifications"
+ );
+};
+
+export interface Event {
+ id: string;
+ enabled: boolean;
+}
+
+interface Subscription {
+ id: string;
+ device: string;
+ events: Event[];
+ enabled: boolean;
+}
+
+export const useNotifications = () => {
+ const { data, ...props } = useQuery({
+ queryKey: ["notifications"],
+ queryFn: getNotifications,
+ staleTime: Duration.fromObject({
+ hours: 1, // 1 hour
+ }).toMillis(),
+ gcTime: Duration.fromObject({
+ days: 3, // 3 days
+ }).toMillis(),
+ });
+ return {
+ notifications: (data as Subscription[]) || [],
+ ...props,
+ };
+};
+
+export const testNotification = async (id: string) => {
+ return makePostRequest(
+ `/notifications/${id}/test`,
+ {},
+ "Échec de l'envoi de la notification de test"
+ );
+};
diff --git a/app/lib/notification.ts b/app/lib/notification.ts
index ceaa147..ef77bee 100644
--- a/app/lib/notification.ts
+++ b/app/lib/notification.ts
@@ -1,6 +1,6 @@
import { subscribe, unsubscribe } from "./api";
-const STORAGE_KEY = "notification_enabled";
+export const STORAGE_KEY = "notification_enabled";
export async function registerNotification() {
const permission = await Notification.requestPermission();
@@ -20,9 +20,9 @@ export async function registerNotification() {
userVisibleOnly: true,
applicationServerKey: import.meta.env.VITE_PUBLIC_VAPID_KEY,
});
- await subscribe(subscription);
+ const data = await subscribe(subscription);
// Store to local storage
- localStorage.setItem(STORAGE_KEY, "true");
+ localStorage.setItem(STORAGE_KEY, data.id?.toString());
return subscription;
} catch (err) {
return {
@@ -32,15 +32,16 @@ export async function registerNotification() {
}
export function isNotificationEnabled() {
- return localStorage.getItem(STORAGE_KEY) === "true";
+ return !!localStorage.getItem(STORAGE_KEY);
}
export async function unregisterNotification() {
- const registration = await navigator.serviceWorker.ready;
- const subscription = await registration.pushManager.getSubscription();
- if (subscription) {
- await subscription.unsubscribe();
- localStorage.removeItem(STORAGE_KEY);
- await unsubscribe(subscription);
+ const subscriptionId = localStorage.getItem(STORAGE_KEY);
+ if (!subscriptionId) {
+ return {
+ error: "E_NOT_REGISTERED",
+ };
}
+ await unsubscribe(subscriptionId);
+ localStorage.removeItem(STORAGE_KEY);
}