Show “Already booked” / booking status per time slot in public booking widget (family-friendly) + prevent duplicate bookings

Many of my clients book recurring weekly classes with limited capacity. They can see multiple similar upcoming slots (e.g., same weekday/time across the next weeks). Currently, when they revisit the booking link days later, the public widget only shows availability and gives no indication that they are already booked for a specific date/time. As a result, users often book the same slot again “just to be safe”, creating duplicate bookings and blocking seats.

Important edge case: Families/partners often use the same email address to book for multiple people (e.g., two children or partner + myself). So any “already booked” logic must not block legitimate bookings that share an email but have different attendee names.

What would solve this:

  1. Per-slot status in the public widget after entering email (or after a booking):

    • “Already booked for this slot” + “Manage booking” (view/reschedule/cancel)
  2. Duplicate prevention only when the exact combination matches: Attendee Name + Email + Timeslot (NOT email alone).

    • Same email, different name → allow booking
  3. Optional: “My bookings” view (no login, via link/code) so users can verify which upcoming slots they booked.

Why it matters:
This reduces duplicate bookings, improves user confidence, and prevents seats from being blocked unnecessarily—especially for recurring weekly schedules.

Acceptance criteria (clear expectations):

  • If a user tries to book the same timeslot again with the same Name + Email → show “Already booked” and do not create a duplicate booking.

  • If the email is the same but the Name differs → allow booking (family/partner scenario).

  • Provide a “Manage booking” link/button where possible.

Optional attachments:

  • Screenshot: calendar availability view without booking status

  • Screenshot: booking modal

  • Screenshot: thank-you page (booking confirmed, but revisiting the widget later shows no status)