450 lines
18 KiB
HTML
450 lines
18 KiB
HTML
{% extends 'base.html' %}
|
|
{% load static %}
|
|
|
|
{% block title %}Donor Eligibility Check - {{ donor.full_name }}{% endblock %}
|
|
|
|
{% block css %}
|
|
<style>
|
|
.eligibility-card {
|
|
border: 2px solid #e9ecef;
|
|
border-radius: 10px;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.eligibility-card.eligible {
|
|
border-color: #28a745;
|
|
background-color: #f8fff9;
|
|
}
|
|
|
|
.eligibility-card.not-eligible {
|
|
border-color: #dc3545;
|
|
background-color: #fff8f8;
|
|
}
|
|
|
|
.question-card {
|
|
border: 1px solid #e9ecef;
|
|
border-radius: 8px;
|
|
margin-bottom: 1rem;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.question-card:hover {
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
}
|
|
|
|
.question-card.answered-yes {
|
|
border-color: #28a745;
|
|
background-color: #f8fff9;
|
|
}
|
|
|
|
.question-card.answered-no {
|
|
border-color: #dc3545;
|
|
background-color: #fff8f8;
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<!-- BEGIN breadcrumb -->
|
|
<ol class="breadcrumb float-xl-end">
|
|
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Home</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'blood_bank:dashboard' %}">Blood Bank</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'blood_bank:donor_list' %}">Donors</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'blood_bank:donor_detail' donor.id %}">{{ donor.donor_id }}</a></li>
|
|
<li class="breadcrumb-item active">Eligibility Check</li>
|
|
</ol>
|
|
<!-- END breadcrumb -->
|
|
|
|
<!-- BEGIN page-header -->
|
|
<h1 class="page-header">
|
|
Donor Eligibility Check
|
|
<small>{{ donor.full_name }} ({{ donor.donor_id }})</small>
|
|
</h1>
|
|
<!-- END page-header -->
|
|
|
|
<!-- BEGIN row -->
|
|
<div class="row">
|
|
<!-- BEGIN col-4 -->
|
|
<div class="col-xl-4">
|
|
<!-- BEGIN donor info panel -->
|
|
<div class="panel panel-inverse">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">Donor Information</h4>
|
|
</div>
|
|
<div class="panel-body">
|
|
<div class="text-center mb-3">
|
|
<i class="fa fa-user fa-3x text-muted mb-2"></i>
|
|
<h5>{{ donor.full_name }}</h5>
|
|
<p class="text-muted">{{ donor.donor_id }}</p>
|
|
</div>
|
|
|
|
<table class="table table-borderless">
|
|
<tr>
|
|
<td class="fw-bold">Blood Group:</td>
|
|
<td>
|
|
<span class="badge bg-primary">{{ donor.blood_group.display_name }}</span>
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Age:</td>
|
|
<td>{{ donor.age }} years</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Weight:</td>
|
|
<td>{{ donor.weight }} kg</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Total Donations:</td>
|
|
<td>{{ donor.total_donations }}</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="fw-bold">Last Donation:</td>
|
|
<td>
|
|
{% if donor.last_donation_date %}
|
|
{{ donor.last_donation_date|date:"M d, Y" }}
|
|
{% else %}
|
|
<span class="text-muted">Never</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
<!-- END donor info panel -->
|
|
|
|
<!-- BEGIN eligibility status -->
|
|
<div class="eligibility-card p-4 {% if is_eligible %}eligible{% else %}not-eligible{% endif %}">
|
|
<div class="text-center">
|
|
<i class="fa {% if is_eligible %}fa-check-circle text-success{% else %}fa-times-circle text-danger{% endif %} fa-3x mb-3"></i>
|
|
<h4>
|
|
{% if is_eligible %}
|
|
Eligible for Donation
|
|
{% else %}
|
|
Not Eligible for Donation
|
|
{% endif %}
|
|
</h4>
|
|
<p class="mb-0">
|
|
{% if is_eligible %}
|
|
This donor meets the basic eligibility criteria.
|
|
{% else %}
|
|
Next eligible date: {{ next_eligible_date|date:"M d, Y" }}
|
|
{% endif %}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<!-- END eligibility status -->
|
|
</div>
|
|
<!-- END col-4 -->
|
|
|
|
<!-- BEGIN col-8 -->
|
|
<div class="col-xl-8">
|
|
<!-- BEGIN eligibility screening panel -->
|
|
<div class="panel panel-inverse">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">Eligibility Screening Questionnaire</h4>
|
|
<div class="panel-heading-btn">
|
|
<span class="badge bg-info">Required before donation</span>
|
|
</div>
|
|
</div>
|
|
<div class="panel-body">
|
|
<form method="post" id="eligibilityForm">
|
|
{% csrf_token %}
|
|
|
|
<!-- BEGIN basic health questions -->
|
|
<div class="mb-4">
|
|
<h5 class="text-primary mb-3">
|
|
<i class="fa fa-heartbeat"></i> Basic Health Questions
|
|
</h5>
|
|
|
|
<div class="question-card p-3" data-question="feeling_well">
|
|
<div class="form-check">
|
|
{{ form.feeling_well }}
|
|
<label class="form-check-label fw-bold" for="{{ form.feeling_well.id_for_label }}">
|
|
{{ form.feeling_well.label }}
|
|
</label>
|
|
</div>
|
|
{% if form.feeling_well.errors %}
|
|
<div class="text-danger small mt-1">{{ form.feeling_well.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="question-card p-3" data-question="adequate_sleep">
|
|
<div class="form-check">
|
|
{{ form.adequate_sleep }}
|
|
<label class="form-check-label fw-bold" for="{{ form.adequate_sleep.id_for_label }}">
|
|
{{ form.adequate_sleep.label }}
|
|
</label>
|
|
</div>
|
|
{% if form.adequate_sleep.errors %}
|
|
<div class="text-danger small mt-1">{{ form.adequate_sleep.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<div class="question-card p-3" data-question="eaten_today">
|
|
<div class="form-check">
|
|
{{ form.eaten_today }}
|
|
<label class="form-check-label fw-bold" for="{{ form.eaten_today.id_for_label }}">
|
|
{{ form.eaten_today.label }}
|
|
</label>
|
|
</div>
|
|
{% if form.eaten_today.errors %}
|
|
<div class="text-danger small mt-1">{{ form.eaten_today.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<!-- END basic health questions -->
|
|
|
|
<!-- BEGIN medical history -->
|
|
<div class="mb-4">
|
|
<h5 class="text-primary mb-3">
|
|
<i class="fa fa-stethoscope"></i> Medical History
|
|
</h5>
|
|
|
|
<div class="question-card p-3" data-question="recent_illness">
|
|
<div class="form-check">
|
|
{{ form.recent_illness }}
|
|
<label class="form-check-label fw-bold" for="{{ form.recent_illness.id_for_label }}">
|
|
{{ form.recent_illness.label }}
|
|
</label>
|
|
</div>
|
|
<small class="text-muted">Including cold, flu, fever, or any infection</small>
|
|
</div>
|
|
|
|
<div class="question-card p-3" data-question="medications">
|
|
<div class="form-check">
|
|
{{ form.medications }}
|
|
<label class="form-check-label fw-bold" for="{{ form.medications.id_for_label }}">
|
|
{{ form.medications.label }}
|
|
</label>
|
|
</div>
|
|
<small class="text-muted">Including prescription and over-the-counter medications</small>
|
|
</div>
|
|
|
|
<div class="question-card p-3" data-question="recent_travel">
|
|
<div class="form-check">
|
|
{{ form.recent_travel }}
|
|
<label class="form-check-label fw-bold" for="{{ form.recent_travel.id_for_label }}">
|
|
{{ form.recent_travel.label }}
|
|
</label>
|
|
</div>
|
|
<small class="text-muted">Travel to malaria-endemic areas may require deferral</small>
|
|
</div>
|
|
</div>
|
|
<!-- END medical history -->
|
|
|
|
<!-- BEGIN risk factors -->
|
|
<div class="mb-4">
|
|
<h5 class="text-primary mb-3">
|
|
<i class="fa fa-exclamation-triangle"></i> Risk Factors
|
|
</h5>
|
|
|
|
<div class="question-card p-3" data-question="recent_tattoo">
|
|
<div class="form-check">
|
|
{{ form.recent_tattoo }}
|
|
<label class="form-check-label fw-bold" for="{{ form.recent_tattoo.id_for_label }}">
|
|
{{ form.recent_tattoo.label }}
|
|
</label>
|
|
</div>
|
|
<small class="text-muted">Including permanent makeup and body piercing</small>
|
|
</div>
|
|
|
|
<div class="question-card p-3" data-question="recent_surgery">
|
|
<div class="form-check">
|
|
{{ form.recent_surgery }}
|
|
<label class="form-check-label fw-bold" for="{{ form.recent_surgery.id_for_label }}">
|
|
{{ form.recent_surgery.label }}
|
|
</label>
|
|
</div>
|
|
<small class="text-muted">Any surgical procedure or dental work</small>
|
|
</div>
|
|
</div>
|
|
<!-- END risk factors -->
|
|
|
|
<!-- BEGIN additional notes -->
|
|
<div class="mb-4">
|
|
<h5 class="text-primary mb-3">
|
|
<i class="fa fa-notes-medical"></i> Additional Information
|
|
</h5>
|
|
|
|
<div class="form-group">
|
|
<label class="form-label" for="{{ form.notes.id_for_label }}">
|
|
{{ form.notes.label }}
|
|
</label>
|
|
{{ form.notes }}
|
|
{% if form.notes.errors %}
|
|
<div class="text-danger small">{{ form.notes.errors.0 }}</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
<!-- END additional notes -->
|
|
|
|
<!-- BEGIN form actions -->
|
|
<div class="d-flex justify-content-between">
|
|
<a href="{% url 'blood_bank:donor_detail' donor.id %}" class="btn btn-default">
|
|
<i class="fa fa-arrow-left"></i> Back to Donor
|
|
</a>
|
|
<div>
|
|
<button type="button" class="btn btn-info" onclick="reviewAnswers()">
|
|
<i class="fa fa-eye"></i> Review Answers
|
|
</button>
|
|
<button type="submit" class="btn btn-success" id="proceedBtn" disabled>
|
|
<i class="fa fa-arrow-right"></i> Proceed to Donation
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<!-- END form actions -->
|
|
</form>
|
|
</div>
|
|
</div>
|
|
<!-- END eligibility screening panel -->
|
|
</div>
|
|
<!-- END col-8 -->
|
|
</div>
|
|
<!-- END row -->
|
|
{% endblock %}
|
|
|
|
{% block js %}
|
|
<script>
|
|
$(document).ready(function() {
|
|
// Check form validity on load and when inputs change
|
|
checkFormValidity();
|
|
|
|
$('input[type="checkbox"]').on('change', function() {
|
|
updateQuestionCard(this);
|
|
checkFormValidity();
|
|
});
|
|
|
|
// Initialize question cards based on current values
|
|
$('input[type="checkbox"]').each(function() {
|
|
updateQuestionCard(this);
|
|
});
|
|
});
|
|
|
|
function updateQuestionCard(checkbox) {
|
|
var $card = $(checkbox).closest('.question-card');
|
|
var questionName = $card.data('question');
|
|
|
|
$card.removeClass('answered-yes answered-no');
|
|
|
|
if ($(checkbox).is(':checked')) {
|
|
if (['feeling_well', 'adequate_sleep', 'eaten_today'].includes(questionName)) {
|
|
$card.addClass('answered-yes');
|
|
} else {
|
|
$card.addClass('answered-no');
|
|
}
|
|
} else {
|
|
if (['feeling_well', 'adequate_sleep', 'eaten_today'].includes(questionName)) {
|
|
$card.addClass('answered-no');
|
|
} else {
|
|
$card.addClass('answered-yes');
|
|
}
|
|
}
|
|
}
|
|
|
|
function checkFormValidity() {
|
|
var isValid = true;
|
|
var requiredQuestions = ['feeling_well', 'adequate_sleep', 'eaten_today'];
|
|
|
|
// Check required questions
|
|
requiredQuestions.forEach(function(question) {
|
|
var checkbox = $('input[data-question="' + question + '"]');
|
|
if (!checkbox.is(':checked')) {
|
|
isValid = false;
|
|
}
|
|
});
|
|
|
|
// Check if any disqualifying answers
|
|
var disqualifyingQuestions = ['recent_illness', 'recent_tattoo', 'recent_surgery'];
|
|
disqualifyingQuestions.forEach(function(question) {
|
|
var checkbox = $('input[name="' + question + '"]');
|
|
if (checkbox.is(':checked')) {
|
|
isValid = false;
|
|
}
|
|
});
|
|
|
|
// Enable/disable proceed button
|
|
$('#proceedBtn').prop('disabled', !isValid);
|
|
|
|
if (isValid) {
|
|
$('#proceedBtn').removeClass('btn-secondary').addClass('btn-success');
|
|
} else {
|
|
$('#proceedBtn').removeClass('btn-success').addClass('btn-secondary');
|
|
}
|
|
}
|
|
|
|
function reviewAnswers() {
|
|
var answers = [];
|
|
|
|
$('input[type="checkbox"]').each(function() {
|
|
var label = $(this).next('label').text();
|
|
var answer = $(this).is(':checked') ? 'Yes' : 'No';
|
|
answers.push('<tr><td>' + label + '</td><td><strong>' + answer + '</strong></td></tr>');
|
|
});
|
|
|
|
var notesValue = $('textarea[name="notes"]').val();
|
|
if (notesValue) {
|
|
answers.push('<tr><td>Additional Notes</td><td>' + notesValue + '</td></tr>');
|
|
}
|
|
|
|
Swal.fire({
|
|
title: 'Review Screening Answers',
|
|
html: '<table class="table table-sm">' + answers.join('') + '</table>',
|
|
width: '600px',
|
|
confirmButtonText: 'Looks Good',
|
|
showCancelButton: true,
|
|
cancelButtonText: 'Make Changes'
|
|
});
|
|
}
|
|
|
|
// Form submission handling
|
|
$('#eligibilityForm').on('submit', function(e) {
|
|
var requiredAnswered = $('#{{ form.feeling_well.id_for_label }}').is(':checked') &&
|
|
$('#{{ form.adequate_sleep.id_for_label }}').is(':checked') &&
|
|
$('#{{ form.eaten_today.id_for_label }}').is(':checked');
|
|
|
|
var hasDisqualifyingFactors = $('#{{ form.recent_illness.id_for_label }}').is(':checked') ||
|
|
$('#{{ form.recent_tattoo.id_for_label }}').is(':checked') ||
|
|
$('#{{ form.recent_surgery.id_for_label }}').is(':checked');
|
|
|
|
if (!requiredAnswered) {
|
|
e.preventDefault();
|
|
Swal.fire({
|
|
icon: 'error',
|
|
title: 'Incomplete Screening',
|
|
text: 'Please answer all required health questions.',
|
|
confirmButtonText: 'OK'
|
|
});
|
|
return;
|
|
}
|
|
|
|
if (hasDisqualifyingFactors) {
|
|
e.preventDefault();
|
|
Swal.fire({
|
|
icon: 'warning',
|
|
title: 'Temporary Deferral',
|
|
text: 'Based on the answers provided, this donor should be temporarily deferred.',
|
|
confirmButtonText: 'Understood'
|
|
});
|
|
return;
|
|
}
|
|
|
|
// Show confirmation before proceeding
|
|
e.preventDefault();
|
|
Swal.fire({
|
|
title: 'Proceed to Donation?',
|
|
text: 'The donor has passed the eligibility screening. Proceed to blood collection?',
|
|
icon: 'question',
|
|
showCancelButton: true,
|
|
confirmButtonText: 'Yes, Proceed',
|
|
cancelButtonText: 'Cancel'
|
|
}).then((result) => {
|
|
if (result.isConfirmed) {
|
|
// Submit the form
|
|
$('#eligibilityForm')[0].submit();
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
{% endblock %}
|
|
|