HH/templates/accounts/onboarding/step_checklist.html
2026-01-06 13:36:43 +03:00

274 lines
11 KiB
HTML

{% extends "layouts/base.html" %}
{% load i18n %}
{% block title %}{% trans "Acknowledgement Checklist" %}{% endblock %}
{% block content %}
<div class="container-fluid py-4">
<div class="row">
<!-- Progress Sidebar -->
<div class="col-lg-3 mb-4">
<div class="card">
<div class="card-body">
<h5 class="card-title mb-3">{% trans "Progress" %}</h5>
<div class="progress mb-3" style="height: 10px;">
<div class="progress-bar bg-success" role="progressbar"
style="width: {{ progress_percentage }}%"
aria-valuenow="{{ progress_percentage }}"
aria-valuemin="0" aria-valuemax="100">
{{ progress_percentage }}%
</div>
</div>
<div class="alert alert-info small">
<strong>{% trans "Completed" %}:</strong> {{ acknowledged_count }} / {{ total_count }}
</div>
</div>
</div>
</div>
<!-- Checklist -->
<div class="col-lg-9">
<div class="card shadow-sm">
<div class="card-header bg-primary text-white">
<h4 class="mb-0">
<i class="fas fa-clipboard-check me-2"></i>
{% trans "Acknowledgement Checklist" %}
</h4>
</div>
<div class="card-body p-5">
<div class="alert alert-warning mb-4">
<i class="fas fa-exclamation-triangle me-2"></i>
{% trans "Please review and acknowledge all required items below. Your digital signature will be recorded for compliance purposes." %}
</div>
<form id="checklistForm">
<div class="list-group mb-4">
{% for item in checklist_items %}
<div class="list-group-item {% if item.is_required %}list-group-item-action{% endif %}">
<div class="d-flex align-items-start">
<div class="form-check flex-grow-1">
<input class="form-check-input"
type="checkbox"
id="item_{{ item.id }}"
value="{{ item.id }}"
{% if item.is_acknowledged %}checked disabled{% endif %}
onchange="toggleItem(this, '{{ item.id }}')"
{% if not item.is_required %}data-required="false"{% endif %}>
<label class="form-check-label" for="item_{{ item.id }}">
<strong>
{% if request.user.language == 'ar' %}{{ item.text_ar }}{% else %}{{ item.text_en }}{% endif %}
</strong>
{% if item.is_required %}
<span class="badge bg-danger ms-2">{% trans "Required" %}</span>
{% endif %}
</label>
{% if item.description_en %}
<p class="text-muted small mt-2 mb-0">
{% if request.user.language == 'ar' %}{{ item.description_ar }}{% else %}{{ item.description_en }}{% endif %}
</p>
{% endif %}
{% if item.content %}
<p class="text-info small mb-0">
<i class="fas fa-link me-1"></i>
{% if request.user.language == 'ar' %}{{ item.content.title_ar }}{% else %}{{ item.content.title_en }}{% endif %}
</p>
{% endif %}
</div>
{% if item.is_acknowledged %}
<i class="fas fa-check-circle text-success fa-2x ms-3"></i>
{% endif %}
</div>
</div>
{% endfor %}
</div>
<div id="signatureSection" class="mb-4" style="display: none;">
<hr class="my-4">
<h5 class="mb-3">{% trans "Digital Signature" %}</h5>
<div class="alert alert-info">
{% trans "By providing your digital signature below, you acknowledge that you have read, understood, and agreed to all the items listed above." %}
</div>
<canvas id="signatureCanvas" class="border rounded"
style="width: 100%; height: 200px; cursor: crosshair;"></canvas>
<div class="mt-2">
<button type="button" onclick="clearSignature()" class="btn btn-sm btn-outline-secondary">
<i class="fas fa-eraser me-1"></i> {% trans "Clear" %}
</button>
</div>
</div>
<div class="d-grid gap-2">
<button type="button" id="proceedBtn"
onclick="proceedToActivation()"
class="btn btn-primary btn-lg"
disabled>
<i class="fas fa-arrow-right me-2"></i>
{% trans "Proceed to Account Setup" %}
</button>
<button type="button" onclick="goBack()" class="btn btn-outline-secondary">
<i class="fas fa-arrow-left me-2"></i>
{% trans "Back to Content" %}
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
<script>
let requiredItems = {{ required_items_json|safe }};
let acknowledgedItems = new Set();
let isSigning = false;
// Initialize
document.addEventListener('DOMContentLoaded', function() {
// Load acknowledged items
{% for item in checklist_items %}
{% if item.is_acknowledged %}
acknowledgedItems.add('{{ item.id }}');
{% endif %}
{% endfor %}
checkProgress();
initSignaturePad();
});
function toggleItem(checkbox, itemId) {
if (checkbox.checked) {
acknowledgedItems.add(itemId);
} else {
acknowledgedItems.delete(itemId);
}
// Save acknowledgement
fetch('/api/accounts/users/onboarding/acknowledge/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + localStorage.getItem('token')
},
body: JSON.stringify({
checklist_item_id: itemId
})
})
.then(response => response.json())
.then(data => {
if (!data.success) {
checkbox.checked = !checkbox.checked;
alert('Error: ' + (data.error || 'Failed to save acknowledgement'));
}
checkProgress();
});
}
function checkProgress() {
let allRequiredAck = true;
requiredItems.forEach(id => {
if (!acknowledgedItems.has(id)) {
allRequiredAck = false;
}
});
const proceedBtn = document.getElementById('proceedBtn');
const signatureSection = document.getElementById('signatureSection');
if (allRequiredAck) {
proceedBtn.disabled = false;
signatureSection.style.display = 'block';
} else {
proceedBtn.disabled = true;
signatureSection.style.display = 'none';
}
}
function initSignaturePad() {
const canvas = document.getElementById('signatureCanvas');
const ctx = canvas.getContext('2d');
let isDrawing = false;
// Set canvas size
canvas.width = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;
canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', stopDrawing);
canvas.addEventListener('mouseout', stopDrawing);
// Touch support
canvas.addEventListener('touchstart', handleTouch);
canvas.addEventListener('touchmove', handleTouch);
canvas.addEventListener('touchend', stopDrawing);
function startDrawing(e) {
isDrawing = true;
draw(e);
}
function draw(e) {
if (!isDrawing) return;
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
ctx.lineWidth = 2;
ctx.lineCap = 'round';
ctx.strokeStyle = '#000';
ctx.lineTo(x, y);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(x, y);
}
function stopDrawing() {
isDrawing = false;
ctx.beginPath();
}
function handleTouch(e) {
e.preventDefault();
const touch = e.touches[0];
const mouseEvent = new MouseEvent(e.type === 'touchstart' ? 'mousedown' : 'mousemove', {
clientX: touch.clientX,
clientY: touch.clientY
});
canvas.dispatchEvent(mouseEvent);
}
window.signatureCanvas = canvas;
window.signatureCtx = ctx;
}
function clearSignature() {
const canvas = window.signatureCanvas;
const ctx = window.signatureCtx;
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
function proceedToActivation() {
const canvas = window.signatureCanvas;
const signatureData = canvas.toDataURL('image/png');
// Store signature for final submission
localStorage.setItem('onboardingSignature', signatureData);
window.location.href = '/accounts/onboarding/wizard/activation/';
}
function goBack() {
window.location.href = '/accounts/onboarding/wizard/step/1/';
}
</script>
{% endblock %}