feat: add status workflow to MC and Open Day bookings, refactor into separate files
- 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>
This commit is contained in:
@@ -229,6 +229,19 @@ const migrations: Migration[] = [
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
version: 12,
|
||||
name: "add_status_to_mc_and_openday",
|
||||
up: (db) => {
|
||||
for (const table of ["mc_registrations", "open_day_bookings"]) {
|
||||
const cols = db.prepare(`PRAGMA table_info(${table})`).all() as { name: string }[];
|
||||
const colNames = new Set(cols.map((c) => c.name));
|
||||
if (!colNames.has("status")) {
|
||||
db.exec(`ALTER TABLE ${table} ADD COLUMN status TEXT NOT NULL DEFAULT 'new'`);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
function runMigrations(db: Database.Database) {
|
||||
@@ -510,6 +523,7 @@ interface McRegistrationRow {
|
||||
notified_confirm: number;
|
||||
notified_reminder: number;
|
||||
reminder_status: string | null;
|
||||
status: string;
|
||||
}
|
||||
|
||||
export interface McRegistration {
|
||||
@@ -523,6 +537,7 @@ export interface McRegistration {
|
||||
notifiedConfirm: boolean;
|
||||
notifiedReminder: boolean;
|
||||
reminderStatus?: string;
|
||||
status: string;
|
||||
}
|
||||
|
||||
export function addMcRegistration(
|
||||
@@ -572,9 +587,15 @@ function mapMcRow(r: McRegistrationRow): McRegistration {
|
||||
notifiedConfirm: !!r.notified_confirm,
|
||||
notifiedReminder: !!r.notified_reminder,
|
||||
reminderStatus: r.reminder_status ?? undefined,
|
||||
status: r.status || "new",
|
||||
};
|
||||
}
|
||||
|
||||
export function setMcRegistrationStatus(id: number, status: string): void {
|
||||
const db = getDb();
|
||||
db.prepare("UPDATE mc_registrations SET status = ? WHERE id = ?").run(status, id);
|
||||
}
|
||||
|
||||
export function updateMcRegistration(
|
||||
id: number,
|
||||
name: string,
|
||||
@@ -928,6 +949,7 @@ interface OpenDayBookingRow {
|
||||
notified_confirm: number;
|
||||
notified_reminder: number;
|
||||
reminder_status: string | null;
|
||||
status: string;
|
||||
created_at: string;
|
||||
class_style?: string;
|
||||
class_trainer?: string;
|
||||
@@ -946,6 +968,7 @@ export interface OpenDayBooking {
|
||||
notifiedConfirm: boolean;
|
||||
notifiedReminder: boolean;
|
||||
reminderStatus?: string;
|
||||
status: string;
|
||||
createdAt: string;
|
||||
classStyle?: string;
|
||||
classTrainer?: string;
|
||||
@@ -982,6 +1005,11 @@ function mapClassRow(r: OpenDayClassRow): OpenDayClass {
|
||||
};
|
||||
}
|
||||
|
||||
export function setOpenDayBookingStatus(id: number, status: string): void {
|
||||
const db = getDb();
|
||||
db.prepare("UPDATE open_day_bookings SET status = ? WHERE id = ?").run(status, id);
|
||||
}
|
||||
|
||||
function mapBookingRow(r: OpenDayBookingRow): OpenDayBooking {
|
||||
return {
|
||||
id: r.id,
|
||||
@@ -994,6 +1022,7 @@ function mapBookingRow(r: OpenDayBookingRow): OpenDayBooking {
|
||||
notifiedConfirm: !!r.notified_confirm,
|
||||
notifiedReminder: !!r.notified_reminder,
|
||||
reminderStatus: r.reminder_status ?? undefined,
|
||||
status: r.status || "new",
|
||||
createdAt: r.created_at,
|
||||
classStyle: r.class_style ?? undefined,
|
||||
classTrainer: r.class_trainer ?? undefined,
|
||||
|
||||
Reference in New Issue
Block a user