feat: booking UX improvements — waiting list, card focus, sort order

- 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
This commit is contained in:
2026-03-25 12:53:45 +03:00
parent b251ee5138
commit eb949f1a37
9 changed files with 75 additions and 28 deletions

View File

@@ -593,15 +593,16 @@ export function addMcRegistration(
name: string,
instagram: string,
telegram?: string,
phone?: string
phone?: string,
notes?: string
): number {
const db = getDb();
const result = db
.prepare(
`INSERT INTO mc_registrations (master_class_title, name, instagram, telegram, phone)
VALUES (?, ?, ?, ?, ?)`
`INSERT INTO mc_registrations (master_class_title, name, instagram, telegram, phone, notes)
VALUES (?, ?, ?, ?, ?, ?)`
)
.run(masterClassTitle, name, instagram, telegram || null, phone || null);
.run(masterClassTitle, name, instagram, telegram || null, phone || null, notes || null);
return result.lastInsertRowid as number;
}
@@ -1103,6 +1104,14 @@ function mapClassRow(r: OpenDayClassRow): OpenDayClass {
};
}
export function getConfirmedOpenDayBookingCount(classId: number): number {
const db = getDb();
const row = db.prepare(
"SELECT COUNT(*) as cnt FROM open_day_bookings WHERE class_id = ? AND status = 'confirmed'"
).get(classId) as { cnt: number };
return row.cnt;
}
export function setOpenDayBookingStatus(id: number, status: string): void {
const db = getDb();
db.prepare("UPDATE open_day_bookings SET status = ?, notified_confirm = 1 WHERE id = ?").run(status, id);
@@ -1297,15 +1306,15 @@ export function deleteOpenDayClass(id: number): void {
export function addOpenDayBooking(
classId: number,
eventId: number,
data: { name: string; phone: string; instagram?: string; telegram?: string }
data: { name: string; phone: string; instagram?: string; telegram?: string; notes?: string }
): number {
const db = getDb();
const result = db
.prepare(
`INSERT INTO open_day_bookings (class_id, event_id, name, phone, instagram, telegram)
VALUES (?, ?, ?, ?, ?, ?)`
`INSERT INTO open_day_bookings (class_id, event_id, name, phone, instagram, telegram, notes)
VALUES (?, ?, ?, ?, ?, ?, ?)`
)
.run(classId, eventId, data.name, data.phone, data.instagram || null, data.telegram || null);
.run(classId, eventId, data.name, data.phone, data.instagram || null, data.telegram || null, data.notes || null);
return result.lastInsertRowid as number;
}