This commit is contained in:
frontend perkafean
2024-09-28 07:00:51 +00:00
parent 3869b4d589
commit 55eb5c189a
6 changed files with 136 additions and 78 deletions

View File

@@ -1,28 +1,29 @@
// public/firebase-messaging-sw.js // public/firebase-messaging-sw.js
self.addEventListener('push', function(event) { self.addEventListener("push", function (event) {
const data = event.data.json(); const data = event.data.json();
const options = { const options = {
body: data.body, body: data.body,
icon: 'https://i.pinimg.com/originals/3c/44/67/3c446785968272f79aaac7ace5ded0fe.jpg', // Path to your icon icon: "https://i.pinimg.com/originals/3c/44/67/3c446785968272f79aaac7ace5ded0fe.jpg", // Path to your icon
badge: 'badge.png', // Path to your badge badge: "badge.png", // Path to your badge
data: { // Add data to the notification data: {
cafeId: data.cafeId, // Add data to the notification
transactionId: data.transactionId, cafeId: data.cafeId,
} transactionId: data.transactionId,
}; },
};
event.waitUntil( event.waitUntil(self.registration.showNotification(data.title, options));
self.registration.showNotification(data.title, options)
);
}); });
self.addEventListener('notificationclick', (event) => { self.addEventListener("notificationclick", (event) => {
event.notification.close(); // Close the notification event.notification.close(); // Close the notification
const { cafeId, transactionId } = event.notification.data; // Get the notification data const { cafeId, transactionId } = event.notification.data; // Get the notification data
// Open the URL with the cafeId and transactionId // Open the URL with the cafeId and transactionId
event.waitUntil( event.waitUntil(
clients.openWindow(`https://r7l7gs-3000.csb.app/${cafeId}modal=new_transaction&transactionId=${transactionId}`) clients.openWindow(
); `https://srrk5s-3000.csb.app/${cafeId}?modal=new_transaction&transactionId=${transactionId}`
)
);
}); });

View File

@@ -37,6 +37,10 @@ import {
removeLocalStorage, removeLocalStorage,
} from "./helpers/localStorageHelpers"; } from "./helpers/localStorageHelpers";
import { calculateTotals } from "./helpers/cartHelpers"; import { calculateTotals } from "./helpers/cartHelpers";
import {
subscribeUser,
resetNotificationSubscription,
} from "./helpers/subscribeHelpers.js";
import Modal from "./components/Modal"; // Import your modal component import Modal from "./components/Modal"; // Import your modal component
function App() { function App() {
@@ -153,58 +157,28 @@ function App() {
// } // }
// }; // };
useEffect(() => { useEffect(() => {
const getVapidKey = async () => {
const response = await fetch(`${API_BASE_URL}/vapid-key`);
const { publicVapidKey } = await response.json();
return publicVapidKey;
};
const askNotificationPermission = async () => { const askNotificationPermission = async () => {
const permission = await Notification.requestPermission(); let permission = Notification.permission;
if (permission === 'granted') { if (permission === "default") {
console.log('Notification permission granted.'); setModal("req_notification");
const publicVapidKey = await getVapidKey(); }
await subscribeUser(publicVapidKey); if (permission === "granted") await resetNotificationSubscription();
} else {
console.error('Notification permission denied.'); permission = await Notification.requestPermission();
} if (permission === "granted") {
await subscribeUser();
} else if (permission === "denied") {
setModal("blocked_notification");
console.error("Notification permission denied.");
}
}; };
// Utility function to convert base64 to Uint8Array if ("serviceWorker" in navigator) {
function urlBase64ToUint8Array(base64String) { window.addEventListener("load", async () => {
const padding = '='.repeat((4 - base64String.length % 4) % 4); await askNotificationPermission();
const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/'); });
const rawData = window.atob(base64);
return Uint8Array.from([...rawData].map(char => char.charCodeAt(0)));
}
const subscribeUser = async (publicVapidKey) => {
try {
const registration = await navigator.serviceWorker.register('/service-worker.js');
console.log('Service Worker registered with scope:', registration.scope);
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(publicVapidKey),
});
await fetch(`${API_BASE_URL}/subscribe`, {
method: 'POST',
body: JSON.stringify(subscription),
headers: {
'Content-Type': 'application/json',
},
});
} catch (error) {
console.error('Subscription failed:', error);
}
};
if ('serviceWorker' in navigator) {
window.addEventListener('load', async () => {
await askNotificationPermission();
});
} }
}, []); }, []);
useEffect(() => { useEffect(() => {
if (socket == null) return; if (socket == null) return;
@@ -350,7 +324,6 @@ function urlBase64ToUint8Array(base64String) {
setModalContent(content); setModalContent(content);
}; };
// Function to close the modal // Function to close the modal
const closeModal = () => { const closeModal = () => {
setIsModalOpen(false); setIsModalOpen(false);

View File

@@ -1,5 +1,5 @@
// src/config.js // src/config.js
const API_BASE_URL = "https://p8hlyz-5000.csb.app"; // Replace with your actual backend URL const API_BASE_URL = "https://sswsts-5000.csb.app"; // Replace with your actual backend URL
export default API_BASE_URL; export default API_BASE_URL;

View File

@@ -0,0 +1,76 @@
import API_BASE_URL from "../config.js";
import { getLocalStorage } from "./localStorageHelpers";
const urlBase64ToUint8Array = (base64String) => {
const padding = "=".repeat((4 - (base64String.length % 4)) % 4);
const base64 = (base64String + padding).replace(/-/g, "+").replace(/_/g, "/");
const rawData = window.atob(base64);
return Uint8Array.from([...rawData].map((char) => char.charCodeAt(0)));
};
const getVapidKey = async () => {
const response = await fetch(`${API_BASE_URL}/vapid-key`);
const { publicVapidKey } = await response.json();
return publicVapidKey;
};
const subscribeUser = async () => {
try {
const publicVapidKey = await getVapidKey();
const registration = await navigator.serviceWorker.register(
"/service-worker.js"
);
console.log("Service Worker registered with scope:", registration.scope);
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(publicVapidKey),
});
await fetch(`${API_BASE_URL}/subscribe`, {
method: "POST",
body: JSON.stringify({
subscription,
token: getLocalStorage("auth"), // Ensure this function is defined elsewhere
}),
headers: {
"Content-Type": "application/json",
},
});
return subscription; // Return subscription if needed
} catch (error) {
console.error("Subscription failed:", error);
}
};
const unsubscribeUser = async () => {
const registration = await navigator.serviceWorker.getRegistration();
if (registration) {
const subscription = await registration.pushManager.getSubscription();
if (subscription) {
await fetch(`${API_BASE_URL}/unsubscribe`, {
method: "POST",
body: JSON.stringify({
subscription,
token: getLocalStorage("auth"), // Ensure this function is defined elsewhere
}),
headers: {
"Content-Type": "application/json",
},
});
await subscription.unsubscribe();
console.log("User unsubscribed from notifications.");
} else {
console.log("No subscription found.");
}
}
};
const resetNotificationSubscription = async () => {
await unsubscribeUser(); // First unsubscribe the user
await subscribeUser(); // Then subscribe the user again
};
export { subscribeUser, unsubscribeUser, resetNotificationSubscription };

View File

@@ -1,7 +1,12 @@
// src/CafePage.js // src/CafePage.js
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { useParams, useSearchParams, useNavigate, useLocation } from "react-router-dom"; import {
useParams,
useSearchParams,
useNavigate,
useLocation,
} from "react-router-dom";
import "../App.css"; import "../App.css";
import SearchInput from "../components/SearchInput"; import SearchInput from "../components/SearchInput";
@@ -18,6 +23,7 @@ import {
getLocalStorage, getLocalStorage,
updateLocalStorage, updateLocalStorage,
} from "../helpers/localStorageHelpers"; } from "../helpers/localStorageHelpers";
import { unsubscribeUser } from "../helpers/subscribeHelpers.js";
function CafePage({ function CafePage({
table, table,
@@ -60,7 +66,6 @@ function CafePage({
} }
}, [user, shopId]); }, [user, shopId]);
useEffect(() => { useEffect(() => {
if (token) { if (token) {
updateLocalStorage("auth", token); updateLocalStorage("auth", token);
@@ -73,6 +78,7 @@ function CafePage({
const handleLogout = () => { const handleLogout = () => {
updateLocalStorage("auth", ""); updateLocalStorage("auth", "");
unsubscribeUser();
navigate(0); navigate(0);
}; };

View File

@@ -8,6 +8,7 @@ import { getAllCafeOwner, createCafeOwner } from "../helpers/userHelpers";
import { getOwnedCafes, createCafe, updateCafe } from "../helpers/cafeHelpers"; import { getOwnedCafes, createCafe, updateCafe } from "../helpers/cafeHelpers";
import { ThreeDots } from "react-loader-spinner"; import { ThreeDots } from "react-loader-spinner";
import { unsubscribeUser } from "../helpers/subscribeHelpers.js";
const Dashboard = ({ user, setModal }) => { const Dashboard = ({ user, setModal }) => {
const navigate = useNavigate(); const navigate = useNavigate();
@@ -50,6 +51,7 @@ const Dashboard = ({ user, setModal }) => {
const handleLogout = () => { const handleLogout = () => {
updateLocalStorage("auth", ""); updateLocalStorage("auth", "");
unsubscribeUser();
navigate(0); navigate(0);
}; };