feat: added create ticket site
This commit is contained in:
70
ticketsystem/templates/ticketsystem/detail.html
Normal file
70
ticketsystem/templates/ticketsystem/detail.html
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
{% block content %}
|
||||||
|
<style>
|
||||||
|
.ticket-container {
|
||||||
|
max-width: 700px;
|
||||||
|
margin: 2rem auto;
|
||||||
|
padding: 2rem;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticket-container h1 {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
font-size: 1.8rem;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticket-attribute {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticket-attribute strong {
|
||||||
|
display: inline-block;
|
||||||
|
width: 150px;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticket-meta {
|
||||||
|
margin-top: 2rem;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="ticket-container">
|
||||||
|
<h1>🎫 Ticket #{{ ticket.id }} – {{ ticket.title }}</h1>
|
||||||
|
|
||||||
|
<div class="ticket-attribute">
|
||||||
|
<strong>Status:</strong> {{ ticket.get_status_display }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ticket-attribute">
|
||||||
|
<strong>Priorität:</strong> {{ ticket.get_priority_display }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ticket-attribute">
|
||||||
|
<strong>Beschreibung:</strong><br>
|
||||||
|
<div style="margin-top: 0.5rem;">{{ ticket.description }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ticket-attribute">
|
||||||
|
<strong>Erstellt von:</strong> {{ ticket.created_by.username }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ticket-attribute">
|
||||||
|
<strong>Bearbeitet von:</strong>
|
||||||
|
{% if ticket.assigned_to %}
|
||||||
|
{{ ticket.assigned_to.username }}
|
||||||
|
{% else %}
|
||||||
|
<em>Niemand zugewiesen</em>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ticket-meta">
|
||||||
|
🕒 Erstellt am: {{ ticket.created_at|date:"d.m.Y H:i" }}<br>
|
||||||
|
🔄 Aktualisiert: {{ ticket.updated_at|date:"d.m.Y H:i" }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
77
ticketsystem/templates/ticketsystem/index.html
Normal file
77
ticketsystem/templates/ticketsystem/index.html
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
{% block content %}
|
||||||
|
<style>
|
||||||
|
.ticket-list-container {
|
||||||
|
max-width: 700px;
|
||||||
|
margin: 2rem auto;
|
||||||
|
padding: 2rem;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 8px;
|
||||||
|
background-color: #fafafa;
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticket-list-container h1 {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
font-size: 1.8rem;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticket-item {
|
||||||
|
padding: 1rem;
|
||||||
|
border-bottom: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticket-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticket-item a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #007bff;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticket-item a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ticket-meta {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: #666;
|
||||||
|
margin-top: 0.3rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="ticket-list-container">
|
||||||
|
<h1>🎫 Alle Tickets</h1>
|
||||||
|
|
||||||
|
<p style="text-align: right;">
|
||||||
|
<a href="{% url 'create' %}" style="text-decoration: none; font-weight: bold;">➕ Neues Ticket</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<form method="get" style="margin-bottom: 1rem;">
|
||||||
|
<label for="status">🔍 Filtern nach Status:</label>
|
||||||
|
<select name="status" id="status" onchange="this.form.submit()">
|
||||||
|
<option value="">Alle</option>
|
||||||
|
<option value="open" {% if selected_status == "open" %}selected{% endif %}>Offen</option>
|
||||||
|
<option value="in_progress" {% if selected_status == "in_progress" %}selected{% endif %}>In Bearbeitung</option>
|
||||||
|
<option value="closed" {% if selected_status == "closed" %}selected{% endif %}>Erledigt</option>
|
||||||
|
</select>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{% for ticket in tickets %}
|
||||||
|
<div class="ticket-item">
|
||||||
|
<a href="{% url 'detail' ticket.pk %}">
|
||||||
|
#{{ ticket.id }} – {{ ticket.title }}
|
||||||
|
</a>
|
||||||
|
<div class="ticket-meta">
|
||||||
|
Status: {{ ticket.get_status_display }} |
|
||||||
|
Priorität: {{ ticket.get_priority_display }} |
|
||||||
|
Angelegt am {{ ticket.created_at|date:"d.m.Y H:i" }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% empty %}
|
||||||
|
<p>Es sind derzeit keine Tickets vorhanden.</p>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
57
ticketsystem/templates/ticketsystem/ticket_form.html
Normal file
57
ticketsystem/templates/ticketsystem/ticket_form.html
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
{% block content %}
|
||||||
|
<style>
|
||||||
|
.form-container {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 2rem auto;
|
||||||
|
padding: 2rem;
|
||||||
|
background: #f9f9f9;
|
||||||
|
border-radius: 8px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-container h1 {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-container form {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-container label {
|
||||||
|
margin-top: 1rem;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-container input, .form-container select, .form-container textarea {
|
||||||
|
padding: 0.5rem;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
margin-top: 0.3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-container button {
|
||||||
|
margin-top: 2rem;
|
||||||
|
padding: 0.7rem;
|
||||||
|
background-color: #007bff;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-container button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="form-container">
|
||||||
|
<h1>🎫 Neues Ticket erstellen</h1>
|
||||||
|
<form method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form.as_p }}
|
||||||
|
<button type="submit">Erstellen</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@@ -1,10 +1,13 @@
|
|||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
|
from .views import TicketListView, TicketCreateView
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
# /ticketsystem/
|
# /ticketsystem/
|
||||||
path("", views.index, name="index"),
|
path("", TicketListView.as_view(), name="index"),
|
||||||
# /ticketsystem/detail/
|
# /ticketsystem/detail/
|
||||||
path("<int:ticket_id>/", views.detail, name="detail"),
|
path("<int:ticket_id>/", views.detail, name="detail"),
|
||||||
|
# /ticketsystem/new/
|
||||||
|
path("new/", TicketCreateView.as_view(), name="create"),
|
||||||
]
|
]
|
||||||
@@ -1,12 +1,44 @@
|
|||||||
from django.http import HttpResponse
|
from django.shortcuts import get_object_or_404, render
|
||||||
|
from django.views.generic import ListView
|
||||||
|
from django.views.generic.edit import CreateView
|
||||||
|
from django.urls import reverse_lazy
|
||||||
|
|
||||||
from .models import Ticket
|
from .models import Ticket
|
||||||
|
|
||||||
|
|
||||||
def index(request):
|
class TicketListView(ListView):
|
||||||
latest_ticket_list = Ticket.objects.order_by("-created_at")[:5]
|
model = Ticket
|
||||||
output = ", ".join([t.title for t in latest_ticket_list])
|
template_name = "ticketsystem/index.html"
|
||||||
return HttpResponse(output)
|
context_object_name = "tickets"
|
||||||
|
ordering = ["-created_at"] # neueste zuerst
|
||||||
|
paginate_by = 10 # optional: Pagination (10 Tickets pro Seite)
|
||||||
|
|
||||||
|
def get_queryset(self):
|
||||||
|
queryset = super().get_queryset()
|
||||||
|
status = self.request.GET.get("status")
|
||||||
|
|
||||||
|
if status:
|
||||||
|
queryset = queryset.filter(status=status)
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context["selected_status"] = self.request.GET.get("status", "")
|
||||||
|
return context
|
||||||
|
|
||||||
|
|
||||||
def detail(request, ticket_id):
|
def detail(request, ticket_id):
|
||||||
return HttpResponse("You're looking at Ticket %s." % ticket_id)
|
ticket = get_object_or_404(Ticket, pk=ticket_id)
|
||||||
|
return render(request, "ticketsystem/detail.html", {"ticket": ticket})
|
||||||
|
|
||||||
|
|
||||||
|
class TicketCreateView(CreateView):
|
||||||
|
model = Ticket
|
||||||
|
fields = ["title", "description", "priority", "assigned_to"] # user & status setzen wir automatisch
|
||||||
|
template_name = "ticketsystem/ticket_form.html"
|
||||||
|
success_url = reverse_lazy("index")
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
form.instance.created_by = self.request.user # Der angemeldete User wird automatisch gesetzt
|
||||||
|
form.instance.status = "open" # Neues Ticket beginnt immer als "offen"
|
||||||
|
return super().form_valid(form)
|
||||||
|
|||||||
Reference in New Issue
Block a user