456 lines
23 KiB
HTML
456 lines
23 KiB
HTML
{% extends "base.html" %}
|
|
{% load static %}
|
|
|
|
{% block title %}{% if form.instance.pk %}Edit{% else %}Create{% endif %} Department{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container-fluid">
|
|
<!-- Breadcrumb -->
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<div class="page-title-box d-sm-flex align-items-center justify-content-between">
|
|
<h4 class="mb-sm-0">{% if form.instance.pk %}Edit{% else %}Create{% endif %} Department</h4>
|
|
<div class="page-title-right">
|
|
<ol class="breadcrumb m-0">
|
|
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'core:department_list' %}">Departments</a></li>
|
|
<li class="breadcrumb-item active">{% if form.instance.pk %}Edit{% else %}Create{% endif %} Department</li>
|
|
</ol>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<!-- Main Form -->
|
|
<div class="col-lg-8">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title mb-0">
|
|
<i class="fas fa-{% if form.instance.pk %}edit{% else %}plus{% endif %} me-2"></i>
|
|
{% if form.instance.pk %}Edit{% else %}Create{% endif %} Department
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<form method="post" id="departmentForm">
|
|
{% csrf_token %}
|
|
|
|
{% if form.non_field_errors %}
|
|
<div class="alert alert-danger">
|
|
<div class="d-flex">
|
|
<div class="flex-shrink-0">
|
|
<i class="fas fa-exclamation-triangle"></i>
|
|
</div>
|
|
<div class="flex-grow-1 ms-3">
|
|
{% for error in form.non_field_errors %}
|
|
<p class="mb-0">{{ error }}</p>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endif %}
|
|
|
|
<div class="row mb-3">
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
{{ form.name.errors }}
|
|
{{ form.name }}
|
|
<label for="{{ form.name.id_for_label }}">Department Name *</label>
|
|
{% if form.name.help_text %}
|
|
<div class="form-text">{{ form.name.help_text }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
{{ form.code.errors }}
|
|
{{ form.code }}
|
|
<label for="{{ form.code.id_for_label }}">Department Code *</label>
|
|
{% if form.code.help_text %}
|
|
<div class="form-text">{{ form.code.help_text }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
{{ form.department_type.errors }}
|
|
{{ form.department_type }}
|
|
<label for="{{ form.department_type.id_for_label }}">Department Type *</label>
|
|
{% if form.department_type.help_text %}
|
|
<div class="form-text">{{ form.department_type.help_text }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
{{ form.parent_department.errors }}
|
|
{{ form.parent_department }}
|
|
<label for="{{ form.parent_department.id_for_label }}">Parent Department</label>
|
|
{% if form.parent_department.help_text %}
|
|
<div class="form-text">{{ form.parent_department.help_text }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="{{ form.description.id_for_label }}" class="form-label">Description</label>
|
|
{{ form.description.errors }}
|
|
{{ form.description }}
|
|
{% if form.description.help_text %}
|
|
<div class="form-text">{{ form.description.help_text }}</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
{{ form.contact_number.errors }}
|
|
{{ form.contact_number }}
|
|
<label for="{{ form.contact_number.id_for_label }}">Contact Number</label>
|
|
{% if form.contact_number.help_text %}
|
|
<div class="form-text">{{ form.contact_number.help_text }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
{{ form.email.errors }}
|
|
{{ form.email }}
|
|
<label for="{{ form.email.id_for_label }}">Email</label>
|
|
{% if form.email.help_text %}
|
|
<div class="form-text">{{ form.email.help_text }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
{{ form.location.errors }}
|
|
{{ form.location }}
|
|
<label for="{{ form.location.id_for_label }}">Location</label>
|
|
{% if form.location.help_text %}
|
|
<div class="form-text">{{ form.location.help_text }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
{{ form.working_hours.errors }}
|
|
{{ form.working_hours }}
|
|
<label for="{{ form.working_hours.id_for_label }}">Working Hours</label>
|
|
{% if form.working_hours.help_text %}
|
|
<div class="form-text">{{ form.working_hours.help_text }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row mb-3">
|
|
<div class="col-md-6">
|
|
<div class="form-floating mb-3">
|
|
{{ form.department_head.errors }}
|
|
{{ form.department_head }}
|
|
<label for="{{ form.department_head.id_for_label }}">Department Head</label>
|
|
{% if form.department_head.help_text %}
|
|
<div class="form-text">{{ form.department_head.help_text }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="form-check form-switch mt-4">
|
|
{{ form.is_active.errors }}
|
|
{{ form.is_active }}
|
|
<label class="form-check-label" for="{{ form.is_active.id_for_label }}">Active</label>
|
|
{% if form.is_active.help_text %}
|
|
<div class="form-text">{{ form.is_active.help_text }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<label for="{{ form.notes.id_for_label }}" class="form-label">Additional Notes</label>
|
|
{{ form.notes.errors }}
|
|
{{ form.notes }}
|
|
{% if form.notes.help_text %}
|
|
<div class="form-text">{{ form.notes.help_text }}</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="d-flex justify-content-between">
|
|
<a href="{% url 'core:department_list' %}" class="btn btn-secondary">
|
|
<i class="fas fa-times me-1"></i>
|
|
Cancel
|
|
</a>
|
|
<button type="submit" class="btn btn-primary">
|
|
<i class="fas fa-save me-1"></i>
|
|
{% if form.instance.pk %}Update{% else %}Create{% endif %} Department
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Sidebar -->
|
|
<div class="col-lg-4">
|
|
<!-- Help Card -->
|
|
<div class="card mb-4">
|
|
<div class="card-header">
|
|
<h5 class="card-title mb-0">
|
|
<i class="fas fa-question-circle me-2"></i>
|
|
Help & Guidelines
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="accordion" id="helpAccordion">
|
|
<div class="accordion-item">
|
|
<h2 class="accordion-header" id="headingOne">
|
|
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
|
|
Department Types
|
|
</button>
|
|
</h2>
|
|
<div id="collapseOne" class="accordion-collapse collapse show" aria-labelledby="headingOne" data-bs-parent="#helpAccordion">
|
|
<div class="accordion-body">
|
|
<p><strong>Clinical:</strong> Departments directly involved in patient care (e.g., Cardiology, Pediatrics).</p>
|
|
<p><strong>Administrative:</strong> Departments handling operational aspects (e.g., HR, Finance).</p>
|
|
<p><strong>Support:</strong> Departments providing support services (e.g., IT, Maintenance).</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="accordion-item">
|
|
<h2 class="accordion-header" id="headingTwo">
|
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
|
|
Department Codes
|
|
</button>
|
|
</h2>
|
|
<div id="collapseTwo" class="accordion-collapse collapse" aria-labelledby="headingTwo" data-bs-parent="#helpAccordion">
|
|
<div class="accordion-body">
|
|
<p>Department codes should be unique, short, and recognizable.</p>
|
|
<p>Examples:</p>
|
|
<ul>
|
|
<li>CARD - Cardiology</li>
|
|
<li>PEDS - Pediatrics</li>
|
|
<li>HR - Human Resources</li>
|
|
<li>IT - Information Technology</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="accordion-item">
|
|
<h2 class="accordion-header" id="headingThree">
|
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
|
|
Department Hierarchy
|
|
</button>
|
|
</h2>
|
|
<div id="collapseThree" class="accordion-collapse collapse" aria-labelledby="headingThree" data-bs-parent="#helpAccordion">
|
|
<div class="accordion-body">
|
|
<p>Departments can be organized hierarchically by setting a parent department.</p>
|
|
<p>This creates a tree structure that reflects your organization's structure.</p>
|
|
<p>Example: The Cardiac Surgery department might have Cardiology as its parent department.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="accordion-item">
|
|
<h2 class="accordion-header" id="headingFour">
|
|
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseFour" aria-expanded="false" aria-controls="collapseFour">
|
|
Department Head
|
|
</button>
|
|
</h2>
|
|
<div id="collapseFour" class="accordion-collapse collapse" aria-labelledby="headingFour" data-bs-parent="#helpAccordion">
|
|
<div class="accordion-body">
|
|
<p>The department head is the employee responsible for managing the department.</p>
|
|
<p>Only active employees can be assigned as department heads.</p>
|
|
<p>You can change the department head later if needed.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Preview Card -->
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h5 class="card-title mb-0">
|
|
<i class="fas fa-eye me-2"></i>
|
|
Department Preview
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="text-center mb-3">
|
|
<div class="avatar-lg mx-auto mb-3">
|
|
<span class="avatar-title rounded-circle bg-primary text-white" style="font-size: 2rem;" id="previewInitial">
|
|
?
|
|
</span>
|
|
</div>
|
|
<h5 class="mb-1" id="previewName">Department Name</h5>
|
|
<p class="text-muted mb-0" id="previewCode">CODE</p>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<div class="d-flex align-items-center mb-2">
|
|
<div class="flex-shrink-0">
|
|
<i class="fas fa-tag text-muted me-2"></i>
|
|
</div>
|
|
<div class="flex-grow-1">
|
|
<h6 class="mb-0">Type</h6>
|
|
<p class="mb-0" id="previewType">Department Type</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<div class="d-flex align-items-center mb-2">
|
|
<div class="flex-shrink-0">
|
|
<i class="fas fa-info-circle text-muted me-2"></i>
|
|
</div>
|
|
<div class="flex-grow-1">
|
|
<h6 class="mb-0">Status</h6>
|
|
<p class="mb-0" id="previewStatus">Active</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-3">
|
|
<div class="d-flex align-items-center mb-2">
|
|
<div class="flex-shrink-0">
|
|
<i class="fas fa-user-tie text-muted me-2"></i>
|
|
</div>
|
|
<div class="flex-grow-1">
|
|
<h6 class="mb-0">Department Head</h6>
|
|
<p class="mb-0" id="previewHead">Not assigned</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="mb-0">
|
|
<div class="d-flex align-items-center mb-2">
|
|
<div class="flex-shrink-0">
|
|
<i class="fas fa-map-marker-alt text-muted me-2"></i>
|
|
</div>
|
|
<div class="flex-grow-1">
|
|
<h6 class="mb-0">Location</h6>
|
|
<p class="mb-0" id="previewLocation">Not specified</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block css %}
|
|
<style>
|
|
.form-floating > .form-control {
|
|
height: calc(3.5rem + 2px);
|
|
padding: 1rem 0.75rem;
|
|
}
|
|
|
|
.form-floating > textarea.form-control {
|
|
height: auto;
|
|
min-height: 100px;
|
|
}
|
|
|
|
.form-floating > label {
|
|
padding: 1rem 0.75rem;
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block js %}
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Initialize form elements with Bootstrap classes
|
|
document.querySelectorAll('input[type="text"], input[type="email"], input[type="tel"], select, textarea').forEach(function(element) {
|
|
if (!element.classList.contains('form-check-input')) {
|
|
element.classList.add('form-control');
|
|
}
|
|
});
|
|
|
|
document.querySelectorAll('input[type="checkbox"]').forEach(function(element) {
|
|
element.classList.add('form-check-input');
|
|
});
|
|
|
|
// Live preview functionality
|
|
const nameInput = document.getElementById('{{ form.name.id_for_label }}');
|
|
const codeInput = document.getElementById('{{ form.code.id_for_label }}');
|
|
const typeSelect = document.getElementById('{{ form.department_type.id_for_label }}');
|
|
const activeCheckbox = document.getElementById('{{ form.is_active.id_for_label }}');
|
|
const headSelect = document.getElementById('{{ form.department_head.id_for_label }}');
|
|
const locationInput = document.getElementById('{{ form.location.id_for_label }}');
|
|
|
|
const previewName = document.getElementById('previewName');
|
|
const previewCode = document.getElementById('previewCode');
|
|
const previewInitial = document.getElementById('previewInitial');
|
|
const previewType = document.getElementById('previewType');
|
|
const previewStatus = document.getElementById('previewStatus');
|
|
const previewHead = document.getElementById('previewHead');
|
|
const previewLocation = document.getElementById('previewLocation');
|
|
|
|
// Initial values
|
|
if (nameInput.value) {
|
|
previewName.textContent = nameInput.value;
|
|
previewInitial.textContent = nameInput.value.charAt(0).toUpperCase();
|
|
}
|
|
|
|
if (codeInput.value) {
|
|
previewCode.textContent = codeInput.value;
|
|
}
|
|
|
|
if (typeSelect.value) {
|
|
const selectedOption = typeSelect.options[typeSelect.selectedIndex];
|
|
previewType.textContent = selectedOption.textContent;
|
|
}
|
|
|
|
previewStatus.textContent = activeCheckbox.checked ? 'Active' : 'Inactive';
|
|
|
|
if (headSelect.value) {
|
|
const selectedOption = headSelect.options[headSelect.selectedIndex];
|
|
previewHead.textContent = selectedOption.textContent;
|
|
}
|
|
|
|
if (locationInput.value) {
|
|
previewLocation.textContent = locationInput.value;
|
|
}
|
|
|
|
// Event listeners for live updates
|
|
nameInput.addEventListener('input', function() {
|
|
previewName.textContent = this.value || 'Department Name';
|
|
previewInitial.textContent = this.value ? this.value.charAt(0).toUpperCase() : '?';
|
|
});
|
|
|
|
codeInput.addEventListener('input', function() {
|
|
previewCode.textContent = this.value || 'CODE';
|
|
});
|
|
|
|
typeSelect.addEventListener('change', function() {
|
|
const selectedOption = this.options[this.selectedIndex];
|
|
previewType.textContent = selectedOption.textContent || 'Department Type';
|
|
});
|
|
|
|
activeCheckbox.addEventListener('change', function() {
|
|
previewStatus.textContent = this.checked ? 'Active' : 'Inactive';
|
|
});
|
|
|
|
headSelect.addEventListener('change', function() {
|
|
const selectedOption = this.options[this.selectedIndex];
|
|
previewHead.textContent = selectedOption.textContent || 'Not assigned';
|
|
});
|
|
|
|
locationInput.addEventListener('input', function() {
|
|
previewLocation.textContent = this.value || 'Not specified';
|
|
});
|
|
});
|
|
</script>
|
|
{% endblock %}
|
|
|