feat: add the booking board with floor plan and calendar
This commit is contained in:
1 parent
f4741e1bee
commit
59feca2f8e
22 files changed
+1015
-17
No files matched your search
@@ -0,0 +1,40 @@
|
||||
{#
|
||||
The booking modal. Extending htmx_modal.html.twig keeps it a standalone fragment -- it is a
|
||||
valid response on its own, which is what the opener's hx-swap="beforeend" onto <body> needs.
|
||||
|
||||
The form targets the modal itself with outerHTML, which does double duty:
|
||||
* invalid submit -> Symfony returns 422, htmx swaps it (see responseHandling in app.js) and
|
||||
the modal replaces itself with the errors showing;
|
||||
* success -> the response is nothing but out-of-band board blocks, so the modal is replaced
|
||||
with an empty fragment, i.e. it closes.
|
||||
#}
|
||||
{% extends 'htmx_modal.html.twig' %}
|
||||
|
||||
{% block title %}{{ resource.label }} buchen{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{{ form_start(form, { attr: {
|
||||
'hx-post': form.vars.action,
|
||||
'hx-target': '#htmx-modal',
|
||||
'hx-swap': 'outerHTML',
|
||||
} }) }}
|
||||
{# Root-level errors, which is where a rejected booking lands -- form_end/form_rest does
|
||||
NOT render these, so leaving this out makes the 422 path silently blank. #}
|
||||
{{ form_errors(form) }}
|
||||
|
||||
<p class="pb-4 text-sm text-gray-500">
|
||||
{{ resource.type.label }} · {{ resource.label }}
|
||||
</p>
|
||||
|
||||
{{ form_row(form.date) }}
|
||||
|
||||
<div class="flex justify-end gap-2 pt-6">
|
||||
<button type="button" class="button button--neutral" {{ stimulus_action('modal', 'close') }}>
|
||||
Abbrechen
|
||||
</button>
|
||||
<button type="submit" class="button button--primary">
|
||||
Buchen
|
||||
</button>
|
||||
</div>
|
||||
{{ form_end(form) }}
|
||||
{% endblock %}
|
||||
@@ -4,4 +4,36 @@
|
||||
|
||||
{% block content %}
|
||||
<h1>Meine Buchungen</h1>
|
||||
<p class="subline">Alles, was ab heute für dich reserviert ist.</p>
|
||||
|
||||
{% if bookings is empty %}
|
||||
<p class="mt-8 text-sm text-gray-500">
|
||||
Noch nichts gebucht. <a class="underline" href="{{ path('app_dashboard') }}">Zum Raumplan</a>.
|
||||
</p>
|
||||
{% else %}
|
||||
<ul class="mt-8 divide-y divide-gray-200 border-y border-gray-200">
|
||||
{% for booking in bookings %}
|
||||
<li class="flex items-center justify-between gap-4 py-3">
|
||||
<div>
|
||||
<div class="font-semibold">
|
||||
{{ booking.date|format_datetime(pattern: 'EEEE, d. MMMM y') }}
|
||||
</div>
|
||||
<div class="text-sm text-gray-500">
|
||||
{{ booking.resource.type.label }} · {{ booking.resource.label }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<a class="text-sm underline"
|
||||
href="{{ path('app_dashboard', { tag: booking.date|date('Y-m-d') }) }}">Im Plan</a>
|
||||
{# Ordinary form post: this page has no board fragments to swap, so it
|
||||
reloads afterwards rather than pretending to be htmx. #}
|
||||
<form method="post" action="{{ path('app_booking_release', { id: booking.id }) }}">
|
||||
<input type="hidden" name="_token" value="{{ csrf_token('release-' ~ booking.id) }}">
|
||||
<button type="submit" class="button button--small button--neutral">Freigeben</button>
|
||||
</form>
|
||||
</div>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
Reference in new issue
Block a user