Marwan Alwali fd2f7259c0 update
2025-08-14 18:05:05 +03:00

672 lines
35 KiB
HTML

{% extends "base.html" %}
{% load static %}
{% block title %}Imaging Studies{% endblock %}
{% block content %}
<!-- BEGIN breadcrumb -->
<ol class="breadcrumb float-xl-end">
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
<li class="breadcrumb-item"><a href="{% url 'radiology:dashboard' %}">Radiology</a></li>
<li class="breadcrumb-item active">Imaging Studies</li>
</ol>
<!-- END breadcrumb -->
<!-- BEGIN page-header -->
<h1 class="page-header">
Imaging Studies
<small>Manage and monitor imaging studies</small>
</h1>
<!-- END page-header -->
<!-- BEGIN row -->
<div class="row">
<div class="col-xl-12">
<!-- Statistics Cards -->
<div class="row mb-3">
<div class="col-xl-3 col-md-6">
<div class="widget widget-stats bg-blue">
<div class="stats-icon"><i class="fa fa-camera"></i></div>
<div class="stats-info">
<h4>{{ total_studies|default:0 }}</h4>
<p>Total Studies</p>
</div>
<div class="stats-link">
<a href="javascript:;" onclick="filterByStatus('all')">View All <i class="fa fa-arrow-alt-circle-right"></i></a>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="widget widget-stats bg-info">
<div class="stats-icon"><i class="fa fa-play-circle"></i></div>
<div class="stats-info">
<h4>{{ in_progress_studies|default:0 }}</h4>
<p>In Progress</p>
</div>
<div class="stats-link">
<a href="javascript:;" onclick="filterByStatus('in_progress')">View Details <i class="fa fa-arrow-alt-circle-right"></i></a>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="widget widget-stats bg-orange">
<div class="stats-icon"><i class="fa fa-clock"></i></div>
<div class="stats-info">
<h4>{{ pending_studies|default:0 }}</h4>
<p>Pending</p>
</div>
<div class="stats-link">
<a href="javascript:;" onclick="filterByStatus('pending')">View Details <i class="fa fa-arrow-alt-circle-right"></i></a>
</div>
</div>
</div>
<div class="col-xl-3 col-md-6">
<div class="widget widget-stats bg-red">
<div class="stats-icon"><i class="fa fa-exclamation-triangle"></i></div>
<div class="stats-info">
<h4>{{ overdue_studies|default:0 }}</h4>
<p>Overdue</p>
</div>
<div class="stats-link">
<a href="javascript:;" onclick="filterByStatus('overdue')">View Details <i class="fa fa-arrow-alt-circle-right"></i></a>
</div>
</div>
</div>
</div>
<!-- Filters and Search -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">
<i class="fa fa-filter me-2"></i>Filters & Search
</h4>
<div class="panel-heading-btn">
<button type="button" class="btn btn-xs btn-icon btn-circle btn-default" onclick="resetFilters()">
<i class="fa fa-undo"></i>
</button>
<button type="button" class="btn btn-xs btn-icon btn-circle btn-default" data-toggle="panel-collapse">
<i class="fa fa-minus"></i>
</button>
</div>
</div>
<div class="panel-body">
<form method="get" id="filterForm" class="row g-3">
<div class="col-md-3">
<label for="search" class="form-label">Search</label>
<input type="text" class="form-control" id="search" name="search"
value="{{ request.GET.search }}"
placeholder="Study ID, patient name, MRN...">
</div>
<div class="col-md-2">
<label for="status" class="form-label">Status</label>
<select class="form-select" id="status" name="status">
<option value="">All Statuses</option>
<option value="pending" {% if request.GET.status == 'pending' %}selected{% endif %}>Pending</option>
<option value="in_progress" {% if request.GET.status == 'in_progress' %}selected{% endif %}>In Progress</option>
<option value="completed" {% if request.GET.status == 'completed' %}selected{% endif %}>Completed</option>
<option value="cancelled" {% if request.GET.status == 'cancelled' %}selected{% endif %}>Cancelled</option>
<option value="on_hold" {% if request.GET.status == 'on_hold' %}selected{% endif %}>On Hold</option>
</select>
</div>
<div class="col-md-2">
<label for="modality" class="form-label">Modality</label>
<select class="form-select" id="modality" name="modality">
<option value="">All Modalities</option>
<option value="CT" {% if request.GET.modality == 'CT' %}selected{% endif %}>CT</option>
<option value="MRI" {% if request.GET.modality == 'MRI' %}selected{% endif %}>MRI</option>
<option value="X-Ray" {% if request.GET.modality == 'X-Ray' %}selected{% endif %}>X-Ray</option>
<option value="Ultrasound" {% if request.GET.modality == 'Ultrasound' %}selected{% endif %}>Ultrasound</option>
<option value="Nuclear" {% if request.GET.modality == 'Nuclear' %}selected{% endif %}>Nuclear Medicine</option>
<option value="Mammography" {% if request.GET.modality == 'Mammography' %}selected{% endif %}>Mammography</option>
</select>
</div>
<div class="col-md-2">
<label for="priority" class="form-label">Priority</label>
<select class="form-select" id="priority" name="priority">
<option value="">All Priorities</option>
<option value="stat" {% if request.GET.priority == 'stat' %}selected{% endif %}>STAT</option>
<option value="urgent" {% if request.GET.priority == 'urgent' %}selected{% endif %}>Urgent</option>
<option value="routine" {% if request.GET.priority == 'routine' %}selected{% endif %}>Routine</option>
</select>
</div>
<div class="col-md-2">
<label for="date_range" class="form-label">Date Range</label>
<select class="form-select" id="date_range" name="date_range">
<option value="">All Dates</option>
<option value="today" {% if request.GET.date_range == 'today' %}selected{% endif %}>Today</option>
<option value="yesterday" {% if request.GET.date_range == 'yesterday' %}selected{% endif %}>Yesterday</option>
<option value="this_week" {% if request.GET.date_range == 'this_week' %}selected{% endif %}>This Week</option>
<option value="last_week" {% if request.GET.date_range == 'last_week' %}selected{% endif %}>Last Week</option>
<option value="this_month" {% if request.GET.date_range == 'this_month' %}selected{% endif %}>This Month</option>
</select>
</div>
<div class="col-md-1">
<label class="form-label">&nbsp;</label>
<div class="d-grid">
<button type="submit" class="btn btn-primary">
<i class="fa fa-search"></i>
</button>
</div>
</div>
</form>
</div>
</div>
<!-- Studies List -->
<div class="panel panel-inverse">
<div class="panel-heading">
<h4 class="panel-title">
<i class="fa fa-list me-2"></i>Imaging Studies
{% if object_list %}
<span class="badge bg-primary ms-2">{{ object_list|length }}</span>
{% endif %}
</h4>
<div class="panel-heading-btn">
<div class="btn-group">
<button type="button" class="btn btn-xs btn-primary dropdown-toggle" data-bs-toggle="dropdown">
<i class="fa fa-download me-1"></i>Export
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="?{{ request.GET.urlencode }}&export=csv">
<i class="fa fa-file-csv me-2"></i>CSV
</a></li>
<li><a class="dropdown-item" href="?{{ request.GET.urlencode }}&export=excel">
<i class="fa fa-file-excel me-2"></i>Excel
</a></li>
<li><a class="dropdown-item" href="?{{ request.GET.urlencode }}&export=pdf">
<i class="fa fa-file-pdf me-2"></i>PDF
</a></li>
</ul>
</div>
<button type="button" class="btn btn-xs btn-success" onclick="refreshStudies()">
<i class="fa fa-refresh"></i>
</button>
</div>
</div>
<div class="panel-body">
{% if object_list %}
<!-- Bulk Actions -->
<div class="row mb-3">
<div class="col-md-6">
<div class="d-flex align-items-center">
<div class="form-check me-3">
<input class="form-check-input" type="checkbox" id="selectAll">
<label class="form-check-label" for="selectAll">
Select All
</label>
</div>
<div class="btn-group" id="bulkActions" style="display: none;">
<button type="button" class="btn btn-sm btn-outline-primary" onclick="bulkAction('start')">
<i class="fa fa-play me-1"></i>Start Selected
</button>
<button type="button" class="btn btn-sm btn-outline-success" onclick="bulkAction('complete')">
<i class="fa fa-check me-1"></i>Complete Selected
</button>
<button type="button" class="btn btn-sm btn-outline-warning" onclick="bulkAction('hold')">
<i class="fa fa-pause me-1"></i>Put on Hold
</button>
<button type="button" class="btn btn-sm btn-outline-danger" onclick="bulkAction('cancel')">
<i class="fa fa-times me-1"></i>Cancel Selected
</button>
</div>
</div>
</div>
<div class="col-md-6 text-end">
<div class="btn-group">
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="toggleView('table')" id="tableViewBtn">
<i class="fa fa-table me-1"></i>Table
</button>
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="toggleView('cards')" id="cardsViewBtn">
<i class="fa fa-th-large me-1"></i>Cards
</button>
</div>
</div>
</div>
<!-- Table View -->
<div id="tableView">
<div class="table-responsive">
<table class="table table-striped table-hover" id="studiesTable">
<thead>
<tr>
<th width="30">
<input type="checkbox" id="selectAllTable">
</th>
<th>Study ID</th>
<th>Patient</th>
<th>Study Type</th>
<th>Modality</th>
<th>Priority</th>
<th>Status</th>
<th>Technologist</th>
<th>Start Time</th>
<th>Duration</th>
<th width="120">Actions</th>
</tr>
</thead>
<tbody>
{% for study in object_list %}
<tr data-study-id="{{ study.id }}">
<td>
<input type="checkbox" class="study-checkbox" value="{{ study.id }}">
</td>
<td>
<a href="{% url 'radiology:imaging_study_detail' study.pk %}" class="text-decoration-none">
{{ study.study_id }}
</a>
</td>
<td>
<div>
<strong>{{ study.patient.get_full_name }}</strong><br>
<small class="text-muted">MRN: {{ study.patient.medical_record_number }}</small>
</div>
</td>
<td>{{ study.study_type }}</td>
<td>
<span class="badge bg-secondary">{{ study.modality }}</span>
</td>
<td>
{% if study.priority == 'stat' %}
<span class="badge bg-danger">STAT</span>
{% elif study.priority == 'urgent' %}
<span class="badge bg-warning text-dark">Urgent</span>
{% else %}
<span class="badge bg-success">Routine</span>
{% endif %}
</td>
<td>
{% if study.status == 'pending' %}
<span class="badge bg-secondary">Pending</span>
{% elif study.status == 'in_progress' %}
<span class="badge bg-info">In Progress</span>
{% elif study.status == 'completed' %}
<span class="badge bg-success">Completed</span>
{% elif study.status == 'cancelled' %}
<span class="badge bg-danger">Cancelled</span>
{% elif study.status == 'on_hold' %}
<span class="badge bg-warning text-dark">On Hold</span>
{% endif %}
</td>
<td>
{% if study.technologist %}
{{ study.technologist.get_full_name }}
{% else %}
<span class="text-muted">Not assigned</span>
{% endif %}
</td>
<td>
{% if study.start_time %}
{{ study.start_time|date:"M d, Y g:i A" }}
{% else %}
<span class="text-muted">Not started</span>
{% endif %}
</td>
<td>
{% if study.duration %}
{{ study.duration }} min
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
<td>
<div class="btn-group">
<a href="{% url 'radiology:imaging_study_detail' study.pk %}"
class="btn btn-xs btn-outline-primary" title="View Details">
<i class="fa fa-eye"></i>
</a>
{% if study.status == 'pending' %}
<button type="button" class="btn btn-xs btn-outline-success"
onclick="startStudy('{{ study.id }}')" title="Start Study">
<i class="fa fa-play"></i>
</button>
{% elif study.status == 'in_progress' %}
<button type="button" class="btn btn-xs btn-outline-info"
onclick="completeStudy('{{ study.id }}')" title="Complete Study">
<i class="fa fa-check"></i>
</button>
{% endif %}
<div class="btn-group">
<button type="button" class="btn btn-xs btn-outline-secondary dropdown-toggle"
data-bs-toggle="dropdown" title="More Actions">
<i class="fa fa-ellipsis-h"></i>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="{% url 'radiology:imaging_study_update' study.pk %}">
<i class="fa fa-edit me-2"></i>Edit
</a></li>
{% if study.dicom_files.exists %}
<li><a class="dropdown-item" href="{% url 'radiology:dicom_viewer' study.pk %}">
<i class="fa fa-image me-2"></i>View Images
</a></li>
{% endif %}
<li><hr class="dropdown-divider"></li>
{# <li><a class="dropdown-item text-danger" href="{% url 'radiology:im' study.pk %}">#}
{# <i class="fa fa-trash me-2"></i>Delete#}
{# </a></li>#}
</ul>
</div>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<!-- Cards View -->
<div id="cardsView" style="display: none;">
<div class="row">
{% for study in object_list %}
<div class="col-xl-4 col-lg-6 mb-3">
<div class="card study-card" data-study-id="{{ study.id }}">
<div class="card-header d-flex justify-content-between align-items-center">
<div>
<input type="checkbox" class="study-checkbox me-2" value="{{ study.id }}">
<strong>{{ study.study_id }}</strong>
</div>
<div>
{% if study.priority == 'stat' %}
<span class="badge bg-danger">STAT</span>
{% elif study.priority == 'urgent' %}
<span class="badge bg-warning text-dark">Urgent</span>
{% else %}
<span class="badge bg-success">Routine</span>
{% endif %}
</div>
</div>
<div class="card-body">
<h6 class="card-title">{{ study.patient.get_full_name }}</h6>
<p class="card-text">
<small class="text-muted">MRN: {{ study.patient.medical_record_number }}</small><br>
<strong>Study:</strong> {{ study.study_type }}<br>
<strong>Modality:</strong> <span class="badge bg-secondary">{{ study.modality }}</span><br>
<strong>Status:</strong>
{% if study.status == 'pending' %}
<span class="badge bg-secondary">Pending</span>
{% elif study.status == 'in_progress' %}
<span class="badge bg-info">In Progress</span>
{% elif study.status == 'completed' %}
<span class="badge bg-success">Completed</span>
{% elif study.status == 'cancelled' %}
<span class="badge bg-danger">Cancelled</span>
{% elif study.status == 'on_hold' %}
<span class="badge bg-warning text-dark">On Hold</span>
{% endif %}
</p>
{% if study.technologist %}
<p class="card-text">
<strong>Technologist:</strong> {{ study.technologist.get_full_name }}
</p>
{% endif %}
{% if study.start_time %}
<p class="card-text">
<strong>Started:</strong> {{ study.start_time|date:"M d, Y g:i A" }}
</p>
{% endif %}
</div>
<div class="card-footer">
<div class="btn-group w-100">
<a href="{% url 'radiology:imaging_study_detail' study.pk %}"
class="btn btn-sm btn-outline-primary">
<i class="fa fa-eye me-1"></i>View
</a>
{% if study.status == 'pending' %}
<button type="button" class="btn btn-sm btn-outline-success"
onclick="startStudy('{{ study.id }}')">
<i class="fa fa-play me-1"></i>Start
</button>
{% elif study.status == 'in_progress' %}
<button type="button" class="btn btn-sm btn-outline-info"
onclick="completeStudy('{{ study.id }}')">
<i class="fa fa-check me-1"></i>Complete
</button>
{% endif %}
<div class="btn-group">
<button type="button" class="btn btn-sm btn-outline-secondary dropdown-toggle"
data-bs-toggle="dropdown">
<i class="fa fa-ellipsis-h"></i>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="{% url 'radiology:imaging_study_update' study.pk %}">
<i class="fa fa-edit me-2"></i>Edit
</a></li>
{% if study.dicom_files.exists %}
<li><a class="dropdown-item" href="{% url 'radiology:dicom_viewer' study.pk %}">
<i class="fa fa-image me-2"></i>View Images
</a></li>
{% endif %}
<li><hr class="dropdown-divider"></li>
{# <li><a class="dropdown-item text-danger" href="{% url 'radiology:imaging_study_delete' study.pk %}">#}
{# <i class="fa fa-trash me-2"></i>Delete#}
{# </a></li>#}
</ul>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
<!-- Pagination -->
{% if is_paginated %}
<nav aria-label="Studies pagination">
<ul class="pagination justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link" href="?{{ request.GET.urlencode }}&page=1">First</a>
</li>
<li class="page-item">
<a class="page-link" href="?{{ request.GET.urlencode }}&page={{ page_obj.previous_page_number }}">Previous</a>
</li>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<li class="page-item active">
<span class="page-link">{{ num }}</span>
</li>
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
<li class="page-item">
<a class="page-link" href="?{{ request.GET.urlencode }}&page={{ num }}">{{ num }}</a>
</li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link" href="?{{ request.GET.urlencode }}&page={{ page_obj.next_page_number }}">Next</a>
</li>
<li class="page-item">
<a class="page-link" href="?{{ request.GET.urlencode }}&page={{ page_obj.paginator.num_pages }}">Last</a>
</li>
{% endif %}
</ul>
</nav>
{% endif %}
{% else %}
<div class="text-center py-5">
<i class="fa fa-camera fa-3x text-muted mb-3"></i>
<h5 class="text-muted">No imaging studies found</h5>
<p class="text-muted">No studies match your current filters.</p>
<button type="button" class="btn btn-primary" onclick="resetFilters()">
<i class="fa fa-undo me-1"></i>Reset Filters
</button>
</div>
{% endif %}
</div>
</div>
</div>
</div>
<!-- END row -->
<!-- Quick Action Modals -->
<div class="modal fade" id="startStudyModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Start Study</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<!-- Start study form content -->
</div>
</div>
</div>
</div>
<div class="modal fade" id="completeStudyModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Complete Study</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<!-- Complete study form content -->
</div>
</div>
</div>
</div>
{% endblock %}
{% block js %}
<script>
$(document).ready(function() {
// Auto-refresh every 30 seconds
setInterval(function() {
if ($('#auto-refresh').is(':checked')) {
refreshStudies();
}
}, 30000);
// Handle select all checkboxes
$('#selectAll, #selectAllTable').change(function() {
var isChecked = $(this).is(':checked');
$('.study-checkbox').prop('checked', isChecked);
toggleBulkActions();
});
// Handle individual checkboxes
$(document).on('change', '.study-checkbox', function() {
toggleBulkActions();
updateSelectAllState();
});
// Initialize DataTable for better sorting and searching
$('#studiesTable').DataTable({
"pageLength": 25,
"order": [[ 8, "desc" ]], // Sort by start time
"columnDefs": [
{ "orderable": false, "targets": [0, 10] } // Disable sorting for checkbox and actions
]
});
});
function filterByStatus(status) {
$('#status').val(status);
$('#filterForm').submit();
}
function resetFilters() {
$('#filterForm')[0].reset();
window.location.href = window.location.pathname;
}
function toggleView(viewType) {
if (viewType === 'table') {
$('#tableView').show();
$('#cardsView').hide();
$('#tableViewBtn').addClass('active');
$('#cardsViewBtn').removeClass('active');
} else {
$('#tableView').hide();
$('#cardsView').show();
$('#tableViewBtn').removeClass('active');
$('#cardsViewBtn').addClass('active');
}
localStorage.setItem('studiesViewType', viewType);
}
function toggleBulkActions() {
var checkedCount = $('.study-checkbox:checked').length;
if (checkedCount > 0) {
$('#bulkActions').show();
} else {
$('#bulkActions').hide();
}
}
function updateSelectAllState() {
var totalCheckboxes = $('.study-checkbox').length;
var checkedCheckboxes = $('.study-checkbox:checked').length;
$('#selectAll, #selectAllTable').prop('checked', totalCheckboxes === checkedCheckboxes);
}
function bulkAction(action) {
var selectedStudies = $('.study-checkbox:checked').map(function() {
return $(this).val();
}).get();
if (selectedStudies.length === 0) {
alert('Please select at least one study.');
return;
}
var actionText = {
'start': 'start',
'complete': 'complete',
'hold': 'put on hold',
'cancel': 'cancel'
};
if (confirm(`Are you sure you want to ${actionText[action]} ${selectedStudies.length} selected studies?`)) {
// Perform bulk action via AJAX
$.ajax({
url: '',
method: 'POST',
data: {
'action': action,
'study_ids': selectedStudies,
'csrfmiddlewaretoken': '{{ csrf_token }}'
},
success: function(response) {
if (response.success) {
location.reload();
} else {
alert('Error: ' + response.message);
}
},
error: function() {
alert('An error occurred while processing the request.');
}
});
}
}
function startStudy(studyId) {
// Load start study modal
$('#startStudyModal').modal('show');
}
function completeStudy(studyId) {
// Load complete study modal
$('#completeStudyModal').modal('show');
}
function refreshStudies() {
location.reload();
}
// Load saved view preference
$(document).ready(function() {
var savedView = localStorage.getItem('studiesViewType') || 'table';
toggleView(savedView);
});
</script>
{% endblock %}