add rental

This commit is contained in:
2025-02-22 15:24:13 +01:00
parent 1f3fc92f6b
commit 3adc98144f
16 changed files with 748 additions and 0 deletions

View File

@@ -61,6 +61,7 @@ INSTALLED_APPS = [
"gallery.apps.GalleryConfig", "gallery.apps.GalleryConfig",
"intern.apps.InternConfig", "intern.apps.InternConfig",
"finance.apps.FinanceConfig", "finance.apps.FinanceConfig",
"rental.apps.RentalConfig",
] ]

View File

@@ -38,6 +38,7 @@ urlpatterns = [
path("intern/", include("intern.urls")), path("intern/", include("intern.urls")),
path("jobs/", include("blackboard.urls")), path("jobs/", include("blackboard.urls")),
path("posts/", include("posts.urls")), path("posts/", include("posts.urls")),
path("rental/", include("rental.urls")),
path("search/", include("search.urls")), path("search/", include("search.urls")),
path( path(
"discord/", "discord/",

View File

84
fet2020/rental/admin.py Normal file
View File

@@ -0,0 +1,84 @@
from django.contrib import admin
from .forms import RentalAdminForm, RentalItemAdminForm
from .models import Rental, RentalItem
@admin.register(Rental)
class RentalAdmin(admin.ModelAdmin):
form = RentalAdminForm
model = Rental
list_display = [
"id",
"firstname",
"surname",
"status",
"date_start",
"date_end",
]
fieldsets = (
(
"Persönliche Daten",
{
"fields": (
("firstname", "surname"),
("organization", "matriculation_number"),
("email", "phone"),
),
},
),
(
"Verleih",
{
"fields": (
("date_start", "date_end"),
"reason",
"rentalitems",
),
},
),
(
"Sonstiges",
{
"fields": (
"comment",
"status",
),
},
),
)
def add_view(self, request, form_url="", extra_context=None):
extra_context = extra_context or {}
extra_context["help_text"] = "Fette Schriften sind Pflichtfelder."
return super().add_view(request, form_url, extra_context=extra_context)
def change_view(self, request, object_id, form_url="", extra_context=None):
extra_context = extra_context or {}
extra_context["help_text"] = "Fette Schriften sind Pflichtfelder."
return super().change_view(request, object_id, form_url, extra_context=extra_context)
def save_model(self, request, obj, form, change):
obj.author = request.user
super().save_model(request, obj, form, change)
@admin.register(RentalItem)
class RentalItemAdmin(admin.ModelAdmin):
form = RentalItemAdminForm
model = RentalItem
def add_view(self, request, form_url="", extra_context=None):
extra_context = extra_context or {}
extra_context["help_text"] = "Fette Schriften sind Pflichtfelder."
return super().add_view(request, form_url, extra_context=extra_context)
def change_view(self, request, object_id, form_url="", extra_context=None):
extra_context = extra_context or {}
extra_context["help_text"] = "Fette Schriften sind Pflichtfelder."
return super().change_view(request, object_id, form_url, extra_context=extra_context)
def save_model(self, request, obj, form, change):
obj.author = request.user
super().save_model(request, obj, form, change)

12
fet2020/rental/apps.py Normal file
View File

@@ -0,0 +1,12 @@
from django.apps import AppConfig
from django.db.models.signals import post_migrate
from fet2020.utils import create_perms
class RentalConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "rental"
def ready(self):
post_migrate.connect(create_perms, sender=self)

60
fet2020/rental/forms.py Normal file
View File

@@ -0,0 +1,60 @@
from django import forms
from django.forms import DateInput
from .models import Rental, RentalItem
class DateInput(DateInput):
input_type = "date"
class RentalCreateForm(forms.ModelForm):
# Conformation
conformation = forms.BooleanField(
required=True,
label=(
"1. Fachschaft Elektrotechnik (FET) hat stets Vorrecht. 2. Bereits bestätigte Objekte "
"können storniert werden, falls FET sie selber braucht. 3. Sachen dürfen nur über das "
"Verleihsystem verborgt werden. 4. Objekte müssen pünktlich und gereinigt retouniert "
"werden. 5. Verleihpersonen entscheiden über Kaution (lediglich für Pünktlichkeit und "
"Reinheit) 6. Geht was kaputt, muss dies umgehend mitgeteilt werden und finanziell "
"dafür aufgekommen werden. "
),
initial=False,
)
class Meta:
model = Rental
fields = [
"firstname",
"surname",
"matriculation_number",
"email",
"phone",
"organization",
"date_start",
"date_end",
"reason",
"comment",
"rentalitems",
]
widgets = {
"date_start": DateInput(format=("%Y-%m-%d")),
"date_end": DateInput(format=("%Y-%m-%d")),
}
class RentalAdminForm(forms.ModelForm):
class Meta:
model = Rental
fields = "__all__"
widgets = {"rentalitems": forms.CheckboxSelectMultiple()}
class RentalItemAdminForm(forms.ModelForm):
class Meta:
model = RentalItem
fields = "__all__"

71
fet2020/rental/models.py Normal file
View File

@@ -0,0 +1,71 @@
from django.db import models
from django.forms import ValidationError
from .validators import PhoneNumberValidator
class RentalItem(models.Model):
name = models.CharField(verbose_name="Name", max_length=128)
description = models.CharField(
verbose_name="Beschreibung", max_length=128, blank=True, default=""
)
class Meta:
verbose_name = "Verleihgegenstand"
verbose_name_plural = "Verleihgegenstände"
def __str__(self):
return self.name
class Rental(models.Model):
firstname = models.CharField(max_length=128, verbose_name="Vorname")
surname = models.CharField(max_length=128, verbose_name="Nachname")
matriculation_number = models.CharField(verbose_name="Matrikelnummer", max_length=8)
email = models.EmailField(verbose_name="E-Mail")
phone = models.CharField(
verbose_name="Telefonnummer", max_length=32, validators=[PhoneNumberValidator()]
)
organization = models.CharField(verbose_name="Organisation", max_length=128)
date_start = models.DateField(verbose_name="Abholdatum")
date_end = models.DateField(verbose_name="Rückgabedatum")
reason = models.TextField(verbose_name="Grund der Ausleihe", max_length=500)
comment = models.TextField(verbose_name="Kommentar", max_length=500, blank=True, default="")
class Status(models.TextChoices):
SUBMITTED = "S", "Eingereicht"
APPROVED = "A", "Verleih genehmigt"
REJECTED = "J", "Verleih abgelehnt"
ISSUED = "I", "Verleihgegenstände ausgegeben"
RETURNED = "R", "Verleihgegenstände zurückgegeben"
status = models.CharField(
verbose_name="Status",
max_length=1,
choices=Status.choices,
default=Status.SUBMITTED,
)
rentalitems = models.ManyToManyField(
RentalItem,
verbose_name="Verleihgegenstände",
)
class Meta:
verbose_name = "Verleih"
verbose_name_plural = "Verleih"
def __str__(self):
return f"Verleih #{self.id}: {self.firstname} {self.surname}"
def clean(self):
if not self.date_end:
self.date_end = self.date_start
if self.date_start > self.date_end:
raise ValidationError("Das Abholdatum muss vor dem Rückgabedatum liegen.")

3
fet2020/rental/tests.py Normal file
View File

@@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

16
fet2020/rental/urls.py Normal file
View File

@@ -0,0 +1,16 @@
from django.urls import path
from . import apps
from .views import RentalCreateDoneView, RentalCreateView, RentalListView
app_name = apps.RentalConfig.name
urlpatterns = [
path("rental/", RentalListView.as_view(), name="index"),
path("request-rental/", RentalCreateView.as_view(), name="rental_create"),
path(
"request-rental/<int:pk>/done/",
RentalCreateDoneView.as_view(),
name="rental_create_done",
),
]

View File

@@ -0,0 +1,11 @@
from django.core.validators import RegexValidator
from django.utils.deconstruct import deconstructible
@deconstructible
class PhoneNumberValidator(RegexValidator):
regex = r"^\+?1?\d{9,15}$"
message = (
"Telefonnummer muss in diesem Format +999999999999 eingegeben werden. Bis zu 15 Zahlen "
"sind erlaubt."
)

152
fet2020/rental/views.py Normal file
View File

@@ -0,0 +1,152 @@
import calendar
import datetime
from django.db.models import Q
from django.urls import reverse
from django.views.generic import ListView, TemplateView
from django.views.generic.edit import CreateView
from .forms import RentalCreateForm
from .models import Rental, RentalItem
class RentalListView(ListView):
model = Rental
template_name = "rental/calendar.html"
# Month is the month displayed in the calendar (and should be the first day of the month)
month = None
# Rental items to filter
rentalitem_filters = []
def get(self, request, *args, **kwargs):
# Get the rental items from the filter
self.rentalitem_filters = request.GET.getlist("rentalitems", [])
if not self.rentalitem_filters:
for rentalitem in RentalItem.objects.all():
self.rentalitem_filters.append(rentalitem.name)
# Get the displayed month from the request
_date_str = request.GET.get("month", "")
if _date_str:
self.month = (
datetime.datetime.strptime(_date_str, "%Y-%m").replace(tzinfo=datetime.UTC).date()
)
else:
self.month = datetime.datetime.now(tz=datetime.UTC).date().replace(day=1)
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# Calculate the day of the previous month from Monday
days_of_prev_month = []
if self.month.weekday() != calendar.MONDAY:
for i in range(1, 7):
day = self.month + datetime.timedelta(days=-i)
days_of_prev_month.append(day)
if day.weekday() == calendar.MONDAY:
break
# Calculate the days of the next month until Sunday
last_day_of_month = self.month.replace(
day=calendar.monthrange(self.month.year, self.month.month)[1]
)
days_of_next_month = []
if last_day_of_month.weekday() != calendar.SUNDAY:
for i in range(1, 7):
day = last_day_of_month + datetime.timedelta(days=i)
days_of_next_month.append(day)
if day.weekday() == calendar.SUNDAY:
break
# Calculate the days of the displayed month
days_of_month = [
self.month + datetime.timedelta(days=i)
for i in range((last_day_of_month - self.month).days + 1)
]
# Create a dictionary with the rental items for each day
rental_dict = {}
for rental in self.get_queryset():
for day in days_of_month:
if rental["date_start"] <= day and rental["date_end"] >= day:
if day not in rental_dict:
rental_dict[day] = []
if rental["rentalitems__name"] not in rental_dict[day]:
rental_dict[day].append(rental["rentalitems__name"])
# Add the displayed, previous and next month
context["month"] = self.month
context["prev_month"] = self.month + datetime.timedelta(days=-1)
context["next_month"] = self.month + datetime.timedelta(
days=calendar.monthrange(self.month.year, self.month.month)[1] + 1
)
# Add the days of the displayed, previous and next month
context["days_of_month"] = days_of_month
context["days_of_prev_month"] = sorted(days_of_prev_month)
context["days_of_next_month"] = days_of_next_month
# Get the current date for the calendar
context["today"] = datetime.datetime.now(tz=datetime.UTC).date()
# Add rental items to the context for the filter
context["rentalitems"] = RentalItem.objects.all()
# Add the (max. 4) selected rental items to the context for the filter
context["rentalitem_filters"] = {"rentalitems": self.rentalitem_filters[:4]}
context["rental_dict"] = rental_dict
return context
def get_queryset(self):
qs = (
super()
.get_queryset()
.filter(
Q(status=Rental.Status.APPROVED)
| Q(status=Rental.Status.ISSUED)
| Q(status=Rental.Status.RETURNED)
)
)
last_day_of_month = self.month.replace(
day=calendar.monthrange(self.month.year, self.month.month)[1]
)
# Filter by date
qs_new = qs.filter(date_start__gte=self.month, date_start__lte=last_day_of_month)
qs_new |= qs.filter(date_end__gte=self.month, date_end__lte=last_day_of_month)
# Filter by rental items
qs = qs.filter(rentalitems__name__in=self.rentalitem_filters).distinct()
qs = qs.values("id", "date_start", "date_end", "rentalitems__name").distinct()
return qs
class RentalCreateView(CreateView):
form_class = RentalCreateForm
model = Rental
template_name = "rental/create.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["rentalitems_addinfo"] = RentalItem.objects.all()
return context
def get_success_url(self):
return reverse("rental:rental_create_done", kwargs={"pk": self.object.pk})
class RentalCreateDoneView(TemplateView):
template_name = "rental/create_done.html"

View File

@@ -111,6 +111,7 @@
<li class="{% if 'posts' in request.path %}active{% endif %}"><a href="{% url 'posts:index' %}">News</a></li> <li class="{% if 'posts' in request.path %}active{% endif %}"><a href="{% url 'posts:index' %}">News</a></li>
<li class="{% if 'members' in request.path %}active{% endif %}"><a href="{% url 'members:index' %}">Fachschaft</a></li> <li class="{% if 'members' in request.path %}active{% endif %}"><a href="{% url 'members:index' %}">Fachschaft</a></li>
<li class="{% if 'gallery' in request.path %}active{% endif %}"><a href="{% url 'gallery:index' %}">Galerie</a></li> <li class="{% if 'gallery' in request.path %}active{% endif %}"><a href="{% url 'gallery:index' %}">Galerie</a></li>
<li class="{% if 'rental' in request.path %}active{% endif %}"><a href="{% url 'rental:index' %}">Verleih</a></li>
<li class="{% if 'jobs' in request.path %}active{% endif %}"><a href="{% url 'blackboard:index' %}">Jobs</a></li> <li class="{% if 'jobs' in request.path %}active{% endif %}"><a href="{% url 'blackboard:index' %}">Jobs</a></li>
{% get_flatpages '/kontakt/' as pages %} {% get_flatpages '/kontakt/' as pages %}

View File

@@ -0,0 +1,20 @@
<label>
<span>{{ field.label }} {% if not field.field.required %}(optional){% endif %}</span>
{% if field.errors %}
<div class="alert alert-danger">
<div class="alert-body">{{ field.errors }}</div>
</div>
{% endif %}
<input
type="email"
name="{{ field.name }}"
{% if field.value %}value="{{ field.value }}"{% endif %}
{% if field.field.required %}required{% endif %}
{% if field.field.disabled %}disabled{% endif %}
{% if field.field.autofocus %}autofocus{% endif %}
class="w-full"
>
{% if field.help_text %}
<small class="text-gray-700 dark:text-gray-200">{{ field.help_text }}</small>
{% endif %}
</label>

View File

@@ -0,0 +1,187 @@
{% extends 'base.html' %}
{% load static %}
{% block title %}Verleih{% endblock %}
{% block content %}
<main class="container mx-auto w-full px-4 my-8 flex-1">
<h1 class="page-title">Verleih</h1>
<section class="text-center my-6">
<p class="my-6 text-gray-900 dark:text-gray-100">
Willkommen bei unserem Verleih!
</p>
<a href="{% url 'rental:rental_create' %}" class="page-subtitle block btn-small btn-primary max-w-xs mx-auto sm:w-max sm:mr-0 sm:ml-auto">
<i class="fa-solid fa-plus mr-1"></i> Verleih anfragen
</a>
</section>
<form action="" method="GET">
<section>
<div class="grid grid-cols-1 gap-x-6 gap-y-6 lg:grid-cols-6 sm:grid-cols-3 pb-6">
<button
id="filterDropdownButton"
data-dropdown-toggle="filterDropdown"
class="w-full md:w-auto flex items-center justify-center py-2 px-4 text-sm font-medium text-gray-900 focus:outline-none bg-white rounded-lg border border-gray-200 hover:bg-gray-100 hover:text-primary-700 focus:z-10 focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 dark:bg-gray-800 dark:text-gray-400 dark:border-gray-600 dark:hover:text-white dark:hover:bg-gray-700"
type="button"
>
<i class="h-4 w-4 mr-2 fa-solid fa-filter"></i>
Filter
<i class="-mr-1 ml-1.5 mt-1 w-5 h-5 fa-solid fa-chevron-down"></i>
</button>
<div id="filterDropdown" class="z-10 hidden w-56 p-3 bg-white rounded-lg shadow dark:bg-gray-700">
<h6 class="mb-3 text-sm font-medium text-gray-900 dark:text-white">Verleihgegenstände</h6>
<ul class="space-y-2 text-sm" aria-labelledby="filterDropdownButton">
{% for item in rentalitems %}
<li class="flex items-center">
<input
id="item_{{ item.id }}"
type="checkbox"
name="rentalitems"
value="{{ item.name }}"
{% for key, value in rentalitem_filters.items %}
{% if key == "rentalitems" and item.name in value %}
checked
{% endif %}
{% endfor %}
class="w-4 h-4 bg-gray-100 border-gray-300 rounded text-primary-600 focus:ring-primary-500 dark:focus:ring-primary-600 dark:ring-offset-gray-700 focus:ring-2 dark:bg-gray-600 dark:border-gray-500"
>
<label for="item_{{ item.id }}" class="ml-2 text-sm font-medium text-gray-900 dark:text-gray-100">{{ item.name }}</label>
</li>
{% endfor %}
</ul>
</div>
<button type="submit" class="block btn btn-primary" name="" value="Submit">Filter anwenden</button>
</div>
</section>
<section class="text-center">
<div class="wrapper mx-auto bg-white rounded shadow max-w-full">
<div class="header flex justify-between border-b p-2">
<span class="text-lg font-bold">{{ month|date:'F Y' }}</span>
<div class="buttons">
<button type="submit" class="p-1" name="month" value="{{ prev_month|date:'Y-m' }}">
<i class="fa-regular fa-circle-left"></i>
</button>
<button type="submit" class="p-1" name="month" value="{{ next_month|date:'Y-m' }}">
<i class="fa-regular fa-circle-right"></i>
</button>
</div>
</div>
<table class="table-fixed w-full mx-auto">
<thead>
<tr>
<th class="p-2 border-r h-10 xl:text-sm text-xs">
<span class="xl:block lg:block md:block sm:block hidden">Monday</span>
<span class="xl:hidden lg:hidden md:hidden sm:hidden block">Mon</span>
</th>
<th class="p-2 border-r h-10 xl:text-sm text-xs">
<span class="xl:block lg:block md:block sm:block hidden">Tuesday</span>
<span class="xl:hidden lg:hidden md:hidden sm:hidden block">Tue</span>
</th>
<th class="p-2 border-r h-10 xl:text-sm text-xs">
<span class="xl:block lg:block md:block sm:block hidden">Wednesday</span>
<span class="xl:hidden lg:hidden md:hidden sm:hidden block">Wed</span>
</th>
<th class="p-2 border-r h-10 xl:text-sm text-xs">
<span class="xl:block lg:block md:block sm:block hidden">Thursday</span>
<span class="xl:hidden lg:hidden md:hidden sm:hidden block">Thu</span>
</th>
<th class="p-2 border-r h-10 xl:text-sm text-xs">
<span class="xl:block lg:block md:block sm:block hidden">Friday</span>
<span class="xl:hidden lg:hidden md:hidden sm:hidden block">Fri</span>
</th>
<th class="p-2 border-r h-10 xl:text-sm text-xs">
<span class="xl:block lg:block md:block sm:block hidden">Saturday</span>
<span class="xl:hidden lg:hidden md:hidden sm:hidden block">Sat</span>
</th>
<th class="p-2 border-r h-10 xl:text-sm text-xs">
<span class="xl:block lg:block md:block sm:block hidden">Sunday</span>
<span class="xl:hidden lg:hidden md:hidden sm:hidden block">Sun</span>
</th>
</tr>
</thead>
<tbody>
{% for day in days_of_prev_month %}
{% if day.weekday == 0 %}
<tr class="text-center h-20">
{% endif %}
<td class="border p-1 h-40">
<div class="flex flex-col h-40">
<div class="top h-5 w-full">
<span class="text-gray-500 text-sm">{{ day.day }}</span>
</div>
<div class="bottom flex-grow h-30 py-1 w-full"></div>
</div>
</td>
{% endfor %}
{% for day in days_of_month %}
{% if day.weekday == 0 %}
<tr class="text-center h-20">
{% endif %}
<td class="border p-1 h-40">
<div class="flex flex-col h-40">
<div class="top h-5 w-full">
{% if day == today %}
<span class="text-gray-100 dark:text-gray-900 border-2 border-blue-900 dark:border-blue-100 rounded-full bg-blue-900 dark:bg-blue-100">{{ day.day }}</span>
{% else %}
<span class="text-gray-900 dark:text-gray-100">{{ day.day }}</span>
{% endif %}
</div>
{% for key, names in rental_dict.items %}
{% if key == day %}
{% for name in names %}
<div class="bottom h-30 py-1 w-full">
<div class="event bg-purple-400 text-white rounded p-1 text-sm">
<span class="event-name xl:block lg:hidden md:hidden sm:hidden hidden">{{ name }}</span>
<span class="event-name xl:hidden lg:block md:hidden sm:hidden hidden">{{ name|truncatechars:15 }}</span>
<span class="event-name xl:hidden lg:hidden md:block sm:hidden hidden">{{ name|truncatechars:10 }}</span>
<span class="event-name xl:hidden lg:hidden md:hidden sm:block hidden">{{ name|truncatechars:6 }}</span>
<span class="event-name xl:hidden lg:hidden md:hidden sm:hidden block">{{ name|truncatechars:3 }}</span>
</div>
</div>
{% empty %}
<div class="bottom flex-grow h-30 py-1 w-full"></div>
{% endfor %}
{% endif %}
{% endfor %}
</div>
</td>
{% if day.weekday == 6 %}
</tr>
{% endif %}
{% endfor %}
{% for day in days_of_next_month %}
<td class="border p-1 h-40">
<div class="flex flex-col h-40">
<div class="top h-5 w-full">
<span class="text-gray-500 text-sm">{{ day.day }}</span>
</div>
<div class="bottom flex-grow h-30 py-1 w-full"></div>
</div>
</td>
{% if day.weekday == 6 %}
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
</section>
</form>
</main>
{% endblock content %}

View File

@@ -0,0 +1,112 @@
{% extends 'base.html' %}
{% block title %}Verleih Anfrage{% endblock %}
{% block content %}
<!-- Main Content -->
<main class="container mx-auto w-full px-4 my-8 flex-1">
<h1 class="page-title">Verleih Anfrage</h1>
<form action="" enctype="multipart/form-data" method="POST" class="multiSectionForm max-w-2xl">
{% csrf_token %}
{% include "baseform/non_field_errors.html" %}
<section>
<h2>Persönliche Daten</h2>
<small>Bitte geben Sie Ihre persönlichen Daten ein.</small>
<div class="grid grid-cols-1 gap-x-6 gap-y-6 sm:grid-cols-6">
<div class="sm:col-span-3">
{% include "baseform/text.html" with field=form.firstname %}
</div>
<div class="sm:col-span-3">
{% include "baseform/text.html" with field=form.surname %}
</div>
<div class="sm:col-span-3">
{% include "baseform/text.html" with field=form.organization %}
</div>
<div class="sm:col-span-3">
{% include "baseform/text.html" with field=form.matriculation_number %}
</div>
<div class="sm:col-span-3">
{% include "baseform/email.html" with field=form.email %}
</div>
<div class="sm:col-span-3">
{% include "baseform/text.html" with field=form.phone %}
</div>
</div>
</section>
<section>
<h2>Verleihgegenstände</h2>
<small>Wählen Sie die gewünschten Verleihgegenstände aus.</small>
<div class="grid grid-cols-1 gap-x-6 gap-y-6 sm:grid-cols-6 pb-6 col-span-full">
{% if form.rentalitems.errors %}
<div class="col-span-full alert alert-danger">
<div class="alert-body">{{ form.rentalitems.errors }}</div>
</div>
{% endif %}
<div id="{{ form.rentalitems.auto_id }}" class="col-span-full">
{% for elem in form.rentalitems %}
<div class="col-span-2 mb-2">
<label for="{{ elem.id_for_label }}">
<input
type="checkbox"
id="{{ elem.id_for_label }}"
name="{{ form.rentalitems.html_name }}"
value="{{ elem.data.value }}"
class="rounded border-gray-300 dark:border-none text-proprietary shadow-sm focus:border-blue-300 focus:ring focus:ring-offset-0 focus:ring-blue-200 dark:focus:ring-sky-700 focus:ring-opacity-50"
>
<span>{{ elem.choice_label }}</span>
</label>
{% for item in rentalitems_addinfo %}
{% if item.name == elem.choice_label and item.description %}
<p class="text-xs text-gray-700 dark:text-gray-200">{{ item.description }}</p>
{% endif %}
{% endfor %}
</div>
{% endfor %}
</div>
</div>
<div class="grid grid-cols-1 gap-x-6 gap-y-6 sm:grid-cols-6">
<div class="sm:col-span-3">
{% include "baseform/date.html" with field=form.date_start %}
</div>
<div class="sm:col-span-3">
{% include "baseform/date.html" with field=form.date_end %}
</div>
<div class="col-span-full">
{% include "baseform/textarea.html" with field=form.reason %}
</div>
</div>
</section>
<section>
<h2>Zusätzliche Informationen</h2>
<small>Hier können Sie zusätzliche Informationen, Anliegen und Sonstiges angeben.</small>
<div class="grid grid-cols-1 gap-x-6 gap-y-6 sm:grid-cols-6">
<div class="col-span-full">
{% include "baseform/textarea.html" with field=form.comment %}
</div>
</div>
</section>
<section>
<div class="grid grid-cols-1 gap-x-6 gap-y-6 sm:grid-cols-6">
<div class="col-span-full">
{% include "baseform/checkbox.html" with field=form.conformation %}
</div>
</div>
</section>
<section class="flex justify-end">
<button type="submit" class="btn btn-primary w-full sm:w-auto" value="Einreichen">Anfrage abschicken</button>
</section>
</form>
</main>
{% endblock content %}

View File

@@ -0,0 +1,17 @@
{% extends 'base.html' %}
{% block title %}Verleihanfrage erfolgreich eingereicht{% endblock %}
{% block content %}
<!-- Main Content -->
<main class="container mx-auto w-full px-4 my-8 flex-1">
<section class="w-full text-center">
<p class="mt-6 text-gray-900 dark:text-gray-100">
Die Verleihanfrage mit der Nummer #{{ pk }} wurde erfolgreich eingereicht.
</p>
<div class="mt-10 flex items-center justify-center">
<a href="{% url 'home' %}" type="submit" class="block btn btn-primary">Zur Startseite</a>
</div>
</section>
</main>
{% endblock content %}