HH/templates/observations/public_new.html
2026-04-08 17:13:35 +03:00

256 lines
12 KiB
HTML

{% extends "layouts/public_base.html" %}
{% load i18n %}
{% load static %}
{% block title %}{% trans "Report an Observation" %}{% endblock %}
{% block extra_css %}
<style>
.severity-option {
cursor: pointer;
padding: 12px 16px;
border: 2px solid #e2e8f0;
border-radius: 12px;
text-align: center;
transition: all 0.2s ease;
}
.severity-option:hover {
border-color: #005696;
background: #f8fafc;
}
.severity-option.selected {
border-color: #005696;
background: #eef6fb;
box-shadow: 0 0 0 3px rgba(0, 86, 150, 0.1);
}
.severity-option.selected i {
transform: scale(1.2);
}
.file-upload-area {
border: 2px dashed #e2e8f0;
border-radius: 12px;
padding: 30px;
text-align: center;
cursor: pointer;
transition: all 0.2s ease;
}
.file-upload-area:hover {
border-color: #005696;
background: #f8fafc;
}
</style>
{% endblock %}
{% block content %}
<div class="min-h-screen bg-gradient-to-br from-light via-blue-50 to-light py-8 px-4 sm:px-6 lg:px-8">
<div class="max-w-2xl mx-auto">
<!-- Main Card -->
<div class="glass-card rounded-3xl shadow-2xl p-8 md:p-10 animate-fade-in">
<!-- Header -->
<div class="text-center mb-6">
<div class="w-16 h-16 bg-gradient-to-br from-navy to-blue rounded-2xl flex items-center justify-center mx-auto mb-4 shadow-lg">
<i data-lucide="eye" class="w-8 h-8 text-white"></i>
</div>
<h1 class="text-2xl font-bold text-navy mb-2">{% trans "Report an Observation" %}</h1>
<p class="text-slate">{% trans "Help us improve by reporting issues you notice" %}</p>
</div>
<!-- Anonymous Notice -->
<div class="bg-blue-50 border border-blue-100 rounded-xl p-4 mb-6">
<div class="flex items-start gap-3">
<i data-lucide="shield-check" class="w-5 h-5 text-navy mt-0.5 flex-shrink-0"></i>
<div>
<strong class="text-navy text-sm">{% trans "Anonymous Reporting" %}</strong>
<p class="text-slate text-sm mt-1 mb-0">
{% trans "You can submit this report anonymously. Providing your information is optional but may help us follow up if needed." %}
</p>
</div>
</div>
</div>
<!-- Messages -->
{% if messages %}
{% for message in messages %}
<div class="bg-green-50 border border-green-200 rounded-xl p-4 mb-4 text-sm text-green-800">
{{ message }}
</div>
{% endfor %}
{% endif %}
<!-- Form -->
<form method="post" enctype="multipart/form-data" id="observationForm">
{% csrf_token %}
<!-- Honeypot field (hidden) -->
{{ form.website }}
<!-- Category -->
<div class="mb-6">
<label class="flex items-center gap-2 text-sm font-bold text-navy mb-3">
<i data-lucide="tag" class="w-4 h-4"></i>
{% trans "Category" %}
<span class="text-xs font-normal text-slate">({% trans "optional" %})</span>
</label>
{{ form.category }}
</div>
<!-- Severity -->
<div class="mb-6">
<label class="flex items-center gap-2 text-sm font-bold text-navy mb-3">
<i data-lucide="alert-triangle" class="w-4 h-4"></i>
{% trans "Severity" %}
</label>
<div class="grid grid-cols-2 md:grid-cols-4 gap-3">
<div class="severity-option" data-value="low" onclick="selectSeverity(this)">
<i data-lucide="info" class="w-5 h-5 text-green-600 mx-auto mb-1 transition"></i>
<div class="text-xs font-bold text-slate">{% trans "Low" %}</div>
</div>
<div class="severity-option selected" data-value="medium" onclick="selectSeverity(this)">
<i data-lucide="alert-circle" class="w-5 h-5 text-yellow-600 mx-auto mb-1 transition"></i>
<div class="text-xs font-bold text-slate">{% trans "Medium" %}</div>
</div>
<div class="severity-option" data-value="high" onclick="selectSeverity(this)">
<i data-lucide="alert-triangle" class="w-5 h-5 text-red-500 mx-auto mb-1 transition"></i>
<div class="text-xs font-bold text-slate">{% trans "High" %}</div>
</div>
<div class="severity-option" data-value="critical" onclick="selectSeverity(this)">
<i data-lucide="x-octagon" class="w-5 h-5 text-gray-800 mx-auto mb-1 transition"></i>
<div class="text-xs font-bold text-slate">{% trans "Critical" %}</div>
</div>
</div>
<input type="hidden" name="severity" id="severityInput" value="medium">
</div>
<!-- Title -->
<div class="mb-6">
<label class="flex items-center gap-2 text-sm font-bold text-navy mb-3">
<i data-lucide="type" class="w-4 h-4"></i>
{% trans "Title" %}
<span class="text-xs font-normal text-slate">({% trans "optional" %})</span>
</label>
{{ form.title }}
</div>
<!-- Description -->
<div class="mb-6">
<label class="flex items-center gap-2 text-sm font-bold text-navy mb-3">
<i data-lucide="file-text" class="w-4 h-4"></i>
{% trans "Description" %}
<span class="text-red-500">*</span>
</label>
{{ form.description }}
<p class="text-xs text-slate mt-1.5">{% trans "Please describe what you observed in detail." %}</p>
</div>
<!-- Location -->
<div class="mb-6">
<label class="flex items-center gap-2 text-sm font-bold text-navy mb-3">
<i data-lucide="map-pin" class="w-4 h-4"></i>
{% trans "Location" %}
<span class="text-xs font-normal text-slate">({% trans "optional" %})</span>
</label>
{{ form.location_text }}
</div>
<!-- Incident Date/Time -->
<div class="mb-6">
<label class="flex items-center gap-2 text-sm font-bold text-navy mb-3">
<i data-lucide="calendar" class="w-4 h-4"></i>
{% trans "When did this occur?" %}
</label>
{{ form.incident_datetime }}
</div>
<!-- Attachments -->
<div class="mb-6">
<label class="flex items-center gap-2 text-sm font-bold text-navy mb-3">
<i data-lucide="paperclip" class="w-4 h-4"></i>
{% trans "Attachments" %}
<span class="text-xs font-normal text-slate">({% trans "optional" %})</span>
</label>
<div class="file-upload-area" onclick="document.getElementById('attachments').click()">
<i data-lucide="cloud-upload" class="w-8 h-8 text-navy mx-auto mb-2"></i>
<p class="text-sm font-semibold text-slate mb-1">{% trans "Click to upload files" %}</p>
<p class="text-xs text-slate mb-0">{% trans "Images, PDF, Word, Excel (max 10MB each)" %}</p>
</div>
<input type="file" id="attachments" name="attachments" multiple
accept=".jpg,.jpeg,.png,.gif,.pdf,.doc,.docx,.xls,.xlsx"
style="display: none;" onchange="updateFileList()">
<div id="fileList" class="mt-2"></div>
</div>
<!-- Reporter Information -->
<div class="mb-8">
<label class="flex items-center gap-2 text-sm font-bold text-navy mb-2">
<i data-lucide="user" class="w-4 h-4"></i>
{% trans "Your Information" %}
<span class="text-xs font-normal text-slate">({% trans "optional" %})</span>
</label>
<p class="text-xs text-slate mb-3">{% trans "Providing your information helps us follow up if needed. Leave blank to submit anonymously." %}</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label class="block text-xs font-semibold text-slate mb-1.5">{% trans "Staff ID" %}</label>
{{ form.reporter_staff_id }}
</div>
<div>
<label class="block text-xs font-semibold text-slate mb-1.5">{% trans "Name" %}</label>
{{ form.reporter_name }}
</div>
<div>
<label class="block text-xs font-semibold text-slate mb-1.5">{% trans "Phone" %}</label>
{{ form.reporter_phone }}
</div>
<div>
<label class="block text-xs font-semibold text-slate mb-1.5">{% trans "Email" %}</label>
{{ form.reporter_email }}
</div>
</div>
</div>
<!-- Submit -->
<button type="submit" class="w-full bg-navy text-white py-4 rounded-xl font-bold text-lg hover:bg-blue transition shadow-lg shadow-navy/25 flex items-center justify-center gap-2 btn-hover">
<i data-lucide="send" class="w-5 h-5"></i>
{% trans "Submit Observation" %}
</button>
<!-- Track Link -->
<div class="text-center mt-4">
<a href="{% url 'observations:observation_track' %}" class="text-slate hover:text-navy text-sm font-medium transition inline-flex items-center gap-1">
<i data-lucide="search" class="w-4 h-4"></i>
{% trans "Track an existing observation" %}
</a>
</div>
</form>
</div>
</div>
</div>
{% endblock %}
{% block extra_js %}
<script>
function selectSeverity(el) {
document.querySelectorAll('.severity-option').forEach(o => o.classList.remove('selected'));
el.classList.add('selected');
document.getElementById('severityInput').value = el.dataset.value;
lucide.createIcons();
}
function updateFileList() {
const input = document.getElementById('attachments');
const fileList = document.getElementById('fileList');
fileList.innerHTML = '';
if (input.files.length > 0) {
let html = '<div class="space-y-2 mt-3">';
for (let i = 0; i < input.files.length; i++) {
html += '<div class="flex items-center gap-2 bg-slate-50 rounded-lg px-3 py-2 text-sm text-slate"><i data-lucide="file" class="w-4 h-4"></i>' + input.files[i].name + '</div>';
}
html += '</div>';
fileList.innerHTML = html;
lucide.createIcons();
}
}
</script>
{% endblock %}