128 lines
6.9 KiB
HTML
128 lines
6.9 KiB
HTML
|
|
{% extends "shared/frontend/base.html" %}
|
||
|
|
|
||
|
|
{% block title %}Tekniker Dashboard V2 - Workboard{% endblock %}
|
||
|
|
|
||
|
|
{% block content %}
|
||
|
|
<div class="container-fluid py-4">
|
||
|
|
<div class="d-flex justify-content-between align-items-start flex-wrap gap-3 mb-4">
|
||
|
|
<div>
|
||
|
|
<h1 class="h3 mb-1">🛠️ Tekniker Dashboard V2</h1>
|
||
|
|
<p class="text-muted mb-0">Workboard-visning for {{ technician_name }} (bruger #{{ technician_user_id }})</p>
|
||
|
|
</div>
|
||
|
|
<div class="d-flex gap-2">
|
||
|
|
<a href="/ticket/dashboard/technician?technician_user_id={{ technician_user_id }}" class="btn btn-outline-secondary btn-sm">Tilbage til valg</a>
|
||
|
|
<a href="/ticket/dashboard/technician/v1?technician_user_id={{ technician_user_id }}" class="btn btn-outline-primary btn-sm">Se V1</a>
|
||
|
|
<a href="/ticket/dashboard/technician/v3?technician_user_id={{ technician_user_id }}" class="btn btn-outline-primary btn-sm">Se V3</a>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="row g-4">
|
||
|
|
<div class="col-lg-4">
|
||
|
|
<div class="card border-0 shadow-sm h-100">
|
||
|
|
<div class="card-header bg-white border-0 d-flex justify-content-between align-items-center">
|
||
|
|
<h5 class="mb-0">Dagens opgaver</h5>
|
||
|
|
<span class="badge bg-primary">{{ kpis.today_tasks_count }}</span>
|
||
|
|
</div>
|
||
|
|
<div class="card-body">
|
||
|
|
{% for item in today_tasks %}
|
||
|
|
<div class="border rounded p-2 mb-2">
|
||
|
|
<div class="fw-semibold">{{ item.title }}</div>
|
||
|
|
<div class="small text-muted">{{ item.customer_name }} · {{ item.task_reason }}</div>
|
||
|
|
<a href="{{ '/sag/' ~ item.item_id if item.item_type == 'case' else '/ticket/tickets/' ~ item.item_id }}" class="btn btn-sm btn-outline-primary mt-2">Åbn</a>
|
||
|
|
</div>
|
||
|
|
{% else %}
|
||
|
|
<p class="text-muted mb-0">Ingen opgaver i dag.</p>
|
||
|
|
{% endfor %}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="col-lg-4">
|
||
|
|
<div class="card border-0 shadow-sm h-100">
|
||
|
|
<div class="card-header bg-white border-0 d-flex justify-content-between align-items-center">
|
||
|
|
<h5 class="mb-0">Mine sager</h5>
|
||
|
|
<span class="badge bg-secondary">{{ kpis.my_cases_count }}</span>
|
||
|
|
</div>
|
||
|
|
<div class="card-body">
|
||
|
|
{% for item in my_cases %}
|
||
|
|
<div class="border rounded p-2 mb-2">
|
||
|
|
<div class="fw-semibold">#{{ item.id }} · {{ item.titel }}</div>
|
||
|
|
<div class="small text-muted">{{ item.customer_name }} · Deadline: {{ item.deadline.strftime('%d/%m/%Y') if item.deadline else '-' }}</div>
|
||
|
|
<a href="/sag/{{ item.id }}" class="btn btn-sm btn-outline-primary mt-2">Åbn</a>
|
||
|
|
</div>
|
||
|
|
{% else %}
|
||
|
|
<p class="text-muted mb-0">Ingen aktive sager.</p>
|
||
|
|
{% endfor %}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="col-lg-4">
|
||
|
|
<div class="card border-0 shadow-sm h-100">
|
||
|
|
<div class="card-header bg-white border-0 d-flex justify-content-between align-items-center">
|
||
|
|
<h5 class="mb-0 text-danger">Haste / over SLA</h5>
|
||
|
|
<span class="badge bg-danger">{{ kpis.urgent_overdue_count }}</span>
|
||
|
|
</div>
|
||
|
|
<div class="card-body">
|
||
|
|
{% for item in urgent_overdue %}
|
||
|
|
<div class="border border-danger rounded p-2 mb-2">
|
||
|
|
<div class="fw-semibold">{{ item.title }}</div>
|
||
|
|
<div class="small text-muted">{{ item.customer_name }} · {{ item.attention_reason }}</div>
|
||
|
|
<a href="{{ '/sag/' ~ item.item_id if item.item_type == 'case' else '/ticket/tickets/' ~ item.item_id }}" class="btn btn-sm btn-danger mt-2">Åbn</a>
|
||
|
|
</div>
|
||
|
|
{% else %}
|
||
|
|
<p class="text-muted mb-0">Ingen kritiske emner.</p>
|
||
|
|
{% endfor %}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="col-lg-8">
|
||
|
|
<div class="card border-0 shadow-sm h-100">
|
||
|
|
<div class="card-header bg-white border-0 d-flex justify-content-between align-items-center">
|
||
|
|
<h5 class="mb-0">Nye sager</h5>
|
||
|
|
<span class="badge bg-info">{{ kpis.new_cases_count }}</span>
|
||
|
|
</div>
|
||
|
|
<div class="card-body p-0">
|
||
|
|
<div class="table-responsive">
|
||
|
|
<table class="table table-sm table-hover mb-0">
|
||
|
|
<thead class="table-light"><tr><th>ID</th><th>Titel</th><th>Kunde</th><th>Oprettet</th></tr></thead>
|
||
|
|
<tbody>
|
||
|
|
{% for item in new_cases %}
|
||
|
|
<tr onclick="window.location.href='/sag/{{ item.id }}'" style="cursor:pointer;">
|
||
|
|
<td>#{{ item.id }}</td><td>{{ item.titel }}</td><td>{{ item.customer_name }}</td><td>{{ item.created_at.strftime('%d/%m %H:%M') if item.created_at else '-' }}</td>
|
||
|
|
</tr>
|
||
|
|
{% else %}
|
||
|
|
<tr><td colspan="4" class="text-center text-muted py-3">Ingen nye sager</td></tr>
|
||
|
|
{% endfor %}
|
||
|
|
</tbody>
|
||
|
|
</table>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div class="col-lg-4">
|
||
|
|
<div class="card border-0 shadow-sm h-100">
|
||
|
|
<div class="card-header bg-white border-0 d-flex justify-content-between align-items-center">
|
||
|
|
<h5 class="mb-0">Mine opportunities</h5>
|
||
|
|
<span class="badge bg-dark">{{ kpis.my_opportunities_count }}</span>
|
||
|
|
</div>
|
||
|
|
<div class="card-body">
|
||
|
|
{% for item in my_opportunities %}
|
||
|
|
<div class="border rounded p-2 mb-2">
|
||
|
|
<div class="fw-semibold">{{ item.titel }}</div>
|
||
|
|
<div class="small text-muted">{{ item.customer_name }} · {{ item.pipeline_stage or 'Uden stage' }}</div>
|
||
|
|
<div class="small text-muted">Sandsynlighed: {{ "%.0f"|format(item.pipeline_probability or 0) }}%</div>
|
||
|
|
<a href="/sag/{{ item.id }}" class="btn btn-sm btn-outline-primary mt-2">Åbn</a>
|
||
|
|
</div>
|
||
|
|
{% else %}
|
||
|
|
<p class="text-muted mb-0">Ingen opportunities.</p>
|
||
|
|
{% endfor %}
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
{% endblock %}
|