2025-08-12 13:33:25 +03:00

478 lines
24 KiB
HTML

{% extends "base.html" %}
{% load static %}
{% block title %}Bed Management{% endblock %}
{% block content %}
<div class="d-flex align-items-center mb-3">
<div>
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'inpatients:dashboard' %}">Inpatients</a></li>
<li class="breadcrumb-item active">Bed Management</li>
</ol>
<h1 class="page-header mb-0">Bed Management</h1>
</div>
<div class="ms-auto">
<div class="btn-group">
<a href="{% url 'inpatients:bed_form' %}" class="btn btn-primary">
<i class="fas fa-plus me-2"></i>Add Bed
</a>
<button type="button" class="btn btn-outline-secondary dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown">
<span class="visually-hidden">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#" onclick="exportBeds()">
<i class="fas fa-download me-2"></i>Export List
</a></li>
<li><a class="dropdown-item" href="#" onclick="printBeds()">
<i class="fas fa-print me-2"></i>Print List
</a></li>
<li><hr class="dropdown-divider"></li>
<li><a class="dropdown-item" href="#" onclick="bulkUpdate()">
<i class="fas fa-edit me-2"></i>Bulk Update
</a></li>
</ul>
</div>
</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">
<div class="fs-6 text-white-75">Total Beds</div>
<div class="fs-2 fw-bold">{{ total_beds|default:0 }}</div>
</div>
<div class="flex-shrink-0">
<i class="fas fa-bed fa-2x text-white-50"></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">
<div class="fs-6 text-white-75">Available</div>
<div class="fs-2 fw-bold">{{ available_beds|default:0 }}</div>
</div>
<div class="flex-shrink-0">
<i class="fas fa-check-circle fa-2x text-white-50"></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">
<div class="fs-6 text-white-75">Occupied</div>
<div class="fs-2 fw-bold">{{ occupied_beds|default:0 }}</div>
</div>
<div class="flex-shrink-0">
<i class="fas fa-user fa-2x text-white-50"></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">
<div class="fs-6 text-white-75">Occupancy Rate</div>
<div class="fs-2 fw-bold">{{ occupancy_rate|default:0 }}%</div>
</div>
<div class="flex-shrink-0">
<i class="fas fa-chart-pie fa-2x text-white-50"></i>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">
<i class="fas fa-bed me-2"></i>
Bed List
</h4>
<div class="card-toolbar">
<div class="d-flex align-items-center">
<!-- View Toggle -->
<div class="btn-group btn-group-sm me-3" role="group">
<input type="radio" class="btn-check" name="viewType" id="gridView" autocomplete="off" checked>
<label class="btn btn-outline-secondary" for="gridView">
<i class="fas fa-th"></i>
</label>
<input type="radio" class="btn-check" name="viewType" id="listView" autocomplete="off">
<label class="btn btn-outline-secondary" for="listView">
<i class="fas fa-list"></i>
</label>
</div>
<!-- Filters -->
<div class="d-flex align-items-center">
<select class="form-select form-select-sm me-2" id="wardFilter" onchange="filterBeds()">
<option value="">All Wards</option>
{% for ward in wards %}
<option value="{{ ward.id }}">{{ ward.name }}</option>
{% endfor %}
</select>
<select class="form-select form-select-sm me-2" id="statusFilter" onchange="filterBeds()">
<option value="">All Status</option>
<option value="available">Available</option>
<option value="occupied">Occupied</option>
<option value="maintenance">Maintenance</option>
<option value="cleaning">Cleaning</option>
</select>
<button type="button" class="btn btn-sm btn-outline-secondary" onclick="clearFilters()">
<i class="fas fa-times"></i>
</button>
</div>
</div>
</div>
</div>
<div class="card-body">
<!-- Grid View -->
<div id="gridViewContent">
{% if object_list %}
<div class="row" id="bedGrid">
{% for bed in object_list %}
<div class="col-xl-3 col-lg-4 col-md-6 mb-4 bed-item"
data-ward="{{ bed.ward.id }}"
data-status="{{ bed.status }}"
data-bed-type="{{ bed.bed_type }}">
<div class="card h-100 bed-card {% if bed.status == 'occupied' %}border-warning{% elif bed.status == 'available' %}border-success{% elif bed.status == 'maintenance' %}border-danger{% else %}border-info{% endif %}">
<div class="card-header d-flex justify-content-between align-items-center">
<h6 class="card-title mb-0">
<i class="fas fa-bed me-2"></i>
Bed {{ bed.bed_number }}
</h6>
<span class="badge bg-{% if bed.status == 'available' %}success{% elif bed.status == 'occupied' %}warning{% elif bed.status == 'maintenance' %}danger{% else %}info{% endif %}">
{{ bed.get_status_display }}
</span>
</div>
<div class="card-body">
<div class="mb-2">
<small class="text-muted">Ward:</small>
<div class="fw-bold">{{ bed.ward.name }}</div>
</div>
<div class="mb-2">
<small class="text-muted">Room:</small>
<div>{{ bed.room_number|default:"Not assigned" }}</div>
</div>
<div class="mb-2">
<small class="text-muted">Type:</small>
<div>{{ bed.get_bed_type_display }}</div>
</div>
{% if bed.current_patient %}
<div class="mb-2">
<small class="text-muted">Patient:</small>
<div class="fw-bold text-primary">
<a href="{% url 'patients:patient_detail' bed.current_patient.pk %}">
{{ bed.current_patient.get_full_name }}
</a>
</div>
<small class="text-muted">{{ bed.current_patient.medical_record_number }}</small>
</div>
{% endif %}
<div class="mb-3">
{% if bed.has_oxygen %}
<span class="badge bg-info me-1">O2</span>
{% endif %}
{% if bed.has_suction %}
<span class="badge bg-info me-1">Suction</span>
{% endif %}
{% if bed.has_monitor %}
<span class="badge bg-info me-1">Monitor</span>
{% endif %}
{% if bed.is_isolation %}
<span class="badge bg-warning me-1">Isolation</span>
{% endif %}
</div>
</div>
<div class="card-footer">
<div class="d-flex justify-content-between">
<a href="{% url 'inpatients:bed_detail' bed.pk %}" class="btn btn-sm btn-outline-primary">
<i class="fas fa-eye me-1"></i>View
</a>
<div class="btn-group">
<a href="{% url 'inpatients:bed_form' bed.pk %}" class="btn btn-sm btn-outline-secondary">
<i class="fas fa-edit"></i>
</a>
<button type="button" class="btn btn-sm btn-outline-secondary dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown">
<span class="visually-hidden">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu">
<li><a class="dropdown-item" href="#" onclick="updateBedStatus('{{ bed.pk }}', 'available')">
<i class="fas fa-check text-success me-2"></i>Mark Available
</a></li>
<li><a class="dropdown-item" href="#" onclick="updateBedStatus('{{ bed.pk }}', 'maintenance')">
<i class="fas fa-tools text-warning me-2"></i>Maintenance
</a></li>
<li><a class="dropdown-item" href="#" onclick="updateBedStatus('{{ bed.pk }}', 'cleaning')">
<i class="fas fa-broom text-info me-2"></i>Cleaning
</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="text-center text-muted py-5">
<i class="fas fa-bed fa-3x mb-3"></i>
<h5>No Beds Found</h5>
<p>No beds match your current filters. Try adjusting your search criteria.</p>
<a href="{% url 'inpatients:bed_form' %}" class="btn btn-primary">
<i class="fas fa-plus me-2"></i>Add First Bed
</a>
</div>
{% endif %}
</div>
<!-- List View -->
<div id="listViewContent" style="display: none;">
{% if object_list %}
<div class="table-responsive">
<table class="table table-hover" id="bedTable">
<thead>
<tr>
<th>
<input type="checkbox" id="selectAll" onchange="toggleSelectAll()">
</th>
<th>Bed Number</th>
<th>Ward</th>
<th>Room</th>
<th>Type</th>
<th>Status</th>
<th>Current Patient</th>
<th>Features</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for bed in object_list %}
<tr class="bed-row"
data-ward="{{ bed.ward.id }}"
data-status="{{ bed.status }}"
data-bed-type="{{ bed.bed_type }}">
<td>
<input type="checkbox" class="bed-checkbox" value="{{ bed.pk }}">
</td>
<td>
<a href="{% url 'inpatients:bed_detail' bed.pk %}" class="fw-bold">
{{ bed.bed_number }}
</a>
</td>
<td>{{ bed.ward.name }}</td>
<td>{{ bed.room_number|default:"-" }}</td>
<td>{{ bed.get_bed_type_display }}</td>
<td>
<span class="badge bg-{% if bed.status == 'available' %}success{% elif bed.status == 'occupied' %}warning{% elif bed.status == 'maintenance' %}danger{% else %}info{% endif %}">
{{ bed.get_status_display }}
</span>
</td>
<td>
{% if bed.current_patient %}
<a href="{% url 'patients:patient_detail' bed.current_patient.pk %}">
{{ bed.current_patient.get_full_name }}
</a>
<div class="small text-muted">{{ bed.current_patient.medical_record_number }}</div>
{% else %}
<span class="text-muted">-</span>
{% endif %}
</td>
<td>
{% if bed.has_oxygen %}
<span class="badge bg-info me-1">O2</span>
{% endif %}
{% if bed.has_suction %}
<span class="badge bg-info me-1">Suction</span>
{% endif %}
{% if bed.has_monitor %}
<span class="badge bg-info me-1">Monitor</span>
{% endif %}
{% if bed.is_isolation %}
<span class="badge bg-warning me-1">Isolation</span>
{% endif %}
</td>
<td>
<div class="btn-group btn-group-sm">
<a href="{% url 'inpatients:bed_detail' bed.pk %}" class="btn btn-outline-primary">
<i class="fas fa-eye"></i>
</a>
<a href="{% url 'inpatients:bed_form' bed.pk %}" class="btn btn-outline-secondary">
<i class="fas fa-edit"></i>
</a>
<button type="button" class="btn btn-outline-danger" onclick="deleteBed('{{ bed.pk }}')">
<i class="fas fa-trash"></i>
</button>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
</div>
<!-- Pagination -->
{% if is_paginated %}
<nav aria-label="Bed 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>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// View toggle functionality
const gridViewRadio = document.getElementById('gridView');
const listViewRadio = document.getElementById('listView');
const gridViewContent = document.getElementById('gridViewContent');
const listViewContent = document.getElementById('listViewContent');
gridViewRadio.addEventListener('change', function() {
if (this.checked) {
gridViewContent.style.display = 'block';
listViewContent.style.display = 'none';
}
});
listViewRadio.addEventListener('change', function() {
if (this.checked) {
gridViewContent.style.display = 'none';
listViewContent.style.display = 'block';
}
});
});
function filterBeds() {
const wardFilter = document.getElementById('wardFilter').value;
const statusFilter = document.getElementById('statusFilter').value;
// Grid view filtering
const bedItems = document.querySelectorAll('.bed-item');
bedItems.forEach(item => {
const wardMatch = !wardFilter || item.dataset.ward === wardFilter;
const statusMatch = !statusFilter || item.dataset.status === statusFilter;
if (wardMatch && statusMatch) {
item.style.display = 'block';
} else {
item.style.display = 'none';
}
});
// List view filtering
const bedRows = document.querySelectorAll('.bed-row');
bedRows.forEach(row => {
const wardMatch = !wardFilter || row.dataset.ward === wardFilter;
const statusMatch = !statusFilter || row.dataset.status === statusFilter;
if (wardMatch && statusMatch) {
row.style.display = '';
} else {
row.style.display = 'none';
}
});
}
function clearFilters() {
document.getElementById('wardFilter').value = '';
document.getElementById('statusFilter').value = '';
filterBeds();
}
function toggleSelectAll() {
const selectAll = document.getElementById('selectAll');
const checkboxes = document.querySelectorAll('.bed-checkbox');
checkboxes.forEach(checkbox => {
checkbox.checked = selectAll.checked;
});
}
function updateBedStatus(bedId, status) {
if (confirm(`Are you sure you want to mark this bed as ${status}?`)) {
// In a real implementation, this would submit via AJAX
console.log(`Updating bed ${bedId} to status ${status}`);
location.reload();
}
}
function deleteBed(bedId) {
if (confirm('Are you sure you want to delete this bed? This action cannot be undone.')) {
// In a real implementation, this would submit via AJAX
window.location.href = `/inpatients/beds/${bedId}/delete/`;
}
}
function exportBeds() {
// In a real implementation, this would export the bed list
alert('Export functionality would be implemented here.');
}
function printBeds() {
window.print();
}
function bulkUpdate() {
const selectedBeds = document.querySelectorAll('.bed-checkbox:checked');
if (selectedBeds.length === 0) {
alert('Please select at least one bed to update.');
return;
}
// In a real implementation, this would open a bulk update modal
alert(`Bulk update functionality for ${selectedBeds.length} beds would be implemented here.`);
}
</script>
{% endblock %}