When a booking status is changed, confirmed, or deleted in any tab,
the dashboard summary cards re-fetch to show updated counts. Previously
the dashboard was stale until page reload.
Multi-session master classes are a series — once the first session
passes, the group has started and registration closes. Changed all
MC date logic from "latest slot" / "any future slot" to "earliest slot":
- DashboardSummary: upcoming = earliest slot >= today
- McRegistrationsTab: archive = earliest slot < today
- AddBookingModal: only show MCs where earliest slot >= today
- Public MasterClasses: isUpcoming checks earliest slot
- Status filter chips stay visible during text search
- Search results filtered by selected status (search + filter = AND)
- Shows "Нет записей по фильтру" when search has results but filter excludes all
- Remove FilterTabs from inside each booking tab
- Add compact status chips (Все/Новая/Связались/Подтверждено/Отказ)
below the search bar — one global filter for all tabs
- Filter chips hidden during active text search
- Status filter toggles on click (click again to deselect)
- GenericBookingsList accepts filter as prop instead of managing internally
When all booking groups are archived (e.g. past MC events), the filter
pills no longer show 'Новая 5' etc. Instead shows 'Все записи в архиве'
with archive auto-expanded. Filter counts now exclude archived items.
- BUG-1: Strip HTML tags in sanitizeName (prevent stored XSS)
- BUG-2: Strip HTML tags in notes via sanitizeText across all 3 booking APIs
- BUG-3: Dashboard excludes archived/past MCs and expired Open Day events from counts
- BUG-4: Truncate long names in booking cards to prevent overflow
- #1 Delete confirmation dialog before removing bookings
- #2 Error toasts instead of silent .catch(() => {})
- #3 Optimistic rollback — UI reverts on API failure
- #4 Loading indicator on reminder status buttons
- #5 Search results are now actionable (status change + delete)
- #6 New bookings banner instead of full tab remount
- #7 Error states for failed data loads
- #8 InlineNotes only saves on blur when value changed
- #9 AddBookingModal supports Instagram/Telegram fields
- #10 Polling pauses when browser tab is hidden
- #11 Enter key submits ConfirmModal
- Reminders query now includes 'contacted' group bookings with confirmed_date,
preventing people from being forgotten when admin hasn't clicked "Подтвердить"
- Confirmation details (group, date) remain visible regardless of booking status,
so "Вернуть" no longer hides previously entered info
Phase 1 — Refactor:
- Split monolith _shared.tsx into types.ts, BookingComponents, InlineNotes,
GenericBookingsList, AddBookingModal, SearchBar (no more _ prefix)
- All 3 tabs use GenericBookingsList — shared status workflow, filters, archive
Phase 2 — Features:
- DB migration 13: add notes column to all booking tables
- Inline notes with amber highlight, auto-save 800ms debounce
- Confirm modal comment saves to notes field
- Manual add: 2 tabs (Занятие / Мероприятие), filters expired MCs, Open Day support
- Search bar: cross-table search by name/phone
- 10s polling for real-time updates (bookings page + sidebar badge)
- Status change marks booking as seen (fixes unread count on reset)
- Confirm modal stores human-readable group label instead of raw groupId
- Confirmed group bookings appear in Reminders tab
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Dashboard cards show new/pending counts per tab, click to navigate
- MC tab: expired master classes (past date or deleted) move to collapsible archive
- Open Day tab: past events move to archive section
- Date badges on MC group headers (gold active, strikethrough archived)
- Fix MC content API key (masterClasses not master-classes)
- Fuzzy title matching for MC registration → content date lookup
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- DB migration v12: add status column to mc_registrations and open_day_bookings
- MC and Open Day tabs now have full status workflow (new → contacted → confirmed/declined)
- Filter tabs with counts, status badges, action buttons matching group bookings
- Extract shared components (_shared.tsx): FilterTabs, StatusBadge, StatusActions, BookingCard, ContactLinks
- Split monolith into _McRegistrationsTab.tsx, _OpenDayBookingsTab.tsx, _shared.tsx
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add confirmed_date, confirmed_group, confirmed_comment to group_bookings (migration #10)
- Linear booking flow: Новая → Связались → Подтвердить (modal) / Отказ
- Confirm modal with cascading selects: Hall → Trainer → Group → Date → Comment
- Groups merged by groupId — shows all days/times (e.g. "СР 20:00, ПТ 16:15")
- Auto-prefill hall/trainer/group from booking's groupInfo via fuzzy scoring
- Proper SHORT_DAYS constant for weekday abbreviations
- Filter chips with status counts, declined sorted to bottom
- "Вернуть" on confirmed/declined returns to "Связались" (not "Новая")
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Admin already contacted the person, so reopened bookings skip "Новая" state.
Renamed button from "Сбросить" to "Вернуть".
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add status + confirmed_date columns to group_bookings (migration #10)
- Linear flow: Новая shows "Связались →", Связались shows date picker + "Отказ"
- Date picker for confirmation allows only today and future dates
- Confirmed bookings show the scheduled date
- Filter chips: Все / Новая / Связались / Подтверждено / Отказ with counts
- Declined bookings sorted to bottom of list
- "Сбросить" button on confirmed/declined to restart flow
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Group reminders by event within each day (e.g. "Master class · 16:00")
- Stats (придёт/не придёт/нет ответа/не спрошены) shown per event, not per day
- People separated by status with colored tag labels for easy scanning
- "Нет ответа" now amber when active (was neutral gray, confused with unselected)
- Cancelled people faded (opacity-50)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Auto-surfaces bookings for today and tomorrow. Admin sets status per
person: coming, no answer, or cancelled. Summary stats per day.
DB migration 8 adds reminder_status column to all booking tables.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- MC registrations: notification toggles (confirm/remind) with urgency
- Group bookings: save to DB from BookingModal, admin CRUD at /admin/bookings
- Open Day: full event system with schedule grid (halls × time), per-class
booking, discount pricing (30 BYN / 20 BYN from 3+), auto-cancel threshold
- Unified SignupModal replaces 3 separate forms — consistent fields
(name, phone, instagram, telegram), Instagram DM fallback on network error
- Centralized /admin/bookings page with 3 tabs (classes, MC, Open Day),
collapsible sections, notification toggles, filter chips
- Unread booking badge on sidebar + dashboard widget with per-type breakdown
- Pricing: contact hint (Instagram/Telegram/phone) on price & rental tabs,
admin toggle to show/hide
- DB migrations 5-7: group_bookings table, open_day tables, unified fields
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>