// Initialize Web Audio API (lazy loading to respect autoplay policies)
initAudioContext();
+ // Setup event delegation for confirm button (works for both server-rendered and dynamic modals)
+ $(document).on('click', '#shift-reminder-confirm-btn, #shift-reminder-confirm-btn-dynamic', function() {
+ const reminderKey = $('#shift-reminder-key').val() || $(this).data('reminder-key');
+ if (reminderKey) {
+ confirmReminder(reminderKey);
+ } else {
+ console.error('ShiftReminder: reminder_key not found');
+ }
+ });
+
// First check on load — response will schedule the next one via next_check_at
checkReminder();
}
state.isModalVisible = true;
- // Create modal HTML
- // Create modal structure without user data (XSS protection)
- const $modal = $('<div>').attr('id', 'shift-reminder-modal').addClass('shift-reminder-overlay');
- const $content = $('<div>').addClass('shift-reminder-content');
- const $icon = $('<div>').addClass('shift-reminder-icon').html('<i class="fa fa-bell fa-3x"></i>');
- const $title = $('<h2>').addClass('shift-reminder-title').text('Напоминание о смене');
- const $message = $('<p>').addClass('shift-reminder-message');
- const $button = $('<button>')
- .attr('id', 'shift-reminder-confirm-btn')
- .addClass('btn btn-primary btn-lg')
- .text('Подтвердить');
+ // Check if server-rendered modal exists
+ const $existingModal = $('#shift-reminder-overlay');
- // Safely set message text (prevents XSS)
- const messageText = data.message || 'Пожалуйста, подтвердите, что вы ознакомились с напоминанием о смене.';
- $message.text(messageText);
+ if ($existingModal.length > 0) {
+ // Use server-rendered modal
+ const messageText = data.message || 'Пожалуйста, подтвердите, что вы ознакомились с напоминанием о смене.';
+ $('#shift-reminder-message-text').text(messageText);
+ $('#shift-reminder-key').val(data.reminder_key);
- // Assemble modal
- $content.append($icon, $title, $message, $button);
- $modal.append($content);
-
- // Add modal to DOM
- $('body').append($modal);
-
- // Add modal styles
- addModalStyles();
+ // Show the modal
+ $existingModal.fadeIn(300);
+ } else {
+ // Fallback: create modal dynamically (for backward compatibility)
+ const $modal = $('<div>').attr('id', 'shift-reminder-modal').addClass('shift-reminder-overlay');
+ const $content = $('<div>').addClass('shift-reminder-content');
+ const $icon = $('<div>').addClass('shift-reminder-icon').html('<i class="fa fa-bell fa-3x"></i>');
+ const $title = $('<h2>').addClass('shift-reminder-title').text('Напоминание о смене');
+ const $message = $('<p>').addClass('shift-reminder-message');
+ const $button = $('<button>')
+ .attr('id', 'shift-reminder-confirm-btn-dynamic')
+ .addClass('btn btn-primary btn-lg')
+ .text('Подтвердить')
+ .data('reminder-key', data.reminder_key);
+
+ // Safely set message text (prevents XSS)
+ const messageText = data.message || 'Пожалуйста, подтвердите, что вы ознакомились с напоминанием о смене.';
+ $message.text(messageText);
+
+ // Assemble modal
+ $content.append($icon, $title, $message, $button);
+ $modal.append($content);
+
+ // Add modal to DOM
+ $('body').append($modal);
+
+ // Add modal styles
+ addModalStyles();
+ }
// Play audio alert
playAudioAlert();
type: 'modal_shown',
timestamp: new Date().getTime()
});
-
- // Handle confirmation
- $('#shift-reminder-confirm-btn').on('click', function() {
- confirmReminder(data.reminder_key);
- });
}
/**
* Close reminder modal
*/
function closeModal() {
- $('#shift-reminder-modal').fadeOut(300, function() {
- $(this).remove();
+ // Close server-rendered modal if it exists
+ const $serverModal = $('#shift-reminder-overlay');
+ if ($serverModal.length > 0 && $serverModal.is(':visible')) {
+ $serverModal.fadeOut(300, function() {
+ state.isModalVisible = false;
+ });
+ return;
+ }
+
+ // Close dynamic modal if it exists
+ const $dynamicModal = $('#shift-reminder-modal');
+ if ($dynamicModal.length > 0) {
+ $dynamicModal.fadeOut(300, function() {
+ $(this).remove();
+ state.isModalVisible = false;
+ });
+ } else {
state.isModalVisible = false;
- });
+ }
}
/**