- ArrayEditor shows ChevronsUpDown toggle when collapsible with 2+ items
- Toggle appears even without label prop (fixes pricing missing icon)
- Pricing: centralized section state with toggle-all button for all 3 sections
- Collapsible cards with title + hall in label, archive badge
- Archived MCs sorted to bottom, dimmed with "Архив" badge
- Cards have hover + focus-within gold border highlight
- Date validation: error text for missing dates and invalid time ranges
- Search by title/trainer + filter by date (upcoming/past) and hall
- Photo preview with hover overlay (like trainer page)
- ArrayEditor: hiddenItems, getItemBadge props, focus-within styles
- New admin page for shared popup texts (success, waiting list, error, Instagram hint)
- Removed popup fields from MC and Open Day admin editors
- All SignupModals now read from centralized popups config
- Stored as "popups" section in DB with fallback defaults
Admin classes:
- Collapsible cards in ArrayEditor (start collapsed, expand on click)
- Curated 29 dance-relevant icons shown by default, full search as fallback
- Color swatches: used colors dimmed instead of hidden (no layout shift)
User side:
- Classes: icon + name side by side on photo overlay
- ShowcaseLayout: fix image flash during transition (2-frame swap while hidden)
- Team bio: section headings gold, admin cards focus-within highlight
- Replace VictoryItem (type/place/category/competition/city/date) with RichListItem (text + optional link/image)
- Remove VictoryItemListField, DateRangeField, CityField and related helpers
- Remove experience field from admin form and user profile (can be in bio text)
- Simplify TeamProfile: remove victory tabs, show achievements as RichCards
- Fix auto-save: snapshot comparison prevents false saves on focus/blur
- Add save on tab leave (visibilitychange) and page close (sendBeacon)
- Add save after image uploads (main photo, achievements, education)
- Auto-migrate old VictoryItem data to RichListItem format in DB parser
- Photo 150px wide, stretches to match fields height (no empty space)
- Profile header: photo + name/role/instagram inline
- Full-width descriptions and biography below
- Remove extra closing div that caused TS error
- Extract base input classes (baseInput, textAreaInput, smallInput, dashedInput) with gold hover
- Move AutocompleteMulti to shared FormField, support · separator
- Team editor: auto-save with toast, split name into first/last, autocomplete role from class styles
- Team photo: click-to-upload overlay, smaller 130px thumbnail
- Hero videos: play on hover, file size display, 8MB warning, total size performance table
- Remove ctaHref field from Hero admin (unused on frontend)
- Move Toast to shared _components for reuse across admin pages
- Add hall badge to Open Day and Classes booking cards
- Hall in group labels for Open Day and MC tabs
- Hall in reminders event labels
- Save confirmed_hall for group bookings (migration 17)
- Page-level hall filter for all tabs
- Waiting list uses total bookings (matches public display)
- Notes styling: subtle gray text, gold icon + white text on hover
- Cards: sort newly changed to top of status group
- Fix Open Day notes not showing (missing from row type + mapper)
- Auto-note "Лист ожидания" for registrations when class is full
- Waiting list triggers on confirmed count (not total registrations)
- Card highlight + scroll after status change
- Hover effect on booking cards
- Freshly changed cards appear first in their status group
- Polling no longer remounts tabs (fixes page jump on approve)
- Fix MasterClassesData missing waitingListText type
- Add Turbopack troubleshooting docs to CLAUDE.md
- Admin: "Добавить скидку" toggle — OFF hides discount fields and sets to 0
- Public: discount line hidden when discountPrice=0
- Success popup: removed price/booking count info
- 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
- Class duration: editable end time (was hardcoded +1h), shown as range
- Max participants per class (0 = unlimited), shown as "3/10 чел."
- New DB migration 14: max_participants column on open_day_classes
- Min bookings moved to separate row with hint text
- "Скидка" renamed to "Цена со скидкой" for clarity
- Cancel/recover icon: Ban for cancel, RotateCcw for recover
Replace wide multi-column hall grid with hall selector tabs + single
column time slots. Each hall tab shows class count badge. Scales
better as more halls are added.
Напоминания card now shows: не спрош. (gold), придёт (green),
не придёт (red) — same visual style as booking cards. Clickable
to navigate to reminders tab. Skipped "нет ответа" per user request.
- Clicking a status count always sets that filter, even when navigating
to a different tab (previously toggled off if same filter was active)
- Click card background to reset filter to 'all'
- Hover underline on status count links
- Dashboard cards show all 4 statuses inline: new (gold), contacted (blue),
confirmed (green), declined (red) — big numbers with consistent status colors
- Each number+label is clickable to filter the tab by that status
- Tab bar restored below dashboard
- Removed filter chips from SearchBar (dashboard handles filtering)
- Open Day card uses cyan border (distinct from blue contacted status)
- Extract MS_PER_DAY constant to lib/constants.ts
- ConfirmModal date: max=1 year, rejects past dates and malformed years
- ConfirmModal pre-fills existing date + group when re-editing (✎)
- Confirmed date display handles malformed dates gracefully
- Red border + error for invalid dates, submit disabled
Confirming a booking for today or tomorrow auto-sets reminder_status
to 'coming'. Confirming for later dates leaves it unset — admin will
need to check closer to the event.
When a group booking is confirmed with a date, the reminder status
is automatically set to 'coming' — no need to manually mark it again
in the Reminders tab.
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