feat: added faqs

This commit is contained in:
2025-05-30 00:04:35 +02:00
parent c77c966e0e
commit 51bf409e3c
6 changed files with 123 additions and 5 deletions

View File

@@ -1,6 +1,7 @@
from django.contrib import admin from django.contrib import admin
from .models import Ticket, Course from .models import Ticket, Course, FAQ
admin.site.register(Ticket) admin.site.register(Ticket)
admin.site.register(Course) admin.site.register(Course)
admin.site.register(FAQ)

View File

@@ -95,3 +95,19 @@ class TicketHistory(models.Model):
class Meta: class Meta:
ordering = ["-changed_at"] ordering = ["-changed_at"]
class FAQ(models.Model):
"""Einfaches FAQ Model"""
question = models.CharField(max_length=300, verbose_name="Frage")
answer = models.TextField(verbose_name="Antwort")
order = models.IntegerField(default=0, verbose_name="Reihenfolge")
is_active = models.BooleanField(default=True, verbose_name="Aktiv")
class Meta:
ordering = ['order', 'question']
verbose_name = "FAQ"
verbose_name_plural = "FAQs"
def __str__(self):
return self.question

View File

@@ -16,6 +16,7 @@
<a href="{% url 'ticket-list' %}" class="text-white hover:text-gray-300">📋 Tickets</a> <a href="{% url 'ticket-list' %}" class="text-white hover:text-gray-300">📋 Tickets</a>
<a href="{% url 'assigned-tickets' %}" <a href="{% url 'assigned-tickets' %}"
class="text-white hover:text-gray-300">🧾 Meine Tickets</a> class="text-white hover:text-gray-300">🧾 Meine Tickets</a>
<a href="{% url 'faq-list' %}" class="text-white hover:text-gray-300">❓ FAQ</a>
</div> </div>
<div class="flex items-center space-x-4"> <div class="flex items-center space-x-4">
{% if user.is_authenticated %} {% if user.is_authenticated %}
@@ -30,8 +31,7 @@
</nav> </nav>
<!-- Global Container --> <!-- Global Container -->
<div class="max-w-4xl mx-auto mt-8 px-4"> <div class="max-w-4xl mx-auto mt-8 px-4">
{% block content %} {% block content %}{% endblock %}
{% endblock %}
</div> </div>
</body> </body>
</html> </html>

View File

@@ -0,0 +1,24 @@
{% extends "ticketsystem/base.html" %}
{% block content %}
<div class="max-w-4xl 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">
<h1 class="text-3xl font-bold">❓ Häufig gestellte Fragen</h1>
<a href="{% url 'faq-pdf-download' %}"
class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded">📄 PDF Download</a>
</div>
</div>
<!-- FAQ Liste -->
{% for faq in faqs %}
<div class="bg-white rounded-lg shadow p-6 mb-4">
<h3 class="font-bold text-lg mb-2">{{ forloop.counter }}. {{ faq.question }}</h3>
<div class="text-gray-700">{{ faq.answer|linebreaks }}</div>
</div>
{% empty %}
<div class="bg-white rounded-lg shadow p-8 text-center">
<p class="text-gray-500">Noch keine FAQs vorhanden.</p>
</div>
{% endfor %}
</div>
{% endblock %}

View File

@@ -7,6 +7,8 @@ from .views import (
HomeView, HomeView,
AssignedTicketListView, AssignedTicketListView,
TicketDetailUpdateView, TicketDetailUpdateView,
faq_list,
faq_pdf_download
) )
urlpatterns = [ urlpatterns = [
@@ -20,4 +22,6 @@ urlpatterns = [
path("new/", TicketCreateView.as_view(), name="create"), path("new/", TicketCreateView.as_view(), name="create"),
path("<int:pk>/modify/", TicketUpdateView.as_view(), name="modify"), path("<int:pk>/modify/", TicketUpdateView.as_view(), name="modify"),
path("meine-tickets/", AssignedTicketListView.as_view(), name="assigned-tickets"), path("meine-tickets/", AssignedTicketListView.as_view(), name="assigned-tickets"),
path('faq/', faq_list, name='faq-list'),
path('faq/download/', faq_pdf_download, name='faq-pdf-download'),
] ]

View File

@@ -7,10 +7,16 @@ from .forms import CommentForm, TicketForm
from django.urls import reverse from django.urls import reverse
from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib import messages from django.contrib import messages
from django.shortcuts import redirect from django.shortcuts import redirect, render
from django.db.models import Q from django.db.models import Q
from django.http import HttpResponse
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
from reportlab.lib.enums import TA_LEFT, TA_CENTER
from .models import Ticket, TicketHistory from .models import Ticket, TicketHistory, FAQ
class HomeView(TemplateView): class HomeView(TemplateView):
@@ -239,3 +245,70 @@ class TicketUpdateView(LoginRequiredMixin, UpdateView):
def get_success_url(self): def get_success_url(self):
return reverse_lazy("detail", kwargs={"pk": self.object.pk}) return reverse_lazy("detail", kwargs={"pk": self.object.pk})
def faq_list(request):
"""Zeigt alle aktiven FAQs an"""
faqs = FAQ.objects.filter(is_active=True)
return render(request, 'ticketsystem/faq.html', {'faqs': faqs})
def faq_pdf_download(request):
"""Generiert PDF mit allen FAQs"""
# Response Setup
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'attachment; filename="FAQ_Ticketsystem.pdf"'
# PDF erstellen
doc = SimpleDocTemplate(response, pagesize=A4, topMargin=2 * cm, bottomMargin=2 * cm)
# Styles
styles = getSampleStyleSheet()
title_style = ParagraphStyle(
'CustomTitle',
parent=styles['Heading1'],
fontSize=24,
textColor='#1a1a1a',
spaceAfter=30,
alignment=TA_CENTER
)
question_style = ParagraphStyle(
'Question',
parent=styles['Heading2'],
fontSize=14,
textColor='#2563eb',
spaceAfter=10
)
answer_style = ParagraphStyle(
'Answer',
parent=styles['Normal'],
fontSize=11,
spaceAfter=20,
alignment=TA_LEFT
)
# Content
elements = []
# Titel
elements.append(Paragraph("Häufig gestellte Fragen (FAQ)", title_style))
elements.append(Spacer(1, 20))
# FAQs holen
faqs = FAQ.objects.filter(is_active=True)
# FAQs hinzufügen
for i, faq in enumerate(faqs, 1):
# Frage
elements.append(Paragraph(f"{i}. {faq.question}", question_style))
# Antwort
elements.append(Paragraph(faq.answer.replace('\n', '<br/>'), answer_style))
# Abstand zwischen FAQs
elements.append(Spacer(1, 10))
# PDF generieren
doc.build(elements)
return response