feat: added some responsiveness
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>
|
||||
{% block title %}TicketSystem{% endblock %}
|
||||
</title>
|
||||
@@ -10,26 +11,61 @@
|
||||
</head>
|
||||
<body class="bg-gray-100">
|
||||
<nav class="bg-gray-700 text-white py-4">
|
||||
<div class="max-w-4xl mx-auto flex justify-between items-center px-4">
|
||||
<div class="flex space-x-4">
|
||||
<a href="{% url 'home' %}" class="text-white hover:text-gray-300">🏠 Start</a>
|
||||
<a href="{% url 'ticket-list' %}" class="text-white hover:text-gray-300">📋 Tickets</a>
|
||||
<a href="{% url 'faq-list' %}" class="text-white hover:text-gray-300">❓ FAQ</a>
|
||||
<div class="max-w-6xl mx-auto px-4">
|
||||
<!-- Mobile Header -->
|
||||
<div class="flex justify-between items-center md:hidden">
|
||||
<h1 class="text-lg font-semibold">🎫 TicketSystem</h1>
|
||||
<button id="mobile-menu-btn" class="text-2xl">☰</button>
|
||||
</div>
|
||||
<div class="flex items-center space-x-4">
|
||||
|
||||
<!-- Desktop Menu -->
|
||||
<div class="hidden md:flex md:justify-between md:items-center">
|
||||
<div class="flex space-x-6">
|
||||
<a href="{% url 'home' %}" class="text-white hover:text-gray-300">🏠 Start</a>
|
||||
<a href="{% url 'ticket-list' %}" class="text-white hover:text-gray-300">📋 Tickets</a>
|
||||
<a href="{% url 'faq-list' %}" class="text-white hover:text-gray-300">❓ FAQ</a>
|
||||
</div>
|
||||
{% if user.is_authenticated %}
|
||||
<span class="text-white">👤 {{ user.username }}</span>
|
||||
<form method="post" action="{% url 'logout' %}" class="inline">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="text-white hover:text-gray-300">🚪 Logout</button>
|
||||
</form>
|
||||
<div class="flex items-center space-x-4">
|
||||
<span>👤 {{ user.username }}</span>
|
||||
<form method="post" action="{% url 'logout' %}" class="inline">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="text-white hover:text-gray-300">🚪 Logout</button>
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Mobile Menu -->
|
||||
<div id="mobile-menu" class="hidden mt-4">
|
||||
<a href="{% url 'home' %}" class="block text-white py-2">🏠 Start</a>
|
||||
<a href="{% url 'ticket-list' %}" class="block text-white py-2">📋 Tickets</a>
|
||||
<a href="{% url 'faq-list' %}" class="block text-white py-2">❓ FAQ</a>
|
||||
{% if user.is_authenticated %}
|
||||
<div class="border-t border-gray-600 pt-3 mt-3">
|
||||
<span class="block text-white py-1">👤 {{ user.username }}</span>
|
||||
<form method="post" action="{% url 'logout' %}">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="text-white py-2">🚪 Logout</button>
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Global Container -->
|
||||
<div class="max-w-5xl mx-auto mt-8 px-4">
|
||||
<div class="max-w-6xl mx-auto mt-8 px-4">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
|
||||
<!-- Mobile Menu Script -->
|
||||
<script>
|
||||
const menuBtn = document.getElementById('mobile-menu-btn');
|
||||
const menu = document.getElementById('mobile-menu');
|
||||
if (menuBtn && menu) {
|
||||
menuBtn.onclick = () => menu.classList.toggle('hidden');
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
@@ -1,7 +1,6 @@
|
||||
{% extends "ticketsystem/base.html" %}
|
||||
{% load static %}
|
||||
{% block content %}
|
||||
<div class="max-w-6xl mx-auto px-4 py-6">
|
||||
<!-- Header -->
|
||||
<div class="bg-white rounded-lg shadow p-6 mb-6">
|
||||
<div class="flex justify-between items-center">
|
||||
@@ -47,7 +46,6 @@
|
||||
<p class="text-gray-500">Noch keine FAQs vorhanden.</p>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<!-- FAQ JavaScript -->
|
||||
<script src="{% static 'js/faq.js' %}"></script>
|
||||
|
||||
@@ -2,167 +2,168 @@
|
||||
{% block content %}
|
||||
<!-- Messages -->
|
||||
{% if messages %}
|
||||
<div class="max-w-6xl mx-auto px-4 pt-4">
|
||||
<div class="mb-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 %}">
|
||||
<div class="mb-2 p-3 rounded text-sm {% 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">
|
||||
<!-- Header -->
|
||||
<div class="flex flex-col sm:flex-row sm:justify-between sm:items-center mb-6">
|
||||
<div>
|
||||
<h1 class="text-2xl sm: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 block text-center sm:inline-block">
|
||||
➕ 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>
|
||||
<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>
|
||||
<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 %}
|
||||
</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 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 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 %}
|
||||
{% 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>
|
||||
<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>
|
||||
<!-- 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">
|
||||
{% endif %}
|
||||
</div>
|
||||
<!-- Ticket Tabelle -->
|
||||
{% if tickets %}
|
||||
<!-- Desktop -->
|
||||
<div class="hidden lg:block bg-white rounded-lg shadow overflow-hidden">
|
||||
<div class="overflow-x-auto">
|
||||
<table class="w-full">
|
||||
<thead class="bg-blue-600 text-white">
|
||||
<tr>
|
||||
@@ -204,62 +205,100 @@
|
||||
{% 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>
|
||||
</td>
|
||||
<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>
|
||||
</div>
|
||||
<!-- Mobile -->
|
||||
<div class="lg:hidden space-y-4">
|
||||
{% for ticket in tickets %}
|
||||
<div class="bg-white rounded-lg shadow p-4">
|
||||
<div class="flex justify-between items-start mb-2">
|
||||
<span class="text-sm font-bold text-gray-500">#{{ ticket.id }}</span>
|
||||
<span class="text-xs text-gray-500">{{ ticket.created_at|date:"d.m.Y" }}</span>
|
||||
</div>
|
||||
<a href="{% url 'detail' ticket.pk %}"
|
||||
class="font-bold text-blue-600 hover:text-blue-800 block mb-2">{{ ticket.title|truncatechars:30 }}</a>
|
||||
<div class="space-y-2">
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-sm text-gray-600">Status:</span>
|
||||
{% 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">{{ 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 == 'closed' %}
|
||||
<span class="px-2 py-1 rounded-full text-xs font-bold bg-gray-600 text-white">{{ ticket.get_status_display }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-sm text-gray-600">Kurs:</span>
|
||||
<span class="text-sm font-medium">{{ ticket.course.code }}</span>
|
||||
</div>
|
||||
{% if ticket.assigned_to %}
|
||||
<div class="flex justify-between items-center">
|
||||
<span class="text-sm text-gray-600">Zugewiesen:</span>
|
||||
<span class="text-sm">{{ ticket.assigned_to.username }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
</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>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</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>
|
||||
{% endblock %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user