feat: hall info on booking cards, notes styling, sort + highlight fixes

- 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)
This commit is contained in:
2026-03-25 14:40:24 +03:00
parent eb949f1a37
commit e64119aaa0
7 changed files with 98 additions and 28 deletions

View File

@@ -288,6 +288,16 @@ const migrations: Migration[] = [
}
},
},
{
version: 17,
name: "add_confirmed_hall_to_group_bookings",
up: (db) => {
const cols = db.prepare("PRAGMA table_info(group_bookings)").all() as { name: string }[];
if (!cols.some((c) => c.name === "confirmed_hall")) {
db.exec("ALTER TABLE group_bookings ADD COLUMN confirmed_hall TEXT");
}
},
},
];
function runMigrations(db: Database.Database) {
@@ -689,6 +699,7 @@ interface GroupBookingRow {
status: string;
confirmed_date: string | null;
confirmed_group: string | null;
confirmed_hall: string | null;
confirmed_comment: string | null;
notes: string | null;
created_at: string;
@@ -709,6 +720,7 @@ export interface GroupBooking {
status: BookingStatus;
confirmedDate?: string;
confirmedGroup?: string;
confirmedHall?: string;
confirmedComment?: string;
notes?: string;
createdAt: string;
@@ -748,6 +760,7 @@ export function getGroupBookings(): GroupBooking[] {
status: (r.status || "new") as BookingStatus,
confirmedDate: r.confirmed_date ?? undefined,
confirmedGroup: r.confirmed_group ?? undefined,
confirmedHall: r.confirmed_hall ?? undefined,
confirmedComment: r.confirmed_comment ?? undefined,
notes: r.notes ?? undefined,
createdAt: r.created_at,
@@ -757,7 +770,7 @@ export function getGroupBookings(): GroupBooking[] {
export function setGroupBookingStatus(
id: number,
status: BookingStatus,
confirmation?: { date: string; group: string; comment?: string }
confirmation?: { date: string; group: string; hall?: string; comment?: string }
): void {
const db = getDb();
if (status === "confirmed" && confirmation) {
@@ -766,8 +779,8 @@ export function setGroupBookingStatus(
const tomorrow = new Date(Date.now() + MS_PER_DAY).toISOString().split("T")[0];
const reminderStatus = (confirmation.date === today || confirmation.date === tomorrow) ? "coming" : null;
db.prepare(
"UPDATE group_bookings SET status = ?, confirmed_date = ?, confirmed_group = ?, confirmed_comment = ?, notified_confirm = 1, reminder_status = ? WHERE id = ?"
).run(status, confirmation.date, confirmation.group, confirmation.comment || null, reminderStatus, id);
"UPDATE group_bookings SET status = ?, confirmed_date = ?, confirmed_group = ?, confirmed_hall = ?, confirmed_comment = ?, notified_confirm = 1, reminder_status = ? WHERE id = ?"
).run(status, confirmation.date, confirmation.group, confirmation.hall || null, confirmation.comment || null, reminderStatus, id);
} else {
db.prepare(
"UPDATE group_bookings SET status = ?, confirmed_date = NULL, confirmed_group = NULL, confirmed_comment = NULL, notified_confirm = 1 WHERE id = ?"
@@ -920,6 +933,7 @@ export function getUpcomingReminders(): ReminderItem[] {
telegram: r.telegram ?? undefined,
reminderStatus: r.reminder_status ?? undefined,
eventLabel: r.confirmed_group || "Занятие",
eventHall: r.confirmed_hall ?? undefined,
eventDate: r.confirmed_date!,
});
}
@@ -947,7 +961,8 @@ export function getUpcomingReminders(): ReminderItem[] {
instagram: r.instagram ?? undefined,
telegram: r.telegram ?? undefined,
reminderStatus: r.reminder_status ?? undefined,
eventLabel: `${r.class_style} · ${r.class_trainer} · ${r.class_time} (${r.class_hall})`,
eventLabel: `${r.class_style} · ${r.class_trainer} · ${r.class_time}`,
eventHall: r.class_hall ?? undefined,
eventDate: ev.date,
});
}
@@ -1045,6 +1060,7 @@ interface OpenDayBookingRow {
notified_reminder: number;
reminder_status: string | null;
status: string;
notes: string | null;
created_at: string;
class_style?: string;
class_trainer?: string;
@@ -1064,6 +1080,7 @@ export interface OpenDayBooking {
notifiedReminder: boolean;
reminderStatus?: string;
status: string;
notes?: string;
createdAt: string;
classStyle?: string;
classTrainer?: string;
@@ -1130,6 +1147,7 @@ function mapBookingRow(r: OpenDayBookingRow): OpenDayBooking {
notifiedReminder: !!r.notified_reminder,
reminderStatus: r.reminder_status ?? undefined,
status: r.status || "new",
notes: r.notes ?? undefined,
createdAt: r.created_at,
classStyle: r.class_style ?? undefined,
classTrainer: r.class_trainer ?? undefined,