All checks were successful
Build and Push Docker Image / build (push) Successful in 2m15s
Tests the full onboarding flow: token activation (auto-login) → welcome → wizard content steps → checklist → activation (password) → completion → invalid token → admin provisional list. Key finding: the wizard UI renders but the onboarding flow doesn't actually COMPLETE — after walking all steps + submitting the password form, the user is still is_provisional=True with no password set. The activation step lacks a POST handler to finalize onboarding. Details in the test observations. Harness: seed_e2e_provisional + get_e2e_onboarding_state CLI + spec.
116 lines
6.0 KiB
HTML
116 lines
6.0 KiB
HTML
{% extends "layouts/base.html" %}
|
|
{% load i18n %}
|
|
|
|
{% block title %}{% trans "My Tasks" %} - PX360{% endblock %}
|
|
|
|
{% block content %}
|
|
<header class="mb-6">
|
|
<div class="flex items-center gap-2 text-sm text-slate mb-2">
|
|
<i data-lucide="list-checks" class="w-4 h-4"></i>
|
|
<span class="font-bold text-navy">{% trans "My Tasks" %}</span>
|
|
</div>
|
|
<h1 class="text-2xl font-bold text-navy">{% trans "My Tasks" %}</h1>
|
|
<p class="text-slate text-sm mt-1">{% trans "All pending items assigned to you across the system" %}</p>
|
|
</header>
|
|
|
|
<div class="grid grid-cols-2 gap-4 mb-6">
|
|
<div class="bg-white rounded-2xl shadow-sm border border-slate-100 p-4">
|
|
<div class="flex items-center gap-3">
|
|
<div class="w-10 h-10 bg-amber-50 rounded-xl flex items-center justify-center">
|
|
<i data-lucide="clock" class="w-5 h-5 text-amber-600"></i>
|
|
</div>
|
|
<div>
|
|
<p class="text-[10px] uppercase font-bold text-slate-500">{% trans "Pending" %}</p>
|
|
<p class="text-2xl font-bold text-navy">{{ pending }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="bg-white rounded-2xl shadow-sm border border-slate-100 p-4">
|
|
<div class="flex items-center gap-3">
|
|
<div class="w-10 h-10 bg-red-50 rounded-xl flex items-center justify-center">
|
|
<i data-lucide="alert-triangle" class="w-5 h-5 text-red-600"></i>
|
|
</div>
|
|
<div>
|
|
<p class="text-[10px] uppercase font-bold text-slate-500">{% trans "Overdue" %}</p>
|
|
<p class="text-2xl font-bold {% if overdue > 0 %}text-red-600{% else %}text-navy{% endif %}">{{ overdue }}</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{% if tasks %}
|
|
<div class="space-y-3">
|
|
{% for task in tasks %}
|
|
<div class="bg-white rounded-2xl shadow-sm border border-slate-100 p-4 hover:shadow-md transition
|
|
{% if task.is_overdue %}border-l-4 border-l-red-400{% endif %}">
|
|
<div class="flex items-start gap-3">
|
|
<div class="w-9 h-9 rounded-xl flex items-center justify-center shrink-0
|
|
{% if task.color == 'red' %}bg-red-50
|
|
{% elif task.color == 'amber' %}bg-amber-50
|
|
{% elif task.color == 'orange' %}bg-orange-50
|
|
{% elif task.color == 'blue' %}bg-blue-50
|
|
{% elif task.color == 'cyan' %}bg-cyan-50
|
|
{% elif task.color == 'purple' %}bg-purple-50
|
|
{% else %}bg-slate-50{% endif %}">
|
|
<i data-lucide="{{ task.icon }}" class="w-4 h-4
|
|
{% if task.color == 'red' %}text-red-600
|
|
{% elif task.color == 'amber' %}text-amber-600
|
|
{% elif task.color == 'orange' %}text-orange-600
|
|
{% elif task.color == 'blue' %}text-blue-600
|
|
{% elif task.color == 'cyan' %}text-cyan-600
|
|
{% elif task.color == 'purple' %}text-purple-600
|
|
{% else %}text-slate-600{% endif %}"></i>
|
|
</div>
|
|
<div class="flex-1 min-w-0">
|
|
<div class="flex items-center gap-2 mb-1">
|
|
<span class="px-1.5 py-0.5 rounded text-[9px] font-bold uppercase tracking-wide
|
|
{% if task.color == 'red' %}bg-red-100 text-red-700
|
|
{% elif task.color == 'amber' %}bg-amber-100 text-amber-700
|
|
{% elif task.color == 'orange' %}bg-orange-100 text-orange-700
|
|
{% elif task.color == 'blue' %}bg-blue-100 text-blue-700
|
|
{% elif task.color == 'cyan' %}bg-cyan-100 text-cyan-700
|
|
{% elif task.color == 'purple' %}bg-purple-100 text-purple-700
|
|
{% else %}bg-slate-100 text-slate-700{% endif %}">
|
|
{{ task.type_label }}
|
|
</span>
|
|
<span class="font-mono text-xs text-slate-400">{{ task.reference }}</span>
|
|
</div>
|
|
<p class="text-sm font-semibold text-navy">{{ task.title }}</p>
|
|
{% if task.description %}
|
|
<p class="text-xs text-slate-500 mt-0.5 truncate">{{ task.description }}</p>
|
|
{% endif %}
|
|
{% if task.due_date %}
|
|
<p class="text-xs mt-1 {% if task.is_overdue %}text-red-600 font-bold{% else %}text-slate-400{% endif %}">
|
|
<i data-lucide="calendar" class="w-3 h-3 inline"></i>
|
|
{{ task.due_date|date:"M d, Y" }}
|
|
{% if task.is_overdue %} — {% trans "Overdue" %}{% endif %}
|
|
</p>
|
|
{% endif %}
|
|
</div>
|
|
{% if task.type == 'dept_response' %}
|
|
<button onclick="openDeptResponseModal('{{ task.modal_type }}', '{{ task.modal_pk }}', '{{ task.modal_url }}', '{{ task.modal_ref|escapejs }}', '{{ task.modal_subject|escapejs }}')"
|
|
class="shrink-0 px-3 py-1.5 bg-navy text-white rounded-lg text-xs font-semibold hover:bg-blue transition inline-flex items-center gap-1">
|
|
{% trans "Respond" %}
|
|
<i data-lucide="message-square" class="w-3 h-3"></i>
|
|
</button>
|
|
{% else %}
|
|
<a href="{{ task.url }}" class="shrink-0 px-3 py-1.5 bg-navy text-white rounded-lg text-xs font-semibold hover:bg-blue transition inline-flex items-center gap-1">
|
|
{% trans "Action" %}
|
|
<i data-lucide="arrow-right" class="w-3 h-3"></i>
|
|
</a>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
{% else %}
|
|
<div class="bg-white rounded-2xl shadow-sm border border-slate-100 p-12 text-center">
|
|
<i data-lucide="check-circle" class="w-12 h-12 text-green-500 mx-auto mb-3"></i>
|
|
<p class="text-slate-600 font-semibold text-lg">{% trans "You're all caught up!" %}</p>
|
|
<p class="text-slate-400 text-sm mt-1">{% trans "No pending tasks assigned to you." %}</p>
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% include "components/department_response_modal.html" %}
|
|
{% endblock %}
|