I wanted to use a regular <a>, but apparently rendering that many
anchors is too resource-intensive for Firefox, and it is noticeably
slower. It was even worse, in fact, because i had to have different
content for the main grid and the grid show in the new booking form,
as i did not want to have these links there, and had call a template for
each cell: 3 months × ~30 days × ~100 campsites = 9000 calls!
Using JavaScript for that is shameful, but it does not add much to the
existing markup, and no need for template fuckery.
I am using double-click to follow these links, instead of single click,
because it would be too easy to misclik on the grid, but that forced me
to add `user-select: none` to prevent the selection of text when double-
clicking.
It does nothing but compute the total of a booking, much like it does
for guests. In fact, i use the same payment relations to do the exact
same computation, otherwise i am afraid i will make a mistake in the
ACSI or such, now or in future version; better if both are exactly the
same.
The idea is that once the user creates the booking, i will delete that
payment, because it makes no sense to keep it in this case; nobody is
going to pay for it.
Had to reuse the grid showing the bookings of campsites because
employees need to select one or more campsites to book, and need to see
which are available. In this case, i have to filter by campsite type
and use the arrival and departure dates to filter the months, now up to
the day, not just month.
Had to change max width of th and td in the grid to take into account
that now a month could have a single day, for instance, and the month
heading can not stretch the day or booking spans would not be in their
correct positions.
For that, i needed to access campsiteEntry, bookingEntry, and Month from
campsite package, but campsite imports campsite/types, and
campsite/types already imports booking for the BookingDates type. To
break the cycle, had to move all that to booking and use from campsite;
it is mostly unchanged, except for the granularity of dates up to days
instead of just months.
The design of this form calls for a different way of showing the totals,
because here employees have to see the amount next to the input with
the units, instead of having a footer with the table. I did not like
the idea of having to query the database for that, therefore i “lifter”
the payment draft into a struct that both public and admin forms use
to show they respective views of the cart.
I need the campsite_id in booking to know what row to show the booking
at. Besides the need of knowing which actual campsite has been booked,
of course.
This field is nullable because we can not now it until an employee has
confirmed the booking; until that point we only know the campsite type
customer requested. I do not care much if the campsite_id is from a
different campsite_type, because maybe the customer requested the change
by phone or what have you, therefore the database can not be that
strict. It must have a value if the booking is confirmed.
It helps me if the arrival_date and departure_date is a single
daterange, because then i can use `&&` and other range operators to work
with these dates. For instance, i have to intersect it with the range
displayed on the screen in order to know which day i have to put it.
But then i have to know whether the booking begins and ends in the
display range, because i only have to show arrival and departure (i.e.,
the box half-way within the first or last boxes) on these days only.
Customer told us that they are used to a view of the booking status of
each campsite in the form of a grid: each campsite is a row, and each
day a column; bookings are show as boxes from the first day to the last
day on the corresponding campsite’s row.
I do not yet show the booking boxes, but at least now i have the grid
and date selector form in place.
In the form i would need a couple of input[type=month], but this is not
yet supported in Firefox and Safari. According to MDN, one common way
to bypass that problem is to have two fields, one for the month and the
other for the year; i just did that, but had to create a new input type
in the `form` package just for this.
A small page with a brief description, carousel, and feature list of
each individual accommodation.
Most of the relations and functions for carousel and features are like
the ones for campsite types, but i had to use the accommodation’s label
to find them, because they do not have slugs; i did not even though
these would be public, and they already have a label, although not
unique for all companies, like UUID slugs are.
It seems that the prefix got removed in one of the edits.
Also, Affinity does not give a fuck to what classes we give to the
elements, and just removes them, thus .guest-only no longer matches, and
had to hide the layers by id. Hope they hold this time.
I tried to use ../, and ../../ to make the routes relatives, but it
would not work well because the same page would have two URLs, one
ending with slash and another without, and the relative links would be
different on each case.
This is mostly because it is required for the “Digital Kit”, but it also
works in our favor because now i can version the URL to the static
resources.
Go 1.18 adds the info from git if the package is build from a git
repository, but this is not the case in OBS, so i instead relay on a
constant for the version number. This constant is “updated” by Debian’s
rules, mostly due to the discussion in [0].
[0]: https://github.com/golang/go/issues/22706
We discussed with Oriol how to show these “extra” menu items, as they
can’t be in the horizontal menu we have intended for employees, because
there is not enough horizontal space.
Oriol suggested to move these into the user menu. In fact, the company
settings was already there, which means that i already wanted to do that
from the very beginning, i believe, but i must have forgotten it along
the way…. Or maybe it was because this is where Numerus has the company
settings menu item, too, and i did not see the relation with the rest;
i do not know.
I am using the US terms for campground and campsite, that’s why the
relation is called ‘campsite’ instead of ‘pitch’, but i used the wrong
terminology in the SVG map because the customer uses the UK term and
call themselves campsite, so i mixed things.
It is now the campground map and each individual area is a campsite,
as i have been using all along.
I intend to use the same SVG file for customers and employees, so i had
to change Oriol’s design to add a class to layers that are supposed to
be only for customers, like trees. These are hidden in the admin area.
I understood that customers and employees have to click on a campsite to
select it, and then they can book or whatever they need to do to them.
Since customers and employees most certainly will need to have different
listeners on campsites, i decided to add the link with JavaScript. To
do so, i need a custom XML attribute with the campsite’s identifier.
Since i have seen that all campsites have a label, i changed the
“identifier” to the unique combination (company_id, label). The
company_id is there because different companies could have the same
label; i left the campsite_id primary key for foreign constraints.
In this case, as a test, i add an <a> element to the campsite with a
link to edit it; we’ll discuss with Oriol what exactly it needs to do.
However, the original design had the labels in a different layer, that
interfered with the link, as the numbers must be above the path and
the link must wrap the path in order to “inherit” its shape. I had no
other recourse than to move the labels in the same layer as the paths’.
I realized that tax details, campsite types, and campsites pages are all
part of the settings of the company, in the sense that all of them are
set up by a company administrator, and should be under the same item in
the user menu.
The template for these tabs is in the same layout.gohtml file because
i did not want to repeat the tabs everywhere it were used, or i would
forget some of them when adding new tabs, and did not want to add a new
file just for that.
For now, there is only the label, type, and active fields. We will need
some field to hold the area on the map, but this requires #4, and
possibly #6, to be finished.
Part of #27.