notification popup
This commit is contained in:
parent
28f4523014
commit
1729d077ab
@ -24,7 +24,65 @@ let authToken = null;
|
||||
let lastAdminTab = 'overview';
|
||||
export { lastAdminTab };
|
||||
|
||||
// --- EVENT HANDLERS (The "Logic") ---
|
||||
// --- NOTIFICATION LOGIC ---
|
||||
|
||||
// This helper function converts the VAPID public key for the browser
|
||||
function urlBase64ToUint8Array(base64String) {
|
||||
const padding = '='.repeat((4 - base64String.length % 4) % 4);
|
||||
const base64 = (base64String + padding).replace(/\-/g, '+').replace(/_/g, '/');
|
||||
const rawData = window.atob(base64);
|
||||
const outputArray = new Uint8Array(rawData.length);
|
||||
for (let i = 0; i < rawData.length; ++i) {
|
||||
outputArray[i] = rawData.charCodeAt(i);
|
||||
}
|
||||
return outputArray;
|
||||
}
|
||||
|
||||
// This function handles the actual subscription process
|
||||
async function subscribeToNotifications() {
|
||||
try {
|
||||
const publicVapidKey = process.env.PUBLIC_VAPID_KEY; // Make sure this is set in your .env
|
||||
const token = localStorage.getItem('authToken');
|
||||
|
||||
if (!token || !publicVapidKey) {
|
||||
return console.error('Auth token or VAPID key is missing.');
|
||||
}
|
||||
|
||||
const register = await navigator.serviceWorker.register('/sw.js', { scope: '/' });
|
||||
const subscription = await register.pushManager.subscribe({
|
||||
userVisibleOnly: true,
|
||||
applicationServerKey: urlBase64ToUint8Array(publicVapidKey)
|
||||
});
|
||||
|
||||
await apiCall('/subscribe', 'POST', subscription);
|
||||
showMessage('You are now subscribed to notifications!', 'success');
|
||||
} catch (error) {
|
||||
console.error('Error subscribing to notifications:', error);
|
||||
showMessage('Failed to subscribe. Please ensure notifications are allowed for this site.', 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// NEW: This function creates the pop-up prompt for the user
|
||||
function promptForNotifications() {
|
||||
// 1. Don't ask if permission is already granted or denied
|
||||
if (Notification.permission !== 'default') {
|
||||
return;
|
||||
}
|
||||
// 2. Don't ask if we've already prompted them before
|
||||
if (localStorage.getItem('notificationPrompted')) {
|
||||
return;
|
||||
}
|
||||
// 3. Wait a couple of seconds after login to ask
|
||||
setTimeout(() => {
|
||||
if (confirm("Enable notifications to receive important updates about your time-off requests and notes?")) {
|
||||
subscribeToNotifications();
|
||||
}
|
||||
// Remember that we've prompted them, so we don't ask again
|
||||
localStorage.setItem('notificationPrompted', 'true');
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
// --- EVENT HANDLERS ---
|
||||
async function handleAuthSubmit(e) {
|
||||
e.preventDefault();
|
||||
const username = e.target.elements.username.value;
|
||||
@ -251,7 +309,6 @@ async function handleEditTimeOffSubmit(e) {
|
||||
}
|
||||
}
|
||||
|
||||
// --- NEW: Handler for clicks specifically on the Time Off History page ---
|
||||
function handleTimeOffHistoryClick(e) {
|
||||
const target = e.target.closest('button');
|
||||
if (!target) return;
|
||||
@ -264,7 +321,7 @@ function handleTimeOffHistoryClick(e) {
|
||||
.then(res => {
|
||||
if (res.success) {
|
||||
showMessage('Request status set to pending.', 'success');
|
||||
renderTimeOffHistoryView(); // Refresh the history view
|
||||
renderTimeOffHistoryView();
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -276,7 +333,7 @@ function handleTimeOffHistoryClick(e) {
|
||||
.then(res => {
|
||||
if (res.success) {
|
||||
showMessage('Request deleted.', 'success');
|
||||
renderTimeOffHistoryView(); // Refresh the history view
|
||||
renderTimeOffHistoryView();
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -334,7 +391,6 @@ export function attachAdminDashboardListeners() {
|
||||
setupTabbedInterface();
|
||||
}
|
||||
|
||||
// --- NEW: Listener attachment function for the history page ---
|
||||
export function attachTimeOffHistoryListeners() {
|
||||
const historyView = document.getElementById('admin-time-off-history-view');
|
||||
if (historyView) {
|
||||
@ -348,8 +404,8 @@ function initializeApp() {
|
||||
const userString = localStorage.getItem('user');
|
||||
user = userString ? JSON.parse(userString) : null;
|
||||
|
||||
if (authToken && user) {
|
||||
const userControls = document.getElementById('nav-user-controls');
|
||||
if (authToken && user) {
|
||||
userControls.classList.remove('hidden');
|
||||
userControls.querySelector('#welcome-message').textContent = `Welcome, ${user.username}`;
|
||||
if (user.role === 'admin') {
|
||||
@ -357,8 +413,10 @@ function initializeApp() {
|
||||
} else {
|
||||
renderEmployeeDashboard();
|
||||
}
|
||||
// Ask for notification permission after user is logged in
|
||||
promptForNotifications();
|
||||
} else {
|
||||
document.getElementById('nav-user-controls').classList.add('hidden');
|
||||
userControls.classList.add('hidden');
|
||||
renderAuthView();
|
||||
}
|
||||
}
|
||||
@ -388,72 +446,9 @@ function setupTabbedInterface() {
|
||||
document.getElementById(`tab-content-${tabTarget}`).classList.remove('hidden');
|
||||
});
|
||||
}
|
||||
// This converts the VAPID public key string to the format the browser needs.
|
||||
function urlBase64ToUint8Array(base64String) {
|
||||
const padding = '='.repeat((4 - base64String.length % 4) % 4);
|
||||
const base64 = (base64String + padding)
|
||||
.replace(/\-/g, '+')
|
||||
.replace(/_/g, '/');
|
||||
|
||||
const rawData = window.atob(base64);
|
||||
const outputArray = new Uint8Array(rawData.length);
|
||||
|
||||
for (let i = 0; i < rawData.length; ++i) {
|
||||
outputArray[i] = rawData.charCodeAt(i);
|
||||
}
|
||||
return outputArray;
|
||||
}
|
||||
|
||||
// --- Subscription Logic ---
|
||||
async function subscribeToNotifications() {
|
||||
// IMPORTANT: Replace with your actual public VAPID key
|
||||
const publicVapidKey = 'YOUR_PUBLIC_VAPID_KEY';
|
||||
const token = localStorage.getItem('token');
|
||||
|
||||
// Check if user is logged in first
|
||||
if (!token) {
|
||||
console.error('User is not logged in.');
|
||||
alert('You must be logged in to enable notifications.');
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. Register the service worker
|
||||
const register = await navigator.serviceWorker.register('/sw.js', {
|
||||
scope: '/'
|
||||
});
|
||||
|
||||
// 2. Get the push subscription
|
||||
const subscription = await register.pushManager.subscribe({
|
||||
userVisibleOnly: true,
|
||||
applicationServerKey: urlBase64ToUint8Array(publicVapidKey)
|
||||
});
|
||||
|
||||
// 3. Send the subscription to your authenticated backend
|
||||
await fetch('/subscribe', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(subscription),
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${token}` // The crucial update!
|
||||
}
|
||||
});
|
||||
|
||||
alert('You are now subscribed to notifications!');
|
||||
}
|
||||
|
||||
// --- Attach to a Button ---
|
||||
// Assuming you have a button in your HTML with id="notifyBtn"
|
||||
const notifyBtn = document.getElementById('notifyBtn');
|
||||
if (notifyBtn) {
|
||||
notifyBtn.addEventListener('click', () => {
|
||||
subscribeToNotifications().catch(error => {
|
||||
console.error('Error subscribing to notifications:', error);
|
||||
alert('Failed to subscribe. Please make sure notifications are allowed for this site.');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// --- START THE APP ---
|
||||
// Register the service worker when the page loads
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', () => {
|
||||
navigator.serviceWorker.register('/sw.js')
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user