feat: added comment function and new home page
This commit is contained in:
@@ -26,3 +26,12 @@ class Ticket(models.Model):
|
|||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"[{self.get_priority_display()}] {self.title} ({self.get_status_display()})"
|
return f"[{self.get_priority_display()}] {self.title} ({self.get_status_display()})"
|
||||||
|
|
||||||
|
class Comment(models.Model):
|
||||||
|
ticket = models.ForeignKey("Ticket", on_delete=models.CASCADE, related_name="comments")
|
||||||
|
author = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||||
|
text = models.TextField()
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"Kommentar von {self.author} zu Ticket #{self.ticket.id}"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{% block content %}
|
{% block content %}
|
||||||
<style>
|
<style>
|
||||||
.ticket-container {
|
.ticket-container {
|
||||||
max-width: 700px;
|
max-width: 700px;
|
||||||
margin: 2rem auto;
|
margin: 2rem auto;
|
||||||
@@ -31,44 +31,93 @@
|
|||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
</style>
|
|
||||||
|
|
||||||
<div class="ticket-container">
|
.comment {
|
||||||
|
margin: 1rem 0;
|
||||||
|
padding: 1rem;
|
||||||
|
border-left: 4px solid #007bff;
|
||||||
|
background: #f0f4ff;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-form textarea {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.5rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comment-form button {
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
background: #007bff;
|
||||||
|
color: white;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="ticket-container">
|
||||||
<h1>🎫 Ticket #{{ ticket.id }} – {{ ticket.title }}</h1>
|
<h1>🎫 Ticket #{{ ticket.id }} – {{ ticket.title }}</h1>
|
||||||
|
|
||||||
<p style="text-align: right;">
|
<p style="text-align: right;">
|
||||||
<a href="{% url 'modify' ticket.pk %}" style="text-decoration: none; font-weight: bold;">✏️ Dieses Ticket bearbeiten</a>
|
<a href="{% url 'modify' ticket.pk %}" style="text-decoration: none; font-weight: bold;">✏️ Dieses Ticket
|
||||||
|
bearbeiten</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="ticket-attribute">
|
<div class="ticket-attribute">
|
||||||
<strong>Status:</strong> {{ ticket.get_status_display }}
|
<strong>Status:</strong> {{ ticket.get_status_display }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ticket-attribute">
|
<div class="ticket-attribute">
|
||||||
<strong>Priorität:</strong> {{ ticket.get_priority_display }}
|
<strong>Priorität:</strong> {{ ticket.get_priority_display }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ticket-attribute">
|
<div class="ticket-attribute">
|
||||||
<strong>Beschreibung:</strong><br>
|
<strong>Beschreibung:</strong><br>
|
||||||
<div style="margin-top: 0.5rem;">{{ ticket.description }}</div>
|
<div style="margin-top: 0.5rem;">{{ ticket.description }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ticket-attribute">
|
<div class="ticket-attribute">
|
||||||
<strong>Erstellt von:</strong> {{ ticket.created_by.username }}
|
<strong>Erstellt von:</strong> {{ ticket.created_by.username }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ticket-attribute">
|
<div class="ticket-attribute">
|
||||||
<strong>Bearbeitet von:</strong>
|
<strong>Zugewiesen an:</strong>
|
||||||
{% if ticket.assigned_to %}
|
{% if ticket.assigned_to %}
|
||||||
{{ ticket.assigned_to.username }}
|
{{ ticket.assigned_to.username }}
|
||||||
{% else %}
|
{% else %}
|
||||||
<em>Niemand zugewiesen</em>
|
<em>Niemand zugewiesen</em>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="ticket-meta">
|
<div class="ticket-meta">
|
||||||
🕒 Erstellt am: {{ ticket.created_at|date:"d.m.Y H:i" }}<br>
|
🕒 Erstellt am: {{ ticket.created_at|date:"d.m.Y H:i" }}<br>
|
||||||
🔄 Aktualisiert: {{ ticket.updated_at|date:"d.m.Y H:i" }}
|
🔄 Aktualisiert: {{ ticket.updated_at|date:"d.m.Y H:i" }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="ticket-container" style="margin-top: 2rem;">
|
||||||
|
<h2>💬 Kommentare</h2>
|
||||||
|
|
||||||
|
{% if ticket.comments.exists %}
|
||||||
|
{% for comment in ticket.comments.all %}
|
||||||
|
<div class="comment">
|
||||||
|
<p><strong>{{ comment.author.username }}</strong> am {{ comment.created_at|date:"d.m.Y H:i" }}</p>
|
||||||
|
<p>{{ comment.text }}</p>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% else %}
|
||||||
|
<p>Keine Kommentare vorhanden.</p>
|
||||||
|
{% endif %}
|
||||||
|
{% if user.is_authenticated %}
|
||||||
|
<h3>📝 Neuen Kommentar schreiben</h3>
|
||||||
|
<form method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form.as_p }}
|
||||||
|
<button type="submit">Absenden</button>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
44
ticketsystem/templates/ticketsystem/home.html
Normal file
44
ticketsystem/templates/ticketsystem/home.html
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
{% block content %}
|
||||||
|
<style>
|
||||||
|
.home-container {
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 3rem auto;
|
||||||
|
text-align: center;
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
.home-container h1 {
|
||||||
|
font-size: 2rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
.actions {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 1rem;
|
||||||
|
margin-top: 2rem;
|
||||||
|
}
|
||||||
|
.actions a {
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
background: #007bff;
|
||||||
|
color: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight: bold;
|
||||||
|
transition: background 0.2s ease;
|
||||||
|
}
|
||||||
|
.actions a:hover {
|
||||||
|
background: #0056b3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="home-container">
|
||||||
|
<h1>Willkommen im Korrekturmanagementsystem 🎫</h1>
|
||||||
|
<p>Was möchten Sie tun?</p>
|
||||||
|
|
||||||
|
<div class="actions">
|
||||||
|
<a href="{% url 'ticket-list' %}">📄 Alle Tickets anzeigen</a>
|
||||||
|
<a href="{% url 'create' %}">➕ Neues Ticket erstellen</a>
|
||||||
|
<a href="{% url 'ticket-list' %}?status=open">📂 Offene Tickets</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@@ -1,13 +1,15 @@
|
|||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
from . import views
|
from . import views
|
||||||
from .views import TicketListView, TicketCreateView, TicketUpdateView
|
from .views import TicketListView, TicketCreateView, TicketUpdateView, HomeView, TicketDetailView
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
# /ticketsystem/
|
# /ticketsystem/
|
||||||
path("", TicketListView.as_view(), name="index"),
|
path("", HomeView.as_view(), name="home"),
|
||||||
|
# /ticketsystem/tickets
|
||||||
|
path("tickets", TicketListView.as_view(), name="ticket-list"),
|
||||||
# /ticketsystem/detail/
|
# /ticketsystem/detail/
|
||||||
path("<int:pk>/", views.detail, name="detail"),
|
path("<int:pk>/", TicketDetailView.as_view(), name="detail"),
|
||||||
# /ticketsystem/new/
|
# /ticketsystem/new/
|
||||||
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"),
|
||||||
|
|||||||
@@ -1,11 +1,19 @@
|
|||||||
from django.shortcuts import get_object_or_404, render
|
from django.shortcuts import get_object_or_404, render
|
||||||
from django.views.generic import ListView
|
from django.views.generic import ListView, TemplateView
|
||||||
from django.views.generic.edit import CreateView, UpdateView
|
from django.views.generic.edit import CreateView, UpdateView
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
|
from django.views.generic.detail import DetailView
|
||||||
|
from django.views.generic.edit import FormMixin
|
||||||
|
from .forms import CommentForm
|
||||||
|
from django.urls import reverse
|
||||||
|
|
||||||
from .models import Ticket
|
from .models import Ticket
|
||||||
|
|
||||||
|
|
||||||
|
class HomeView(TemplateView):
|
||||||
|
template_name = "ticketsystem/home.html"
|
||||||
|
|
||||||
|
|
||||||
class TicketListView(ListView):
|
class TicketListView(ListView):
|
||||||
model = Ticket
|
model = Ticket
|
||||||
template_name = "ticketsystem/index.html"
|
template_name = "ticketsystem/index.html"
|
||||||
@@ -27,10 +35,30 @@ class TicketListView(ListView):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
def detail(request, pk):
|
class TicketDetailView(FormMixin, DetailView):
|
||||||
ticket = get_object_or_404(Ticket, pk=pk)
|
model = Ticket # <- das ist wichtig!
|
||||||
return render(request, "ticketsystem/detail.html", {"ticket": ticket})
|
template_name = "ticketsystem/detail.html"
|
||||||
|
context_object_name = "ticket"
|
||||||
|
form_class = CommentForm
|
||||||
|
|
||||||
|
def get_success_url(self):
|
||||||
|
return reverse("detail", kwargs={"pk": self.object.pk})
|
||||||
|
|
||||||
|
def post(self, request, *args, **kwargs):
|
||||||
|
self.object = self.get_object()
|
||||||
|
form = self.get_form()
|
||||||
|
if form.is_valid():
|
||||||
|
comment = form.save(commit=False)
|
||||||
|
comment.ticket = self.object
|
||||||
|
comment.author = request.user
|
||||||
|
comment.save()
|
||||||
|
return super().form_valid(form)
|
||||||
|
return self.form_invalid(form)
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs):
|
||||||
|
context = super().get_context_data(**kwargs)
|
||||||
|
context["form"] = self.get_form()
|
||||||
|
return context
|
||||||
|
|
||||||
class TicketCreateView(CreateView):
|
class TicketCreateView(CreateView):
|
||||||
model = Ticket
|
model = Ticket
|
||||||
|
|||||||
Reference in New Issue
Block a user