Files
LT_Janitorial_Quality_Control/app/templates/inspections/execute.html
T
2026-02-21 12:29:26 -05:00

163 lines
7.1 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% extends "base.html" %}
{% block title %}Execute Inspection{% endblock %}
{% block extra_css %}
<style>
.item-card { border-left: 4px solid #dee2e6; transition: border-color .2s; }
.item-card.answered { border-left-color: #198754; }
.item-card.flagged { border-left-color: #dc3545; }
.pass-fail-group .btn-check:checked + .btn-outline-success { background:#198754; color:#fff; }
.pass-fail-group .btn-check:checked + .btn-outline-danger { background:#dc3545; color:#fff; }
.progress-bar-label { font-size:.75rem; font-weight:600; }
.sticky-toolbar { position:sticky; top:56px; z-index:20; background:#fff; border-bottom:1px solid #dee2e6; padding:.6rem 1rem; }
</style>
{% endblock %}
{% block content %}
<form method="post" enctype="multipart/form-data" id="inspectionForm">
{{ csrf_token() | safe }}
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
{# Sticky toolbar #}
<div class="sticky-toolbar d-flex align-items-center gap-3 mb-4">
<div class="flex-grow-1">
<h5 class="mb-0">{{ inspection.template.name }}</h5>
<small class="text-muted">{{ inspection.facility.name }}{% if inspection.area %} · {{ inspection.area.name }}{% endif %}</small>
</div>
<div class="text-center" style="min-width:120px;">
<div class="progress" style="height:8px;">
<div class="progress-bar bg-success" style="width:{{ (answered / results|length * 100)|int if results else 0 }}%"></div>
</div>
<span class="progress-bar-label text-muted">{{ answered }}/{{ results|length }} answered</span>
</div>
<a href="{{ url_for('inspections.flag_issue', inspection_id=inspection.id) }}"
class="btn btn-sm btn-outline-danger">
<i class="bi bi-exclamation-triangle"></i> Flag Issue
</a>
<button type="submit" name="action" value="save" class="btn btn-sm btn-outline-secondary">
<i class="bi bi-floppy"></i> Save
</button>
<button type="submit" name="action" value="complete" class="btn btn-success"
onclick="return confirm('Mark this inspection as complete?')">
<i class="bi bi-check-circle"></i> Complete
</button>
</div>
{% if inspection.notes %}
<div class="alert alert-info py-2"><i class="bi bi-sticky"></i> <strong>Notes:</strong> {{ inspection.notes }}</div>
{% endif %}
{% set ns = namespace(current_cat='') %}
{% for result in results %}
{% set item = result.checklist_item %}
{% if item.category != ns.current_cat %}
{% set ns.current_cat = item.category %}
<h5 class="text-primary border-bottom pb-1 mt-4 mb-3">
<i class="bi bi-folder2"></i> {{ item.category or 'General' }}
</h5>
{% endif %}
{% set is_answered = result.passed is not none or result.score is not none %}
<div class="card shadow-sm mb-3 item-card {{ 'answered' if is_answered }}">
<div class="card-body">
<div class="d-flex justify-content-between align-items-start mb-2">
<div>
<span class="fw-semibold">{{ item.item_description }}</span>
{% if item.requires_photo %}
<span class="badge bg-warning text-dark ms-1"><i class="bi bi-camera"></i> Photo required</span>
{% endif %}
</div>
<span class="badge bg-secondary text-uppercase" style="font-size:.65rem;">{{ item.scoring_type|replace('_',' ') }}</span>
</div>
{# ── Pass/Fail ── #}
{% if item.scoring_type == 'pass_fail' %}
<div class="pass-fail-group d-flex gap-2 mb-2">
<input class="btn-check" type="radio" name="item_{{ result.id }}_passed"
id="pass_{{ result.id }}" value="pass" {{ 'checked' if result.passed == true }}>
<label class="btn btn-outline-success btn-sm" for="pass_{{ result.id }}">
<i class="bi bi-check-lg"></i> Pass
</label>
<input class="btn-check" type="radio" name="item_{{ result.id }}_passed"
id="fail_{{ result.id }}" value="fail" {{ 'checked' if result.passed == false }}>
<label class="btn btn-outline-danger btn-sm" for="fail_{{ result.id }}">
<i class="bi bi-x-lg"></i> Fail
</label>
</div>
{# ── Rating 5 ── #}
{% elif item.scoring_type == 'rating_5' %}
<div class="mb-2">
<label class="form-label small">Rating (15)</label>
<div class="d-flex gap-2">
{% for v in [1,2,3,4,5] %}
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="item_{{ result.id }}_score"
id="r5_{{ result.id }}_{{ v }}" value="{{ v }}"
{{ 'checked' if result.score == v }}>
<label class="form-check-label" for="r5_{{ result.id }}_{{ v }}">{{ v }}</label>
</div>
{% endfor %}
</div>
</div>
{# ── Rating 10 ── #}
{% elif item.scoring_type == 'rating_10' %}
<div class="mb-2">
<label class="form-label small">Rating (110)</label>
<div class="d-flex flex-wrap gap-2">
{% for v in range(1,11) %}
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" name="item_{{ result.id }}_score"
id="r10_{{ result.id }}_{{ v }}" value="{{ v }}"
{{ 'checked' if result.score == v }}>
<label class="form-check-label" for="r10_{{ result.id }}_{{ v }}">{{ v }}</label>
</div>
{% endfor %}
</div>
</div>
{% endif %}
<div class="row g-2">
<div class="col-md-6">
<textarea class="form-control form-control-sm" name="item_{{ result.id }}_comments"
rows="2" placeholder="Comments (optional)">{{ result.comments or '' }}</textarea>
</div>
<div class="col-md-6">
{% if result.photo_path %}
<div class="mb-1">
<img src="{{ url_for('static', filename=result.photo_path) }}"
class="img-thumbnail" style="max-height:80px;" alt="Photo">
</div>
{% endif %}
<input type="file" class="form-control form-control-sm"
name="item_{{ result.id }}_photo" accept="image/*">
</div>
</div>
</div>
</div>
{% endfor %}
{# Bottom submit bar #}
<div class="d-flex justify-content-end gap-2 mt-4 pb-4">
<button type="submit" name="action" value="save" class="btn btn-outline-secondary">
<i class="bi bi-floppy"></i> Save Progress
</button>
<button type="submit" name="action" value="complete" class="btn btn-success btn-lg"
onclick="return confirm('Mark this inspection as complete? This cannot be undone.')">
<i class="bi bi-check-circle-fill"></i> Complete Inspection
</button>
</div>
</form>
{% endblock %}
{% block extra_js %}
<script>
// Auto-mark item cards as answered on interaction
document.querySelectorAll('input[type=radio]').forEach(r => {
r.addEventListener('change', () => {
const card = r.closest('.item-card');
if (card) card.classList.add('answered');
});
});
</script>
{% endblock %}