improve test push notifications;

renames; more alerts (merge)
This commit is contained in:
Dobromir Popov
2024-05-23 02:51:15 +03:00
parent 8b3f13d2ee
commit cfc78abff9
10 changed files with 50 additions and 25 deletions

View File

@ -242,7 +242,10 @@ function PwaManager({ subs }) {
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
body: JSON.stringify({ subscription }) //sends test notification to the current subscription
// body: JSON.stringify({ subscription })
//sends test notification to all subscriptions of this user
body: JSON.stringify({ id: session.user.id, title: "Тестово уведомление", message: "Това е тестово уведомление" })
}); });
}; };

View File

@ -7,6 +7,7 @@ function PwaManagerNotifications() {
const [isPermissionGranted, setIsPermissionGranted] = useState(false); const [isPermissionGranted, setIsPermissionGranted] = useState(false);
const [subscription, setSubscription] = useState(null); const [subscription, setSubscription] = useState(null);
const [registration, setRegistration] = useState(null); const [registration, setRegistration] = useState(null);
const [isSubSaved, setIsSubSaved] = useState(false);
const { data: session } = useSession(); const { data: session } = useSession();
// Check if all required APIs are supported // Check if all required APIs are supported
@ -53,6 +54,7 @@ function PwaManagerNotifications() {
if (existingSubscription) { if (existingSubscription) {
console.log('Already subscribed.'); console.log('Already subscribed.');
setSubscription(existingSubscription); setSubscription(existingSubscription);
sendSubscriptionToServer(existingSubscription);
} else if (Notification.permission === "granted") { } else if (Notification.permission === "granted") {
// Permission was already granted but no subscription exists, so subscribe now // Permission was already granted but no subscription exists, so subscribe now
subscribeToNotifications(registration); subscribeToNotifications(registration);
@ -90,6 +92,7 @@ function PwaManagerNotifications() {
}; };
const sendSubscriptionToServer = async (sub) => { const sendSubscriptionToServer = async (sub) => {
if (isSubSaved) { return; }
if (session.user?.id != null) { if (session.user?.id != null) {
await fetch(`/api/notify`, { await fetch(`/api/notify`, {
method: 'PUT', method: 'PUT',
@ -105,6 +108,7 @@ function PwaManagerNotifications() {
console.log('Subscription data saved on server.'); console.log('Subscription data saved on server.');
const s = await response.json(); const s = await response.json();
setSubscription(sub); setSubscription(sub);
setIsSubSaved(true);
console.log('Web push subscribed!'); console.log('Web push subscribed!');
} }
}); });

View File

@ -412,7 +412,7 @@ export default function AvailabilityForm({ publisherId, existingItems, inline, o
<ToastContainer></ToastContainer> <ToastContainer></ToastContainer>
<form id="formAv" className="form p-5 bg-white shadow-md rounded-lg" onSubmit={handleSubmit}> <form id="formAv" className="form p-5 bg-white shadow-md rounded-lg" onSubmit={handleSubmit}>
<h3 className="text-xl font-semibold mb-5 text-gray-800 border-b pb-2"> <h3 className="text-xl font-semibold mb-5 text-gray-800 border-b pb-2">
{editMode ? "Редактирай" : "Нова"} възможност: {common.getDateFormatedShort(new Date(day))} {editMode ? "Редактирай" : "Нова"} възможност: {common.getDateFormattedShort(new Date(day))}
</h3> </h3>
<LocalizationProvider dateAdapter={AdapterDateFns} localeText={bgBG} adapterLocale={bg}> <LocalizationProvider dateAdapter={AdapterDateFns} localeText={bgBG} adapterLocale={bg}>

View File

@ -239,7 +239,7 @@ const AvCalendar = ({ publisherId, events, selectedDate, cartEvents, lastPublish
if (startdate < new Date() || end < new Date() || startdate > end) return; if (startdate < new Date() || end < new Date() || startdate > end) return;
//or if schedule is published (lastPublishedDate) //or if schedule is published (lastPublishedDate)
if (editLockedBefore && startdate < editLockedBefore) { if (editLockedBefore && startdate < editLockedBefore) {
toast.error(`Не можете да променяте предпочитанията си за дати преди ${common.getDateFormatedShort(editLockedBefore)}.`, { autoClose: 5000 }); toast.error(`Не можете да променяте предпочитанията си за дати преди ${common.getDateFormattedShort(editLockedBefore)}.`, { autoClose: 5000 });
return; return;
} }

View File

@ -362,7 +362,7 @@ export default async function handler(req, res) {
break; break;
case "getAllPublishersWithStatistics": case "getAllPublishersWithStatistics":
let noEndDate = common.parseBool(req.query.noEndDate); let noEndDate = common.parseBool(req.query.noEndDate);
res.status(200).json(await dataHelper.getAllPublishersWithStatistics(day, noEndDate)); res.status(200).json(await dataHelper.getAllPublishersWithStatisticsMonth(day, noEndDate));
default: default:
res.status(200).json({ res.status(200).json({
@ -643,7 +643,7 @@ export async function filterPublishers(selectFields, searchText, filterDate, fet
} }
//if not full day, match by date and time //if not full day, match by date and time
else { else {
//match exact time (should be same as data.findPublisherAvailability()) //match exact time (should be same as data.FindPublisherAvailability())
whereClause["availabilities"] = { whereClause["availabilities"] = {
some: { some: {
OR: [ OR: [
@ -723,7 +723,7 @@ export async function filterPublishers(selectFields, searchText, filterDate, fet
} }
}); });
console.log(`publishers: ${publishers.length}, WhereClause: ${JSON.stringify(whereClause)}`); //console.log(`publishers: ${publishers.length}, WhereClause: ${JSON.stringify(whereClause)}`);
if (filterDate) { if (filterDate) {

View File

@ -56,15 +56,17 @@ const Notification = async (req, res) => {
if (index !== -1) { if (index !== -1) {
subscriptions[index] = subscription; // Update existing subscription subscriptions[index] = subscription; // Update existing subscription
console.log('Subscription for publisher', id, 'updated.')
} else { } else {
subscriptions.push(subscription); // Add new subscription subscriptions.push(subscription); // Add new subscription
console.log('Subscription for publisher', id, 'saved.')
} }
await prisma.publisher.update({ await prisma.publisher.update({
where: { id }, where: { id },
data: { pushSubscription: subscriptions } data: { pushSubscription: subscriptions }
}); });
console.log('Subscription for publisher', id, 'updated:', subscription) console.log('Subscription update successful', subscription.keys.auth, ". Total subscriptions:", subscriptions.length)
res.send({ subs: subscriptions.length }) res.send({ subs: subscriptions.length })
res.statusCode = 200 res.statusCode = 200
res.end() res.end()
@ -111,6 +113,7 @@ const Notification = async (req, res) => {
return return
} }
else if (id) { else if (id) {
console.log('Sending push notification to publisher ', id)
await sendPush(id, title, message.actions) await sendPush(id, title, message.actions)
res.statusCode = 200 res.statusCode = 200
res.end() res.end()
@ -148,22 +151,25 @@ export const sendPush = async (id, title, message, actions) => {
const publisher = await prisma.publisher.findUnique({ const publisher = await prisma.publisher.findUnique({
where: { id } where: { id }
}) })
if (!publisher.pushSubscription) {
console.log('No push subscription found for publisher', id)
return
}
await webPush if (Array.isArray(publisher.pushSubscription) && publisher.pushSubscription.length) {
.sendNotification( for (const subscription of publisher.pushSubscription) {
publisher.pushSubscription, await webPush
JSON.stringify({ title, message, actions }) .sendNotification(
) subscription,
.then(response => { JSON.stringify({ title, message, actions })
console.log('Push notification sent to publisher', id) )
}) .then(response => {
.catch(err => { console.log('Push notification sent to publisher', id)
console.error('Error sending push notification to publisher', id, ':', err) })
}) .catch(err => {
console.error('Error sending push notification to publisher', id, ':', err)
})
}
} else {
console.log('No valid subscriptions found for publisher', id)
}
} }
//export breoadcastNotification for use in other files //export breoadcastNotification for use in other files
export const broadcastPush = async (title, message, actions) => { export const broadcastPush = async (title, message, actions) => {

View File

@ -34,6 +34,12 @@ const SchedulePage = () => {
fetchHtmlContent(); // Call the function to fetch HTML content fetchHtmlContent(); // Call the function to fetch HTML content
}, []); // Empty dependency array means this effect runs once on component mount }, []); // Empty dependency array means this effect runs once on component mount
// temporary alert for the users
useEffect(() => {
alert("Мили братя, искаме само да ви напомним да ни изпратите вашите предпочитания за юни до 25-то число като използвате меню 'Възможности'. Ако имате проблем, моля пишете ни на 'specialnosvidetelstvanesofia@gmail.com'");
}, []);
return ( return (
<Layout> <Layout>
<ProtectedRoute deniedMessage=""> <ProtectedRoute deniedMessage="">

View File

@ -1,4 +1,4 @@
import { useState } from 'react'; import { useState, useEffect } from 'react';
import Layout from "../../../components/layout"; import Layout from "../../../components/layout";
import ProtectedRoute from '../../../components/protectedRoute'; import ProtectedRoute from '../../../components/protectedRoute';
import { UserRole } from '@prisma/client'; import { UserRole } from '@prisma/client';
@ -29,6 +29,11 @@ export default function MySchedulePage({ assignments }) {
if (status === "loading") { if (status === "loading") {
return <div className="flex justify-center items-center h-screen">Loading...</div>; return <div className="flex justify-center items-center h-screen">Loading...</div>;
} }
// temporary alert for the users
useEffect(() => {
alert("Мили братя, искаме само да ви напомним да ни изпратите вашите предпочитания за юни до 25-то число като използвате меню 'Възможности'. Ако имате проблем, моля пишете ни на 'specialnosvidetelstvanesofia@gmail.com'");
}, []);
const handleReplaceInAssignment = () => { const handleReplaceInAssignment = () => {
// Add publisher as assignment logic // Add publisher as assignment logic

View File

@ -323,7 +323,7 @@ export default ContactsPage;
export const getServerSideProps = async (context) => { export const getServerSideProps = async (context) => {
const allPublishers = await data.getAllPublishersWithStatistics(new Date()); const allPublishers = await data.getAllPublishersWithStatisticsMonth(new Date());
//merge first and last name //merge first and last name
allPublishers.forEach(publisher => { allPublishers.forEach(publisher => {
publisher.name = `${publisher.firstName} ${publisher.lastName}`; publisher.name = `${publisher.firstName} ${publisher.lastName}`;

View File

@ -54,7 +54,8 @@ export default function DashboardPage({ initialItems, initialUserId, cartEvents,
//const [notificationsVisible, setNotificationsVisible] = useState(false); //const [notificationsVisible, setNotificationsVisible] = useState(false);
useEffect(() => { useEffect(() => {
if (newLogin === 'true') { //if (newLogin === 'true')
{
alert("Мили братя, искаме само да ви напомним да ни изпратите вашите предпочитания за юни до 25-то число като използвате меню 'Възможности'. Ако имате проблем, моля пишете ни на 'specialnosvidetelstvanesofia@gmail.com'"); alert("Мили братя, искаме само да ви напомним да ни изпратите вашите предпочитания за юни до 25-то число като използвате меню 'Възможности'. Ако имате проблем, моля пишете ни на 'specialnosvidetelstvanesofia@gmail.com'");
const currentPath = router.pathname; const currentPath = router.pathname;
router.replace(currentPath, undefined, { shallow: true }); // Removes the query without affecting the history router.replace(currentPath, undefined, { shallow: true }); // Removes the query without affecting the history