162 lines
6.8 KiB
HTML
162 lines
6.8 KiB
HTML
{% extends "base.html" %}
|
|
{% block title %}Dashboard{% endblock %}
|
|
{% block page_title %}Dashboard{% endblock %}
|
|
|
|
{% block content %}
|
|
<!-- Stats Row -->
|
|
<div class="row g-3 mb-4">
|
|
<div class="col-sm-4">
|
|
<div class="stat-card">
|
|
<div class="stat-icon" style="background:rgba(96,165,250,.1);color:var(--info);">
|
|
<i class="bi bi-ticket-detailed"></i>
|
|
</div>
|
|
<div>
|
|
<div class="stat-value">{{ open_count }}</div>
|
|
<div class="stat-label">Open Tickets</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-4">
|
|
<div class="stat-card">
|
|
<div class="stat-icon" style="background:rgba(0,180,216,.1);color:var(--accent3);">
|
|
<i class="bi bi-arrow-repeat"></i>
|
|
</div>
|
|
<div>
|
|
<div class="stat-value">{{ active_count }}</div>
|
|
<div class="stat-label">In Progress</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col-sm-4">
|
|
<div class="stat-card">
|
|
<div class="stat-icon" style="background:rgba(45,212,191,.1);color:var(--success);">
|
|
<i class="bi bi-check-circle"></i>
|
|
</div>
|
|
<div>
|
|
<div class="stat-value">{{ resolved_count }}</div>
|
|
<div class="stat-label">Resolved</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-4">
|
|
<!-- My Tickets -->
|
|
<div class="col-lg-7">
|
|
<div class="card">
|
|
<div class="card-header d-flex align-items-center justify-content-between">
|
|
<span><i class="bi bi-ticket-detailed me-2"></i>My Recent Tickets</span>
|
|
<a href="{{ url_for('tickets.create_ticket') }}" class="btn btn-primary btn-sm">
|
|
<i class="bi bi-plus-lg me-1"></i>New Ticket
|
|
</a>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
{% if my_tickets %}
|
|
<div class="table-responsive">
|
|
<table class="table mb-0">
|
|
<thead>
|
|
<tr>
|
|
<th>Ticket #</th>
|
|
<th>Title</th>
|
|
<th>Progress</th>
|
|
<th>Priority</th>
|
|
<th>Date</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for t in my_tickets %}
|
|
{% set is_done = t.status in ('resolved', 'closed') %}
|
|
{% set is_overdue = t.due_date and not is_done and t.due_date < now %}
|
|
{% set stage = 0 %}
|
|
{% if t.status == 'in_progress' %}{% set stage = 1 %}{% endif %}
|
|
{% if t.status == 'pending' %}{% set stage = 2 %}{% endif %}
|
|
{% if is_done %}{% set stage = 3 %}{% endif %}
|
|
<tr style="cursor:pointer;" onclick="window.location='/tickets/{{ t.id }}'">
|
|
<td style="white-space:nowrap;">
|
|
<span class="mono" style="font-size:12px;color:var(--accent3);">{{ t.ticket_number }}</span>
|
|
</td>
|
|
<td>
|
|
<div style="font-size:13px;">
|
|
{{ t.title[:40] }}{% if t.title|length > 40 %}…{% endif %}
|
|
</div>
|
|
<div style="margin-top:3px;display:flex;gap:4px;flex-wrap:wrap;">
|
|
{% if is_overdue %}
|
|
<span style="font-size:10px;padding:1px 6px;border-radius:4px;background:rgba(220,38,38,.12);color:var(--danger);font-weight:600;">
|
|
<i class="bi bi-exclamation-triangle-fill" style="font-size:9px;"></i> Overdue
|
|
</span>
|
|
{% endif %}
|
|
{% if t.priority == 'critical' %}
|
|
<span style="font-size:10px;padding:1px 6px;border-radius:4px;background:rgba(220,38,38,.12);color:var(--danger);font-weight:600;">Critical</span>
|
|
{% elif t.priority == 'high' %}
|
|
<span style="font-size:10px;padding:1px 6px;border-radius:4px;background:rgba(217,119,6,.12);color:var(--warning);font-weight:600;">High</span>
|
|
{% endif %}
|
|
</div>
|
|
</td>
|
|
<td style="min-width:110px;">
|
|
<div style="font-size:10px;color:var(--muted);margin-bottom:4px;">
|
|
{{ t.status.replace('_',' ').title() }}
|
|
</div>
|
|
<div style="display:flex;gap:2px;">
|
|
{% for i in range(4) %}
|
|
<div style="height:4px;flex:1;border-radius:2px;
|
|
background:{% if i <= stage %}{% if is_overdue %}var(--danger){% elif is_done %}var(--success){% else %}var(--accent){% endif %}{% else %}var(--border2){% endif %};"></div>
|
|
{% endfor %}
|
|
</div>
|
|
</td>
|
|
<td><span class="badge badge-{{ t.priority }}">{{ t.priority.upper() }}</span></td>
|
|
<td style="font-size:12px;color:var(--muted);white-space:nowrap;">{{ t.created_at | localtime("%b %d") }}</td>
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
{% else %}
|
|
<div class="p-5 text-center" style="color:var(--muted);">
|
|
<i class="bi bi-inbox" style="font-size:36px;display:block;margin-bottom:12px;"></i>
|
|
No tickets yet. <a href="{{ url_for('tickets.create_ticket') }}">Submit your first ticket →</a>
|
|
</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Quick Actions + KB -->
|
|
<div class="col-lg-5">
|
|
<div class="card mb-3">
|
|
<div class="card-header"><i class="bi bi-lightning-charge me-2"></i>Quick Actions</div>
|
|
<div class="card-body d-grid gap-2">
|
|
<a href="{{ url_for('tickets.create_ticket') }}" class="btn btn-primary">
|
|
<i class="bi bi-plus-circle me-2"></i>Report New Issue
|
|
</a>
|
|
<a href="{{ url_for('tickets.ticket_list') }}" class="btn btn-secondary">
|
|
<i class="bi bi-list-ul me-2"></i>View All My Tickets
|
|
</a>
|
|
<button class="btn btn-secondary" onclick="toggleChat()">
|
|
<i class="bi bi-robot me-2"></i>Ask IT Assistant
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-header d-flex align-items-center justify-content-between">
|
|
<span><i class="bi bi-book me-2"></i>Knowledge Base</span>
|
|
<a href="{{ url_for('tickets.knowledge_base') }}" style="font-size:12px;color:var(--accent3);">View all →</a>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
{% if articles %}
|
|
{% for art in articles %}
|
|
<a href="{{ url_for('tickets.kb_article', article_id=art.id) }}" style="display:flex;align-items:center;gap:10px;padding:11px 16px;border-bottom:1px solid var(--border);color:var(--text);">
|
|
<i class="bi bi-file-earmark-text" style="color:var(--accent3);font-size:16px;flex-shrink:0;"></i>
|
|
<span style="font-size:13px;">{{ art.title[:55] }}</span>
|
|
<span style="margin-left:auto;font-size:11px;color:var(--muted);">{{ art.view_count }} views</span>
|
|
</a>
|
|
{% endfor %}
|
|
{% else %}
|
|
<div class="p-3 text-center" style="font-size:13px;color:var(--muted);">No articles yet.</div>
|
|
{% endif %}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|