feat: groups price calculator admin crud, booking/offer flow and api
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-8 pb-4">
|
||||
{% for monthData in months %}
|
||||
<div class="mb-10">
|
||||
|
||||
<h3 class="text-base font-semibold mb-3">{{ monthData.label }}</h3>
|
||||
|
||||
{# Weekday headers (Mon–Sun) #}
|
||||
<div class="grid grid-cols-7 text-center text-xs font-medium text-gray-400 mb-1">
|
||||
<div>Mo</div>
|
||||
<div>Di</div>
|
||||
<div>Mi</div>
|
||||
<div>Do</div>
|
||||
<div>Fr</div>
|
||||
<div>Sa</div>
|
||||
<div>So</div>
|
||||
</div>
|
||||
|
||||
{# Day grid #}
|
||||
<div class="grid grid-cols-7 gap-0.5">
|
||||
{% for week in monthData.weeks %}
|
||||
{% for dayData in week %}
|
||||
{% if dayData.inMonth %}
|
||||
{% set dateStr = dayData.date|date('Y-m-d') %}
|
||||
{% set entry = enrichedByDate[dateStr] ?? null %}
|
||||
{% set status = (dateStr < todayStr) ? 'past' : (entry ? entry.status : 'ok') %}
|
||||
{% set minNights = entry ? entry.minNights : 0 %}
|
||||
<button type="button"
|
||||
class="pc-day"
|
||||
data-price-calendar-target="day"
|
||||
data-action="price-calendar#selectDate"
|
||||
data-date="{{ dateStr }}"
|
||||
data-status="{{ status }}"
|
||||
data-min-nights="{{ minNights }}"
|
||||
{% if status == 'blocked' %}title="Nicht verfügbar"{% elseif minNights > 1 %}title="Mindestaufenthalt {{ minNights }} Nächte"{% endif %}>
|
||||
{{ dayData.date|date('j') }}
|
||||
</button>
|
||||
{% else %}
|
||||
<div class="pc-day pc-day--out-of-month"></div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between">
|
||||
{# Status message (arrival hint, short-stay warning, etc.) #}
|
||||
<div class="text-sm text-primary-medium mb-2 min-h-[1.25rem]"
|
||||
data-price-calendar-target="message"></div>
|
||||
|
||||
{# Reset link — revealed once a start date is selected #}
|
||||
<button type="button"
|
||||
class="text-sm text-gray-400 underline mb-4"
|
||||
data-price-calendar-target="resetButton"
|
||||
data-action="price-calendar#reset">
|
||||
Auswahl zurücksetzen
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{# Navigation — prev/next trigger HTMX month swap; no Stimulus involvement #}
|
||||
<div class="flex items-center justify-between">
|
||||
<button type="button"
|
||||
class="button button--secondary"
|
||||
{% if offset == 0 %}disabled{% endif %}
|
||||
hx-get="{{ path('app_groups_booking_calendar_grid', {'offset': offset - 1}) }}"
|
||||
hx-target="#calendar-mount"
|
||||
hx-swap="innerHTML">
|
||||
← früher
|
||||
</button>
|
||||
<button type="button"
|
||||
class="button button--secondary"
|
||||
{% if offset >= totalMonths - 2 %}disabled{% endif %}
|
||||
hx-get="{{ path('app_groups_booking_calendar_grid', {'offset': offset + 1}) }}"
|
||||
hx-target="#calendar-mount"
|
||||
hx-swap="innerHTML">
|
||||
später →
|
||||
</button>
|
||||
</div>
|
||||
Reference in New Issue
Block a user