HH/templates/observations/observation_create.html
2026-07-19 12:27:55 +03:00

325 lines
15 KiB
HTML

{% extends "layouts/base.html" %}
{% load i18n %}
{% load static %}
{% block title %}{% trans "New Observation" %} - PX360{% endblock %}
{% block content %}
<div class="mb-6">
<a href="{% url 'observations:observation_list' %}" class="text-slate hover:text-navy text-sm font-medium inline-flex items-center gap-1 mb-4 transition">
<i data-lucide="arrow-left" class="w-4 h-4"></i>
{% trans "Back to Observations" %}
</a>
</div>
<div class="max-w-3xl mx-auto">
<!-- Header -->
<div class="text-center mb-8">
<div class="w-16 h-16 bg-gradient-to-br from-navy to-blue rounded-2xl flex items-center justify-center mx-auto mb-4 shadow-lg">
<i data-lucide="eye" class="w-8 h-8 text-white"></i>
</div>
<h1 class="text-2xl font-bold text-navy mb-2">{% trans "Report an Observation" %}</h1>
<p class="text-slate">{% trans "Help us improve by reporting issues you notice" %}</p>
</div>
{% if messages %}
{% for message in messages %}
<div class="bg-{% if message.tags == 'error' %}red{% elif message.tags == 'warning' %}yellow{% else %}green{% endif %}-50 border border-{% if message.tags == 'error' %}red{% elif message.tags == 'warning' %}yellow{% else %}green{% endif %}-200 rounded-xl p-4 mb-4 text-sm text-{% if message.tags == 'error' %}red{% elif message.tags == 'warning' %}yellow{% else %}green{% endif %}-800">
{{ message }}
</div>
{% endfor %}
{% endif %}
<!-- Form Card -->
<div class="bg-white rounded-2xl shadow-sm border border-slate-100 p-8">
<form method="post" enctype="multipart/form-data" id="observationForm">
{% csrf_token %}
{% if communication_request %}
<input type="hidden" name="comm_req" value="{{ communication_request.id }}">
{% endif %}
<!-- Hospital -->
<div class="mb-6">
<label class="flex items-center gap-2 text-sm font-bold text-navy mb-3">
<i data-lucide="building-2" class="w-4 h-4"></i>
{% trans "Hospital" %}
<span class="text-red-500">*</span>
</label>
{{ form.hospital }}
{% if form.hospital.errors %}<p class="text-xs text-red-500 mt-1">{{ form.hospital.errors.0 }}</p>{% endif %}
</div>
<!-- Location Type -->
<div class="mb-6">
<label class="flex items-center gap-2 text-sm font-bold text-navy mb-3">
<i data-lucide="map-pin" class="w-4 h-4"></i>
{% trans "Location Type" %}
<span class="text-red-500">*</span>
</label>
{{ form.location_type }}
{% if form.location_type.errors %}<p class="text-xs text-red-500 mt-1">{{ form.location_type.errors.0 }}</p>{% endif %}
</div>
<!-- Area -->
<div class="mb-6">
<label class="flex items-center gap-2 text-sm font-bold text-navy mb-3">
<i data-lucide="map" class="w-4 h-4"></i>
{% trans "Area" %}
<span class="text-xs font-normal text-slate">({% trans "optional" %})</span>
</label>
{{ form.area }}
{% if form.area.errors %}<p class="text-xs text-red-500 mt-1">{{ form.area.errors.0 }}</p>{% endif %}
</div>
<!-- Department + Section (2-col) -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
<div>
<label class="flex items-center gap-2 text-sm font-bold text-navy mb-3">
<i data-lucide="building" class="w-4 h-4"></i>
{% trans "Department" %}
<span class="text-xs font-normal text-slate">({% trans "optional" %})</span>
</label>
{{ form.assigned_department }}
</div>
<div>
<label class="flex items-center gap-2 text-sm font-bold text-navy mb-3">
<i data-lucide="layers" class="w-4 h-4"></i>
{% trans "Section" %}
<span class="text-xs font-normal text-slate">({% trans "optional" %})</span>
</label>
{{ form.section }}
</div>
</div>
<!-- Title -->
<div class="mb-6">
<label class="flex items-center gap-2 text-sm font-bold text-navy mb-3">
<i data-lucide="type" class="w-4 h-4"></i>
{% trans "Title" %}
<span class="text-xs font-normal text-slate">({% trans "optional" %})</span>
</label>
{{ form.title }}
</div>
<!-- Description -->
<div class="mb-6">
<label class="flex items-center gap-2 text-sm font-bold text-navy mb-3">
<i data-lucide="file-text" class="w-4 h-4"></i>
{% trans "Description" %}
<span class="text-red-500">*</span>
</label>
{{ form.description }}
<p class="text-xs text-slate mt-1.5">{% trans "Please describe what you observed in detail." %}</p>
{% if form.description.errors %}<p class="text-xs text-red-500 mt-1">{{ form.description.errors.0 }}</p>{% endif %}
</div>
<!-- Location Details + Incident Datetime (2-col) -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
<div>
<label class="flex items-center gap-2 text-sm font-bold text-navy mb-3">
<i data-lucide="map-pin" class="w-4 h-4"></i>
{% trans "Location Details" %}
<span class="text-xs font-normal text-slate">({% trans "optional" %})</span>
</label>
{{ form.location_text }}
</div>
<div>
<label class="flex items-center gap-2 text-sm font-bold text-navy mb-3">
<i data-lucide="calendar" class="w-4 h-4"></i>
{% trans "When did this occur?" %}
</label>
{{ form.incident_datetime }}
</div>
</div>
<!-- Department + Source (2-col) -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-6">
<div>
<label class="flex items-center gap-2 text-sm font-bold text-navy mb-3">
<i data-lucide="source" class="w-4 h-4"></i>
{% trans "Source" %}
<span class="text-xs font-normal text-slate">({% trans "optional" %})</span>
</label>
{{ form.px_source }}
</div>
</div>
<!-- Patient Information -->
<div class="mb-8 pt-6 border-t border-slate-100">
<label class="flex items-center gap-2 text-sm font-bold text-navy mb-2">
<i data-lucide="user" class="w-4 h-4"></i>
{% trans "Patient Information" %}
<span class="text-xs font-normal text-slate">({% trans "optional" %})</span>
</label>
<p class="text-xs text-slate mb-4">{% trans "Fill in if this observation involves a specific patient." %}</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label class="block text-xs font-semibold text-slate mb-1.5">{% trans "Patient Name" %}</label>
{{ form.patient_name }}
</div>
<div>
<label class="block text-xs font-semibold text-slate mb-1.5">{% trans "National ID/Iqama" %}</label>
{{ form.patient_national_id }}
</div>
<div>
<label class="block text-xs font-semibold text-slate mb-1.5">{% trans "Phone" %}</label>
{{ form.patient_phone }}
</div>
<div>
<label class="block text-xs font-semibold text-slate mb-1.5">{% trans "Email" %}</label>
{{ form.patient_email }}
</div>
</div>
</div>
<!-- Submit -->
<div class="flex gap-3">
<a href="{% url 'observations:observation_list' %}" class="px-5 py-3 border border-slate-200 text-slate-600 rounded-xl font-semibold text-sm hover:bg-slate-50 transition flex items-center gap-2">
{% trans "Cancel" %}
</a>
<button type="submit" class="flex-1 bg-navy text-white py-3 rounded-xl font-bold text-sm hover:bg-blue transition shadow-lg shadow-navy/20 flex items-center justify-center gap-2">
<i data-lucide="send" class="w-5 h-5"></i>
{% trans "Create Observation" %}
</button>
</div>
</form>
</div>
</div>
{% endblock %}
{% block extra_js %}
<script>
{% trans "Select assignee (optional)" as trans_select_assignee %}
document.addEventListener('DOMContentLoaded', function() {
const selAssignee = '{{ trans_select_assignee|escapejs }}';
const locationTypeSelect = document.getElementById('locationTypeSelect');
const areaSelect = document.getElementById('areaSelect');
const deptSelect = document.getElementById('id_assigned_department');
const assigneeSelect = document.getElementById('id_assigned_to');
const sectionSelect = document.getElementById('sectionSelect');
function getHospitalId() {
const sel = document.getElementById('hospitalSelect');
return sel ? sel.value : null;
}
function loadAreas(locationType) {
if (!areaSelect) return;
areaSelect.innerHTML = '<option value="">{% trans "Loading..." %}</option>';
var hospitalId = getHospitalId();
if (!hospitalId) {
areaSelect.innerHTML = '<option value="">{% trans "Select Area (optional)" %}</option>';
return;
}
var url = '/organizations/dropdowns/areas/?hospital=' + encodeURIComponent(hospitalId);
if (locationType) url += '&location_type=' + encodeURIComponent(locationType);
fetch(url)
.then(function(r) { return r.json(); })
.then(function(data) {
areaSelect.innerHTML = '<option value="">{% trans "Select Area (optional)" %}</option>';
(data || []).forEach(function(a) {
var opt = document.createElement('option');
opt.value = a.id;
opt.textContent = a.name_en;
areaSelect.appendChild(opt);
});
})
.catch(function(err) {
console.error('Error loading areas:', err);
areaSelect.innerHTML = '<option value="">{% trans "Error loading areas" %}</option>';
});
}
function loadDepartments(hospitalId) {
if (!deptSelect) return;
deptSelect.innerHTML = '<option value="">{% trans "Loading..." %}</option>';
if (!hospitalId) {
deptSelect.innerHTML = '<option value="">{% trans "Select Department" %}</option>';
return;
}
fetch('/organizations/dropdowns/departments-by-category/?hospital=' + encodeURIComponent(hospitalId))
.then(function(r) { return r.json(); })
.then(function(data) {
deptSelect.innerHTML = '<option value="">{% trans "Select Department" %}</option>';
(data || []).forEach(function(d) {
var opt = document.createElement('option');
opt.value = d.id;
opt.textContent = d.name_en || d.name;
deptSelect.appendChild(opt);
});
})
.catch(function(err) {
console.error('Error loading departments:', err);
deptSelect.innerHTML = '<option value="">{% trans "Error loading departments" %}</option>';
});
}
if (locationTypeSelect) {
locationTypeSelect.addEventListener('change', function() {
loadAreas(this.value);
});
}
if (deptSelect) {
deptSelect.addEventListener('change', function() {
var deptId = this.value;
if (!deptId) {
if (assigneeSelect) assigneeSelect.innerHTML = '<option value="">' + selAssignee + '</option>';
if (sectionSelect) sectionSelect.innerHTML = '<option value="">{% trans "Select Section" %}</option>';
return;
}
if (assigneeSelect) {
fetch("{% url 'observations:get_users_by_department' %}?department_id=" + deptId)
.then(function(response) { return response.json(); })
.then(function(data) {
var html = '<option value="">' + selAssignee + '</option>';
data.users.forEach(function(user) {
html += '<option value="' + user.id + '">' + user.name + '</option>';
});
assigneeSelect.innerHTML = html;
})
.catch(function() { console.error('Failed to load users'); });
}
if (sectionSelect) {
sectionSelect.innerHTML = '<option value="">{% trans "Loading..." %}</option>';
fetch('/organizations/dropdowns/sections/' + deptId + '/')
.then(function(r) { return r.json(); })
.then(function(data) {
sectionSelect.innerHTML = '<option value="">{% trans "Select Section" %}</option>';
(data || []).forEach(function(s) {
var opt = document.createElement('option');
opt.value = s.id;
opt.textContent = s.name_en || s.name;
sectionSelect.appendChild(opt);
});
})
.catch(function(err) { console.error(err); });
}
});
}
var initHospitalId = getHospitalId();
if (initHospitalId) {
loadDepartments(initHospitalId);
loadAreas(null);
}
var hospitalSelect = document.getElementById('hospitalSelect');
if (hospitalSelect) {
hospitalSelect.addEventListener('change', function() {
loadDepartments(this.value);
loadAreas(null);
if (sectionSelect) sectionSelect.innerHTML = '<option value="">{% trans "Select Section" %}</option>';
if (assigneeSelect) assigneeSelect.innerHTML = '<option value="">' + selAssignee + '</option>';
});
}
if (typeof lucide !== 'undefined') lucide.createIcons();
});
</script>
{% endblock %}