HH/templates/layouts/source_user_base.html
2026-03-09 16:10:24 +03:00

294 lines
13 KiB
HTML

{% load i18n %}
<!DOCTYPE html>
<html lang="{% get_current_language as LANGUAGE_CODE %}{{ LANGUAGE_CODE }}" dir="{% if LANGUAGE_CODE == 'ar' %}rtl{% else %}ltr{% endif %}">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{% block title %}{% trans "PX360 - Patient Experience Management" %}{% endblock %}</title>
<!-- TailwindCSS -->
<script src="https://cdn.tailwindcss.com"></script>
<!-- Lucide Icons -->
<script src="https://unpkg.com/lucide@latest"></script>
<!-- Google Fonts - Inter -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
<!-- ApexCharts -->
<script src="https://cdn.jsdelivr.net/npm/apexcharts@3.45.1/dist/apexcharts.min.js"></script>
<!-- HTMX for dynamic updates -->
<script src="https://unpkg.com/htmx.org@1.9.10"></script>
<!-- Tailwind Config -->
<script>
tailwind.config = {
theme: {
extend: {
fontFamily: {
'inter': ['Inter', 'sans-serif'],
},
colors: {
'navy': '#005696',
'blue': '#007bbd',
'light': '#eef6fb',
'slate': '#64748b',
}
}
}
}
</script>
<!-- Custom Styles -->
<style>
body {
font-family: 'Inter', sans-serif;
}
/* Custom scrollbar */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background: #f1f5f9;
}
::-webkit-scrollbar-thumb {
background: #cbd5e1;
border-radius: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: #94a3b8;
}
/* Sidebar transitions */
.sidebar-transition {
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
/* Animation */
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.animate-in {
animation: fadeIn 0.5s ease-out forwards;
}
</style>
{% block extra_css %}{% endblock %}
</head>
<body class="bg-gradient-to-br from-light to-blue-50 min-h-screen">
<!-- Sidebar -->
<aside id="sidebar" class="fixed left-0 top-0 h-screen w-64 bg-gradient-to-b from-navy to-blue shadow-xl z-50 sidebar-transition overflow-y-auto">
<!-- Brand -->
<div class="p-6 border-b border-white/10">
<div class="flex items-center gap-3">
<div class="w-10 h-10 bg-white/20 rounded-xl flex items-center justify-center">
<i data-lucide="radio" class="w-6 h-6 text-white"></i>
</div>
<div>
<h1 class="text-xl font-bold text-white">PX360</h1>
<p class="text-xs text-white/70">{% trans "Source Portal" %}</p>
</div>
</div>
</div>
<!-- Navigation -->
<nav class="p-4 space-y-1">
<!-- Dashboard -->
<a href="{% url 'px_sources:source_user_dashboard' %}"
class="flex items-center gap-3 p-3 rounded-xl transition {% if request.resolver_match.url_name == 'source_user_dashboard' %}bg-white/20 text-white{% else %}text-white/80 hover:bg-white/10 hover:text-white{% endif %}">
<i data-lucide="layout-dashboard" class="w-5 h-5"></i>
<span class="font-medium text-sm">{% trans "Dashboard" %}</span>
</a>
<div class="my-4 border-t border-white/10"></div>
<!-- Create -->
<p class="px-3 text-xs font-semibold text-white/50 uppercase tracking-wider mb-2">{% trans "Create" %}</p>
{% if source_user.can_create_complaints %}
<a href="{% url 'px_sources:source_user_create_complaint' %}"
class="flex items-center gap-3 p-3 rounded-xl transition {% if request.resolver_match.url_name == 'source_user_create_complaint' %}bg-white/20 text-white{% else %}text-white/80 hover:bg-white/10 hover:text-white{% endif %}">
<i data-lucide="plus-circle" class="w-5 h-5"></i>
<span class="font-medium text-sm">{% trans "New Complaint" %}</span>
</a>
{% endif %}
{% if source_user.can_create_inquiries %}
<a href="{% url 'px_sources:source_user_create_inquiry' %}"
class="flex items-center gap-3 p-3 rounded-xl transition {% if request.resolver_match.url_name == 'source_user_create_inquiry' %}bg-white/20 text-white{% else %}text-white/80 hover:bg-white/10 hover:text-white{% endif %}">
<i data-lucide="plus-circle" class="w-5 h-5"></i>
<span class="font-medium text-sm">{% trans "New Inquiry" %}</span>
</a>
{% endif %}
<div class="my-4 border-t border-white/10"></div>
<!-- Lists -->
<p class="px-3 text-xs font-semibold text-white/50 uppercase tracking-wider mb-2">{% trans "My Feedback" %}</p>
<a href="{% url 'px_sources:source_user_complaint_list' %}"
class="flex items-center gap-3 p-3 rounded-xl transition {% if 'source_user_complaint_list' in request.path %}bg-white/20 text-white{% else %}text-white/80 hover:bg-white/10 hover:text-white{% endif %}">
<i data-lucide="file-text" class="w-5 h-5"></i>
<span class="font-medium text-sm">{% trans "Complaints" %}</span>
{% if total_complaints > 0 %}
<span class="ml-auto bg-white/20 text-white text-xs px-2 py-0.5 rounded-full">{{ total_complaints }}</span>
{% endif %}
</a>
<a href="{% url 'px_sources:source_user_inquiry_list' %}"
class="flex items-center gap-3 p-3 rounded-xl transition {% if 'source_user_inquiry_list' in request.path %}bg-white/20 text-white{% else %}text-white/80 hover:bg-white/10 hover:text-white{% endif %}">
<i data-lucide="help-circle" class="w-5 h-5"></i>
<span class="font-medium text-sm">{% trans "Inquiries" %}</span>
{% if total_inquiries > 0 %}
<span class="ml-auto bg-white/20 text-white text-xs px-2 py-0.5 rounded-full">{{ total_inquiries }}</span>
{% endif %}
</a>
<div class="my-4 border-t border-white/10"></div>
<!-- Account -->
<a href="{% url 'accounts:password_change' %}"
class="flex items-center gap-3 p-3 rounded-xl transition text-white/80 hover:bg-white/10 hover:text-white">
<i data-lucide="key" class="w-5 h-5"></i>
<span class="font-medium text-sm">{% trans "Change Password" %}</span>
</a>
<a href="{% url 'accounts:logout' %}"
class="flex items-center gap-3 p-3 rounded-xl transition text-red-300 hover:bg-red-500/20 hover:text-red-200">
<i data-lucide="log-out" class="w-5 h-5"></i>
<span class="font-medium text-sm">{% trans "Logout" %}</span>
</a>
</nav>
<!-- Source Info -->
{% if source %}
<div class="absolute bottom-0 left-0 right-0 p-4 border-t border-white/10 bg-white/5">
<div class="flex items-center gap-3">
<div class="w-8 h-8 bg-gradient-to-br from-orange-400 to-red-500 rounded-lg flex items-center justify-center">
<i data-lucide="radio" class="w-4 h-4 text-white"></i>
</div>
<div class="flex-1 min-w-0">
<p class="text-xs font-semibold text-white truncate">{{ source.name_en }}</p>
<p class="text-[10px] text-white/50">{% trans "Your Source" %}</p>
</div>
</div>
</div>
{% endif %}
</aside>
<!-- Main Content -->
<main class="ml-64 min-h-screen">
<!-- Topbar -->
<header class="bg-white/80 backdrop-blur-sm border-b border-blue-100 sticky top-0 z-40">
<div class="px-6 py-4 flex items-center justify-between">
<!-- Hospital Info -->
{% if current_hospital %}
<div class="flex items-center gap-3">
<div class="w-10 h-10 bg-gradient-to-br from-blue to-navy rounded-xl flex items-center justify-center">
<i data-lucide="building-2" class="w-5 h-5 text-white"></i>
</div>
<div>
<p class="font-bold text-navy">{{ current_hospital.name|truncatewords:3 }}</p>
{% if current_hospital.city %}
<p class="text-xs text-slate">{{ current_hospital.city }}</p>
{% endif %}
</div>
</div>
{% endif %}
<!-- User Menu -->
<div class="flex items-center gap-4">
<div class="flex items-center gap-3 px-4 py-2 bg-blue-50 rounded-xl border border-blue-100">
<div class="w-8 h-8 bg-gradient-to-br from-blue to-navy rounded-full flex items-center justify-center">
<span class="text-white font-bold text-xs">{{ request.user.first_name|first|default:"U" }}{{ request.user.last_name|first|default:"" }}</span>
</div>
<div class="hidden md:block">
<p class="text-sm font-bold text-navy">{{ request.user.get_full_name|default:request.user.email|truncatechars:20 }}</p>
<p class="text-xs text-slate">{% trans "Source User" %}</p>
</div>
</div>
</div>
</div>
</header>
<!-- Page Content -->
<div class="p-6 md:p-8">
<!-- Flash Messages -->
{% if messages %}
<div class="space-y-3 mb-6">
{% for message in messages %}
<div class="flex items-center gap-3 p-4 rounded-xl {% if message.tags == 'error' %}bg-red-50 border border-red-200 text-red-700{% elif message.tags == 'success' %}bg-emerald-50 border border-emerald-200 text-emerald-700{% elif message.tags == 'warning' %}bg-orange-50 border border-orange-200 text-orange-700{% else %}bg-blue-50 border border-blue-200 text-blue-700{% endif %}">
<i data-lucide="{% if message.tags == 'error' %}alert-circle{% elif message.tags == 'success' %}check-circle{% elif message.tags == 'warning' %}alert-triangle{% else %}info{% endif %}" class="w-5 h-5"></i>
<p class="font-medium">{{ message }}</p>
</div>
{% endfor %}
</div>
{% endif %}
{% block content %}{% endblock %}
</div>
</main>
<!-- Mobile Menu Toggle -->
<button id="mobileMenuToggle" class="lg:hidden fixed bottom-4 right-4 w-14 h-14 bg-gradient-to-br from-blue to-navy text-white rounded-full shadow-xl z-50 flex items-center justify-center hover:shadow-2xl transition">
<i data-lucide="menu" class="w-6 h-6"></i>
</button>
<!-- Mobile Sidebar Overlay -->
<div id="mobileSidebarOverlay" class="lg:hidden fixed inset-0 bg-black/50 z-40 hidden"></div>
<script>
document.addEventListener('DOMContentLoaded', function() {
lucide.createIcons();
// Mobile menu toggle
const mobileMenuToggle = document.getElementById('mobileMenuToggle');
const sidebar = document.getElementById('sidebar');
const mobileSidebarOverlay = document.getElementById('mobileSidebarOverlay');
if (mobileMenuToggle) {
mobileMenuToggle.addEventListener('click', function() {
const isClosed = sidebar.classList.contains('-translate-x-full');
if (isClosed) {
sidebar.classList.remove('-translate-x-full');
mobileSidebarOverlay.classList.remove('hidden');
} else {
sidebar.classList.add('-translate-x-full');
mobileSidebarOverlay.classList.add('hidden');
}
});
}
if (mobileSidebarOverlay) {
mobileSidebarOverlay.addEventListener('click', function() {
sidebar.classList.add('-translate-x-full');
mobileSidebarOverlay.classList.add('hidden');
});
}
// Initialize sidebar position for mobile
if (window.innerWidth < 1024) {
sidebar.classList.add('-translate-x-full');
}
});
</script>
{% block extra_js %}{% endblock %}
</body>
</html>