All checks were successful
Build and Push Docker Image / build (push) Successful in 4m14s
Reference numbers (unified scheme PREFIX-YYYYMM-HOSP-NNNN, e.g. CMP-202606-HHN-0001): - new ReferenceSequence model + generate_reference() helper (apps/core) - Complaint/Inquiry/Observation/Appreciation/Suggestion emit unified refs via save() - prefix-based auto-routing in public track API (CMP/INQ/OBS trackable; APR/SGT internal-only) - removed legacy CMP-/INQ- generators in ui_views, integrations, px_sources - migrations: core.0003_referencesequence, appreciation.0006, feedback.0008, observations.0012 - unit tests (format, sanitization, monthly reset, 40-thread concurrency) QA audit: - isolated E2E hospital sandbox mirroring HH-N + 10 role users (create_e2e_isolated_env) - feedback-modules-audit.spec.ts + audit helper (headed, run-to-completion) - reports/feedback-modules-qa-report.md Also bundles accumulated in-progress work across complaints, observations, organizations, templates, and other modules.
121 lines
6.0 KiB
HTML
121 lines
6.0 KiB
HTML
{% load i18n %}
|
|
{% load static %}
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>{% trans "Reset Password - PX360" %}</title>
|
|
<link rel="stylesheet" href="{% static 'dist/css/tailwind.css' %}">
|
|
<script src="https://unpkg.com/lucide@latest"></script>
|
|
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
|
|
<link rel="stylesheet" href="{% static 'vendor/fonts/noto-kufi-arabic/arabic.css' %}">
|
|
<style>
|
|
body { font-family: 'Inter', 'Noto Kufi Arabic', sans-serif; }
|
|
[dir="rtl"] body,
|
|
[dir="rtl"] input,
|
|
[dir="rtl"] textarea,
|
|
[dir="rtl"] select,
|
|
[dir="rtl"] button {
|
|
font-family: 'Noto Kufi Arabic', sans-serif;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body class="bg-gradient-to-br from-navy via-blue to-light min-h-screen flex items-center justify-center p-4">
|
|
<div class="w-full max-w-md">
|
|
<div class="bg-white rounded-[2rem] shadow-2xl overflow-hidden">
|
|
<!-- Header -->
|
|
<div class="bg-gradient-to-br from-navy to-blue text-white p-8 text-center">
|
|
<div class="mb-4">
|
|
<i data-lucide="key" class="w-16 h-16 mx-auto"></i>
|
|
</div>
|
|
<h3 class="text-2xl font-bold mb-2">{% trans "Reset Password" %}</h3>
|
|
<p class="text-white/90 text-sm">{% trans "Enter your email to receive reset instructions" %}</p>
|
|
</div>
|
|
|
|
<!-- Body -->
|
|
<div class="p-8">
|
|
<!-- Flash Messages -->
|
|
{% if messages %}
|
|
<div class="mb-6 space-y-3">
|
|
{% for message in messages %}
|
|
<div class="{% if message.tags == 'error' or message.tags == 'danger' %}bg-red-50 border-red-200 text-red-700{% elif message.tags == 'warning' %}bg-amber-50 border-amber-200 text-amber-700{% elif message.tags == 'success' %}bg-green-50 border-green-200 text-green-700{% else %}bg-blue-50 border-blue-200 text-blue-700{% endif %} border rounded-xl px-4 py-3 flex items-start gap-3" role="alert">
|
|
{% if message.tags == 'error' or message.tags == 'danger' %}
|
|
<i data-lucide="alert-triangle" class="w-5 h-5 flex-shrink-0 mt-0.5"></i>
|
|
{% elif message.tags == 'success' %}
|
|
<i data-lucide="check-circle" class="w-5 h-5 flex-shrink-0 mt-0.5"></i>
|
|
{% else %}
|
|
<i data-lucide="info" class="w-5 h-5 flex-shrink-0 mt-0.5"></i>
|
|
{% endif %}
|
|
<p class="text-sm flex-1">{{ message }}</p>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
<!-- Password Reset Form -->
|
|
<form method="post">
|
|
{% csrf_token %}
|
|
|
|
<!-- Email -->
|
|
<div class="mb-6">
|
|
<label for="id_email" class="block text-sm font-semibold text-slate-700 mb-2">
|
|
<i data-lucide="mail" class="w-4 h-4 inline mr-1"></i> {% trans "Email Address" %}
|
|
</label>
|
|
<div class="relative">
|
|
<i data-lucide="at-sign" class="w-5 h-5 absolute left-4 top-1/2 -translate-y-1/2 text-slate-400"></i>
|
|
<input type="email"
|
|
class="w-full pl-12 pr-4 py-3 border border-slate-200 rounded-xl focus:outline-none focus:ring-2 focus:ring-navy focus:border-transparent transition"
|
|
id="id_email"
|
|
name="email"
|
|
placeholder="{% trans 'Enter your email' %}"
|
|
required
|
|
autofocus>
|
|
</div>
|
|
{% if form.email.errors %}
|
|
<div class="text-red-500 text-sm mt-1">
|
|
{{ form.email.errors }}
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
|
|
<!-- Submit Button -->
|
|
<button type="submit" class="w-full bg-navy hover:bg-blue text-white py-3.5 rounded-xl font-semibold shadow-lg hover:shadow-xl transition-all duration-300 flex items-center justify-center gap-2">
|
|
<i data-lucide="send" class="w-5 h-5"></i>
|
|
{% trans "Send Reset Link" %}
|
|
</button>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Footer -->
|
|
<div class="bg-slate-50 px-8 py-6 text-center border-t border-slate-100">
|
|
<a href="{% url 'accounts:login' %}" class="inline-flex items-center gap-2 text-sm text-navy font-medium hover:text-blue transition">
|
|
<i data-lucide="arrow-left" class="w-4 h-4"></i>
|
|
{% trans "Back to Login" %}
|
|
</a>
|
|
<p class="text-xs text-slate mt-3">
|
|
{% trans "Secure password reset powered by" %} <a href="https://tenhal.sa" target="_blank" class="text-navy font-medium hover:underline">tenhal.sa</a>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
lucide.createIcons();
|
|
|
|
// Auto-hide success messages after 5 seconds
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const successMessages = document.querySelectorAll('.bg-green-50');
|
|
successMessages.forEach(msg => {
|
|
setTimeout(() => {
|
|
msg.style.opacity = '0';
|
|
msg.style.transform = 'translateY(-10px)';
|
|
msg.style.transition = 'all 0.3s ease-out';
|
|
setTimeout(() => msg.remove(), 300);
|
|
}, 5000);
|
|
});
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|