hospital-management/templates/radiology/templates/report_template_list.html
2025-08-12 13:33:25 +03:00

424 lines
19 KiB
HTML

{% extends "base.html" %}
{% load static %}
{% block title %}Report Templates{% endblock %}
{% block content %}
<div class="d-flex align-items-center mb-3">
<div>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'radiology:dashboard' %}">Radiology</a></li>
<li class="breadcrumb-item active">Report Templates</li>
</ol>
<h1 class="page-header mb-0">Report Templates</h1>
</div>
<div class="ms-auto">
<a href="{% url 'radiology:report_template_create' %}" class="btn btn-primary">
<i class="fas fa-plus me-2"></i>Create Template
</a>
</div>
</div>
<!-- Statistics Cards -->
<div class="row mb-4">
<div class="col-xl-3 col-md-6">
<div class="card bg-primary text-white">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<h4 class="mb-1">{{ total_templates|default:0 }}</h4>
<p class="mb-0">Total Templates</p>
</div>
<div class="flex-shrink-0">
<i class="fas fa-file-alt fa-2x opacity-75"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="card bg-success text-white">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<h4 class="mb-1">{{ active_templates|default:0 }}</h4>
<p class="mb-0">Active Templates</p>
</div>
<div class="flex-shrink-0">
<i class="fas fa-check-circle fa-2x opacity-75"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="card bg-info text-white">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<h4 class="mb-1">{{ most_used_template|default:"N/A" }}</h4>
<p class="mb-0">Most Used</p>
</div>
<div class="flex-shrink-0">
<i class="fas fa-star fa-2x opacity-75"></i>
</div>
</div>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="card bg-warning text-white">
<div class="card-body">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<h4 class="mb-1">{{ usage_this_month|default:0 }}</h4>
<p class="mb-0">Used This Month</p>
</div>
<div class="flex-shrink-0">
<i class="fas fa-chart-line fa-2x opacity-75"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<h4 class="card-title">
<i class="fas fa-file-alt me-2"></i>
Report Templates
</h4>
<div class="card-toolbar">
<button type="button" class="btn btn-sm btn-outline-secondary me-2" data-bs-toggle="modal" data-bs-target="#filterModal">
<i class="fas fa-filter me-1"></i>Filters
</button>
<div class="btn-group">
<button type="button" class="btn btn-sm btn-outline-primary dropdown-toggle" data-bs-toggle="dropdown">
<i class="fas fa-download me-1"></i>Export
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="?export=csv"><i class="fas fa-file-csv me-2"></i>CSV</a></li>
<li><a class="dropdown-item" href="?export=json"><i class="fas fa-file-code me-2"></i>JSON</a></li>
</ul>
</div>
</div>
</div>
<div class="card-body">
<!-- Search and Quick Filters -->
<div class="row mb-3">
<div class="col-md-4">
<div class="input-group">
<span class="input-group-text"><i class="fas fa-search"></i></span>
<input type="text" class="form-control" id="searchInput" placeholder="Search templates...">
</div>
</div>
<div class="col-md-8">
<div class="btn-group" role="group">
<input type="radio" class="btn-check" name="modalityFilter" id="all" value="" checked>
<label class="btn btn-outline-secondary btn-sm" for="all">All</label>
<input type="radio" class="btn-check" name="modalityFilter" id="xray" value="xray">
<label class="btn btn-outline-primary btn-sm" for="xray">X-Ray</label>
<input type="radio" class="btn-check" name="modalityFilter" id="ct" value="ct">
<label class="btn btn-outline-info btn-sm" for="ct">CT</label>
<input type="radio" class="btn-check" name="modalityFilter" id="mri" value="mri">
<label class="btn btn-outline-success btn-sm" for="mri">MRI</label>
<input type="radio" class="btn-check" name="modalityFilter" id="ultrasound" value="ultrasound">
<label class="btn btn-outline-warning btn-sm" for="ultrasound">Ultrasound</label>
</div>
</div>
</div>
<!-- Templates Grid -->
<div class="row" id="templatesGrid">
{% for template in object_list %}
<div class="col-xl-4 col-lg-6 mb-4 template-card" data-modality="{{ template.modality }}" data-category="{{ template.category }}">
<div class="card h-100">
<div class="card-header">
<div class="d-flex align-items-center">
<div class="flex-grow-1">
<h6 class="card-title mb-0">{{ template.name }}</h6>
<small class="text-muted">{{ template.get_modality_display }}</small>
</div>
<div class="flex-shrink-0">
<span class="badge bg-{% if template.is_active %}success{% else %}secondary{% endif %}">
{% if template.is_active %}Active{% else %}Inactive{% endif %}
</span>
</div>
</div>
</div>
<div class="card-body">
<p class="card-text">{{ template.description|truncatewords:20 }}</p>
<div class="row text-center mb-3">
<div class="col-4">
<div class="text-muted small">Usage</div>
<div class="fw-bold">{{ template.usage_count|default:0 }}</div>
</div>
<div class="col-4">
<div class="text-muted small">Category</div>
<div class="fw-bold">{{ template.get_category_display }}</div>
</div>
<div class="col-4">
<div class="text-muted small">Updated</div>
<div class="fw-bold">{{ template.updated_at|date:"M d" }}</div>
</div>
</div>
<!-- Template Preview -->
<div class="bg-light p-2 rounded mb-3" style="max-height: 100px; overflow: hidden;">
<small class="text-muted">
<strong>Technique:</strong> {{ template.technique|truncatewords:10 }}<br>
<strong>Findings:</strong> {{ template.findings_template|truncatewords:15 }}
</small>
</div>
<div class="d-flex gap-2">
<a href="{% url 'radiology:report_template_detail' template.pk %}" class="btn btn-outline-primary btn-sm flex-fill">
<i class="fas fa-eye me-1"></i>View
</a>
<a href="{% url 'radiology:report_template_update' template.pk %}" class="btn btn-outline-secondary btn-sm flex-fill">
<i class="fas fa-edit me-1"></i>Edit
</a>
<button type="button" class="btn btn-outline-success btn-sm" onclick="useTemplate({{ template.pk }})">
<i class="fas fa-plus me-1"></i>Use
</button>
</div>
</div>
<div class="card-footer">
<div class="d-flex align-items-center justify-content-between">
<small class="text-muted">
<i class="fas fa-user me-1"></i>{{ template.created_by.get_full_name|default:"System" }}
</small>
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-outline-info dropdown-toggle" data-bs-toggle="dropdown">
<i class="fas fa-ellipsis-v"></i>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#" onclick="duplicateTemplate({{ template.pk }})"><i class="fas fa-copy me-2"></i>Duplicate</a></li>
<li><a class="dropdown-item" href="#" onclick="exportTemplate({{ template.pk }})"><i class="fas fa-download me-2"></i>Export</a></li>
<li><hr class="dropdown-divider"></li>
{% if template.is_active %}
<li><a class="dropdown-item" href="#" onclick="toggleTemplate({{ template.pk }}, false)"><i class="fas fa-pause me-2"></i>Deactivate</a></li>
{% else %}
<li><a class="dropdown-item" href="#" onclick="toggleTemplate({{ template.pk }}, true)"><i class="fas fa-play me-2"></i>Activate</a></li>
{% endif %}
<li><a class="dropdown-item text-danger" href="{% url 'radiology:report_template_delete' template.pk %}"><i class="fas fa-trash me-2"></i>Delete</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
{% empty %}
<div class="col-12">
<div class="text-center py-5">
<i class="fas fa-file-alt fa-3x text-muted mb-3"></i>
<h5 class="text-muted">No Report Templates Found</h5>
<p class="text-muted">Create your first report template to standardize radiology reporting.</p>
<a href="{% url 'radiology:report_template_create' %}" class="btn btn-primary">
<i class="fas fa-plus me-2"></i>Create First Template
</a>
</div>
</div>
{% endfor %}
</div>
<!-- Pagination -->
{% if is_paginated %}
<nav aria-label="Templates pagination">
<ul class="pagination justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?page=1">&laquo; First</a>
</li>
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.previous_page_number }}">Previous</a>
</li>
{% endif %}
<li class="page-item active">
<span class="page-link">
Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}
</span>
</li>
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.next_page_number }}">Next</a>
</li>
<li class="page-item">
<a class="page-link" href="?page={{ page_obj.paginator.num_pages }}">Last &raquo;</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
</div>
</div>
<!-- Filter Modal -->
<div class="modal fade" id="filterModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Advanced Filters</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form id="filterForm">
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Category</label>
<select class="form-select" name="category">
<option value="">All categories</option>
<option value="normal">Normal</option>
<option value="abnormal">Abnormal</option>
<option value="emergency">Emergency</option>
<option value="pediatric">Pediatric</option>
</select>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Status</label>
<select class="form-select" name="status">
<option value="">All statuses</option>
<option value="active">Active</option>
<option value="inactive">Inactive</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Created By</label>
<select class="form-select" name="created_by">
<option value="">All users</option>
{% for user in template_creators %}
<option value="{{ user.pk }}">{{ user.get_full_name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">Usage Range</label>
<select class="form-select" name="usage_range">
<option value="">All usage levels</option>
<option value="high">High (>50 uses)</option>
<option value="medium">Medium (10-50 uses)</option>
<option value="low">Low (<10 uses)</option>
<option value="unused">Unused</option>
</select>
</div>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" onclick="applyFilters()">Apply Filters</button>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Search functionality
const searchInput = document.getElementById('searchInput');
const templateCards = document.querySelectorAll('.template-card');
searchInput.addEventListener('input', function() {
const searchTerm = this.value.toLowerCase();
templateCards.forEach(card => {
const text = card.textContent.toLowerCase();
card.style.display = text.includes(searchTerm) ? '' : 'none';
});
});
// Modality filter functionality
const modalityFilters = document.querySelectorAll('input[name="modalityFilter"]');
modalityFilters.forEach(filter => {
filter.addEventListener('change', function() {
const modality = this.value;
templateCards.forEach(card => {
if (!modality || card.dataset.modality === modality) {
card.style.display = '';
} else {
card.style.display = 'none';
}
});
});
});
});
function useTemplate(templateId) {
if (confirm('Create a new report using this template?')) {
window.location.href = `/radiology/reports/create/?template=${templateId}`;
}
}
function duplicateTemplate(templateId) {
if (confirm('Create a copy of this template?')) {
fetch(`/radiology/templates/${templateId}/duplicate/`, {
method: 'POST',
headers: {
'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
location.reload();
} else {
alert('Error duplicating template');
}
});
}
}
function exportTemplate(templateId) {
window.open(`/radiology/templates/${templateId}/export/`, '_blank');
}
function toggleTemplate(templateId, activate) {
const action = activate ? 'activate' : 'deactivate';
if (confirm(`${action.charAt(0).toUpperCase() + action.slice(1)} this template?`)) {
fetch(`/radiology/templates/${templateId}/${action}/`, {
method: 'POST',
headers: {
'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
location.reload();
} else {
alert(`Error ${action}ing template`);
}
});
}
}
function applyFilters() {
const form = document.getElementById('filterForm');
const formData = new FormData(form);
const params = new URLSearchParams(formData);
window.location.href = '?' + params.toString();
}
</script>
{% endblock %}