feat: new CreateView with new HTML/CSS
This commit is contained in:
@@ -56,7 +56,6 @@
|
||||
<option value="low" {% if ticket.priority == 'low' %}selected{% endif %}>Niedrig</option>
|
||||
<option value="medium" {% if ticket.priority == 'medium' %}selected{% endif %}>Normal</option>
|
||||
<option value="high" {% if ticket.priority == 'high' %}selected{% endif %}>Hoch</option>
|
||||
<option value="urgent" {% if ticket.priority == 'urgent' %}selected{% endif %}>Dringend</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,70 +1,127 @@
|
||||
{% extends "ticketsystem/base.html" %}
|
||||
{% 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>
|
||||
{% if object.pk %}
|
||||
✏️ Ticket bearbeiten
|
||||
{% else %}
|
||||
🎫 Neues Ticket erstellen
|
||||
{% endif %}
|
||||
</h1>
|
||||
<form method="post">
|
||||
{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<button type="submit">
|
||||
{% if object.pk %}
|
||||
Speichern
|
||||
{% else %}
|
||||
Erstellen
|
||||
{% endif %}
|
||||
</button>
|
||||
</form>
|
||||
<!-- Messages -->
|
||||
{% if messages %}
|
||||
<div class="max-w-4xl 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-4xl mx-auto px-4 py-6">
|
||||
<!-- Ticket Erstellen -->
|
||||
<div class="bg-white rounded-lg shadow p-6">
|
||||
<h1 class="text-3xl font-bold mb-4">➕ Neues Ticket erstellen</h1>
|
||||
|
||||
<div class="text-sm text-gray-500 mb-6">
|
||||
Fülle die Felder aus um ein neues Ticket zu erstellen
|
||||
</div>
|
||||
|
||||
<form method="post" class="space-y-4">
|
||||
{% csrf_token %}
|
||||
|
||||
<!-- Form Errors -->
|
||||
{% if form.non_field_errors %}
|
||||
<div class="bg-red-100 border border-red-200 rounded p-3">
|
||||
{{ form.non_field_errors }}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Titel -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium mb-1">Titel: *</label>
|
||||
<input type="text" name="title" value="{{ form.title.value|default:'' }}"
|
||||
required
|
||||
class="w-full p-2 border border-gray-300 rounded shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
||||
placeholder="Kurze Beschreibung des Problems">
|
||||
{% if form.title.errors %}
|
||||
<div class="text-red-600 text-sm mt-1">{{ form.title.errors }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Beschreibung -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium mb-1">Beschreibung: *</label>
|
||||
<textarea name="description" rows="6"
|
||||
required
|
||||
class="w-full p-2 border border-gray-300 rounded shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
|
||||
placeholder="Detaillierte Beschreibung des Problems oder der Anfrage">{{ form.description.value|default:'' }}</textarea>
|
||||
{% if form.description.errors %}
|
||||
<div class="text-red-600 text-sm mt-1">{{ form.description.errors }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Status und Priorität -->
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<label class="block text-sm font-medium mb-1">Status:</label>
|
||||
<select name="status"
|
||||
disabled
|
||||
class="w-full p-2 border border-gray-300 bg-gray-300 rounded shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
||||
<option value="open" {% if form.status.value == 'open' or not form.status.value %}selected{% endif %}>Offen</option>
|
||||
</select>
|
||||
<input type="hidden" name="status" value="open">
|
||||
{% if form.status.errors %}
|
||||
<div class="text-red-600 text-sm mt-1">{{ form.status.errors }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div>
|
||||
<label class="block text-sm font-medium mb-1">Priorität:</label>
|
||||
<select name="priority"
|
||||
class="w-full p-2 border border-gray-300 rounded shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
||||
<option value="low" {% if form.priority.value == 'low' %}selected{% endif %}>Niedrig</option>
|
||||
<option value="medium" {% if form.priority.value == 'medium' or not form.priority.value %}selected{% endif %}>Normal</option>
|
||||
<option value="high" {% if form.priority.value == 'high' %}selected{% endif %}>Hoch</option>
|
||||
</select>
|
||||
{% if form.priority.errors %}
|
||||
<div class="text-red-600 text-sm mt-1">{{ form.priority.errors }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Zugewiesen an -->
|
||||
<div>
|
||||
<label class="block text-sm font-medium mb-1">Zugewiesen an:</label>
|
||||
<select name="assigned_to"
|
||||
class="w-full p-2 border border-gray-300 rounded shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
||||
<option value="">Nicht zugewiesen</option>
|
||||
{% for user in form.assigned_to.field.queryset %}
|
||||
<option value="{{ user.pk }}" {% if form.assigned_to.value == user.pk %}selected{% endif %}>
|
||||
{{ user.username }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% if form.assigned_to.errors %}
|
||||
<div class="text-red-600 text-sm mt-1">{{ form.assigned_to.errors }}</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<!-- Buttons -->
|
||||
<div class="flex gap-4 pt-4">
|
||||
<button type="submit"
|
||||
class="bg-green-500 hover:bg-green-600 text-white px-6 py-2 rounded font-medium">
|
||||
✅ Ticket erstellen
|
||||
</button>
|
||||
<a href="{% url 'ticket-list' %}"
|
||||
class="bg-gray-500 hover:bg-gray-600 text-white px-6 py-2 rounded font-medium">
|
||||
❌ Abbrechen
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Hilfe Text -->
|
||||
<div class="mt-8 p-4 bg-blue-50 rounded border-l-4 border-blue-400">
|
||||
<h3 class="font-medium text-blue-900 mb-2">💡 Tipps:</h3>
|
||||
<ul class="text-sm text-blue-800 space-y-1">
|
||||
<li>• Verwende einen <strong>aussagekräftigen Titel</strong></li>
|
||||
<li>• Beschreibe das Problem so <strong>detailliert wie möglich</strong></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@@ -137,6 +137,7 @@ class TicketDetailUpdateView(UpdateView):
|
||||
return redirect(self.get_success_url())
|
||||
return super().post(request, *args, **kwargs)
|
||||
|
||||
|
||||
class AssignedTicketListView(LoginRequiredMixin, ListView):
|
||||
model = Ticket
|
||||
template_name = "ticketsystem/assigned_tickets.html"
|
||||
@@ -151,22 +152,17 @@ class AssignedTicketListView(LoginRequiredMixin, ListView):
|
||||
|
||||
class TicketCreateView(CreateView):
|
||||
model = Ticket
|
||||
fields = [
|
||||
"title",
|
||||
"description",
|
||||
"priority",
|
||||
"assigned_to",
|
||||
] # user & status wird automatisch gesetzt
|
||||
fields = ["title", "description", "status", "priority", "assigned_to"]
|
||||
template_name = "ticketsystem/ticket_form.html"
|
||||
success_url = reverse_lazy("ticket-list")
|
||||
|
||||
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"
|
||||
form.instance.created_by = self.request.user
|
||||
form.instance.status = 'open'
|
||||
return super().form_valid(form)
|
||||
|
||||
def get_success_url(self):
|
||||
return reverse('detail', kwargs={'pk': self.object.pk})
|
||||
|
||||
|
||||
class TicketUpdateView(LoginRequiredMixin, UpdateView):
|
||||
model = Ticket
|
||||
|
||||
Reference in New Issue
Block a user