This week a coaching client was having trouble building a session booking solution in Bubble™. I hadn’t yet built anything like this yet, and couldn’t find any plugin’s that met the need, so I decided to dive in and see what I could do.
Requirements
- Provide various experts with the ability to determine their daily availability
- Provide site users with the ability to book sessions with any of the experts
- Allow the experts to sync their free/busy time from their Google calendar to prevent double-booking
Approach
- Data things
- Availability – each with a range of time and a day of week
- Session – a booked appointment between a User and an Expert
- Logic — I have seen a few solutions that basically chop the available time into slots and store those slots in the database. The problem with that is that you are hard-coding the session duration which seems inflexible to me. I wanted to support a variable duration session, so the available sessions will be displayed in realtime by calculating the number of sessions possible using a user provided session duration along with a session buffer allowing for downtime between sessions. Sessions will be stored in the db in a manner one might expect. An API connection to Google Calendar events getting free/busy information will be used to block out time from the vendor’s schedule outside of this system.
The Build
- Vendor availability – I started with the vendor availability. Bubble™ has a date-range data type, so it makes sense to go with this. It basically is a start and end point of time, but it allows us to make cool comparisons with other time like does it overlap, does it contain, etc. I want the vendor to be able to establish their baseline availability by day of week — in other words, I’m free from 9:00 – 4:00 on Monday’s, 8:30 – 12:00; 1:00 – 5:00 on Tuesday’s, etc. Basically working hours. So all that is needed here, is to let the vendor enter in these date/time ranges for each day of the week — in the db it is simply an entry with day of week, the vendor and a single date-range. The vendor enters these in with simple input fields set for time only since we don’t care about the actual date on availability.
- Session Booking Reusable element
- Weekly calendar – The first main element in booking is a horizontal repeating group used to display 7 columns representing 7 consecutive dates. It allows you to set the first date of the group, and then iterates out 6 more days. It has a couple scroll arrows, and a date selector.
- Each day – By creating this as a repeating group, we are just building the core functionality of sessions for a single day, and then letting that repeat across for each subsequent date.
- Hidden logic elements for availability – Because Bubble™ doesn’t always have the direct “code-like” functions we need, I’m using hidden elements to store calculations, values, etc. In the build, I explode these out for ease of edit, but later in the process, they are ganged together in small space and hidden behind the session displayed information.
-
Number of sessions – The first of these elements needed was to calculate the number of sessions that would be needed if all sessions were available, using the Vendor availability. First, I get the availability records for this vendor, for this day of week (Bubble™ has the extract: modifier so we can easily know the day of week based on any date.) I then calculate the number of minutes by simply subtracting the start of the range from the end (again, Bubble™ makes this easy, with a simple operation.) The total number of minutes however is not quite enough — I also add the number of minutes being used as the session buffer. Without doing this, the available sessions is cut short (in later calcs) because I enforce the need for a buffer, but because the available session ends, I don’t need a buffer for the last session in the list. With total minutes in hand, I can simply divide by the sum of the desired session duration plus the session buffer. Voilà, number of sessions.
-
- Availability ranges – The first repeating group in the day holds the availability ranges of the vendor. They can have none, one, or many ranges within each day, so we repeat our calculations for each range.
-
Hidden logic elements for sessions — for sessions I have some calculated values used later in the establishing of each session time. I’m basically starting with the start time of availability and adding time to each session to figure out the end time and start time of next session.
- Sessions – We finally get down to the actual sessions. This is a repeating group based on the number of sessions from above. (Probably important to note here that because these repeating groups are being calculated on the fly, I’m using a ListofNumbers element from the Toolbox plugin to create all these repeating groups in use throughout this booking feature. The repeating group is therefore, a list of numbers which is nothing more than placeholders for everything.) The display of a session is just a button that displays text of the start and end times for this range. I use the repeating group index to multiple the session information out, and calculate the start and end times of the session.
-
- Unavailable sessions – A session is unavailable in two possible conditions:
- Free/Busy – By pulling in the free/busy information (details in another post someday) we can hide any session that is not valid for a new booking. We use the overlap: operation as a condition on the session display to see if this session overlaps with any busy time from the vendor schedule.
- Booked session – We similarly use the overlap: operation as a condition of session display on the sessions booked for this vendor. The overlap is great here because it accounts for the variable length of sessions. In other words, it will block out a session even it a booked session only overlaps by 10 minutes.
- Hidden logic elements for availability – Because Bubble™ doesn’t always have the direct “code-like” functions we need, I’m using hidden elements to store calculations, values, etc. In the build, I explode these out for ease of edit, but later in the process, they are ganged together in small space and hidden behind the session displayed information.