The shared public booking flow: state, events, and markup used by BOTH
Public.BookLive (the routed page) and Public.BookingWidgetLive (the
live_render/3 embeddable). The two LiveViews stay thin shells that
delegate handle_event/3 + handle_info/2 here — one flow, two mounts,
because an embeddable LiveView must not export handle_params/3
(Phoenix refuses to mount it outside a router live route).
Steps
:pick (mode-aware slot/date/range picker) → :details (customer form
or login gate) → :done (confirmation + manage link). The picker panel
varies by the service's shape:
- fixed slots — date input + slot button grid (
Engine.bookable_slots) - free-form — date + start/end time inputs, validated server-side
- day/night — check-in/check-out date inputs + remaining-capacity note
Live updates
Mounting flows subscribe to the service's PubSub topic; any booking mutation re-runs the current picker query, so a slot taken in another session greys out in real time.
Summary
Functions
Initializes flow assigns for a mounted LiveView. user is the viewer's
%{uuid, email}-shaped struct or nil; prefill optionally seeds the
customer form (embed contract).
Releases the visitor's hold when their LiveView goes away — both public
LVs call this from terminate/2.
Re-queries the data behind the current picker panel.
Functions
Initializes flow assigns for a mounted LiveView. user is the viewer's
%{uuid, email}-shaped struct or nil; prefill optionally seeds the
customer form (embed contract).
Attributes
service(PhoenixKitBookings.Schemas.Service) (required)rules(:list) (required)step(:atom) (required)pick_date(Date) (required)slots(:list) (required)day_capacity(:map) (required)selected_range(:any) (required)customer_form(:any) (required)booking(:any) (required)flow_error(:any) (required)flow_error_reason(:any) - Defaults tonil.waitlist_done(:boolean) - Defaults tofalse.current_user(:any) (required)
Releases the visitor's hold when their LiveView goes away — both public
LVs call this from terminate/2.
Re-queries the data behind the current picker panel.