HH/templates/complaints/oncall/schedule_list.html
2026-03-15 23:48:45 +03:00

313 lines
11 KiB
HTML

{% extends "layouts/base.html" %}
{% load i18n %}
{% load static %}
{% block title %}{{ title }} - PX360{% endblock %}
{% block extra_css %}
<style>
:root {
--hh-navy: #005696;
--hh-blue: #007bbd;
--hh-light: #eef6fb;
--hh-slate: #64748b;
}
.page-header-gradient {
background: linear-gradient(135deg, #005696 0%, #0069a8 50%, #007bbd 100%);
color: white;
padding: 1.5rem 2rem;
border-radius: 1rem;
margin-bottom: 1.5rem;
box-shadow: 0 10px 15px -3px rgba(0, 86, 150, 0.2);
}
.section-card {
background: white;
border-radius: 1rem;
border: 2px solid #e2e8f0;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
overflow: hidden;
transition: all 0.3s ease;
}
.section-card:hover {
border-color: #005696;
box-shadow: 0 10px 25px -5px rgba(0, 86, 150, 0.15);
}
.section-header {
padding: 1rem 1.5rem;
border-bottom: 2px solid #e2e8f0;
background: linear-gradient(to right, #f8fafc, #f1f5f9);
display: flex;
align-items: center;
gap: 0.75rem;
}
.section-icon {
width: 40px;
height: 40px;
border-radius: 0.75rem;
display: flex;
align-items: center;
justify-content: center;
}
.section-icon.primary {
background: linear-gradient(135deg, #005696, #007bbd);
color: white;
}
.section-icon.secondary {
background: linear-gradient(135deg, #f1f5f9, #e2e8f0);
color: #005696;
}
.btn-primary {
background: linear-gradient(135deg, var(--hh-navy) 0%, var(--hh-blue) 100%);
color: white;
padding: 0.625rem 1.25rem;
border-radius: 0.75rem;
font-weight: 600;
border: none;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
display: inline-flex;
align-items: center;
gap: 0.5rem;
text-decoration: none;
font-size: 0.875rem;
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 8px 16px rgba(0, 86, 150, 0.3);
}
.btn-secondary {
background: white;
color: #475569;
padding: 0.625rem 1.25rem;
border-radius: 0.75rem;
font-weight: 600;
border: 2px solid #e2e8f0;
cursor: pointer;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 0.5rem;
text-decoration: none;
font-size: 0.875rem;
}
.btn-secondary:hover {
background: #f1f5f9;
border-color: #cbd5e1;
transform: translateY(-1px);
}
.schedule-card {
background: white;
border-radius: 1rem;
border: 2px solid #e2e8f0;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
overflow: hidden;
transition: all 0.3s ease;
}
.schedule-card:hover {
border-color: #005696;
box-shadow: 0 10px 25px -5px rgba(0, 86, 150, 0.15);
}
.schedule-card-header {
padding: 1rem 1.5rem;
border-bottom: 2px solid #e2e8f0;
background: linear-gradient(to right, #f8fafc, #f1f5f9);
display: flex;
align-items: center;
justify-content: space-between;
}
.icon-box {
width: 40px;
height: 40px;
border-radius: 0.75rem;
display: flex;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, var(--hh-light), #e0f2fe);
color: var(--hh-navy);
}
.status-dot {
width: 10px;
height: 10px;
border-radius: 50%;
}
.status-dot.active {
background: linear-gradient(135deg, #10b981, #059669);
}
.status-dot.inactive {
background: linear-gradient(135deg, #cbd5e1, #94a3b8);
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.animate-in {
animation: fadeIn 0.5s ease-out forwards;
}
</style>
{% endblock %}
{% block content %}
<div class="px-4 py-6">
<!-- Page Header -->
<div class="page-header-gradient animate-in">
<div class="flex items-center justify-between">
<div class="flex items-center gap-4">
<a href="{% url 'complaints:oncall_dashboard' %}" class="text-white/80 hover:text-white transition">
<i data-lucide="arrow-left" class="w-6 h-6"></i>
</a>
<div>
<h1 class="text-2xl font-bold mb-2">
<i data-lucide="calendar-clock" class="w-7 h-7 inline-block me-2"></i>
{{ title }}
</h1>
<p class="text-white/90">{% trans "Configure working hours and on-call admin assignments" %}</p>
</div>
</div>
<a href="{% url 'complaints:oncall_schedule_create' %}" class="btn-secondary">
<i data-lucide="plus" class="w-4 h-4"></i>
{% trans "Create Schedule" %}
</a>
</div>
</div>
<!-- Schedules Grid -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{% for schedule in schedules %}
<div class="schedule-card animate-in">
<div class="schedule-card-header">
<div class="flex items-center gap-2">
{% if schedule.hospital %}
<span class="font-bold text-navy">{{ schedule.hospital.name }}</span>
{% else %}
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-bold bg-[#eef6fb] text-[#005696]">
{% trans "System-wide" %}
</span>
{% endif %}
</div>
{% if schedule.is_active %}
<span class="status-dot active" title="{% trans 'Active' %}"></span>
{% else %}
<span class="status-dot inactive" title="{% trans 'Inactive' %}"></span>
{% endif %}
</div>
<div class="p-6">
<div class="space-y-4">
<!-- Working Hours -->
<div class="flex items-center gap-3">
<div class="icon-box">
<i data-lucide="clock" class="w-5 h-5"></i>
</div>
<div>
<p class="text-sm text-slate font-medium">{% trans "Working Hours" %}</p>
<p class="font-bold text-gray-900">
{{ schedule.work_start_time|time:"H:i" }} - {{ schedule.work_end_time|time:"H:i" }}
</p>
</div>
</div>
<!-- Working Days -->
<div class="flex items-center gap-3">
<div class="icon-box">
<i data-lucide="calendar" class="w-5 h-5"></i>
</div>
<div>
<p class="text-sm text-slate font-medium">{% trans "Working Days" %}</p>
<p class="font-bold text-gray-900 text-sm">
{% for day in schedule.get_working_days_list %}
{% if day == 0 %}{% trans "Mon" %}{% elif day == 1 %}{% trans "Tue" %}{% elif day == 2 %}{% trans "Wed" %}{% elif day == 3 %}{% trans "Thu" %}{% elif day == 4 %}{% trans "Fri" %}{% elif day == 5 %}{% trans "Sat" %}{% elif day == 6 %}{% trans "Sun" %}{% endif %}{% if not forloop.last %}, {% endif %}
{% endfor %}
</p>
</div>
</div>
<!-- Timezone -->
<div class="flex items-center gap-3">
<div class="icon-box">
<i data-lucide="globe" class="w-5 h-5"></i>
</div>
<div>
<p class="text-sm text-slate font-medium">{% trans "Timezone" %}</p>
<p class="font-bold text-gray-900 text-sm">{{ schedule.timezone }}</p>
</div>
</div>
<!-- On-Call Admins Count -->
<div class="flex items-center gap-3">
<div class="icon-box">
<i data-lucide="users" class="w-5 h-5"></i>
</div>
<div>
<p class="text-sm text-slate font-medium">{% trans "On-Call Admins" %}</p>
<p class="font-bold text-[#007bbd]">{{ schedule.on_call_admins.count }}</p>
</div>
</div>
</div>
<!-- Actions -->
<div class="mt-6 pt-4 border-t border-slate-200 flex gap-2">
<a href="{% url 'complaints:oncall_schedule_detail' schedule.id %}"
class="flex-1 px-3 py-2 bg-[#005696] text-white text-sm rounded-lg hover:bg-[#007bbd] transition-colors text-center font-semibold">
{% trans "View" %}
</a>
<a href="{% url 'complaints:oncall_schedule_edit' schedule.id %}"
class="px-3 py-2 border-2 border-slate-200 text-slate-600 text-sm rounded-lg hover:bg-slate-50 transition-colors">
<i data-lucide="edit" class="w-4 h-4"></i>
</a>
<form method="post" action="{% url 'complaints:oncall_schedule_delete' schedule.id %}"
class="inline" onsubmit="return confirm('{% trans "Are you sure you want to delete this schedule?" %}')">
{% csrf_token %}
<button type="submit" class="px-3 py-2 border-2 border-red-200 text-red-600 text-sm rounded-lg hover:bg-red-50 transition-colors">
<i data-lucide="trash-2" class="w-4 h-4"></i>
</button>
</form>
</div>
</div>
</div>
{% empty %}
<div class="col-span-full">
<div class="section-card p-12 text-center animate-in">
<div class="w-16 h-16 bg-slate-100 rounded-full flex items-center justify-center mx-auto mb-4">
<i data-lucide="calendar-x" class="w-8 h-8 text-slate-400"></i>
</div>
<h3 class="text-lg font-bold text-navy mb-2">{% trans "No On-Call Schedules" %}</h3>
<p class="text-slate mb-6 max-w-md mx-auto">
{% trans "Create your first on-call schedule to configure working hours and assign on-call admins for after-hours complaint notifications." %}
</p>
<a href="{% url 'complaints:oncall_schedule_create' %}" class="btn-primary">
<i data-lucide="plus" class="w-5 h-5"></i>
{% trans "Create Schedule" %}
</a>
</div>
</div>
{% endfor %}
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
lucide.createIcons();
});
</script>
{% endblock %}