add read notifications route and update notifications behavior
This commit is contained in:
@@ -1,25 +1,54 @@
|
||||
import styles from "./Header.module.css"
|
||||
import { Link, NavLink } from "react-router";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import {useContext, useEffect, useRef, useState} from "react";
|
||||
import getUserNotifications from "../../utils/notifications/getUserNotifications.js";
|
||||
import deleteNotificationUser from "../../utils/notifications/deleteNotificationUser.js";
|
||||
import initEcho from "../../utils/echo/initEcho.js"
|
||||
import readNotifications from "../../utils/notifications/readNotifications.js";
|
||||
import {AuthContext} from "../../contexts/auth/AuthContext.js";
|
||||
|
||||
|
||||
function Header() {
|
||||
const { update } = useContext(AuthContext);
|
||||
const [notificationMenu, setnotificationMenu] = useState(false);
|
||||
const [unreadNotification, setunreadNotification] = useState(true);
|
||||
const [unreadNotification, setunreadNotification] = useState(false);
|
||||
const [mobileMenu, setMobileMenu] = useState(false);
|
||||
const [notifications, setNotifications] = useState([]);
|
||||
const notificationRef = useRef(null);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
const echo = initEcho();
|
||||
|
||||
echo.private("admins-private")
|
||||
.listen(".user.created", (event) => {
|
||||
const newNotification = {
|
||||
id: Date.now(),
|
||||
content: `Nouvel demande d'inscription : ${event.user.name} ${event.user.lastname}`,
|
||||
is_new: true
|
||||
};
|
||||
setNotifications(prevNotifications => [newNotification, ...prevNotifications]);
|
||||
setunreadNotification(true);
|
||||
});
|
||||
|
||||
return () => {
|
||||
echo.leave("admins-private");
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
async function loadNotifications() {
|
||||
const notifData = await getUserNotifications();
|
||||
const data = notifData || [];
|
||||
setNotifications(notifData || []);
|
||||
const hasUnread = data.some(n => n.pivot && n.pivot.unread === 1);
|
||||
|
||||
setunreadNotification(hasUnread);
|
||||
}
|
||||
|
||||
loadNotifications();
|
||||
|
||||
const handleClickOutside = (event) => {
|
||||
if (
|
||||
notificationRef.current &&
|
||||
@@ -40,12 +69,25 @@ function Header() {
|
||||
|
||||
|
||||
|
||||
const toggleNotificationMenu = async () => {
|
||||
try {
|
||||
setnotificationMenu(!notificationMenu);
|
||||
if (unreadNotification) {
|
||||
const result = await readNotifications();
|
||||
if (result) {
|
||||
setunreadNotification(false);
|
||||
update();
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Erreur suppression notification :', err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function deleteNotification(notificationId) {
|
||||
try {
|
||||
const result = await deleteNotificationUser(notificationId);
|
||||
|
||||
console.log(result);
|
||||
|
||||
if (result) {
|
||||
setNotifications(prev => prev.filter(n => n.id !== notificationId));
|
||||
}
|
||||
@@ -81,10 +123,7 @@ function Header() {
|
||||
<div className={styles.headerRightContent}>
|
||||
<button
|
||||
className={`${styles.bellBtn} ${notificationMenu ? styles.activeBellBtn : ""}`}
|
||||
onClick={() => {
|
||||
setnotificationMenu(!notificationMenu);
|
||||
setunreadNotification(false);
|
||||
}}
|
||||
onClick={() => {toggleNotificationMenu();}}
|
||||
>
|
||||
<img className={styles.notificationsImg} src="bell.svg" alt="notifications"/>
|
||||
{unreadNotification && <span className={styles.notificationBadge}></span>}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import Echo from "laravel-echo";
|
||||
import Pusher from "pusher-js";
|
||||
|
||||
window.Pusher = Pusher;
|
||||
|
||||
export default function initEcho() {
|
||||
const echoInstance = new Echo({
|
||||
broadcaster: import.meta.env.VITE_BROADCASTER,
|
||||
key: import.meta.env.VITE_REVERB_KEY,
|
||||
wsHost: import.meta.env.VITE_REVERB_HOST,
|
||||
wsPort: Number(import.meta.env.VITE_REVERB_PORT),
|
||||
forceTLS: import.meta.env.VITE_FORCE_TLS === 'true',
|
||||
disableStats: import.meta.env.VITE_DISABLE_STATS === 'true',
|
||||
encrypted: import.meta.env.VITE_ENCRYPTED === 'true',
|
||||
cluster: import.meta.env.VITE_CLUSTER,
|
||||
enabledTransports: ['ws', 'wss'],
|
||||
});
|
||||
|
||||
window.Echo = echoInstance;
|
||||
return echoInstance;
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import getXSRFToken from "../getXSRF.js";
|
||||
|
||||
export default async function readNotifications() {
|
||||
|
||||
const csrfToken = await getXSRFToken();
|
||||
|
||||
try {
|
||||
const res = await fetch(`http://${import.meta.env.VITE_API_URL}/api/users/notifications/read`, {
|
||||
method: 'POST',
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'X-XSRF-TOKEN': csrfToken,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error(`Erreur serveur : ${res.status}`);
|
||||
}
|
||||
|
||||
return await res.json();
|
||||
} catch (err) {
|
||||
console.error('Erreur :', err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user