Files
blackheart-website/docs/booking-status-flow-plan.md
diana.dolgolyova d08905ee93 feat: min/max participants — shared ParticipantLimits component
- New ParticipantLimits component in FormField.tsx (reusable)
- Used in both Open Day settings and MC editor — identical layout
- Open Day: event-level min/max (DB migration 15)
- MC: per-event min/max (JSON fields)
- Public: waiting list when full, spots counter, amber success modal
2026-03-24 22:11:10 +03:00

6.1 KiB

Booking Status Flow — Planned Changes

Current Flow (What We Have Now)

new ──["Связались →"]──→ contacted ──["Подтвердить"]──→ confirmed
                                    ──["Отказ"]──→ declined

confirmed ──["Вернуть"]──→ contacted
declined  ──["Вернуть"]──→ contacted

What buttons appear at each status:

Status Buttons shown
new "Связались →"
contacted "Подтвердить", "Отказ"
confirmed "Вернуть"
declined "Вернуть"

Problems Found

1. Can't confirm directly from new

Someone calls, books, and confirms in one conversation. Admin must click "Связались" → wait → click "Подтвердить". Two clicks for one real-world action.

2. Can't decline from new

Spam or invalid booking arrives. Admin must first mark "Связались" (lie) → then "Отказ".

3. Reminders miss non-confirmed group bookings

SQL query in db.ts line 870:

WHERE status = 'confirmed' AND confirmed_date IN (?, ?)

If admin contacted someone and set a date but forgot to click "Подтвердить", that person never shows up in reminders tab.

MC registrations don't have this problem — they show by event date regardless of status.

4. Two status systems don't talk to each other

Same person can be:

  • confirmed in bookings tab
  • cancelled in reminders tab

No warning, no sync.

5. "Вернуть" hides confirmation details

Confirmed booking has group + date info displayed. "Вернуть" → status becomes contacted → info becomes invisible (still in DB, but UI only shows it when status === "confirmed"). Re-confirming requires filling everything again from scratch.


Proposed Flow (What We Want)

new ──["Связались →"]──→ contacted
new ──["Подтвердить"]──→ confirmed       ← NEW shortcut
new ──["Отказ"]──→ declined              ← NEW shortcut

contacted ──["Подтвердить"]──→ confirmed
contacted ──["Отказ"]──→ declined

confirmed ──["Вернуть"]──→ contacted
declined  ──["Вернуть"]──→ new           ← CHANGED (was: contacted)

New buttons at each status:

Status Buttons shown
new "Связались →", "Подтвердить", "Отказ"
contacted "Подтвердить", "Отказ"
confirmed "Вернуть" (→ contacted)
declined "Вернуть" (→ new)

Files To Change

1. src/app/admin/bookings/BookingComponents.tsx (StatusActions)

What: Add "Подтвердить" and "Отказ" buttons to new status. Change "Вернуть" from declined to go to new instead of contacted.

Before:

{status === "new" && actionBtn("Связались →", ...)}
{status === "contacted" && (
  actionBtn("Подтвердить", ...) + actionBtn("Отказ", ...)
)}
{(status === "confirmed" || status === "declined") && actionBtn("Вернуть",  "contacted")}

After:

{status === "new" && (
  actionBtn("Связались →",  "contacted")
  + actionBtn("Подтвердить",  "confirmed")
  + actionBtn("Отказ",  "declined")
)}
{status === "contacted" && (
  actionBtn("Подтвердить",  "confirmed")
  + actionBtn("Отказ",  "declined")
)}
{status === "confirmed" && actionBtn("Вернуть",  "contacted")}
{status === "declined" && actionBtn("Вернуть",  "new")}

2. src/app/admin/bookings/GenericBookingsList.tsx (renderItem)

What: Show confirmation details (group, date) even when status is not confirmed, so they remain visible after "Вернуть".

Before: renderExtra only shows confirmed details when b.status === "confirmed" After: Show confirmed details whenever they exist, regardless of status (this is actually in page.tsx GroupBookingsTab renderExtra — line 291)

3. src/app/admin/bookings/page.tsx (GroupBookingsTab renderExtra)

What: Change condition from b.status === "confirmed" && (b.confirmedGroup || ...) to just (b.confirmedGroup || b.confirmedDate).

Before:

{b.status === "confirmed" && (b.confirmedGroup || b.confirmedDate) && (
  <span className="text-[10px] text-emerald-400/70">...</span>
)}

After:

{(b.confirmedGroup || b.confirmedDate) && (
  <span className="text-[10px] text-emerald-400/70">...</span>
)}

4. src/lib/db.ts (getUpcomingReminders, ~line 870)

What: Include contacted group bookings with a confirmed_date in reminders, not just confirmed ones.

Before:

SELECT * FROM group_bookings WHERE status = 'confirmed' AND confirmed_date IN (?, ?)

After:

SELECT * FROM group_bookings WHERE status IN ('confirmed', 'contacted') AND confirmed_date IN (?, ?)

Files NOT Changed

  • types.ts — BookingStatus type stays the same (new | contacted | confirmed | declined)
  • SearchBar.tsx — No changes needed
  • AddBookingModal.tsx — No changes needed
  • InlineNotes.tsx — No changes needed
  • McRegistrationsTab.tsx — No changes needed (MC doesn't use ConfirmModal)
  • OpenDayBookingsTab.tsx — No changes needed
  • API routes — No changes needed (they already accept any valid status)

Summary

Change File Risk
Add confirm/decline buttons to new status BookingComponents.tsx Low — additive
"Вернуть" from declined → new instead of contacted BookingComponents.tsx Low — minor behavior change
Show confirmation details at any status page.tsx (renderExtra) Low — visual only
Include contacted bookings in reminders db.ts Low — shows more data, not less