Files
korrekturmanagementsystem/ticketsystem/templates/ticketsystem/index.html
2025-06-04 23:47:36 +02:00

267 lines
18 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 "ticketsystem/base.html" %}
{% block content %}
<!-- Messages -->
{% if messages %}
<div class="max-w-6xl mx-auto px-4 pt-4">
{% for message in messages %}
<div class="mb-4 p-3 rounded {% if message.tags == 'error' %}bg-red-100 text-red-700{% elif message.tags == 'success' %}bg-green-100 text-green-700{% else %}bg-yellow-100 text-yellow-700{% endif %}">
{{ message }}
</div>
{% endfor %}
</div>
{% endif %}
<div class="max-w-6xl mx-auto px-4 py-6">
<!-- Header -->
<div class="flex flex-col sm:flex-row sm:justify-between sm:items-center mb-6">
<div>
<h1 class="text-3xl font-bold text-gray-900 mb-2">🎫 Ticket-Übersicht</h1>
<p class="text-gray-600">Verwalte und verfolge alle deine Tickets</p>
</div>
<div class="mt-4 sm:mt-0">
<a href="{% url 'create' %}"
class="bg-green-500 hover:bg-green-600 text-white px-4 py-2 rounded font-medium">
Neues Ticket erstellen
</a>
</div>
</div>
<!-- Filter und Suche -->
<div class="bg-white rounded-lg shadow p-4 mb-6">
<div class="grid grid-cols-1 lg:grid-cols-5 gap-4">
<!-- Status Filter -->
<div>
<form method="get">
<label class="block text-sm font-medium mb-1">Status:</label>
<select name="status"
onchange="this.form.submit()"
class="w-full h-10 px-3 border border-gray-300 rounded shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
<option value="">Alle Status</option>
{% for value, label in status_choices %}
<option value="{{ value }}"
{% if selected_status == value %}selected{% endif %}>{{ label }}</option>
{% endfor %}
</select>
<!-- Andere Filter beibehalten -->
{% if request.GET.assigned_to %}
<input type="hidden"
name="assigned_to"
value="{{ request.GET.assigned_to }}">
{% endif %}
{% if request.GET.course %}<input type="hidden" name="course" value="{{ request.GET.course }}">{% endif %}
{% if search_query %}<input type="hidden" name="q" value="{{ search_query }}">{% endif %}
</form>
</div>
<!-- Meine Tickets Filter -->
<div>
<label class="block text-sm font-medium mb-1">Zuweisung:</label>
{% if request.GET.assigned_to == user.id|stringformat:'s' %}
<!-- Wenn aktiv: Button zum Deaktivieren -->
<a href="?{% if selected_status %}status={{ selected_status }}{% endif %}{% if selected_course %}&course={{ selected_course }}{% endif %}{% if search_query %}&q={{ search_query }}{% endif %}"
class="block w-full h-10 px-3 border border-purple-300 rounded shadow-sm text-center bg-purple-200 hover:bg-purple-300 transition-colors flex items-center justify-center">
👤 Meine Tickets ✓
</a>
{% else %}
<!-- Wenn nicht aktiv: Button zum Aktivieren -->
<a href="?assigned_to={{ user.id }}{% if selected_status %}&status={{ selected_status }}{% endif %}{% if selected_course %}&course={{ selected_course }}{% endif %}{% if search_query %}&q={{ search_query }}{% endif %}"
class="block w-full h-10 px-3 border border-purple-300 rounded shadow-sm text-center bg-purple-50 hover:bg-purple-100 transition-colors flex items-center justify-center">
👤 Meine Tickets
</a>
{% endif %}
</div>
<!-- Kurs Filter -->
<div>
<form method="get">
<label class="block text-sm font-medium mb-1">Kurs:</label>
<select name="course"
onchange="this.form.submit()"
class="w-full h-10 px-3 border border-gray-300 rounded shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
<option value="">Alle Kurse</option>
{% for course in courses %}
<option value="{{ course.id }}"
{% if selected_course == course.id|stringformat:'s' %}selected{% endif %}>
{{ course.code }} - {{ course.name }}
</option>
{% endfor %}
</select>
<!-- Andere Filter beibehalten -->
{% if selected_status %}<input type="hidden" name="status" value="{{ selected_status }}">{% endif %}
{% if selected_course %}<input type="hidden" name="course" value="{{ selected_course }}">{% endif %}
{% if request.GET.assigned_to %}
<input type="hidden"
name="assigned_to"
value="{{ request.GET.assigned_to }}">
{% endif %}
{% if search_query %}<input type="hidden" name="q" value="{{ search_query }}">{% endif %}
</form>
</div>
<!-- Suche -->
<div class="lg:col-span-2">
<form method="get">
<label class="block text-sm font-medium mb-1">Suche:</label>
<div class="flex">
<input type="text"
name="q"
value="{{ search_query }}"
placeholder="Titel oder Beschreibung durchsuchen..."
class="flex-1 h-10 px-3 border border-gray-300 rounded-l shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
{% if selected_status %}<input type="hidden" name="status" value="{{ selected_status }}">{% endif %}
{% if selected_course %}<input type="hidden" name="course" value="{{ selected_course }}">{% endif %}
{% if request.GET.assigned_to %}
<input type="hidden"
name="assigned_to"
value="{{ request.GET.assigned_to }}">
{% endif %}
<button type="submit"
class="bg-blue-500 hover:bg-blue-600 text-white h-10 px-4 rounded-r">🔍</button>
</div>
</form>
</div>
</div>
<!-- Aktive Filter Anzeige -->
{% if selected_status or request.GET.assigned_to or search_query %}
<div class="mt-4 p-3 bg-gray-50 rounded border-l-4 border-blue-400">
<div class="flex flex-wrap items-center gap-2">
<span class="font-medium text-gray-700">Aktive Filter:</span>
{% if selected_status %}
<span class="px-2 py-1 bg-blue-100 text-blue-800 text-sm rounded">
Status:
{% for value, label in status_choices %}
{% if value == selected_status %}{{ label }}{% endif %}
{% endfor %}
<a href="?{% if search_query %}q={{ search_query }}{% endif %}{% if request.GET.assigned_to %}&assigned_to={{ request.GET.assigned_to }}{% endif %}"
class="ml-1 text-blue-600 hover:text-blue-800">×</a>
</span>
{% endif %}
{% if request.GET.assigned_to %}
<span class="px-2 py-1 bg-purple-100 text-purple-800 text-sm rounded">
Meine Tickets
<a href="?{% if selected_status %}status={{ selected_status }}{% endif %}{% if search_query %}&q={{ search_query }}{% endif %}"
class="ml-1 text-purple-600 hover:text-purple-800">×</a>
</span>
{% endif %}
{% if search_query %}
<span class="px-2 py-1 bg-green-100 text-green-800 text-sm rounded">
Suche: "{{ search_query }}"
<a href="?{% if selected_status %}status={{ selected_status }}{% endif %}{% if request.GET.assigned_to %}&assigned_to={{ request.GET.assigned_to }}{% endif %}"
class="ml-1 text-green-600 hover:text-green-800">×</a>
</span>
{% endif %}
{% if selected_course %}
<span class="px-2 py-1 bg-green-100 text-green-800 text-sm rounded">
Kurs:
{% for course in courses %}
{% if course.id|stringformat:'s' == selected_course %}{{ course.code }}{% endif %}
{% endfor %}
<a href="?{% if selected_status %}status={{ selected_status }}{% endif %}{% if search_query %}&q={{ search_query }}{% endif %}{% if request.GET.assigned_to %}&assigned_to={{ request.GET.assigned_to }}{% endif %}"
class="ml-1 text-green-600 hover:text-green-800">×</a>
</span>
{% endif %}
<a href="{% url 'ticket-list' %}"
class="text-sm text-gray-600 hover:text-gray-800 font-medium">Alle Filter entfernen</a>
</div>
</div>
{% endif %}
</div>
<!-- Ticket Tabelle -->
{% if tickets %}
<div class="bg-white rounded-lg shadow overflow-hidden">
<table class="w-full">
<thead class="bg-blue-600 text-white">
<tr>
<th class="px-4 py-3 text-center text-sm font-bold">#</th>
<th class="px-4 py-3 text-left text-sm font-bold">Titel</th>
<th class="px-4 py-3 text-center text-sm font-bold">Kurs</th>
<th class="px-4 py-3 text-center text-sm font-bold">Status</th>
<th class="px-4 py-3 text-center text-sm font-bold">Fehlerart</th>
<th class="px-4 py-3 text-left text-sm font-bold">Zugewiesen an</th>
<th class="px-4 py-3 text-center text-sm font-bold">Erstellt</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
{% for ticket in tickets %}
<tr class="hover:bg-gray-50">
<td class="px-4 py-3 text-center text-sm font-bold text-gray-500">#{{ ticket.id }}</td>
<td class="px-4 py-3">
<a href="{% url 'detail' ticket.pk %}"
class="font-bold text-blue-600 hover:text-blue-800 hover:underline block break-words">
{{ ticket.title|truncatechars:30 }}
</a>
</td>
<td class="px-4 py-3 text-center text-sm">
<span class="px-2 py-1 bg-white border border-gray-900 rounded-full text-xs font-bold text-gray-900">
{{ ticket.course.code }}
</span>
</td>
<td class="px-4 py-3 text-center">
{% if ticket.status == 'new' %}
<span class="px-2 py-1 rounded-full text-xs font-bold bg-blue-500 text-white">{{ ticket.get_status_display }}</span>
{% elif ticket.status == 'in_progress' %}
<span class="px-2 py-1 rounded-full text-xs font-bold bg-yellow-400 text-gray-900 whitespace-nowrap">
{{ ticket.get_status_display }}
</span>
{% elif ticket.status == 'resolved' %}
<span class="px-2 py-1 rounded-full text-xs font-bold bg-green-400 text-white">{{ ticket.get_status_display }}</span>
{% elif ticket.status == 'pending_close' %}
<span class="px-2 py-1 rounded-full text-xs font-bold bg-orange-500 text-white">{{ ticket.get_status_display }}</span>
{% elif ticket.status == 'closed' %}
<span class="px-2 py-1 rounded-full text-xs font-bold bg-gray-600 text-white">{{ ticket.get_status_display }}</span>
{% endif %}
<td class="px-4 py-3 text-center">
<span class="px-2 py-1 rounded-full text-xs font-bold whitespace-nowrap {% if ticket.mistake == 'typo' %}bg-blue-500 {% elif ticket.mistake == 'formatting_issue' %}bg-purple-500 {% elif ticket.mistake == 'missing_content' %}bg-red-500 {% elif ticket.mistake == 'outdated_content' %}bg-orange-500 {% elif ticket.mistake == 'audio_problem' %}bg-green-500 {% elif ticket.mistake == 'video_problem' %}bg-yellow-500 {% elif ticket.mistake == 'other' %}bg-gray-500 {% else %}bg-gray-400 {% endif %} text-white">
{{ ticket.get_mistake_display }}
</span>
</td>
<td class="px-4 py-3 text-sm text-gray-600">
{% if ticket.assigned_to %}
{{ ticket.assigned_to.username }}
{% else %}
<span class="text-gray-400 italic">Nicht zugewiesen</span>
{% endif %}
</td>
<td class="px-4 py-3 text-center text-sm text-gray-500">
<div>{{ ticket.created_at|date:"d.m.Y" }}</div>
<div class="text-xs text-gray-400">{{ ticket.created_at|date:"H:i" }}</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<!-- Pagination -->
{% if is_paginated %}
<div class="mt-6 flex justify-between items-center">
<div class="text-sm text-gray-600">Seite {{ page_obj.number }} von {{ page_obj.paginator.num_pages }}</div>
<div class="flex gap-2">
{% if page_obj.has_previous %}
<a href="?page={{ page_obj.previous_page_number }}{% if selected_status %}&status={{ selected_status }}{% endif %}{% if search_query %}&q={{ search_query }}{% endif %}{% if selected_course %}&course={{ selected_course }}{% endif %}"
class="px-3 py-1 border border-gray-300 rounded hover:bg-gray-50">Zurück</a>
{% endif %}
{% if page_obj.has_next %}
<a href="?page={{ page_obj.next_page_number }}{% if selected_status %}&status={{ selected_status }}{% endif %}{% if search_query %}&q={{ search_query }}{% endif %}{% if selected_course %}&course={{ selected_course }}{% endif %}"
class="px-3 py-1 border border-gray-300 rounded hover:bg-gray-50">Weiter</a>
{% endif %}
</div>
</div>
{% endif %}
{% else %}
<!-- Keine Tickets -->
<div class="text-center py-12 bg-white rounded-lg shadow">
<div class="text-gray-400 text-6xl mb-4">📋</div>
{% if search_query %}
<h3 class="text-lg font-medium text-gray-900 mb-2">Keine Tickets gefunden</h3>
<p class="text-gray-500 mb-4">
Keine Tickets gefunden für die Suche „<strong>{{ search_query }}</strong>"
</p>
<a href="?" class="text-blue-600 hover:text-blue-800 font-medium">Alle Tickets anzeigen</a>
{% else %}
<h3 class="text-lg font-medium text-gray-900 mb-2">Noch keine Tickets vorhanden</h3>
<p class="text-gray-500 mb-4">Erstelle dein erstes Ticket um loszulegen.</p>
<a href="{% url 'create' %}"
class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded font-medium">
Erstes Ticket erstellen
</a>
{% endif %}
</div>
{% endif %}
</div>
{% endblock %}