jordi fita mas 2c36e45663 Compute and show the “cart” for the booking form
I have to ask number and age ranges of hosts of guests for all campsite
types, not only those that have price options for adults, children, etc.
because i must compute the tourist tax for adults.  These numbers will
be used to generate de rows for guests when actually creating the
booking, which is not done already.

To satisfy the campsite types that do have a price per guest, not only
per night, i had to add the prices for each range in the
campsite_type_cost relation.  If a campsite type does not have price
per person, then that should be zero; the website then does not display
the price.

The minimal price for any campsite type is one adult for one night,
thus to compute the price i need at least the campsite type, the dates,
and the number of adults, that has a minimum of one.  I changed the
order of the form to ask for these values first, so i can compute the
initial price as soon as possible.  To help further, i show the
<fieldset>s progressively when visitors select options.
2024-02-04 06:37:25 +01:00

246 lines
13 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
SPDX-FileCopyrightText: 2023 jordi fita mas <jordi@tandem.blog>
SPDX-FileCopyrightText: 2023 Oriol Carbonell <info@oriolcarbonell.cat>
SPDX-License-Identifier: AGPL-3.0-only
-->
{{ define "title" -}}
{{( pgettext "Booking" "title" )}}
{{- end }}
{{ define "head" -}}
{{ template "alpineScript" }}
{{- end }}
{{ define "content" -}}
{{- /*gotype: dev.tandem.ws/tandem/camper/pkg/booking.publicPage*/ -}}
<h2>{{( pgettext "Booking" "title" )}}</h2>
{{ with .Form -}}
<form id="booking" action="/{{ currentLocale }}/booking" method="post"
x-data="{campsiteType: '', arrivalDate: '', departureDate: '', hasCampsite() { return this.campsiteType !== '' }, hasDates() { return this.arrivalDate !== '' && this.departureDate !== ''} }"
x-init="campsiteType = (document.querySelector('[x-model=campsiteType]:checked') || {}).value || ''"
>
<fieldset
data-hx-get="/{{ currentLocale }}/booking/cart"
data-hx-include="#booking"
data-hx-trigger="load,change"
data-hx-target="#booking footer"
>
<fieldset class="accommodation">
<legend>{{( pgettext "Accommodation" "title" )}}</legend>
{{ range .CampsiteType.Options -}}
<label><input type="radio" name="{{ $.Form.CampsiteType.Name }}" value="{{ .Value }}"
x-model="campsiteType"
{{ if $.Form.CampsiteType.IsSelected .Value }}checked{{ end }}
> {{ .Label }}</label><br>
{{- end }}
{{ template "error-message" .CampsiteType }}
</fieldset>
<fieldset class="booking-period"
x-cloak
x-show="hasCampsite()"
x-transition.duration.250ms
>
<legend>{{( pgettext "Booking Period" "title" )}}</legend>
{{ with .ArrivalDate -}}
<label>
{{( pgettext "Arrival date" "input" )}}<br>
<input type="date" required
min="{{ today }}"
name="{{ .Name }}" value="{{ .Val }}" {{ template "error-attrs" . }}
x-model.fill="arrivalDate"
><br>
</label>
{{ template "error-message" . }}
{{- end }}
{{ with .DepartureDate -}}
<label>
{{( pgettext "Departure date" "input" )}}<br>
<input type="date" required
min="{{ tomorrow }}"
name="{{ .Name }}" value="{{ .Val }}" {{ template "error-attrs" . }}
x-model.fill="departureDate"
><br>
</label>
{{ template "error-message" . }}
{{- end }}
</fieldset>
<fieldset class="guests campsite-options"
x-cloak
x-show="hasCampsite() && hasDates()"
x-transition.duration.250ms
>
<legend>{{( pgettext "Guests" "title" )}}</legend>
{{ with .NumberAdults -}}
<label>
{{( pgettext "Adults aged 17 or older" "input" )}}<br>
<input type="number" required
name="{{ .Name }}" value="{{ .Val }}" min="1"
{{ template "error-attrs" . }}
><br>
</label>
{{ template "error-message" . }}
{{- end }}
{{ with .NumberTeenagers -}}
<label>
{{( pgettext "Teenagers from 11 to 16 years old" "input" )}}<br>
<input type="number" required
name="{{ .Name }}" value="{{ .Val }}" min="0"
{{ template "error-attrs" . }}
><br>
</label>
{{ template "error-message" . }}
{{- end }}
{{ with .NumberChildren -}}
<label>
{{( pgettext "Children from 2 to 10 years old" "input" )}}<br>
<input type="number" required
name="{{ .Name }}" value="{{ .Val }}" min="0"
{{ template "error-attrs" . }}
><br>
</label>
{{ template "error-message" . }}
{{- end }}
{{ with .NumberDogs -}}
<label>
{{( pgettext "Dogs" "input" )}}<br>
<input type="number" required
name="{{ .Name }}" value="{{ .Val }}" min="0"
{{ template "error-attrs" . }}
><br>
</label>
{{ template "error-message" . }}
{{- end }}
</fieldset>
{{ range $campsiteType := .CampsiteType.Options -}}
{{ $options := index $.Form.CampsiteTypeOptions .Value }}
{{ $zonePreferences := index $.Form.ZonePreferences .Value }}
{{ if or $options $zonePreferences }}
<fieldset class="campsite-options"
x-cloak
x-show="campsiteType === '{{ $campsiteType.Value }}' && hasDates()"
x-transition.duration.250ms>
<legend>{{ .Label }}</legend>
{{ with $zonePreferences -}}
<label>
<span>
{{( pgettext "Area preferences (optional)" "input" )}}
<a href="/{{ currentLocale }}/campground?zones"
target="_blank">{{( gettext "Campground map" )}}</a>
</span><br>
<input type="text"
name="{{ .Name }}" value="{{ .Val }}" {{ template "error-attrs" . }}
><br>
</label>
{{ template "error-message" . }}
{{- end }}
{{ range $options -}}
<label>
{{ .Label }}<br>
<input type="number" required
name="{{ .Input.Name }}" value="{{ .Input.Val }}"
min="{{ .Min }}" max="{{ .Max }}"
{{ template "error-attrs" .Input }}
><br>
</label>
{{ template "error-message" .Input }}
{{- end }}
</fieldset>
{{- end }}
{{- end }}
<fieldset class="customer-details"
x-cloak
x-show="hasCampsite() && hasDates()"
x-transition.duration.250ms
>
<legend>{{( pgettext "Customer Details" "title" )}}</legend>
{{ with .FullName -}}
<label>
{{( pgettext "Full name" "input" )}}<br>
<input type="text" required autocomplete="name" minlength="2"
name="{{ .Name }}" value="{{ .Val }}" {{ template "error-attrs" . }}
><br>
</label>
{{ template "error-message" . }}
{{- end }}
{{ with .Address -}}
<label>
{{( pgettext "Address (optional)" "input" )}}<br>
<input type="text" autocomplete="billing street-address"
name="{{ .Name }}" value="{{ .Val }}" {{ template "error-attrs" . }}
><br>
</label>
{{ template "error-message" . }}
{{- end }}
{{ with .PostalCode -}}
<label>
{{( pgettext "Postcode (optional)" "input" )}}<br>
<input type="text" autocomplete="billing postal-code"
name="{{ .Name }}" value="{{ .Val }}" {{ template "error-attrs" . }}
><br>
</label>
{{ template "error-message" . }}
{{- end }}
{{ with .City -}}
<label>
{{( pgettext "Town or village (optional)" "input" )}}<br>
<input type="text"
name="{{ .Name }}" value="{{ .Val }}" {{ template "error-attrs" . }}
><br>
</label>
{{ template "error-message" . }}
{{- end }}
{{ with .Country -}}
<label>
{{( pgettext "Country" "input" )}}<br>
<select name="{{ .Name }}"
required autocomplete="country">
<option>{{( gettext "Choose a country" )}}</option>
{{ template "error-attrs" . }}>{{ template "list-options" . }}
</select><br>
</label>
{{ template "error-message" . }}
{{- end }}
{{ with .Email -}}
<label>
{{( pgettext "Email" "input" )}}<br>
<input type="email" required autocomplete="email"
name="{{ .Name }}" value="{{ .Val }}" {{ template "error-attrs" . }}
><br>
</label>
{{ template "error-message" . }}
{{- end }}
{{ with .Phone -}}
<label>
{{( pgettext "Phone" "input" )}}<br>
<input type="tel" required autocomplete="tel"
name="{{ .Name }}" value="{{ .Val }}" {{ template "error-attrs" . }}
><br>
</label>
{{ template "error-message" . }}
{{- end }}
{{ with .ACSICard -}}
<label class="full-row">
<input type="checkbox" name="{{ .Name }}" {{ if .Checked}}checked{{ end }}
{{ template "error-attrs" . }}
> {{( pgettext "ACSI card? (optional)" "input" )}}</label><br>
{{ template "error-message" . }}
{{- end }}
{{ with .Agreement -}}
<label class="full-row">
<input type="checkbox" required name="{{ .Name }}" {{ if .Checked}}checked{{ end }}
{{ template "error-attrs" . }}
> {{ printf ( pgettext "I have read and I accept %[1]sthe reservation conditions%[2]s" "input" ) (printf "<a href=\"/%s/legal/reservation\" rel=\"terms-of-service\" target=\"_blank\">" currentLocale) (print "</a>") | raw }}
</label><br>
{{ template "error-message" . }}
{{- end }}
</fieldset>
</fieldset>
<footer :class="hasCampsite() && hasDates() && 'is-visible'">
{{ template "cart.gohtml" $.Cart }}
</footer>
</form>
{{- end }}
<script src="/static/booking-dates.js"></script>
{{- end }}