300 lines
13 KiB
HTML
300 lines
13 KiB
HTML
{% extends "base.html" %}
|
|
{% load i18n static crispy_forms_tags patient_tags %}
|
|
|
|
{% block title %}{% if form.instance.pk %}{% trans "Edit ABA Session" %}{% else %}{% trans "New ABA Session" %}{% endif %} - Tenhal{% endblock %}
|
|
|
|
{% block css %}
|
|
<link href="{% static 'plugins/select2/css/select2.min.css' %}" rel="stylesheet" />
|
|
<style>
|
|
.formset-row {
|
|
border-left: 3px solid #6f42c1;
|
|
transition: all 0.3s ease;
|
|
}
|
|
.formset-row:hover {
|
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container-fluid">
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
<div>
|
|
<h1 class="page-header mb-0">
|
|
<i class="fas fa-brain me-2"></i>
|
|
{% if form.instance.pk %}{% trans "Edit ABA Session" %}{% else %}{% trans "New ABA Session" %}{% endif %}
|
|
</h1>
|
|
<nav aria-label="breadcrumb">
|
|
<ol class="breadcrumb">
|
|
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">{% trans "Dashboard" %}</a></li>
|
|
<li class="breadcrumb-item"><a href="{% url 'aba:session_list' %}">{% trans "ABA Sessions" %}</a></li>
|
|
<li class="breadcrumb-item active">{% if form.instance.pk %}{% trans "Edit" %}{% else %}{% trans "New" %}{% endif %}</li>
|
|
</ol>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
|
|
<form method="post" id="abaSessionForm">
|
|
{% csrf_token %}
|
|
{{ skill_target_formset.management_form }}
|
|
|
|
<div class="row">
|
|
<div class="col-lg-9">
|
|
<!-- Basic Information -->
|
|
<div class="card mb-3">
|
|
<div class="card-header bg-primary text-white">
|
|
<h5 class="mb-0"><i class="fas fa-info-circle me-2"></i>{% trans "Session Information" %}</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
{% crispy form %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Session Metrics -->
|
|
<div class="card mb-3">
|
|
<div class="card-header bg-success text-white">
|
|
<h5 class="mb-0"><i class="fas fa-chart-bar me-2"></i>{% trans "Session Metrics (1-5 Scale)" %}</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<p class="text-muted small">{% trans "Rate from 1 (Very Low) to 5 (Excellent)" %}</p>
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
{{ form.engagement_level|as_crispy_field }}
|
|
</div>
|
|
<div class="col-md-6">
|
|
{{ form.cooperation_level|as_crispy_field }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Session Content -->
|
|
<div class="card mb-3">
|
|
<div class="card-header bg-info text-white">
|
|
<h5 class="mb-0"><i class="fas fa-tasks me-2"></i>{% trans "Session Content" %}</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
{{ form.target_behaviors|as_crispy_field }}
|
|
{{ form.interventions_used|as_crispy_field }}
|
|
{{ form.activities_performed|as_crispy_field }}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Observations & Progress -->
|
|
<div class="card mb-3">
|
|
<div class="card-header bg-warning text-dark">
|
|
<h5 class="mb-0"><i class="fas fa-eye me-2"></i>{% trans "Observations & Progress" %}</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
{{ form.behavioral_observations|as_crispy_field }}
|
|
{{ form.progress_notes|as_crispy_field }}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Recommendations -->
|
|
<div class="card mb-3">
|
|
<div class="card-header bg-secondary text-white">
|
|
<h5 class="mb-0"><i class="fas fa-lightbulb me-2"></i>{% trans "Recommendations" %}</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
{{ form.recommendations|as_crispy_field }}
|
|
{{ form.home_program|as_crispy_field }}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Skill Targets -->
|
|
<div class="card mb-3">
|
|
<div class="card-header" style="background-color: #6f42c1; color: white;">
|
|
<h5 class="mb-0">
|
|
<i class="fas fa-bullseye me-2"></i>{% trans "Skill Targets" %}
|
|
<span class="badge bg-light text-dark ms-2">{% trans "Minimum 1 required" %}</span>
|
|
</h5>
|
|
</div>
|
|
<div class="card-body">
|
|
<p class="text-muted">{% trans "Document skill targets with mastery levels and trial data" %}</p>
|
|
|
|
<div id="skill-target-formset">
|
|
{% for form in skill_target_formset %}
|
|
<div class="formset-row border rounded p-3 mb-3 bg-light">
|
|
<div class="d-flex justify-content-between align-items-center mb-3">
|
|
<h6 class="mb-0">
|
|
<i class="fas fa-target me-2"></i>
|
|
{% trans "Skill Target" %} #<span class="skill-number">{{ forloop.counter }}</span>
|
|
</h6>
|
|
{% if not forloop.first %}
|
|
<button type="button" class="btn btn-sm btn-outline-danger delete-skill">
|
|
<i class="fas fa-trash"></i>
|
|
</button>
|
|
{% endif %}
|
|
</div>
|
|
{{ form.id }}
|
|
{{ form.DELETE }}
|
|
{{ form.order }}
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
{{ form.skill_name|as_crispy_field }}
|
|
</div>
|
|
<div class="col-md-4">
|
|
{{ form.mastery_level|as_crispy_field }}
|
|
</div>
|
|
<div class="col-md-4">
|
|
{{ form.trials_correct|as_crispy_field }}
|
|
</div>
|
|
<div class="col-md-4">
|
|
{{ form.trials_total|as_crispy_field }}
|
|
</div>
|
|
<div class="col-md-12">
|
|
{{ form.notes|as_crispy_field }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
|
|
<button type="button" class="btn btn-sm btn-outline-primary" id="add-skill-target">
|
|
<i class="fas fa-plus me-1"></i>{% trans "Add Skill Target" %}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Submit Buttons -->
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<button type="submit" class="btn btn-primary btn-lg">
|
|
<i class="fas fa-save me-2"></i>{% trans "Save ABA Session" %}
|
|
</button>
|
|
<a href="{% url 'aba:session_list' %}" class="btn btn-outline-secondary btn-lg">
|
|
<i class="fas fa-times me-2"></i>{% trans "Cancel" %}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Sidebar -->
|
|
<div class="col-lg-3">
|
|
<div class="card mb-3">
|
|
<div class="card-header">
|
|
<h6 class="mb-0"><i class="fas fa-question-circle me-2"></i>{% trans "Help" %}</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
<p class="small">{% trans "Complete the ABA session documentation." %}</p>
|
|
<ul class="small">
|
|
<li>{% trans "Rate engagement & cooperation (1-5)" %}</li>
|
|
<li>{% trans "Document target behaviors" %}</li>
|
|
<li>{% trans "List interventions used" %}</li>
|
|
<li>{% trans "Track skill mastery levels" %}</li>
|
|
<li>{% trans "Record trial data" %}</li>
|
|
<li>{% trans "Provide home program" %}</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h6 class="mb-0"><i class="fas fa-info-circle me-2"></i>{% trans "Mastery Levels" %}</h6>
|
|
</div>
|
|
<div class="card-body">
|
|
<ul class="small">
|
|
<li><strong>{% trans "Not Started" %}</strong></li>
|
|
<li><strong>{% trans "Emerging" %}</strong>: 0-25%</li>
|
|
<li><strong>{% trans "Developing" %}</strong>: 26-50%</li>
|
|
<li><strong>{% trans "Progressing" %}</strong>: 51-75%</li>
|
|
<li><strong>{% trans "Mastered" %}</strong>: 76-100%</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block js %}
|
|
<script src="{% static 'plugins/select2/dist/js/select2.min.js' %}"></script>
|
|
<script>
|
|
$(document).ready(function() {
|
|
// Initialize Select2
|
|
$('.select2').select2({
|
|
|
|
width: '100%'
|
|
});
|
|
|
|
// Formset management
|
|
let formsetIndex = parseInt($('#id_skill_targets-TOTAL_FORMS').val());
|
|
|
|
// Add new skill target
|
|
$('#add-skill-target').click(function() {
|
|
const formsetContainer = $('#skill-target-formset');
|
|
const emptyForm = formsetContainer.find('.formset-row:first').clone();
|
|
|
|
// Update form index
|
|
emptyForm.html(emptyForm.html().replace(/-0-/g, '-' + formsetIndex + '-'));
|
|
emptyForm.html(emptyForm.html().replace(/-__prefix__-/g, '-' + formsetIndex + '-'));
|
|
|
|
// Clear values
|
|
emptyForm.find('input[type="text"], textarea').val('');
|
|
emptyForm.find('input[type="number"]').val('');
|
|
emptyForm.find('select').prop('selectedIndex', 0);
|
|
emptyForm.find('input[type="checkbox"]').prop('checked', false);
|
|
|
|
// Update skill number
|
|
emptyForm.find('.skill-number').text(formsetIndex + 1);
|
|
|
|
// Add delete button if not present
|
|
if (emptyForm.find('.delete-skill').length === 0) {
|
|
emptyForm.find('h6').parent().append(
|
|
'<button type="button" class="btn btn-sm btn-outline-danger delete-skill"><i class="fas fa-trash"></i></button>'
|
|
);
|
|
}
|
|
|
|
// Append to container
|
|
formsetContainer.append(emptyForm);
|
|
|
|
// Update total forms count
|
|
formsetIndex++;
|
|
$('#id_skill_targets-TOTAL_FORMS').val(formsetIndex);
|
|
|
|
// Renumber all skills
|
|
renumberSkills();
|
|
});
|
|
|
|
// Delete skill target
|
|
$(document).on('click', '.delete-skill', function() {
|
|
const row = $(this).closest('.formset-row');
|
|
const deleteInput = row.find('input[id$="-DELETE"]');
|
|
|
|
if (deleteInput.length > 0) {
|
|
// Mark for deletion if it's an existing record
|
|
deleteInput.prop('checked', true);
|
|
row.hide();
|
|
} else {
|
|
// Remove if it's a new record
|
|
row.remove();
|
|
}
|
|
|
|
renumberSkills();
|
|
});
|
|
|
|
// Renumber visible skills
|
|
function renumberSkills() {
|
|
let counter = 1;
|
|
$('#skill-target-formset .formset-row:visible').each(function() {
|
|
$(this).find('.skill-number').text(counter);
|
|
counter++;
|
|
});
|
|
}
|
|
|
|
// Form validation
|
|
$('#abaSessionForm').on('submit', function(e) {
|
|
// Check if at least one skill target is present
|
|
const visibleSkills = $('#skill-target-formset .formset-row:visible').length;
|
|
if (visibleSkills === 0) {
|
|
e.preventDefault();
|
|
showAlertModal('{% trans "Please add at least one skill target" %}', 'warning');
|
|
return false;
|
|
}
|
|
});
|
|
});
|
|
</script>
|
|
{% endblock %}
|