895 lines
46 KiB
HTML
895 lines
46 KiB
HTML
{% extends "base.html" %}
|
|
{% load static %}
|
|
|
|
{% block title %}Notification Settings - {{ block.super }}{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container-fluid">
|
|
<!-- Page Header -->
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<div>
|
|
<h1 class="h3 mb-1">Notification Settings</h1>
|
|
<nav aria-label="breadcrumb">
|
|
<ol class="breadcrumb mb-0">
|
|
<li class="breadcrumb-item"><a href="{% url 'communications:dashboard' %}">Communications</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'communications:notification_list' %}">Notifications</a></li>
|
|
<li class="breadcrumb-item active">Settings</li>
|
|
</ol>
|
|
</nav>
|
|
</div>
|
|
<div class="btn-group">
|
|
<a href="{% url 'communications:notification_list' %}" class="btn btn-outline-secondary">
|
|
<i class="fas fa-arrow-left me-2"></i>Back to Notifications
|
|
</a>
|
|
<button type="button" class="btn btn-outline-info" onclick="testNotifications()">
|
|
<i class="fas fa-bell me-2"></i>Test Notifications
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<form method="post" id="notificationSettingsForm" hx-post="{% url 'communications:notification_settings' %}" hx-target="#settings-container">
|
|
{% csrf_token %}
|
|
|
|
<div id="settings-container">
|
|
<div class="row">
|
|
<!-- General Settings -->
|
|
<div class="col-lg-8">
|
|
<!-- Email Notifications -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-envelope me-2"></i>Email Notifications
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-check form-switch mb-3">
|
|
{{ form.email_enabled }}
|
|
<label class="form-check-label" for="{{ form.email_enabled.id_for_label }}">
|
|
<strong>Enable Email Notifications</strong>
|
|
<div class="small text-muted">Receive notifications via email</div>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-floating">
|
|
{{ form.email_frequency }}
|
|
<label for="{{ form.email_frequency.id_for_label }}">Email Frequency</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="emailSettings" style="{% if not form.email_enabled.value %}display: none;{% endif %}">
|
|
<hr>
|
|
<h6 class="mb-3">Email Notification Types</h6>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-check mb-2">
|
|
{{ form.email_appointments }}
|
|
<label class="form-check-label" for="{{ form.email_appointments.id_for_label }}">
|
|
Appointment Reminders
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-2">
|
|
{{ form.email_lab_results }}
|
|
<label class="form-check-label" for="{{ form.email_lab_results.id_for_label }}">
|
|
Lab Results Available
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-2">
|
|
{{ form.email_medications }}
|
|
<label class="form-check-label" for="{{ form.email_medications.id_for_label }}">
|
|
Medication Reminders
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-2">
|
|
{{ form.email_billing }}
|
|
<label class="form-check-label" for="{{ form.email_billing.id_for_label }}">
|
|
Billing & Payment Updates
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-check mb-2">
|
|
{{ form.email_emergency }}
|
|
<label class="form-check-label" for="{{ form.email_emergency.id_for_label }}">
|
|
Emergency Alerts
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-2">
|
|
{{ form.email_system }}
|
|
<label class="form-check-label" for="{{ form.email_system.id_for_label }}">
|
|
System Updates
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-2">
|
|
{{ form.email_clinical }}
|
|
<label class="form-check-label" for="{{ form.email_clinical.id_for_label }}">
|
|
Clinical Updates
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-2">
|
|
{{ form.email_administrative }}
|
|
<label class="form-check-label" for="{{ form.email_administrative.id_for_label }}">
|
|
Administrative Notices
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- SMS Notifications -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-sms me-2"></i>SMS Notifications
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-check form-switch mb-3">
|
|
{{ form.sms_enabled }}
|
|
<label class="form-check-label" for="{{ form.sms_enabled.id_for_label }}">
|
|
<strong>Enable SMS Notifications</strong>
|
|
<div class="small text-muted">Receive notifications via text message</div>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-floating">
|
|
{{ form.phone_number }}
|
|
<label for="{{ form.phone_number.id_for_label }}">Phone Number</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="smsSettings" style="{% if not form.sms_enabled.value %}display: none;{% endif %}">
|
|
<hr>
|
|
<h6 class="mb-3">SMS Notification Types</h6>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-check mb-2">
|
|
{{ form.sms_appointments }}
|
|
<label class="form-check-label" for="{{ form.sms_appointments.id_for_label }}">
|
|
Appointment Reminders
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-2">
|
|
{{ form.sms_lab_results }}
|
|
<label class="form-check-label" for="{{ form.sms_lab_results.id_for_label }}">
|
|
Lab Results Available
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-2">
|
|
{{ form.sms_medications }}
|
|
<label class="form-check-label" for="{{ form.sms_medications.id_for_label }}">
|
|
Medication Reminders
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-check mb-2">
|
|
{{ form.sms_emergency }}
|
|
<label class="form-check-label" for="{{ form.sms_emergency.id_for_label }}">
|
|
Emergency Alerts
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-2">
|
|
{{ form.sms_billing }}
|
|
<label class="form-check-label" for="{{ form.sms_billing.id_for_label }}">
|
|
Payment Due Reminders
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="alert alert-info mt-3">
|
|
<i class="fas fa-info-circle me-2"></i>
|
|
<strong>SMS Quiet Hours:</strong> SMS notifications will not be sent between 10 PM and 8 AM unless marked as emergency.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Push Notifications -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-mobile-alt me-2"></i>Push Notifications
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="form-check form-switch mb-3">
|
|
{{ form.push_enabled }}
|
|
<label class="form-check-label" for="{{ form.push_enabled.id_for_label }}">
|
|
<strong>Enable Push Notifications</strong>
|
|
<div class="small text-muted">Receive notifications on your devices</div>
|
|
</label>
|
|
</div>
|
|
|
|
<div id="pushSettings" style="{% if not form.push_enabled.value %}display: none;{% endif %}">
|
|
<hr>
|
|
<h6 class="mb-3">Push Notification Types</h6>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-check mb-2">
|
|
{{ form.push_appointments }}
|
|
<label class="form-check-label" for="{{ form.push_appointments.id_for_label }}">
|
|
Appointment Reminders
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-2">
|
|
{{ form.push_lab_results }}
|
|
<label class="form-check-label" for="{{ form.push_lab_results.id_for_label }}">
|
|
Lab Results Available
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-2">
|
|
{{ form.push_medications }}
|
|
<label class="form-check-label" for="{{ form.push_medications.id_for_label }}">
|
|
Medication Reminders
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-2">
|
|
{{ form.push_billing }}
|
|
<label class="form-check-label" for="{{ form.push_billing.id_for_label }}">
|
|
Billing Updates
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-check mb-2">
|
|
{{ form.push_emergency }}
|
|
<label class="form-check-label" for="{{ form.push_emergency.id_for_label }}">
|
|
Emergency Alerts
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-2">
|
|
{{ form.push_system }}
|
|
<label class="form-check-label" for="{{ form.push_system.id_for_label }}">
|
|
System Updates
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-2">
|
|
{{ form.push_clinical }}
|
|
<label class="form-check-label" for="{{ form.push_clinical.id_for_label }}">
|
|
Clinical Updates
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-2">
|
|
{{ form.push_messages }}
|
|
<label class="form-check-label" for="{{ form.push_messages.id_for_label }}">
|
|
New Messages
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- In-App Notifications -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-bell me-2"></i>In-App Notifications
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="form-check form-switch mb-3">
|
|
{{ form.in_app_enabled }}
|
|
<label class="form-check-label" for="{{ form.in_app_enabled.id_for_label }}">
|
|
<strong>Enable In-App Notifications</strong>
|
|
<div class="small text-muted">Show notifications within the application</div>
|
|
</label>
|
|
</div>
|
|
|
|
<div id="inAppSettings" style="{% if not form.in_app_enabled.value %}display: none;{% endif %}">
|
|
<hr>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-check form-switch mb-3">
|
|
{{ form.show_desktop_notifications }}
|
|
<label class="form-check-label" for="{{ form.show_desktop_notifications.id_for_label }}">
|
|
Desktop Notifications
|
|
<div class="small text-muted">Show browser notifications</div>
|
|
</label>
|
|
</div>
|
|
<div class="form-check form-switch mb-3">
|
|
{{ form.play_notification_sound }}
|
|
<label class="form-check-label" for="{{ form.play_notification_sound.id_for_label }}">
|
|
Notification Sounds
|
|
<div class="small text-muted">Play sound for new notifications</div>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
{{ form.notification_position }}
|
|
<label for="{{ form.notification_position.id_for_label }}">Notification Position</label>
|
|
</div>
|
|
<div class="form-floating">
|
|
{{ form.auto_dismiss_time }}
|
|
<label for="{{ form.auto_dismiss_time.id_for_label }}">Auto Dismiss (seconds)</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Priority Settings -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-exclamation-triangle me-2"></i>Priority Settings
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<h6 class="mb-3">Critical Notifications</h6>
|
|
<div class="form-check mb-2">
|
|
{{ form.critical_override_quiet_hours }}
|
|
<label class="form-check-label" for="{{ form.critical_override_quiet_hours.id_for_label }}">
|
|
Override quiet hours for critical notifications
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-2">
|
|
{{ form.critical_all_channels }}
|
|
<label class="form-check-label" for="{{ form.critical_all_channels.id_for_label }}">
|
|
Send critical notifications via all enabled channels
|
|
</label>
|
|
</div>
|
|
<div class="form-check mb-2">
|
|
{{ form.critical_repeat_until_read }}
|
|
<label class="form-check-label" for="{{ form.critical_repeat_until_read.id_for_label }}">
|
|
Repeat critical notifications until read
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<h6 class="mb-3">Escalation Settings</h6>
|
|
<div class="form-floating mb-3">
|
|
{{ form.escalation_delay }}
|
|
<label for="{{ form.escalation_delay.id_for_label }}">Escalation Delay (minutes)</label>
|
|
</div>
|
|
<div class="form-floating">
|
|
{{ form.escalation_contact }}
|
|
<label for="{{ form.escalation_contact.id_for_label }}">Escalation Contact</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Quiet Hours -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-moon me-2"></i>Quiet Hours
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="form-check form-switch mb-3">
|
|
{{ form.quiet_hours_enabled }}
|
|
<label class="form-check-label" for="{{ form.quiet_hours_enabled.id_for_label }}">
|
|
<strong>Enable Quiet Hours</strong>
|
|
<div class="small text-muted">Suppress non-critical notifications during specified hours</div>
|
|
</label>
|
|
</div>
|
|
|
|
<div id="quietHoursSettings" style="{% if not form.quiet_hours_enabled.value %}display: none;{% endif %}">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
{{ form.quiet_hours_start }}
|
|
<label for="{{ form.quiet_hours_start.id_for_label }}">Start Time</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
{{ form.quiet_hours_end }}
|
|
<label for="{{ form.quiet_hours_end.id_for_label }}">End Time</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Quiet Days</label>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-check">
|
|
{{ form.quiet_weekends }}
|
|
<label class="form-check-label" for="{{ form.quiet_weekends.id_for_label }}">
|
|
Weekends (Saturday & Sunday)
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-check">
|
|
{{ form.quiet_holidays }}
|
|
<label class="form-check-label" for="{{ form.quiet_holidays.id_for_label }}">
|
|
Holidays
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Action Buttons -->
|
|
<div class="d-flex justify-content-between">
|
|
<div>
|
|
<a href="{% url 'communications:notification_list' %}" class="btn btn-outline-secondary">
|
|
<i class="fas fa-times me-2"></i>Cancel
|
|
</a>
|
|
</div>
|
|
<div class="btn-group">
|
|
<button type="button" class="btn btn-outline-warning" onclick="resetToDefaults()">
|
|
<i class="fas fa-undo me-2"></i>Reset to Defaults
|
|
</button>
|
|
<button type="submit" class="btn btn-success">
|
|
<i class="fas fa-save me-2"></i>Save Settings
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Sidebar -->
|
|
<div class="col-lg-4">
|
|
<!-- Current Settings Summary -->
|
|
<div class="card mb-3">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-info-circle me-2"></i>Current Settings
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="mb-3">
|
|
<div class="d-flex justify-content-between">
|
|
<span>Email:</span>
|
|
<span class="badge bg-{% if form.email_enabled.value %}success{% else %}secondary{% endif %}">
|
|
{% if form.email_enabled.value %}Enabled{% else %}Disabled{% endif %}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="mb-3">
|
|
<div class="d-flex justify-content-between">
|
|
<span>SMS:</span>
|
|
<span class="badge bg-{% if form.sms_enabled.value %}success{% else %}secondary{% endif %}">
|
|
{% if form.sms_enabled.value %}Enabled{% else %}Disabled{% endif %}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="mb-3">
|
|
<div class="d-flex justify-content-between">
|
|
<span>Push:</span>
|
|
<span class="badge bg-{% if form.push_enabled.value %}success{% else %}secondary{% endif %}">
|
|
{% if form.push_enabled.value %}Enabled{% else %}Disabled{% endif %}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="mb-3">
|
|
<div class="d-flex justify-content-between">
|
|
<span>In-App:</span>
|
|
<span class="badge bg-{% if form.in_app_enabled.value %}success{% else %}secondary{% endif %}">
|
|
{% if form.in_app_enabled.value %}Enabled{% else %}Disabled{% endif %}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
<div class="mb-3">
|
|
<div class="d-flex justify-content-between">
|
|
<span>Quiet Hours:</span>
|
|
<span class="badge bg-{% if form.quiet_hours_enabled.value %}warning{% else %}secondary{% endif %}">
|
|
{% if form.quiet_hours_enabled.value %}Active{% else %}Inactive{% endif %}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Quick Presets -->
|
|
<div class="card mb-3">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-magic me-2"></i>Quick Presets
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="d-grid gap-2">
|
|
<button type="button" class="btn btn-outline-primary" onclick="applyPreset('all_on')">
|
|
<i class="fas fa-bell me-2"></i>All Notifications On
|
|
</button>
|
|
<button type="button" class="btn btn-outline-warning" onclick="applyPreset('essential_only')">
|
|
<i class="fas fa-exclamation-triangle me-2"></i>Essential Only
|
|
</button>
|
|
<button type="button" class="btn btn-outline-info" onclick="applyPreset('work_hours')">
|
|
<i class="fas fa-business-time me-2"></i>Work Hours Only
|
|
</button>
|
|
<button type="button" class="btn btn-outline-secondary" onclick="applyPreset('minimal')">
|
|
<i class="fas fa-volume-mute me-2"></i>Minimal Notifications
|
|
</button>
|
|
<button type="button" class="btn btn-outline-danger" onclick="applyPreset('emergency_only')">
|
|
<i class="fas fa-ambulance me-2"></i>Emergency Only
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Test Notifications -->
|
|
<div class="card mb-3">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-vial me-2"></i>Test Notifications
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<p class="small text-muted mb-3">Test your notification settings to ensure they work correctly.</p>
|
|
<div class="d-grid gap-2">
|
|
<button type="button" class="btn btn-outline-primary btn-sm" onclick="testNotification('email')">
|
|
<i class="fas fa-envelope me-2"></i>Test Email
|
|
</button>
|
|
<button type="button" class="btn btn-outline-success btn-sm" onclick="testNotification('sms')">
|
|
<i class="fas fa-sms me-2"></i>Test SMS
|
|
</button>
|
|
<button type="button" class="btn btn-outline-info btn-sm" onclick="testNotification('push')">
|
|
<i class="fas fa-mobile-alt me-2"></i>Test Push
|
|
</button>
|
|
<button type="button" class="btn btn-outline-warning btn-sm" onclick="testNotification('in_app')">
|
|
<i class="fas fa-bell me-2"></i>Test In-App
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Help & Tips -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-question-circle me-2"></i>Help & Tips
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="accordion accordion-flush" id="helpAccordion">
|
|
<div class="accordion-item">
|
|
<h2 class="accordion-header">
|
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#help1">
|
|
Email Notifications
|
|
</button>
|
|
</h2>
|
|
<div id="help1" class="accordion-collapse collapse" data-bs-parent="#helpAccordion">
|
|
<div class="accordion-body small">
|
|
Email notifications are sent to your registered email address. You can choose to receive them immediately, in a daily digest, or weekly summary.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="accordion-item">
|
|
<h2 class="accordion-header">
|
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#help2">
|
|
SMS Notifications
|
|
</button>
|
|
</h2>
|
|
<div id="help2" class="accordion-collapse collapse" data-bs-parent="#helpAccordion">
|
|
<div class="accordion-body small">
|
|
SMS notifications are sent to your mobile phone. Standard messaging rates may apply. Emergency notifications will override quiet hours.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="accordion-item">
|
|
<h2 class="accordion-header">
|
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#help3">
|
|
Quiet Hours
|
|
</button>
|
|
</h2>
|
|
<div id="help3" class="accordion-collapse collapse" data-bs-parent="#helpAccordion">
|
|
<div class="accordion-body small">
|
|
During quiet hours, only critical and emergency notifications will be sent. All other notifications will be queued and delivered when quiet hours end.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<script>
|
|
// Initialize settings page
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
setupToggleHandlers();
|
|
requestNotificationPermission();
|
|
});
|
|
|
|
function setupToggleHandlers() {
|
|
// Email settings toggle
|
|
document.getElementById('{{ form.email_enabled.id_for_label }}').addEventListener('change', function() {
|
|
const emailSettings = document.getElementById('emailSettings');
|
|
emailSettings.style.display = this.checked ? 'block' : 'none';
|
|
});
|
|
|
|
// SMS settings toggle
|
|
document.getElementById('{{ form.sms_enabled.id_for_label }}').addEventListener('change', function() {
|
|
const smsSettings = document.getElementById('smsSettings');
|
|
smsSettings.style.display = this.checked ? 'block' : 'none';
|
|
});
|
|
|
|
// Push settings toggle
|
|
document.getElementById('{{ form.push_enabled.id_for_label }}').addEventListener('change', function() {
|
|
const pushSettings = document.getElementById('pushSettings');
|
|
pushSettings.style.display = this.checked ? 'block' : 'none';
|
|
});
|
|
|
|
// In-app settings toggle
|
|
document.getElementById('{{ form.in_app_enabled.id_for_label }}').addEventListener('change', function() {
|
|
const inAppSettings = document.getElementById('inAppSettings');
|
|
inAppSettings.style.display = this.checked ? 'block' : 'none';
|
|
});
|
|
|
|
// Quiet hours toggle
|
|
document.getElementById('{{ form.quiet_hours_enabled.id_for_label }}').addEventListener('change', function() {
|
|
const quietHoursSettings = document.getElementById('quietHoursSettings');
|
|
quietHoursSettings.style.display = this.checked ? 'block' : 'none';
|
|
});
|
|
}
|
|
|
|
function requestNotificationPermission() {
|
|
if ('Notification' in window && Notification.permission === 'default') {
|
|
Notification.requestPermission().then(function(permission) {
|
|
if (permission === 'granted') {
|
|
showToast('Success', 'Browser notifications enabled', 'success');
|
|
} else {
|
|
showToast('Info', 'Browser notifications disabled', 'info');
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
function applyPreset(presetName) {
|
|
const presets = {
|
|
'all_on': {
|
|
email_enabled: true,
|
|
sms_enabled: true,
|
|
push_enabled: true,
|
|
in_app_enabled: true,
|
|
quiet_hours_enabled: false,
|
|
// Enable all notification types
|
|
email_appointments: true,
|
|
email_lab_results: true,
|
|
email_medications: true,
|
|
email_billing: true,
|
|
email_emergency: true,
|
|
email_system: true,
|
|
email_clinical: true,
|
|
email_administrative: true,
|
|
sms_appointments: true,
|
|
sms_lab_results: true,
|
|
sms_medications: true,
|
|
sms_emergency: true,
|
|
sms_billing: true,
|
|
push_appointments: true,
|
|
push_lab_results: true,
|
|
push_medications: true,
|
|
push_billing: true,
|
|
push_emergency: true,
|
|
push_system: true,
|
|
push_clinical: true,
|
|
push_messages: true
|
|
},
|
|
'essential_only': {
|
|
email_enabled: true,
|
|
sms_enabled: true,
|
|
push_enabled: true,
|
|
in_app_enabled: true,
|
|
quiet_hours_enabled: true,
|
|
// Only essential notifications
|
|
email_appointments: true,
|
|
email_lab_results: true,
|
|
email_emergency: true,
|
|
sms_appointments: true,
|
|
sms_emergency: true,
|
|
push_appointments: true,
|
|
push_emergency: true,
|
|
push_messages: true
|
|
},
|
|
'work_hours': {
|
|
email_enabled: true,
|
|
sms_enabled: false,
|
|
push_enabled: true,
|
|
in_app_enabled: true,
|
|
quiet_hours_enabled: true,
|
|
quiet_hours_start: '18:00',
|
|
quiet_hours_end: '08:00',
|
|
quiet_weekends: true
|
|
},
|
|
'minimal': {
|
|
email_enabled: true,
|
|
email_frequency: 'DAILY',
|
|
sms_enabled: false,
|
|
push_enabled: false,
|
|
in_app_enabled: true,
|
|
quiet_hours_enabled: true,
|
|
// Only critical notifications
|
|
email_emergency: true,
|
|
email_appointments: true
|
|
},
|
|
'emergency_only': {
|
|
email_enabled: true,
|
|
sms_enabled: true,
|
|
push_enabled: true,
|
|
in_app_enabled: true,
|
|
// Only emergency notifications
|
|
email_emergency: true,
|
|
sms_emergency: true,
|
|
push_emergency: true,
|
|
critical_override_quiet_hours: true,
|
|
critical_all_channels: true
|
|
}
|
|
};
|
|
|
|
const preset = presets[presetName];
|
|
if (!preset) return;
|
|
|
|
// Apply preset values to form
|
|
Object.keys(preset).forEach(key => {
|
|
const field = document.getElementById(`id_${key}`);
|
|
if (field) {
|
|
if (field.type === 'checkbox') {
|
|
field.checked = preset[key];
|
|
field.dispatchEvent(new Event('change'));
|
|
} else {
|
|
field.value = preset[key];
|
|
}
|
|
}
|
|
});
|
|
|
|
showToast('Success', `Applied ${presetName.replace('_', ' ')} preset`, 'success');
|
|
}
|
|
|
|
function resetToDefaults() {
|
|
if (confirm('Reset all notification settings to defaults? This will override your current settings.')) {
|
|
applyPreset('essential_only');
|
|
}
|
|
}
|
|
|
|
function testNotification(type) {
|
|
fetch('{% url "communications:test_notification" %}', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
'X-CSRFToken': getCsrfToken()
|
|
},
|
|
body: JSON.stringify({
|
|
notification_type: type
|
|
})
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
showToast('Success', `Test ${type} notification sent`, 'success');
|
|
|
|
// Show in-app notification for testing
|
|
if (type === 'in_app' || type === 'push') {
|
|
showTestNotification();
|
|
}
|
|
} else {
|
|
showToast('Error', data.error || `Failed to send test ${type} notification`, 'error');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error sending test notification:', error);
|
|
showToast('Error', `Failed to send test ${type} notification`, 'error');
|
|
});
|
|
}
|
|
|
|
function showTestNotification() {
|
|
if ('Notification' in window && Notification.permission === 'granted') {
|
|
new Notification('Test Notification', {
|
|
body: 'This is a test notification from the Hospital Management System.',
|
|
icon: '/static/images/logo.png',
|
|
tag: 'test-notification'
|
|
});
|
|
} else {
|
|
// Fallback to in-app notification
|
|
showToast('Test', 'This is a test notification', 'info');
|
|
}
|
|
}
|
|
|
|
function testNotifications() {
|
|
const enabledTypes = [];
|
|
|
|
if (document.getElementById('{{ form.email_enabled.id_for_label }}').checked) {
|
|
enabledTypes.push('email');
|
|
}
|
|
if (document.getElementById('{{ form.sms_enabled.id_for_label }}').checked) {
|
|
enabledTypes.push('sms');
|
|
}
|
|
if (document.getElementById('{{ form.push_enabled.id_for_label }}').checked) {
|
|
enabledTypes.push('push');
|
|
}
|
|
if (document.getElementById('{{ form.in_app_enabled.id_for_label }}').checked) {
|
|
enabledTypes.push('in_app');
|
|
}
|
|
|
|
if (enabledTypes.length === 0) {
|
|
showToast('Warning', 'No notification types are enabled', 'warning');
|
|
return;
|
|
}
|
|
|
|
enabledTypes.forEach(type => {
|
|
setTimeout(() => testNotification(type), 1000);
|
|
});
|
|
}
|
|
|
|
// Form submission handler
|
|
document.getElementById('notificationSettingsForm').addEventListener('submit', function(e) {
|
|
e.preventDefault();
|
|
|
|
const formData = new FormData(this);
|
|
|
|
fetch('{% url "communications:notification_settings" %}', {
|
|
method: 'POST',
|
|
body: formData
|
|
})
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.success) {
|
|
showToast('Success', 'Notification settings saved successfully', 'success');
|
|
|
|
// Update current settings summary
|
|
updateSettingsSummary();
|
|
} else {
|
|
showToast('Error', data.error || 'Failed to save notification settings', 'error');
|
|
}
|
|
})
|
|
.catch(error => {
|
|
console.error('Error saving notification settings:', error);
|
|
showToast('Error', 'Failed to save notification settings', 'error');
|
|
});
|
|
});
|
|
|
|
function updateSettingsSummary() {
|
|
// Update the current settings summary in the sidebar
|
|
// This would be implemented based on the actual form values
|
|
}
|
|
|
|
function getCsrfToken() {
|
|
return document.querySelector('[name=csrfmiddlewaretoken]').value;
|
|
}
|
|
|
|
function showToast(title, message, type) {
|
|
// Implementation depends on your toast system
|
|
console.log(`${type.toUpperCase()}: ${title} - ${message}`);
|
|
|
|
// Show browser notification if enabled and permission granted
|
|
if (type === 'success' && 'Notification' in window && Notification.permission === 'granted') {
|
|
new Notification(title, {
|
|
body: message,
|
|
icon: '/static/images/logo.png'
|
|
});
|
|
}
|
|
}
|
|
|
|
// Auto-save settings on change (debounced)
|
|
let saveTimeout;
|
|
document.querySelectorAll('input, select').forEach(input => {
|
|
input.addEventListener('change', function() {
|
|
clearTimeout(saveTimeout);
|
|
saveTimeout = setTimeout(() => {
|
|
// Auto-save after 2 seconds of no changes
|
|
document.getElementById('notificationSettingsForm').dispatchEvent(new Event('submit'));
|
|
}, 2000);
|
|
});
|
|
});
|
|
</script>
|
|
{% endblock %}
|
|
|