shadcn.io is not affiliated with official shadcn/ui
Court Booking Calendar Block for Ark UI
Four courts by the hour from 07:00 to 21:00 with a price in every free hour, a Member rates switch, a 60, 90 or 120 minute span that refuses booked hours, and a Reserve button with a receipt and Undo.
Installation
Overview
Let members see what a court costs before they book it, with this court booking calendar for React with Ark UI. A hairline frame with a plus mark on each corner holds a grid of four courts by the hours from 07:00 to 21:00 on shared hairlines, for Friday 16, Saturday 17 or Sunday 18 October. Every free hour shows its price in the club's off-peak or peak rate, a Switch takes 25 percent off for members, and booked hours are hatched. Press a free hour to set the start, and choose 60, 90 or 120 minutes: the span is shaded across the following hours, and if a booked hour is in the way the foot says which ("Court 2 is booked at 19:00") instead of reserving. The foot names the booking and its price ("Court 3, 19:00 to 20:30: £42") and the Shine Button turns it into a receipt with Undo. The grid is one tab stop with arrow keys, and on a phone the court names stay while the hours scroll sideways. The bands are ruled by Guides. It's built from Switch, Button, Shine Button and Guides plus native radios and buttons, with a CSS entrance only. For racquet clubs, sports halls and any venue that sells courts by the hour.
FAQ
How do I fill it with my courts and prices?
Edit DAYS for the days and their rates in cents (off, peak and the hour peak peakFrom), COURTS for the courts and BOOKED_LINES for what is already taken, as "day|court|from-to" in whole hours. FIRST_HOUR and LAST_HOUR set the opening hours and CURRENCY the symbol. A price is the hourly rate times the minutes spent in each hour, in integer cents, rounded once per hour.
What happens when a booked hour is in the way?
The span is shaded as far as it goes, but Reserve refuses and the foot says which hour is taken, such as "Court 2 is booked at 19:00". Choose a shorter length or another start and the problem clears. Pressing a booked hour says it is booked and keeps the previous start.
What does the Member rates switch change?
It takes 25 percent off every hour's rate, in the prices on the grid and in the total, with the same rounding. A reservation keeps the price it was made at, so flipping the switch afterwards does not change the receipt.
How do I use it with the keyboard?
The grid is one tab stop. The arrow keys move between hours and courts, Home and End go to the first and last hour of a court, and Enter or Space sets the start. Each hour is a button named with its court, hour, whether it is free and its price.
What stays local, and how do I wire it up?
Everything. Reserving only changes state in the page and nothing is sent or charged. To make it real, load the day's bookings from your API into BOOKED_LINES, post the reservation from the Reserve handler and show the server's answer in the foot, including the case where someone else took the hour first.