629 lines
20 KiB
HTML
629 lines
20 KiB
HTML
{% extends 'base.html' %}
|
|
{% load static %}
|
|
|
|
{% block title %}{{ template.name }} - Surgical Template{% endblock %}
|
|
|
|
{% block extra_css %}
|
|
<style>
|
|
.template-header {
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
color: white;
|
|
border-radius: 0.5rem;
|
|
padding: 2rem;
|
|
margin-bottom: 2rem;
|
|
}
|
|
|
|
.info-section {
|
|
background: white;
|
|
border: 1px solid #dee2e6;
|
|
border-radius: 0.375rem;
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
|
|
.section-header {
|
|
background: #f8f9fa;
|
|
border-bottom: 1px solid #dee2e6;
|
|
padding: 1rem 1.5rem;
|
|
font-weight: 600;
|
|
color: #495057;
|
|
}
|
|
|
|
.section-content {
|
|
padding: 1.5rem;
|
|
}
|
|
|
|
.info-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
gap: 1rem;
|
|
}
|
|
|
|
.info-item {
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.info-label {
|
|
font-size: 0.875rem;
|
|
color: #6c757d;
|
|
font-weight: 600;
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
|
|
.info-value {
|
|
color: #495057;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.step-item {
|
|
border: 1px solid #dee2e6;
|
|
border-radius: 0.375rem;
|
|
padding: 1rem;
|
|
margin-bottom: 1rem;
|
|
background: white;
|
|
}
|
|
|
|
.step-header {
|
|
display: flex;
|
|
justify-content: between;
|
|
align-items: center;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
|
|
.step-number {
|
|
background: #007bff;
|
|
color: white;
|
|
width: 30px;
|
|
height: 30px;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
font-weight: bold;
|
|
font-size: 0.875rem;
|
|
}
|
|
|
|
.step-title {
|
|
font-weight: 600;
|
|
color: #495057;
|
|
margin-left: 1rem;
|
|
flex-grow: 1;
|
|
}
|
|
|
|
.step-duration {
|
|
background: #e9ecef;
|
|
color: #495057;
|
|
padding: 0.25rem 0.5rem;
|
|
border-radius: 0.25rem;
|
|
font-size: 0.75rem;
|
|
}
|
|
|
|
.equipment-item {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 0.75rem;
|
|
border: 1px solid #dee2e6;
|
|
border-radius: 0.25rem;
|
|
margin-bottom: 0.5rem;
|
|
background: #f8f9fa;
|
|
}
|
|
|
|
.equipment-icon {
|
|
width: 40px;
|
|
height: 40px;
|
|
background: #007bff;
|
|
color: white;
|
|
border-radius: 0.25rem;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-right: 1rem;
|
|
}
|
|
|
|
.equipment-info {
|
|
flex-grow: 1;
|
|
}
|
|
|
|
.equipment-name {
|
|
font-weight: 600;
|
|
color: #495057;
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
|
|
.equipment-details {
|
|
font-size: 0.875rem;
|
|
color: #6c757d;
|
|
}
|
|
|
|
.team-member {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 0.75rem;
|
|
border: 1px solid #dee2e6;
|
|
border-radius: 0.25rem;
|
|
margin-bottom: 0.5rem;
|
|
background: white;
|
|
}
|
|
|
|
.member-avatar {
|
|
width: 40px;
|
|
height: 40px;
|
|
background: #28a745;
|
|
color: white;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
margin-right: 1rem;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.member-info {
|
|
flex-grow: 1;
|
|
}
|
|
|
|
.member-role {
|
|
font-weight: 600;
|
|
color: #495057;
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
|
|
.member-requirements {
|
|
font-size: 0.875rem;
|
|
color: #6c757d;
|
|
}
|
|
|
|
.usage-stats {
|
|
background: #e7f3ff;
|
|
border: 1px solid #b3d9ff;
|
|
border-radius: 0.375rem;
|
|
padding: 1.5rem;
|
|
margin-bottom: 1.5rem;
|
|
}
|
|
|
|
.stats-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
|
gap: 1rem;
|
|
}
|
|
|
|
.stat-item {
|
|
text-align: center;
|
|
}
|
|
|
|
.stat-value {
|
|
font-size: 1.5rem;
|
|
font-weight: bold;
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
|
|
.stat-label {
|
|
font-size: 0.875rem;
|
|
color: #6c757d;
|
|
}
|
|
|
|
.template-tags {
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.template-tag {
|
|
display: inline-block;
|
|
background: #e9ecef;
|
|
color: #495057;
|
|
padding: 0.25rem 0.5rem;
|
|
border-radius: 0.25rem;
|
|
font-size: 0.75rem;
|
|
margin-right: 0.5rem;
|
|
margin-bottom: 0.25rem;
|
|
}
|
|
|
|
.complexity-simple { background: #d4edda; color: #155724; }
|
|
.complexity-moderate { background: #fff3cd; color: #856404; }
|
|
.complexity-complex { background: #f8d7da; color: #721c24; }
|
|
.complexity-highly-complex { background: #d1ecf1; color: #0c5460; }
|
|
|
|
@media (max-width: 768px) {
|
|
.template-header {
|
|
padding: 1.5rem;
|
|
}
|
|
|
|
.info-grid {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.stats-grid {
|
|
grid-template-columns: repeat(2, 1fr);
|
|
}
|
|
|
|
.step-header {
|
|
flex-direction: column;
|
|
align-items: flex-start;
|
|
}
|
|
|
|
.step-title {
|
|
margin-left: 0;
|
|
margin-top: 0.5rem;
|
|
}
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div id="content" class="app-content">
|
|
<!-- Page Header -->
|
|
<div class="d-flex align-items-center mb-3">
|
|
<div>
|
|
<ol class="breadcrumb">
|
|
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'operating_theatre:dashboard' %}">Operating Theatre</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'operating_theatre:template_list' %}">Templates</a></li>
|
|
<li class="breadcrumb-item active">{{ template.name }}</li>
|
|
</ol>
|
|
<h1 class="page-header mb-0">
|
|
<i class="fas fa-file-medical me-2"></i>{{ template.name }}
|
|
</h1>
|
|
</div>
|
|
<div class="ms-auto">
|
|
<div class="btn-group me-2">
|
|
<button class="btn btn-outline-secondary 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="{% url 'operating_theatre:template_export_pdf' template.pk %}">
|
|
<i class="fas fa-file-pdf me-2"></i>Export as PDF
|
|
</a></li>
|
|
<li><a class="dropdown-item" href="{% url 'operating_theatre:template_export_json' template.pk %}">
|
|
<i class="fas fa-file-code me-2"></i>Export as JSON
|
|
</a></li>
|
|
</ul>
|
|
</div>
|
|
<a href="{% url 'operating_theatre:template_edit' template.pk %}" class="btn btn-outline-primary me-2">
|
|
<i class="fas fa-edit me-1"></i>Edit
|
|
</a>
|
|
<button class="btn btn-success" onclick="useTemplate()">
|
|
<i class="fas fa-play me-1"></i>Use Template
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Template Header -->
|
|
<div class="template-header">
|
|
<div class="row">
|
|
<div class="col-md-8">
|
|
<h2 class="mb-3">{{ template.name }}</h2>
|
|
<p class="mb-2">{{ template.description }}</p>
|
|
<div class="template-tags">
|
|
<span class="template-tag">
|
|
<i class="fas fa-user-md me-1"></i>{{ template.get_specialty_display }}
|
|
</span>
|
|
<span class="template-tag complexity-{{ template.complexity }}">
|
|
<i class="fas fa-layer-group me-1"></i>{{ template.get_complexity_display }}
|
|
</span>
|
|
<span class="template-tag">
|
|
<i class="fas fa-clock me-1"></i>{{ template.estimated_duration }} minutes
|
|
</span>
|
|
{% if template.requires_anesthesia %}
|
|
<span class="template-tag">
|
|
<i class="fas fa-syringe me-1"></i>Anesthesia Required
|
|
</span>
|
|
{% endif %}
|
|
{% if template.is_emergency_procedure %}
|
|
<span class="template-tag">
|
|
<i class="fas fa-exclamation-triangle me-1"></i>Emergency Procedure
|
|
</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-4 text-end">
|
|
<div class="mb-2">
|
|
{% if template.status == 'active' %}
|
|
<span class="badge bg-success fs-6">Active</span>
|
|
{% elif template.status == 'draft' %}
|
|
<span class="badge bg-secondary fs-6">Draft</span>
|
|
{% elif template.status == 'under_review' %}
|
|
<span class="badge bg-warning fs-6">Under Review</span>
|
|
{% elif template.status == 'archived' %}
|
|
<span class="badge bg-dark fs-6">Archived</span>
|
|
{% endif %}
|
|
</div>
|
|
<div class="text-white-50">
|
|
Created by {{ template.created_by.get_full_name }}<br>
|
|
{{ template.created_at|date:"M d, Y" }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Usage Statistics -->
|
|
<div class="usage-stats">
|
|
<h5 class="mb-3">
|
|
<i class="fas fa-chart-line me-2"></i>Usage Statistics
|
|
</h5>
|
|
<div class="stats-grid">
|
|
<div class="stat-item">
|
|
<div class="stat-value text-primary">{{ usage_stats.total_uses }}</div>
|
|
<div class="stat-label">Total Uses</div>
|
|
</div>
|
|
<div class="stat-item">
|
|
<div class="stat-value text-success">{{ usage_stats.this_month }}</div>
|
|
<div class="stat-label">This Month</div>
|
|
</div>
|
|
<div class="stat-item">
|
|
<div class="stat-value text-info">{{ usage_stats.avg_duration }}</div>
|
|
<div class="stat-label">Avg Duration (min)</div>
|
|
</div>
|
|
<div class="stat-item">
|
|
<div class="stat-value text-warning">{{ usage_stats.success_rate }}%</div>
|
|
<div class="stat-label">Success Rate</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Basic Information -->
|
|
<div class="info-section">
|
|
<div class="section-header">
|
|
<i class="fas fa-info-circle me-2"></i>Basic Information
|
|
</div>
|
|
<div class="section-content">
|
|
<div class="info-grid">
|
|
<div class="info-item">
|
|
<div class="info-label">Procedure Type</div>
|
|
<div class="info-value">{{ template.get_procedure_type_display }}</div>
|
|
</div>
|
|
<div class="info-item">
|
|
<div class="info-label">Estimated Duration</div>
|
|
<div class="info-value">{{ template.estimated_duration }} minutes</div>
|
|
</div>
|
|
<div class="info-item">
|
|
<div class="info-label">Required Team Size</div>
|
|
<div class="info-value">{{ template.required_team_size }} members</div>
|
|
</div>
|
|
<div class="info-item">
|
|
<div class="info-label">Anesthesia Type</div>
|
|
<div class="info-value">
|
|
{% if template.anesthesia_type %}
|
|
{{ template.get_anesthesia_type_display }}
|
|
{% else %}
|
|
Not specified
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="info-item">
|
|
<div class="info-label">Patient Position</div>
|
|
<div class="info-value">{{ template.patient_position|default:"Not specified" }}</div>
|
|
</div>
|
|
<div class="info-item">
|
|
<div class="info-label">Room Requirements</div>
|
|
<div class="info-value">{{ template.room_requirements|default:"Standard OR" }}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Procedure Steps -->
|
|
<div class="info-section">
|
|
<div class="section-header">
|
|
<i class="fas fa-list-ol me-2"></i>Procedure Steps
|
|
</div>
|
|
<div class="section-content">
|
|
{% for step in template.procedure_steps.all %}
|
|
<div class="step-item">
|
|
<div class="step-header">
|
|
<div class="step-number">{{ step.step_number }}</div>
|
|
<div class="step-title">{{ step.title }}</div>
|
|
<div class="step-duration">{{ step.estimated_duration }} min</div>
|
|
</div>
|
|
<div class="step-description">
|
|
{{ step.description }}
|
|
</div>
|
|
{% if step.critical_points %}
|
|
<div class="mt-2">
|
|
<small class="text-danger">
|
|
<i class="fas fa-exclamation-triangle me-1"></i>
|
|
<strong>Critical Points:</strong> {{ step.critical_points }}
|
|
</small>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% empty %}
|
|
<div class="text-center py-3">
|
|
<i class="fas fa-list-ol fa-2x text-muted mb-2"></i>
|
|
<p class="text-muted">No procedure steps defined</p>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Required Equipment -->
|
|
<div class="info-section">
|
|
<div class="section-header">
|
|
<i class="fas fa-tools me-2"></i>Required Equipment
|
|
</div>
|
|
<div class="section-content">
|
|
{% for equipment in template.equipment_list.all %}
|
|
<div class="equipment-item">
|
|
<div class="equipment-icon">
|
|
<i class="fas fa-tools"></i>
|
|
</div>
|
|
<div class="equipment-info">
|
|
<div class="equipment-name">{{ equipment.name }}</div>
|
|
<div class="equipment-details">
|
|
{{ equipment.category|title }} |
|
|
Quantity: {{ equipment.quantity|default:1 }} |
|
|
{% if equipment.is_critical %}
|
|
<span class="text-danger">Critical</span>
|
|
{% else %}
|
|
<span class="text-muted">Standard</span>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% if equipment.alternatives %}
|
|
<div class="equipment-alternatives">
|
|
<small class="text-muted">
|
|
<i class="fas fa-exchange-alt me-1"></i>
|
|
Alternatives: {{ equipment.alternatives }}
|
|
</small>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% empty %}
|
|
<div class="text-center py-3">
|
|
<i class="fas fa-tools fa-2x text-muted mb-2"></i>
|
|
<p class="text-muted">No equipment requirements defined</p>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Required Team -->
|
|
<div class="info-section">
|
|
<div class="section-header">
|
|
<i class="fas fa-users me-2"></i>Required Team
|
|
</div>
|
|
<div class="section-content">
|
|
{% for member in template.team_requirements.all %}
|
|
<div class="team-member">
|
|
<div class="member-avatar">
|
|
{{ member.role|first|upper }}
|
|
</div>
|
|
<div class="member-info">
|
|
<div class="member-role">{{ member.get_role_display }}</div>
|
|
<div class="member-requirements">
|
|
{% if member.specialization %}
|
|
Specialization: {{ member.specialization }} |
|
|
{% endif %}
|
|
Experience: {{ member.min_experience_years|default:"Any" }} years
|
|
{% if member.certifications_required %}
|
|
| Certifications: {{ member.certifications_required }}
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="member-count">
|
|
<span class="badge bg-primary">{{ member.count|default:1 }}</span>
|
|
</div>
|
|
</div>
|
|
{% empty %}
|
|
<div class="text-center py-3">
|
|
<i class="fas fa-users fa-2x text-muted mb-2"></i>
|
|
<p class="text-muted">No team requirements defined</p>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Pre-operative Requirements -->
|
|
{% if template.preop_requirements %}
|
|
<div class="info-section">
|
|
<div class="section-header">
|
|
<i class="fas fa-clipboard-check me-2"></i>Pre-operative Requirements
|
|
</div>
|
|
<div class="section-content">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<h6>Patient Preparation</h6>
|
|
<ul class="list-unstyled">
|
|
{% for req in template.preop_requirements.patient_prep %}
|
|
<li class="mb-1">
|
|
<i class="fas fa-check text-success me-2"></i>{{ req }}
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<h6>Required Tests</h6>
|
|
<ul class="list-unstyled">
|
|
{% for test in template.preop_requirements.required_tests %}
|
|
<li class="mb-1">
|
|
<i class="fas fa-vial text-info me-2"></i>{{ test }}
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Post-operative Care -->
|
|
{% if template.postop_care %}
|
|
<div class="info-section">
|
|
<div class="section-header">
|
|
<i class="fas fa-heart me-2"></i>Post-operative Care
|
|
</div>
|
|
<div class="section-content">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<h6>Immediate Care</h6>
|
|
<ul class="list-unstyled">
|
|
{% for care in template.postop_care.immediate %}
|
|
<li class="mb-1">
|
|
<i class="fas fa-arrow-right text-primary me-2"></i>{{ care }}
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<h6>Recovery Instructions</h6>
|
|
<ul class="list-unstyled">
|
|
{% for instruction in template.postop_care.recovery %}
|
|
<li class="mb-1">
|
|
<i class="fas fa-info-circle text-warning me-2"></i>{{ instruction }}
|
|
</li>
|
|
{% endfor %}
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Notes and Warnings -->
|
|
{% if template.notes or template.warnings %}
|
|
<div class="info-section">
|
|
<div class="section-header">
|
|
<i class="fas fa-sticky-note me-2"></i>Additional Information
|
|
</div>
|
|
<div class="section-content">
|
|
{% if template.warnings %}
|
|
<div class="alert alert-warning">
|
|
<h6 class="alert-heading">
|
|
<i class="fas fa-exclamation-triangle me-2"></i>Warnings
|
|
</h6>
|
|
<p class="mb-0">{{ template.warnings }}</p>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if template.notes %}
|
|
<div class="alert alert-info">
|
|
<h6 class="alert-heading">
|
|
<i class="fas fa-info-circle me-2"></i>Notes
|
|
</h6>
|
|
<p class="mb-0">{{ template.notes }}</p>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block extra_js %}
|
|
<script>
|
|
function useTemplate() {
|
|
if (confirm('Use this template to create a new surgical case?')) {
|
|
window.location.href = `/operating_theatre/cases/create/?template={{ template.pk }}`;
|
|
}
|
|
}
|
|
|
|
// Print functionality
|
|
$(document).keydown(function(e) {
|
|
// Ctrl/Cmd + P for print
|
|
if ((e.ctrlKey || e.metaKey) && e.keyCode === 80) {
|
|
e.preventDefault();
|
|
window.print();
|
|
}
|
|
});
|
|
</script>
|
|
{% endblock %}
|
|
|