add week view
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import calendar
|
import calendar
|
||||||
import datetime
|
import datetime
|
||||||
|
from datetime import date
|
||||||
|
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
@@ -12,87 +13,176 @@ from .forms import RentalCreateForm
|
|||||||
from .models import Rental, RentalItem
|
from .models import Rental, RentalItem
|
||||||
|
|
||||||
|
|
||||||
|
def _calc_days_from_current_month(month: date) -> list:
|
||||||
|
last_day_of_month = month.replace(day=calendar.monthrange(month.year, month.month)[1])
|
||||||
|
|
||||||
|
return [month + datetime.timedelta(days=i) for i in range((last_day_of_month - month).days + 1)]
|
||||||
|
|
||||||
|
|
||||||
|
def _calc_days_from_prev_month(month: date) -> list:
|
||||||
|
days_of_prev_period = []
|
||||||
|
|
||||||
|
if month.weekday() != calendar.MONDAY:
|
||||||
|
for i in range(1, 7):
|
||||||
|
day = month + datetime.timedelta(days=-i)
|
||||||
|
days_of_prev_period.append(day)
|
||||||
|
if day.weekday() == calendar.MONDAY:
|
||||||
|
break
|
||||||
|
|
||||||
|
return sorted(days_of_prev_period)
|
||||||
|
|
||||||
|
|
||||||
|
def _calc_days_from_next_month(month: date) -> list:
|
||||||
|
last_day_of_month = month.replace(day=calendar.monthrange(month.year, month.month)[1])
|
||||||
|
days_of_next_period = []
|
||||||
|
|
||||||
|
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_period.append(day)
|
||||||
|
if day.weekday() == calendar.SUNDAY:
|
||||||
|
break
|
||||||
|
|
||||||
|
return days_of_next_period
|
||||||
|
|
||||||
|
|
||||||
|
def _get_display_period(view_type: str, period: str) -> tuple[date, bool]:
|
||||||
|
display_date: date = None
|
||||||
|
changed: bool = False # Indicate if the view has changed (used to reset filters)
|
||||||
|
|
||||||
|
# Handle week view
|
||||||
|
if view_type == "week":
|
||||||
|
try:
|
||||||
|
# Parse the requested calendar week
|
||||||
|
display_date = (
|
||||||
|
datetime.datetime.strptime(f"{period}-1", "%G-KW%V-%u")
|
||||||
|
.replace(tzinfo=datetime.UTC)
|
||||||
|
.date()
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
# Get first day of the current week
|
||||||
|
today = datetime.datetime.now(tz=datetime.UTC).date()
|
||||||
|
display_date = today - datetime.timedelta(days=today.weekday())
|
||||||
|
|
||||||
|
changed = True
|
||||||
|
|
||||||
|
# Handle month view
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
# Parse the requested month
|
||||||
|
display_date = (
|
||||||
|
datetime.datetime.strptime(period, "%Y-%m").replace(tzinfo=datetime.UTC).date()
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
# Get the first day of the current month
|
||||||
|
display_date = datetime.datetime.now(tz=datetime.UTC).date().replace(day=1)
|
||||||
|
|
||||||
|
changed = True
|
||||||
|
|
||||||
|
return display_date, changed
|
||||||
|
|
||||||
|
|
||||||
|
def _get_rental_filters(view_type: str, filters: list) -> list:
|
||||||
|
if not filters:
|
||||||
|
items = RentalItem.objects.all()
|
||||||
|
# if view_type == "month":
|
||||||
|
# items = items[:4]
|
||||||
|
filters = [item.name for item in items]
|
||||||
|
# else:
|
||||||
|
# if view_type == "month":
|
||||||
|
# filters = filters[:4]
|
||||||
|
|
||||||
|
return filters
|
||||||
|
|
||||||
|
|
||||||
class RentalListView(ListView):
|
class RentalListView(ListView):
|
||||||
model = Rental
|
model = Rental
|
||||||
template_name = "rental/calendar.html"
|
template_name = "rental/calendar.html"
|
||||||
|
|
||||||
# Month is the month displayed in the calendar (and should be the first day of the month)
|
def __init__(self):
|
||||||
month = None
|
super().__init__()
|
||||||
# Rental items to filter
|
# Current display period and view settings
|
||||||
rentalitem_filters = []
|
self.display_period = None
|
||||||
|
self.view_type = "month" # Default view
|
||||||
|
self.rentalitem_filters = []
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
# Get the rental items from the filter (max. 4)
|
# Get view parameters from request
|
||||||
self.rentalitem_filters = request.GET.getlist("rentalitems", [])[:4]
|
_view_type = request.GET.get("view_type", "week")
|
||||||
if not self.rentalitem_filters:
|
_period = request.GET.get("period_value", "")
|
||||||
for rentalitem in RentalItem.objects.all()[:4]:
|
_prev_period = request.GET.get("prev_period", "")
|
||||||
self.rentalitem_filters.append(rentalitem.name)
|
_next_period = request.GET.get("next_period", "")
|
||||||
|
|
||||||
# Get the displayed month from the request
|
if _prev_period:
|
||||||
_date_str = request.GET.get("month", "")
|
_period = _prev_period
|
||||||
if _date_str:
|
elif _next_period:
|
||||||
self.month = (
|
_period = _next_period
|
||||||
datetime.datetime.strptime(_date_str, "%Y-%m").replace(tzinfo=datetime.UTC).date()
|
|
||||||
)
|
self.view_type = _view_type
|
||||||
else:
|
self.display_period, changed = _get_display_period(_view_type, _period)
|
||||||
self.month = datetime.datetime.now(tz=datetime.UTC).date().replace(day=1)
|
|
||||||
|
_filters = request.GET.getlist("rentalitems", [])
|
||||||
|
# Reset filter if switched to week view
|
||||||
|
# if changed:
|
||||||
|
# _filters = []
|
||||||
|
self.rentalitem_filters = _get_rental_filters(_view_type, _filters)
|
||||||
|
|
||||||
|
# Update request.GET
|
||||||
|
_request_get_list = request.GET.copy()
|
||||||
|
_request_get_list.pop("prev_period", None)
|
||||||
|
_request_get_list.pop("next_period", None)
|
||||||
|
_request_get_list["period_value"] = _period
|
||||||
|
request.GET = _request_get_list
|
||||||
|
|
||||||
return super().get(request, *args, **kwargs)
|
return super().get(request, *args, **kwargs)
|
||||||
|
|
||||||
def get_context_data(self, **kwargs):
|
def get_context_data(self, **kwargs):
|
||||||
context = super().get_context_data(**kwargs)
|
context = super().get_context_data(**kwargs)
|
||||||
|
|
||||||
# Calculate the day of the previous month from Monday
|
if self.view_type != "week":
|
||||||
days_of_prev_month = []
|
# Add the displayed, previous and next month
|
||||||
|
context["view_period"] = self.display_period
|
||||||
|
context["prev_period"] = self.display_period + datetime.timedelta(days=-1)
|
||||||
|
context["next_period"] = self.display_period + datetime.timedelta(
|
||||||
|
days=calendar.monthrange(self.display_period.year, self.display_period.month)[1] + 1
|
||||||
|
)
|
||||||
|
|
||||||
if self.month.weekday() != calendar.MONDAY:
|
# Add the days of the displayed, previous and next month
|
||||||
for i in range(1, 7):
|
days_of_view_period = _calc_days_from_current_month(self.display_period)
|
||||||
day = self.month + datetime.timedelta(days=-i)
|
context["days_of_view_period"] = days_of_view_period
|
||||||
days_of_prev_month.append(day)
|
context["days_of_prev_period"] = _calc_days_from_prev_month(self.display_period)
|
||||||
if day.weekday() == calendar.MONDAY:
|
context["days_of_next_period"] = _calc_days_from_next_month(self.display_period)
|
||||||
break
|
|
||||||
|
|
||||||
# Calculate the days of the next month until Sunday
|
context["view_type"] = "month"
|
||||||
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:
|
context["week_num"] = None
|
||||||
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
|
else:
|
||||||
days_of_month = [
|
# Current week
|
||||||
self.month + datetime.timedelta(days=i)
|
year, week_num, _ = self.display_period.isocalendar()
|
||||||
for i in range((last_day_of_month - self.month).days + 1)
|
context["view_period"] = f"{year}-KW{week_num:02d}" # formats as "2025-KW02"
|
||||||
]
|
|
||||||
|
|
||||||
# Create a dictionary with the rental items for each day
|
# Calculate previous week
|
||||||
rental_dict = {}
|
prev_week = self.display_period - datetime.timedelta(days=7)
|
||||||
for rental in self.get_queryset():
|
prev_year, prev_week_num, _ = prev_week.isocalendar()
|
||||||
for day in days_of_month:
|
context["prev_period"] = f"{prev_year}-KW{prev_week_num:02d}"
|
||||||
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]:
|
# Calculate next week
|
||||||
rental_dict[day].append(rental["rentalitems__name"])
|
next_week = self.display_period + datetime.timedelta(days=7)
|
||||||
|
next_year, next_week_num, _ = next_week.isocalendar()
|
||||||
|
context["next_period"] = f"{next_year}-KW{next_week_num:02d}"
|
||||||
|
|
||||||
# Add the displayed, previous and next month
|
# Add days of week (7 days starting from first_day_of_week)
|
||||||
context["month"] = self.month
|
days_of_view_period = [
|
||||||
context["prev_month"] = self.month + datetime.timedelta(days=-1)
|
self.display_period + datetime.timedelta(days=i) for i in range(7)
|
||||||
context["next_month"] = self.month + datetime.timedelta(
|
]
|
||||||
days=calendar.monthrange(self.month.year, self.month.month)[1] + 1
|
context["days_of_view_period"] = days_of_view_period
|
||||||
)
|
context["days_of_prev_period"] = []
|
||||||
|
context["days_of_next_period"] = []
|
||||||
|
|
||||||
# Add the days of the displayed, previous and next month
|
context["view_type"] = "week"
|
||||||
context["days_of_month"] = days_of_month
|
|
||||||
context["days_of_prev_month"] = sorted(days_of_prev_month)
|
context["week_num"] = week_num
|
||||||
context["days_of_next_month"] = days_of_next_month
|
|
||||||
|
|
||||||
# Get the current date for the calendar
|
# Get the current date for the calendar
|
||||||
context["today"] = datetime.datetime.now(tz=datetime.UTC).date()
|
context["today"] = datetime.datetime.now(tz=datetime.UTC).date()
|
||||||
@@ -103,6 +193,17 @@ class RentalListView(ListView):
|
|||||||
# Add the selected rental items to the context for the filter
|
# Add the selected rental items to the context for the filter
|
||||||
context["rentalitem_filters"] = {"rentalitems": self.rentalitem_filters}
|
context["rentalitem_filters"] = {"rentalitems": self.rentalitem_filters}
|
||||||
|
|
||||||
|
# Create a dictionary with the rental items for each day
|
||||||
|
rental_dict = {}
|
||||||
|
for rental in self.get_queryset():
|
||||||
|
for day in days_of_view_period:
|
||||||
|
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"])
|
||||||
|
|
||||||
context["rental_dict"] = rental_dict
|
context["rental_dict"] = rental_dict
|
||||||
|
|
||||||
return context
|
return context
|
||||||
@@ -118,20 +219,22 @@ class RentalListView(ListView):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
last_day_of_month = self.month.replace(
|
if self.view_type == "week":
|
||||||
day=calendar.monthrange(self.month.year, self.month.month)[1]
|
qs_date_end = self.display_period + datetime.timedelta(days=6)
|
||||||
)
|
else:
|
||||||
|
qs_date_end = self.display_period.replace(
|
||||||
|
day=calendar.monthrange(self.display_period.year, self.display_period.month)[1]
|
||||||
|
)
|
||||||
|
|
||||||
# Filter by date
|
# Filter by date
|
||||||
qs_new = qs.filter(date_start__gte=self.month, date_start__lte=last_day_of_month)
|
if self.display_period and qs_date_end:
|
||||||
qs_new |= qs.filter(date_end__gte=self.month, date_end__lte=last_day_of_month)
|
qs_new = qs.filter(date_start__gte=self.display_period, date_start__lte=qs_date_end)
|
||||||
|
qs_new |= qs.filter(date_end__gte=self.display_period, date_end__lte=qs_date_end)
|
||||||
|
|
||||||
# Filter by rental items
|
# Filter by rental items
|
||||||
qs = qs.filter(rentalitems__name__in=self.rentalitem_filters).distinct()
|
qs = qs.filter(rentalitems__name__in=self.rentalitem_filters).distinct()
|
||||||
|
|
||||||
qs = qs.values("id", "date_start", "date_end", "rentalitems__name").distinct()
|
return qs.values("id", "date_start", "date_end", "rentalitems__name").distinct()
|
||||||
|
|
||||||
return qs
|
|
||||||
|
|
||||||
|
|
||||||
class RentalCreateView(CreateView):
|
class RentalCreateView(CreateView):
|
||||||
@@ -175,7 +278,7 @@ class RentalItemDetailView(DetailView):
|
|||||||
|
|
||||||
def rental_calendar(request):
|
def rental_calendar(request):
|
||||||
"""
|
"""
|
||||||
ICS-calendar for outlook, google calender, ...
|
ICS-calendar for Outlook, Google Calendar, etc.
|
||||||
"""
|
"""
|
||||||
rentals = Rental.objects.all()
|
rentals = Rental.objects.all()
|
||||||
|
|
||||||
|
|||||||
@@ -14,17 +14,27 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
<a href="{% url 'rental:calendar' %}" class="block btn btn-secondary max-w-xs mx-auto sm:w-max sm:mr-0 sm:ml-auto my-6"><i class="fa-solid fa-calendar-days mr-2"></i>Verleih-Kalender abonnieren</a>
|
<a
|
||||||
|
href="{% url 'rental:calendar' %}"
|
||||||
|
class="block btn btn-secondary max-w-xs mx-auto sm:w-max sm:mr-0 sm:ml-auto my-6"
|
||||||
|
title="Kalender im iCal-Format abonnieren"
|
||||||
|
>
|
||||||
|
<i class="fa-solid fa-calendar-days mr-2"></i>Verleih-Kalender abonnieren
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<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">
|
<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"
|
||||||
|
title="Neue Verleihanfrage erstellen"
|
||||||
|
>
|
||||||
<i class="fa-solid fa-plus mr-1"></i> Verleih anfragen
|
<i class="fa-solid fa-plus mr-1"></i> Verleih anfragen
|
||||||
</a>
|
</a>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<form action="" method="GET">
|
<form action="" method="GET">
|
||||||
<section>
|
<section>
|
||||||
<div class="grid grid-cols-1 gap-x-6 gap-y-6 lg:grid-cols-6 sm:grid-cols-3 pb-6">
|
<div class="grid grid-cols-1 gap-x-6 gap-y-6 xl:grid-cols-6 sm:grid-cols-3 pb-6">
|
||||||
<button
|
<button
|
||||||
id="filterDropdownButton"
|
id="filterDropdownButton"
|
||||||
data-dropdown-toggle="filterDropdown"
|
data-dropdown-toggle="filterDropdown"
|
||||||
@@ -36,83 +46,137 @@
|
|||||||
<i class="-mr-1 ml-1.5 mt-1 w-5 h-5 fa-solid fa-chevron-down"></i>
|
<i class="-mr-1 ml-1.5 mt-1 w-5 h-5 fa-solid fa-chevron-down"></i>
|
||||||
</button>
|
</button>
|
||||||
<div id="filterDropdown" class="z-10 hidden w-56 p-3 bg-white rounded-lg shadow dark:bg-gray-700">
|
<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>
|
<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">
|
<ul class="space-y-2 text-sm" aria-labelledby="filterDropdownButton">
|
||||||
{% for item in rentalitems %}
|
{% for item in rentalitems %}
|
||||||
<li class="flex items-center">
|
<li class="flex items-center">
|
||||||
<input
|
<input
|
||||||
id="item_{{ item.id }}"
|
id="item_{{ item.id }}"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
name="rentalitems"
|
name="rentalitems"
|
||||||
value="{{ item.name }}"
|
value="{{ item.name }}"
|
||||||
{% for key, value in rentalitem_filters.items %}
|
{% for key, value in rentalitem_filters.items %}
|
||||||
{% if key == "rentalitems" and item.name in value %}
|
{% if key == "rentalitems" and item.name in value %}
|
||||||
checked
|
checked
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% 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"
|
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>
|
<label for="item_{{ item.id }}" class="ml-2 text-sm font-medium text-gray-900 dark:text-gray-100">{{ item.name }}</label>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button type="submit" class="block btn btn-primary" name="" value="Submit">Filter anwenden</button>
|
<div class="flex w-full md:w-auto items-center justify-center py-2 px-4 border border-gray-200 rounded-sm dark:border-gray-700">
|
||||||
|
<input
|
||||||
|
{% if view_type == 'month' %}checked{% endif %}
|
||||||
|
id="bordered-radio-1"
|
||||||
|
type="radio"
|
||||||
|
value="month"
|
||||||
|
name="view_type"
|
||||||
|
title="Zur Monatsansicht wechseln"
|
||||||
|
class="ml-2 mr-2 w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
|
||||||
|
>
|
||||||
|
<label for="bordered-radio-1" class="w-full ms-2 text-sm font-medium text-gray-900 dark:text-gray-300">Monatsansicht</label>
|
||||||
|
</div>
|
||||||
|
<div class="flex w-full md:w-auto items-center justify-center py-2 px-4 border border-gray-200 rounded-sm dark:border-gray-700">
|
||||||
|
<input
|
||||||
|
{% if view_type == 'week' %}checked{% endif %}
|
||||||
|
id="bordered-radio-2"
|
||||||
|
type="radio"
|
||||||
|
value="week"
|
||||||
|
name="view_type"
|
||||||
|
title="Zur Wochenansicht wechseln"
|
||||||
|
class="ml-2 mr-2 w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600"
|
||||||
|
>
|
||||||
|
<label for="bordered-radio-2" class="w-full ms-2 text-sm font-medium text-gray-900 dark:text-gray-300">Wochenansicht</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input
|
||||||
|
type="hidden" name="period_value"
|
||||||
|
value="{% if view_type == 'month' %}{{ view_period|date:'Y-m' }}{% else %}{{ view_period }}{% endif %}"
|
||||||
|
>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="block btn btn-primary"
|
||||||
|
title="Filter anwenden und Kalender aktualisieren"
|
||||||
|
>
|
||||||
|
Filter anwenden
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="text-center">
|
<section class="text-center">
|
||||||
<div class="wrapper mx-auto bg-white rounded shadow max-w-full">
|
<div class="wrapper mx-auto bg-white rounded shadow max-w-full">
|
||||||
<div class="header flex justify-between border-b p-2">
|
<div class="header flex justify-between border-b p-2">
|
||||||
<span class="text-lg font-bold">{{ month|date:'F Y' }}</span>
|
<span class="text-lg font-bold">
|
||||||
|
{% if view_type == 'month' %}
|
||||||
|
{{ view_period|date:'F Y' }}
|
||||||
|
{% else %}
|
||||||
|
{% if days_of_view_period.0.month != days_of_view_period.6.month %}
|
||||||
|
KW{{ week_num|stringformat:"02d" }} - {{ days_of_view_period.0|date:'F' }} / {{ days_of_view_period.6|date:'F Y' }}
|
||||||
|
{% else %}
|
||||||
|
KW{{ week_num|stringformat:"02d" }} - {{ days_of_view_period.0|date:'F Y' }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
</span>
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<button type="submit" class="p-1" name="month" value="{{ prev_month|date:'Y-m' }}">
|
<button
|
||||||
<i class="fa-regular fa-circle-left"></i>
|
type="submit" class="p-1" name="prev_period"
|
||||||
</button>
|
title="{% if view_type == 'month' %}Zum vorherigen Monat{% else %}Zur vorherigen Woche{% endif %}"
|
||||||
<button type="submit" class="p-1" name="month" value="{{ next_month|date:'Y-m' }}">
|
value="{% if view_type == 'month' %}{{ prev_period|date:'Y-m' }}{% else %}{{ prev_period }}{% endif %}"
|
||||||
<i class="fa-regular fa-circle-right"></i>
|
>
|
||||||
</button>
|
<i class="fa-regular fa-circle-left"></i>
|
||||||
</div>
|
</button>
|
||||||
|
<button
|
||||||
|
type="submit" class="p-1" name="next_period"
|
||||||
|
title="{% if view_type == 'month' %}Zum nächsten Monat{% else %}Zur nächsten Woche{% endif %}"
|
||||||
|
value="{% if view_type == 'month' %}{{ next_period|date:'Y-m' }}{% else %}{{ next_period }}{% endif %}"
|
||||||
|
>
|
||||||
|
<i class="fa-regular fa-circle-right"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table class="table-fixed w-full mx-auto">
|
<table class="table-fixed w-full mx-auto">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th class="p-2 border-r h-10 xl:text-sm text-xs">
|
<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:block lg:block md:block sm:block hidden">Montag</span>
|
||||||
<span class="xl:hidden lg:hidden md:hidden sm:hidden block">Mon</span>
|
<span class="xl:hidden lg:hidden md:hidden sm:hidden block">Mo</span>
|
||||||
</th>
|
</th>
|
||||||
<th class="p-2 border-r h-10 xl:text-sm text-xs">
|
<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:block lg:block md:block sm:block hidden">Dienstag</span>
|
||||||
<span class="xl:hidden lg:hidden md:hidden sm:hidden block">Tue</span>
|
<span class="xl:hidden lg:hidden md:hidden sm:hidden block">Di</span>
|
||||||
</th>
|
</th>
|
||||||
<th class="p-2 border-r h-10 xl:text-sm text-xs">
|
<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:block lg:block md:block sm:block hidden">Mittwoch</span>
|
||||||
<span class="xl:hidden lg:hidden md:hidden sm:hidden block">Wed</span>
|
<span class="xl:hidden lg:hidden md:hidden sm:hidden block">Mi</span>
|
||||||
</th>
|
</th>
|
||||||
<th class="p-2 border-r h-10 xl:text-sm text-xs">
|
<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:block lg:block md:block sm:block hidden">Donnerstag</span>
|
||||||
<span class="xl:hidden lg:hidden md:hidden sm:hidden block">Thu</span>
|
<span class="xl:hidden lg:hidden md:hidden sm:hidden block">Do</span>
|
||||||
</th>
|
</th>
|
||||||
<th class="p-2 border-r h-10 xl:text-sm text-xs">
|
<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:block lg:block md:block sm:block hidden">Freitag</span>
|
||||||
<span class="xl:hidden lg:hidden md:hidden sm:hidden block">Fri</span>
|
<span class="xl:hidden lg:hidden md:hidden sm:hidden block">Fr</span>
|
||||||
</th>
|
</th>
|
||||||
<th class="p-2 border-r h-10 xl:text-sm text-xs">
|
<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:block lg:block md:block sm:block hidden">Samstag</span>
|
||||||
<span class="xl:hidden lg:hidden md:hidden sm:hidden block">Sat</span>
|
<span class="xl:hidden lg:hidden md:hidden sm:hidden block">Sa</span>
|
||||||
</th>
|
</th>
|
||||||
<th class="p-2 border-r h-10 xl:text-sm text-xs">
|
<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:block lg:block md:block sm:block hidden">Sonntag</span>
|
||||||
<span class="xl:hidden lg:hidden md:hidden sm:hidden block">Sun</span>
|
<span class="xl:hidden lg:hidden md:hidden sm:hidden block">So</span>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for day in days_of_prev_month %}
|
{% for day in days_of_prev_period %}
|
||||||
{% if day.weekday == 0 %}
|
{% if day.weekday == 0 %}
|
||||||
<tr class="text-center h-20">
|
<tr class="text-center h-20">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@@ -127,13 +191,15 @@
|
|||||||
</td>
|
</td>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% for day in days_of_month %}
|
{% for day in days_of_view_period %}
|
||||||
{% if day.weekday == 0 %}
|
{% if day.weekday == 0 %}
|
||||||
<tr class="text-center h-20">
|
<tr class="text-center h-40">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<td class="border p-1 h-40">
|
<td class="border p-1 h-full">
|
||||||
<div class="flex flex-col h-40">
|
<div
|
||||||
|
class="flex flex-col{% if view_type == 'month' %} h-40{% else %} h-full{% endif %}"
|
||||||
|
>
|
||||||
<div class="top h-5 w-full">
|
<div class="top h-5 w-full">
|
||||||
{% if day == today %}
|
{% 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>
|
<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>
|
||||||
@@ -144,20 +210,43 @@
|
|||||||
|
|
||||||
{% for key, names in rental_dict.items %}
|
{% for key, names in rental_dict.items %}
|
||||||
{% if key == day %}
|
{% if key == day %}
|
||||||
{% for name in names %}
|
{% if view_type == 'month' %}
|
||||||
<div class="bottom h-30 py-1 w-full">
|
{% for name in names|slice:":3" %}
|
||||||
<div class="event bg-purple-400 text-white rounded p-1 text-sm">
|
<div class="bottom h-30 py-1 w-full">
|
||||||
<span class="event-name whitespace-nowrap 2xl:block xl:hidden lg:hidden md:hidden sm:hidden hidden">{{ name|truncatechars:26 }}</span>
|
<div class="event bg-purple-400 text-white rounded p-1 text-sm" title="{{ name }}">
|
||||||
<span class="event-name whitespace-nowrap 2xl:hidden xl:block lg:hidden md:hidden sm:hidden hidden">{{ name|truncatechars:20 }}</span>
|
<span class="event-name whitespace-nowrap 2xl:block xl:hidden lg:hidden md:hidden sm:hidden hidden">{{ name|truncatechars:26 }}</span>
|
||||||
<span class="event-name whitespace-nowrap 2xl:hidden xl:hidden lg:block md:hidden sm:hidden hidden">{{ name|truncatechars:15 }}</span>
|
<span class="event-name whitespace-nowrap 2xl:hidden xl:block lg:hidden md:hidden sm:hidden hidden">{{ name|truncatechars:20 }}</span>
|
||||||
<span class="event-name whitespace-nowrap 2xl:hidden xl:hidden lg:hidden md:block sm:hidden hidden">{{ name|truncatechars:10 }}</span>
|
<span class="event-name whitespace-nowrap 2xl:hidden xl:hidden lg:block md:hidden sm:hidden hidden">{{ name|truncatechars:15 }}</span>
|
||||||
<span class="event-name whitespace-nowrap 2xl:hidden xl:hidden lg:hidden md:hidden sm:block hidden">{{ name|truncatechars:6 }}</span>
|
<span class="event-name whitespace-nowrap 2xl:hidden xl:hidden lg:hidden md:block sm:hidden hidden">{{ name|truncatechars:10 }}</span>
|
||||||
<span class="event-name whitespace-nowrap 2xl:hidden xl:hidden lg:hidden md:hidden sm:hidden block">{{ name|truncatechars:3 }}</span>
|
<span class="event-name whitespace-nowrap 2xl:hidden xl:hidden lg:hidden md:hidden sm:block hidden">{{ name|truncatechars:6 }}</span>
|
||||||
|
<span class="event-name whitespace-nowrap 2xl:hidden xl:hidden lg:hidden md:hidden sm:hidden block">{{ name|truncatechars:3 }}</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
{% empty %}
|
|
||||||
<div class="bottom flex-grow h-30 py-1 w-full"></div>
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
{% if names|length > 3 %}
|
||||||
|
<div class="bottom h-30 py-1 w-full">
|
||||||
|
<a href="?view_type=week&period_value={{ day|date:'o-\K\WW' }}"
|
||||||
|
class="event bg-gray-300 hover:bg-gray-400 text-gray-700 rounded p-1 text-sm hover:underline block cursor-pointer"
|
||||||
|
title="Alle Verleihgegenstände in der Wochenansicht anzeigen">
|
||||||
|
<span class="event-name whitespace-nowrap sm:block hidden">+{{ names|length|add:"-3" }} weitere</span>
|
||||||
|
<span class="event-name whitespace-nowrap sm:hidden block">+{{ names|length|add:"-3" }}</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% 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" title="{{ name }}">
|
||||||
|
<span class="event-name whitespace-nowrap 2xl:block xl:hidden lg:hidden md:hidden sm:hidden hidden">{{ name|truncatechars:26 }}</span>
|
||||||
|
<span class="event-name whitespace-nowrap 2xl:hidden xl:block lg:hidden md:hidden sm:hidden hidden">{{ name|truncatechars:20 }}</span>
|
||||||
|
<span class="event-name whitespace-nowrap 2xl:hidden xl:hidden lg:block md:hidden sm:hidden hidden">{{ name|truncatechars:15 }}</span>
|
||||||
|
<span class="event-name whitespace-nowrap 2xl:hidden xl:hidden lg:hidden md:block sm:hidden hidden">{{ name|truncatechars:10 }}</span>
|
||||||
|
<span class="event-name whitespace-nowrap 2xl:hidden xl:hidden lg:hidden md:hidden sm:block hidden">{{ name|truncatechars:6 }}</span>
|
||||||
|
<span class="event-name whitespace-nowrap 2xl:hidden xl:hidden lg:hidden md:hidden sm:hidden block">{{ name|truncatechars:3 }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
@@ -168,7 +257,7 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% for day in days_of_next_month %}
|
{% for day in days_of_next_period %}
|
||||||
<td class="border p-1 h-40">
|
<td class="border p-1 h-40">
|
||||||
<div class="flex flex-col h-40">
|
<div class="flex flex-col h-40">
|
||||||
<div class="top h-5 w-full">
|
<div class="top h-5 w-full">
|
||||||
|
|||||||
Reference in New Issue
Block a user