Phase 2: initiate

This commit is contained in:
2026-02-06 16:38:19 -05:00
parent 7a4159b013
commit 66b3bb7642
21 changed files with 1502 additions and 62 deletions
+132
View File
@@ -0,0 +1,132 @@
{% extends "base.html" %}
{% block title %}Edit Template - {{ template.name }}{% endblock %}
{% block extra_css %}
<style>
.checklist-item { cursor: move; }
.checklist-item:hover { background-color: #f8f9fa; }
</style>
{% endblock %}
{% block content %}
<div class="row mb-4">
<div class="col-md-8">
<h2><i class="bi bi-file-earmark-text"></i> {{ template.name }}</h2>
</div>
<div class="col-md-4 text-end">
<a href="{{ url_for('templates.create_checklist_item', template_id=template.id) }}" class="btn btn-primary">
<i class="bi bi-plus-circle"></i> Add Item
</a>
</div>
</div>
<div class="row">
<div class="col-md-4">
<div class="card shadow-sm mb-4">
<div class="card-header bg-light">
<h5 class="mb-0">Template Settings</h5>
</div>
<div class="card-body">
<form method="POST">
{{ form.hidden_tag() }}
<div class="mb-3">
{{ form.name.label(class="form-label") }}
{{ form.name(class="form-control") }}
</div>
<div class="mb-3">
{{ form.description.label(class="form-label") }}
{{ form.description(class="form-control", rows=3) }}
</div>
<div class="mb-3">
{{ form.frequency.label(class="form-label") }}
{{ form.frequency(class="form-select") }}
</div>
<button type="submit" class="btn btn-primary w-100">
<i class="bi bi-save"></i> Update Template
</button>
</form>
</div>
</div>
</div>
<div class="col-md-8">
<div class="card shadow-sm">
<div class="card-header bg-light">
<h5 class="mb-0"><i class="bi bi-check2-square"></i> Checklist Items ({{ checklist_items|length }})</h5>
</div>
<div class="card-body">
{% if checklist_items %}
<div id="checklist-items" class="list-group">
{% for item in checklist_items %}
<div class="list-group-item checklist-item" data-item-id="{{ item.id }}">
<div class="d-flex justify-content-between align-items-start">
<div class="flex-grow-1">
<div class="d-flex align-items-center mb-1">
<i class="bi bi-grip-vertical text-muted me-2"></i>
<span class="badge bg-secondary me-2">{{ item.category }}</span>
<span class="badge bg-info">{{ item.scoring_type.replace('_', ' ')|title }}</span>
{% if item.requires_photo %}
<span class="badge bg-warning ms-2"><i class="bi bi-camera"></i></span>
{% endif %}
</div>
<p class="mb-1">{{ item.item_description }}</p>
<small class="text-muted">Weight: {{ item.weight }}</small>
</div>
<div class="ms-3">
<a href="{{ url_for('templates.edit_checklist_item', item_id=item.id) }}" class="btn btn-sm btn-outline-primary">
<i class="bi bi-pencil"></i>
</a>
<form method="POST" action="{{ url_for('templates.delete_checklist_item', item_id=item.id) }}" class="d-inline" onsubmit="return confirm('Delete this item?');">
<button type="submit" class="btn btn-sm btn-outline-danger">
<i class="bi bi-trash"></i>
</button>
</form>
</div>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="alert alert-info mb-0">
<i class="bi bi-info-circle"></i> No checklist items yet. Click "Add Item" to get started.
</div>
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.15.0/Sortable.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
const el = document.getElementById('checklist-items');
if (el) {
new Sortable(el, {
animation: 150,
handle: '.bi-grip-vertical',
onEnd: function(evt) {
const itemOrder = [];
el.querySelectorAll('.checklist-item').forEach(item => {
itemOrder.push(item.getAttribute('data-item-id'));
});
fetch('{{ url_for("templates.reorder_items", template_id=template.id) }}', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ item_order: itemOrder })
});
}
});
}
});
</script>
{% endblock %}
+44
View File
@@ -0,0 +1,44 @@
{% extends "base.html" %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
<div class="row">
<div class="col-md-6 offset-md-3">
<div class="card shadow-sm">
<div class="card-header bg-primary text-white">
<h4 class="mb-0">{{ title }}</h4>
</div>
<div class="card-body">
<form method="POST">
{{ form.hidden_tag() }}
<div class="mb-3">
{{ form.name.label(class="form-label") }}
{{ form.name(class="form-control") }}
</div>
<div class="mb-3">
{{ form.description.label(class="form-label") }}
{{ form.description(class="form-control", rows=3) }}
</div>
<div class="mb-4">
{{ form.frequency.label(class="form-label") }}
{{ form.frequency(class="form-select") }}
</div>
<div class="d-flex gap-2">
<button type="submit" class="btn btn-primary">
<i class="bi bi-save"></i> Save Template
</button>
<a href="{{ url_for('templates.index') }}" class="btn btn-secondary">
<i class="bi bi-x-circle"></i> Cancel
</a>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
+61
View File
@@ -0,0 +1,61 @@
{% extends "base.html" %}
{% block title %}{{ title }}{% endblock %}
{% block content %}
<div class="row">
<div class="col-md-8 offset-md-2">
<div class="card shadow-sm">
<div class="card-header bg-primary text-white">
<h4 class="mb-0">{{ title }}</h4>
<small>Template: {{ template.name }}</small>
</div>
<div class="card-body">
<form method="POST">
{{ form.hidden_tag() }}
<div class="row">
<div class="col-md-6 mb-3">
{{ form.category.label(class="form-label") }}
{{ form.category(class="form-control", placeholder="e.g., Restrooms, Floors, etc.") }}
</div>
<div class="col-md-6 mb-3">
{{ form.scoring_type.label(class="form-label") }}
{{ form.scoring_type(class="form-select") }}
</div>
</div>
<div class="mb-3">
{{ form.item_description.label(class="form-label") }}
{{ form.item_description(class="form-control", rows=3) }}
</div>
<div class="row">
<div class="col-md-6 mb-3">
{{ form.weight.label(class="form-label") }}
{{ form.weight(class="form-control") }}
<small class="text-muted">1.0 = standard weight</small>
</div>
<div class="col-md-6 mb-3">
<label class="form-label">&nbsp;</label>
<div class="form-check">
{{ form.requires_photo(class="form-check-input") }}
{{ form.requires_photo.label(class="form-check-label") }}
</div>
</div>
</div>
<div class="d-flex gap-2">
<button type="submit" class="btn btn-primary">
<i class="bi bi-save"></i> Save Item
</button>
<a href="{{ url_for('templates.edit_template', template_id=template.id) }}" class="btn btn-secondary">
<i class="bi bi-x-circle"></i> Cancel
</a>
</div>
</form>
</div>
</div>
</div>
</div>
{% endblock %}
+54
View File
@@ -0,0 +1,54 @@
{% extends "base.html" %}
{% block title %}Inspection Templates{% endblock %}
{% block content %}
<div class="row mb-4">
<div class="col-md-6">
<h2><i class="bi bi-file-earmark-text"></i> Inspection Templates</h2>
</div>
<div class="col-md-6 text-end">
{% if current_user.role in ['admin', 'supervisor'] %}
<a href="{{ url_for('templates.create_template') }}" class="btn btn-primary">
<i class="bi bi-plus-circle"></i> Create Template
</a>
{% endif %}
</div>
</div>
<div class="row">
{% for template in templates %}
<div class="col-md-6 col-lg-4 mb-4">
<div class="card shadow-sm h-100">
<div class="card-body">
<h5 class="card-title">
<a href="{{ url_for('templates.view_template', template_id=template.id) }}" class="text-decoration-none">
{{ template.name }}
</a>
</h5>
<p class="card-text text-muted small">{{ template.description or 'No description' }}</p>
<div class="mt-3">
<span class="badge bg-info">{{ template.frequency|title }}</span>
<small class="text-muted ms-2">
<i class="bi bi-check2-square"></i> {{ template.checklist_items.count() }} items
</small>
</div>
</div>
<div class="card-footer bg-transparent">
<a href="{{ url_for('templates.view_template', template_id=template.id) }}" class="btn btn-sm btn-outline-primary">
<i class="bi bi-eye"></i> View Template
</a>
</div>
</div>
</div>
{% else %}
<div class="col-12">
<div class="alert alert-info">
<i class="bi bi-info-circle"></i> No templates created yet.
</div>
</div>
{% endfor %}
</div>
{% endblock %}