Files
arrr-erp/app/modules/employees/templates/employees/work_dashboard.html
T
2026-06-20 15:01:44 +05:30

106 lines
11 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 "ui/templates/base/layout.html" %}
{% block content %}
{% include "modules/managers/templates/managers/_manager_tabs.html" %}
<div class="space-y-6">
<div class="flex flex-wrap items-start justify-between gap-3">
<div>
<h2 class="text-xl font-semibold text-slate-900">Employee Work Allocation</h2>
<p class="mt-1 text-sm text-slate-500">Assign and review engagement/service tasks grouped by priority, client and engagement.</p>
</div>
<a href="/employees/dashboard" class="rounded-xl border border-slate-300 px-4 py-2 text-sm font-semibold text-slate-700 hover:bg-slate-50">Back to HR Dashboard</a>
</div>
<div class="grid gap-4 md:grid-cols-5">
<div class="rounded-2xl border border-slate-200 bg-white p-4 shadow-soft"><div class="text-xs font-semibold uppercase text-slate-500">Total</div><div class="mt-1 text-2xl font-semibold">{{ work_payload.summary.total }}</div></div>
<div class="rounded-2xl border border-slate-200 bg-white p-4 shadow-soft"><div class="text-xs font-semibold uppercase text-slate-500">Open</div><div class="mt-1 text-2xl font-semibold">{{ work_payload.summary.open }}</div></div>
<div class="rounded-2xl border border-orange-200 bg-orange-50 p-4 shadow-soft"><div class="text-xs font-semibold uppercase text-orange-600">Unassigned</div><div class="mt-1 text-2xl font-semibold text-orange-700">{{ work_payload.summary.unassigned }}</div></div>
<div class="rounded-2xl border border-red-200 bg-red-50 p-4 shadow-soft"><div class="text-xs font-semibold uppercase text-red-600">Overdue</div><div class="mt-1 text-2xl font-semibold text-red-700">{{ work_payload.summary.overdue }}</div></div>
<div class="rounded-2xl border border-emerald-200 bg-emerald-50 p-4 shadow-soft"><div class="text-xs font-semibold uppercase text-emerald-600">Completed</div><div class="mt-1 text-2xl font-semibold text-emerald-700">{{ work_payload.summary.completed }}</div></div>
</div>
<form method="get" action="/employees/work" class="rounded-2xl border border-slate-200 bg-white p-4 shadow-soft">
<div class="grid gap-3 md:grid-cols-[1fr_180px_240px_auto]">
<input type="search" name="q" value="{{ q or '' }}" placeholder="Search task, client or engagement" class="rounded-xl border border-slate-300 px-3 py-2 text-sm focus:border-brand-500 focus:outline-none focus:ring-2 focus:ring-brand-100">
<select name="status" class="rounded-xl border border-slate-300 px-3 py-2 text-sm">
<option value="open" {% if status == 'open' %}selected{% endif %}>Open tasks</option>
<option value="unassigned" {% if status == 'unassigned' %}selected{% endif %}>Unassigned</option>
<option value="closed" {% if status == 'closed' %}selected{% endif %}>Closed tasks</option>
<option value="pending" {% if status == 'pending' %}selected{% endif %}>Pending</option>
<option value="in_progress" {% if status == 'in_progress' %}selected{% endif %}>In Progress</option>
<option value="blocked" {% if status == 'blocked' %}selected{% endif %}>Blocked</option>
<option value="completed" {% if status == 'completed' %}selected{% endif %}>Completed</option>
</select>
<select name="assigned_to_user_id" class="rounded-xl border border-slate-300 px-3 py-2 text-sm">
<option value="0">All assignees</option>
{% for user in assignable_users %}
<option value="{{ user.id }}" {% if selected_assigned_to_user_id == user.id %}selected{% endif %}>{{ user.full_name or user.email }}</option>
{% endfor %}
</select>
<button type="submit" class="rounded-xl bg-brand-600 px-4 py-2 text-sm font-semibold text-white hover:bg-brand-700">Filter</button>
</div>
</form>
<div class="space-y-4">
{% for priority_group in work_payload.groups %}
<details class="group rounded-2xl border border-slate-200 bg-white shadow-soft" {% if loop.first %}open{% endif %}>
<summary class="flex cursor-pointer list-none items-center justify-between gap-3 rounded-2xl px-5 py-4 hover:bg-slate-50">
<div><div class="text-sm font-semibold uppercase tracking-wide text-slate-500">Priority</div><div class="text-lg font-semibold text-slate-900">{{ priority_group.label }}</div></div>
<div class="flex items-center gap-3 text-sm text-slate-500"><span>{{ priority_group.task_count }} task{{ '' if priority_group.task_count == 1 else 's' }}</span><span class="text-lg transition group-open:rotate-90"></span></div>
</summary>
<div class="space-y-3 border-t border-slate-100 p-4">
{% for client_group in priority_group.clients %}
<details class="group/client rounded-xl border border-slate-200 bg-slate-50" {% if loop.first %}open{% endif %}>
<summary class="flex cursor-pointer list-none items-center justify-between gap-3 px-4 py-3 hover:bg-slate-100">
<div><div class="font-semibold text-slate-900">{{ client_group.client_name }}</div><div class="text-xs text-slate-500">{{ client_group.client_code or 'No client code' }}</div></div>
<div class="flex items-center gap-3 text-sm text-slate-500"><span>{{ client_group.task_count }} task{{ '' if client_group.task_count == 1 else 's' }}</span><span class="transition group-open/client:rotate-90"></span></div>
</summary>
<div class="space-y-3 border-t border-slate-200 p-3">
{% for engagement_group in client_group.engagements %}
<details class="group/eng rounded-xl border border-slate-200 bg-white" {% if loop.first %}open{% endif %}>
<summary class="flex cursor-pointer list-none items-center justify-between gap-3 px-4 py-3 hover:bg-slate-50">
<div><div class="font-semibold text-slate-900">{{ engagement_group.label }}</div><div class="text-xs text-slate-500">Open: {{ engagement_group.open_count }} · Completed: {{ engagement_group.completed_count }} · Status: {{ engagement_group.status.replace('_',' ').title() }}</div></div>
<div class="flex items-center gap-3 text-sm text-slate-500"><span>{{ engagement_group.task_count }} task{{ '' if engagement_group.task_count == 1 else 's' }}</span><span class="transition group-open/eng:rotate-90"></span></div>
</summary>
<div class="overflow-x-auto border-t border-slate-100">
<table class="min-w-full divide-y divide-slate-200 text-sm">
<thead class="bg-slate-50 text-left text-xs font-semibold uppercase tracking-wide text-slate-500">
<tr><th class="px-4 py-3">Task</th><th class="px-4 py-3">Current</th><th class="px-4 py-3">Assign / Review</th></tr>
</thead>
<tbody class="divide-y divide-slate-100 bg-white">
{% for task in engagement_group.tasks %}
<tr class="align-top {% if task.is_overdue %}bg-red-50{% elif task.is_due_today %}bg-amber-50{% endif %}">
<td class="px-4 py-3 min-w-[260px]"><div class="font-medium text-slate-900">{{ task.task_name }}</div>{% if task.description %}<div class="mt-1 max-w-xl text-xs text-slate-500">{{ task.description }}</div>{% endif %}<div class="mt-2 text-xs text-slate-500">Target: {{ task.internal_target_date or '-' }} · {{ task.date_bucket }}</div></td>
<td class="px-4 py-3 min-w-[180px]"><div><span class="rounded-full bg-slate-100 px-2.5 py-1 text-xs font-semibold text-slate-700">{{ task.status_label }}</span></div><div class="mt-2 text-xs text-slate-600">Assigned: {{ task.assigned_to.full_name if task.assigned_to else 'Unassigned' }}</div><div class="mt-1 text-xs text-slate-600">Priority: {{ task.priority_label }}</div>
<div class="mt-2"><a href="/employees/work/tasks/{{ task.id }}/communication" class="inline-flex rounded-lg border border-slate-300 px-2.5 py-1 text-xs font-semibold text-slate-700 hover:bg-slate-50">Timeline{% if task.comment_count %} · {{ task.comment_count }}{% endif %}</a></div>
{% if task.latest_comment %}<div class="mt-1 max-w-xs truncate text-xs text-slate-500">{{ task.latest_comment.message }}</div>{% endif %}
</td>
<td class="px-4 py-3 min-w-[520px]">
<form method="post" action="/employees/work/tasks/{{ task.id }}/assign" class="grid gap-2 md:grid-cols-5">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<select name="assigned_to_user_id" class="rounded-lg border border-slate-300 px-2 py-1 text-xs"><option value="">Unassigned</option>{% for user in assignable_users %}<option value="{{ user.id }}" {% if task.assigned_to_user_id == user.id %}selected{% endif %}>{{ user.full_name or user.email }}</option>{% endfor %}</select>
<select name="status" class="rounded-lg border border-slate-300 px-2 py-1 text-xs"><option value="pending" {% if task.status == 'pending' %}selected{% endif %}>Pending</option><option value="in_progress" {% if task.status == 'in_progress' %}selected{% endif %}>In Progress</option><option value="blocked" {% if task.status == 'blocked' %}selected{% endif %}>Blocked</option><option value="completed" {% if task.status == 'completed' %}selected{% endif %}>Completed</option><option value="not_applicable" {% if task.status == 'not_applicable' %}selected{% endif %}>Not Applicable</option><option value="cancelled" {% if task.status == 'cancelled' %}selected{% endif %}>Cancelled</option></select>
<select name="priority" class="rounded-lg border border-slate-300 px-2 py-1 text-xs"><option value="low" {% if task.priority == 'low' %}selected{% endif %}>Low</option><option value="normal" {% if task.priority == 'normal' %}selected{% endif %}>Normal</option><option value="high" {% if task.priority == 'high' %}selected{% endif %}>High</option><option value="urgent" {% if task.priority == 'urgent' %}selected{% endif %}>Urgent</option></select>
<input type="date" name="internal_target_date" value="{{ task.internal_target_date or '' }}" class="rounded-lg border border-slate-300 px-2 py-1 text-xs">
<button type="submit" class="rounded-lg bg-brand-600 px-3 py-1 text-xs font-semibold text-white hover:bg-brand-700">Save</button>
<input type="text" name="remarks" value="{{ task.remarks or '' }}" placeholder="Remarks" class="md:col-span-5 rounded-lg border border-slate-300 px-2 py-1 text-xs">
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</details>
{% endfor %}
</div>
</details>
{% endfor %}
</div>
</details>
{% else %}
<div class="rounded-2xl border border-slate-200 bg-white p-8 text-center shadow-soft"><h3 class="font-semibold text-slate-900">No work items found</h3><p class="mt-1 text-sm text-slate-500">No engagement task matches the selected filter.</p></div>
{% endfor %}
</div>
</div>
{% endblock %}