@fayz-ai/plugin-reservations 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/ReservationsPage-5RF5SYZT.js +1157 -0
- package/dist/ReservationsPage-5RF5SYZT.js.map +1 -0
- package/dist/chunk-7KXGSUHT.js +335 -0
- package/dist/chunk-7KXGSUHT.js.map +1 -0
- package/dist/components/CapacityStrip.d.ts +25 -0
- package/dist/components/CapacityStrip.d.ts.map +1 -0
- package/dist/components/ReservationModal.d.ts +23 -0
- package/dist/components/ReservationModal.d.ts.map +1 -0
- package/dist/components/SeatDialog.d.ts +16 -0
- package/dist/components/SeatDialog.d.ts.map +1 -0
- package/dist/context.d.ts +49 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/data/core-supabase.d.ts +32 -0
- package/dist/data/core-supabase.d.ts.map +1 -0
- package/dist/data/mock.d.ts +3 -0
- package/dist/data/mock.d.ts.map +1 -0
- package/dist/data/types.d.ts +37 -0
- package/dist/data/types.d.ts.map +1 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +870 -0
- package/dist/index.js.map +1 -0
- package/dist/locales/en.d.ts +2 -0
- package/dist/locales/en.d.ts.map +1 -0
- package/dist/locales/index.d.ts +2 -0
- package/dist/locales/index.d.ts.map +1 -0
- package/dist/locales/pt-BR.d.ts +2 -0
- package/dist/locales/pt-BR.d.ts.map +1 -0
- package/dist/migrations/index.d.ts +6 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/store.d.ts +48 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/types.d.ts +174 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/views/CapacitySettingsView.d.ts +3 -0
- package/dist/views/CapacitySettingsView.d.ts.map +1 -0
- package/dist/views/ReservationsListView.d.ts +5 -0
- package/dist/views/ReservationsListView.d.ts.map +1 -0
- package/dist/views/ReservationsPage.d.ts +27 -0
- package/dist/views/ReservationsPage.d.ts.map +1 -0
- package/dist/views/ServiceDayView.d.ts +15 -0
- package/dist/views/ServiceDayView.d.ts.map +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/data/mock.ts","../src/store.ts","../src/locales/en.ts","../src/locales/pt-BR.ts","../src/locales/index.ts","../src/types.ts","../src/migrations/index.ts","../src/index.ts"],"names":["rules","exceptions","settings"],"mappings":"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AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA,CAAA;AAwSnC,IAA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","file":"index.js","sourcesContent":["import type { ReservationsDataProvider } from './types'\nimport type {\n Reservation, CapacityRule, CapacityException, ReservationSettings,\n DaySlot, ReservationZone, ReservationTable, ReservationStatus,\n CreateReservationInput, ReservationQuery, SeatReservationInput, ReservationsSummary,\n} from '../types'\nimport { DEFAULT_SETTINGS } from './core-supabase'\n\n// ---------------------------------------------------------------------------\n// The demo salão. Enough of a night for the screen to be judged before a pool\n// exists — an empty screen cannot be evaluated, and the capacity bar is the\n// whole point of this plugin.\n// ---------------------------------------------------------------------------\n\nconst TENANT = 'mock-tenant'\n\nfunction today(offset = 0): string {\n const d = new Date()\n d.setDate(d.getDate() + offset)\n const m = String(d.getMonth() + 1).padStart(2, '0')\n const day = String(d.getDate()).padStart(2, '0')\n return `${d.getFullYear()}-${m}-${day}`\n}\n\nconst ZONES: ReservationZone[] = [\n { id: 'z-salao', name: 'Salão', color: '#3b82f6' },\n { id: 'z-varanda', name: 'Varanda', color: '#22c55e' },\n]\n\nconst TABLES: ReservationTable[] = [\n { id: 't-1', number: 1, seats: 2, zoneId: 'z-salao', isOccupied: false },\n { id: 't-2', number: 2, seats: 4, zoneId: 'z-salao', isOccupied: true },\n { id: 't-3', number: 3, seats: 4, zoneId: 'z-salao', isOccupied: false },\n { id: 't-7', number: 7, seats: 6, zoneId: 'z-varanda', isOccupied: false },\n { id: 't-8', number: 8, seats: 8, zoneId: 'z-varanda', isOccupied: false },\n]\n\nlet settings: ReservationSettings = { ...DEFAULT_SETTINGS }\n\nlet rules: CapacityRule[] = [\n { id: 'r-almoco', zoneId: 'z-salao', zoneName: 'Salão', capacity: 50, startTime: '12:00', endTime: '15:00', weekdays: [1, 2, 3, 4, 5], isActive: true, tenantId: TENANT },\n { id: 'r-jantar', zoneId: 'z-salao', zoneName: 'Salão', capacity: 80, startTime: '19:00', endTime: '23:00', weekdays: [0, 1, 2, 3, 4, 5, 6], isActive: true, tenantId: TENANT },\n { id: 'r-varanda', zoneId: 'z-varanda', zoneName: 'Varanda', capacity: 24, startTime: '19:00', endTime: '23:00', weekdays: [4, 5, 6], isActive: true, tenantId: TENANT },\n]\n\nlet exceptions: CapacityException[] = []\n\nlet reservations: Reservation[] = [\n { id: 'res-1', guestName: 'Marina Costa', phone: '(11) 98888-1010', zoneId: 'z-salao', zoneName: 'Salão', reservedOn: today(), startTime: '20:00', partySize: 4, occasion: 'birthday', status: 'confirmed', tenantId: TENANT, createdAt: '', updatedAt: '' },\n { id: 'res-2', guestName: 'Eduardo Lima', phone: '(11) 97777-2020', zoneId: 'z-salao', zoneName: 'Salão', reservedOn: today(), startTime: '20:30', partySize: 2, status: 'pending', tenantId: TENANT, createdAt: '', updatedAt: '' },\n { id: 'res-3', guestName: 'Família Tanaka', phone: '(11) 96666-3030', zoneId: 'z-varanda', zoneName: 'Varanda', reservedOn: today(), startTime: '19:30', partySize: 6, occasion: 'business', status: 'seated', tableId: 't-2', tableNumber: 2, orderReference: 'PED-000042', seatedAt: new Date().toISOString(), tenantId: TENANT, createdAt: '', updatedAt: '' },\n { id: 'res-4', guestName: 'Paulo Rezende', zoneId: 'z-salao', zoneName: 'Salão', reservedOn: today(1), startTime: '12:30', partySize: 3, status: 'pending', tenantId: TENANT, createdAt: '', updatedAt: '' },\n]\n\nlet nextId = 5\n\nfunction weekdayOf(date: string): number {\n const [y, m, d] = date.split('-').map(Number)\n return new Date(y, m - 1, d).getDay()\n}\n\nexport function createMockReservationsProvider(): ReservationsDataProvider {\n const provider: ReservationsDataProvider = {\n async getReservations(query?: ReservationQuery): Promise<Reservation[]> {\n let rows = [...reservations]\n if (query?.from) rows = rows.filter((r) => r.reservedOn >= query.from!)\n if (query?.to) rows = rows.filter((r) => r.reservedOn <= query.to!)\n if (query?.zoneId) rows = rows.filter((r) => r.zoneId === query.zoneId)\n if (query?.status) {\n const wanted = Array.isArray(query.status) ? query.status : [query.status]\n rows = rows.filter((r) => wanted.includes(r.status))\n }\n if (query?.search) {\n const term = query.search.toLowerCase()\n rows = rows.filter((r) =>\n r.guestName.toLowerCase().includes(term) || (r.phone ?? '').includes(term))\n }\n return rows.sort((a, b) => (a.reservedOn + a.startTime).localeCompare(b.reservedOn + b.startTime))\n },\n\n async getReservation(id: string) {\n return reservations.find((r) => r.id === id) ?? null\n },\n\n async createReservation(input: CreateReservationInput): Promise<Reservation> {\n const zone = ZONES.find((z) => z.id === input.zoneId)\n const row: Reservation = {\n id: `res-${nextId++}`,\n ...input,\n zoneName: zone?.name,\n zoneColor: zone?.color,\n tableNumber: TABLES.find((t) => t.id === input.tableId)?.number,\n status: input.status ?? (settings.autoConfirm ? 'confirmed' : 'pending'),\n tenantId: TENANT,\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n }\n reservations = [...reservations, row]\n return row\n },\n\n async updateReservation(id: string, data: Partial<CreateReservationInput>): Promise<Reservation> {\n reservations = reservations.map((r) => (r.id === id ? { ...r, ...data } as Reservation : r))\n return reservations.find((r) => r.id === id)!\n },\n\n async setStatus(id: string, status: ReservationStatus): Promise<Reservation> {\n reservations = reservations.map((r) => (r.id === id ? { ...r, status } : r))\n return reservations.find((r) => r.id === id)!\n },\n\n async deleteReservation(id: string): Promise<void> {\n reservations = reservations.filter((r) => r.id !== id)\n },\n\n async seatReservation(input: SeatReservationInput): Promise<Reservation> {\n const table = TABLES.find((t) => t.id === input.tableId)\n reservations = reservations.map((r) =>\n r.id === input.reservationId\n ? {\n ...r,\n status: 'seated' as const,\n tableId: input.tableId,\n tableNumber: table?.number,\n partySize: input.guests ?? r.partySize,\n orderReference: `PED-${String(100 + nextId).padStart(6, '0')}`,\n seatedAt: new Date().toISOString(),\n }\n : r)\n if (table) table.isOccupied = true\n return reservations.find((r) => r.id === input.reservationId)!\n },\n\n async getDayCapacity(date: string): Promise<DaySlot[]> {\n const dow = weekdayOf(date)\n const overridden = new Set(\n exceptions.filter((e) => date >= e.startsOn && date <= e.endsOn).map((e) => e.zoneId))\n\n const fromExceptions: DaySlot[] = exceptions\n .filter((e) => date >= e.startsOn && date <= e.endsOn && e.capacity > 0)\n .map((e) => ({\n zoneId: e.zoneId, zoneName: e.zoneName, zoneColor: ZONES.find((z) => z.id === e.zoneId)?.color,\n startTime: e.startTime ?? '00:00', endTime: e.endTime ?? '23:59',\n capacity: e.capacity, booked: 0, remaining: e.capacity, isException: true,\n }))\n\n const fromRules: DaySlot[] = rules\n .filter((r) => r.isActive && r.weekdays.includes(dow) && !overridden.has(r.zoneId))\n .map((r) => ({\n zoneId: r.zoneId, zoneName: r.zoneName, zoneColor: ZONES.find((z) => z.id === r.zoneId)?.color,\n startTime: r.startTime, endTime: r.endTime,\n capacity: r.capacity, booked: 0, remaining: r.capacity, isException: false,\n }))\n\n // The reservation spends the window it STARTS in — the V1's own rule,\n // \"sem rolagem entre faixas\".\n return [...fromExceptions, ...fromRules]\n .map((slot) => {\n const booked = reservations\n .filter((r) => r.reservedOn === date && r.status !== 'cancelled')\n .filter((r) => !slot.zoneId || r.zoneId === slot.zoneId)\n .filter((r) => r.startTime >= slot.startTime && r.startTime < slot.endTime)\n .reduce((sum, r) => sum + r.partySize, 0)\n return { ...slot, booked, remaining: Math.max(slot.capacity - booked, 0) }\n })\n .sort((a, b) => a.startTime.localeCompare(b.startTime))\n },\n\n async getCapacityRules() { return [...rules] },\n\n async saveCapacityRule(rule): Promise<CapacityRule> {\n const zone = ZONES.find((z) => z.id === rule.zoneId)\n if (rule.id) {\n rules = rules.map((r) => (r.id === rule.id ? { ...r, ...rule, zoneName: zone?.name } as CapacityRule : r))\n return rules.find((r) => r.id === rule.id)!\n }\n const row = {\n ...rule, id: `r-${nextId++}`, zoneName: zone?.name,\n weekdays: rule.weekdays ?? [0, 1, 2, 3, 4, 5, 6],\n isActive: rule.isActive !== false, tenantId: TENANT,\n } as CapacityRule\n rules = [...rules, row]\n return row\n },\n\n async deleteCapacityRule(id: string) { rules = rules.filter((r) => r.id !== id) },\n\n async getCapacityExceptions() { return [...exceptions] },\n\n async saveCapacityException(ex): Promise<CapacityException> {\n const zone = ZONES.find((z) => z.id === ex.zoneId)\n if (ex.id) {\n exceptions = exceptions.map((e) => (e.id === ex.id ? { ...e, ...ex, zoneName: zone?.name } as CapacityException : e))\n return exceptions.find((e) => e.id === ex.id)!\n }\n const row = {\n ...ex, id: `e-${nextId++}`, zoneName: zone?.name,\n endsOn: ex.endsOn ?? ex.startsOn!, capacity: ex.capacity ?? 0, tenantId: TENANT,\n } as CapacityException\n exceptions = [...exceptions, row]\n return row\n },\n\n async deleteCapacityException(id: string) { exceptions = exceptions.filter((e) => e.id !== id) },\n\n async getSettings() { return { ...settings } },\n async saveSettings(next: ReservationSettings) { settings = { ...next }; return settings },\n\n async getZones() { return [...ZONES] },\n async getTables(zoneId?: string) {\n return TABLES.filter((t) => !zoneId || t.zoneId === zoneId)\n },\n\n async getSummary(date: string): Promise<ReservationsSummary> {\n const rows = reservations.filter((r) => r.reservedOn === date)\n const count = (s: ReservationStatus) => rows.filter((r) => r.status === s).length\n return {\n total: rows.length,\n pending: count('pending'),\n confirmed: count('confirmed'),\n seated: count('seated'),\n noShow: count('no_show'),\n cancelled: count('cancelled'),\n expectedGuests: rows\n .filter((r) => !['cancelled', 'no_show'].includes(r.status))\n .reduce((sum, r) => sum + r.partySize, 0),\n }\n },\n }\n return provider\n}\n","import { createStore, type StoreApi } from 'zustand/vanilla'\nimport { toast } from 'sonner'\nimport type { ReservationsDataProvider } from './data/types'\nimport type {\n Reservation, CapacityRule, CapacityException, ReservationSettings,\n DaySlot, ReservationZone, ReservationTable, ReservationStatus,\n CreateReservationInput, ReservationQuery, ReservationsSummary,\n} from './types'\n\nexport interface ReservationsUIState {\n /** The day the service view is looking at, as `YYYY-MM-DD` local. */\n selectedDate: string\n\n slots: DaySlot[]\n slotsLoading: boolean\n /** The grid answered nothing for this day. Distinct from \"still loading\" so\n * the screen can say WHICH of the two it is — the V1 could not, and its\n * \"Nenhuma grade configurada\" was really a database error (V1-041). */\n slotsError: string | null\n\n dayReservations: Reservation[]\n dayLoading: boolean\n\n /** The wider list, for the Lista tab and the month markers. */\n reservations: Reservation[]\n listLoading: boolean\n\n summary: ReservationsSummary | null\n\n rules: CapacityRule[]\n exceptions: CapacityException[]\n settings: ReservationSettings | null\n configLoading: boolean\n\n zones: ReservationZone[]\n tables: ReservationTable[]\n\n selectedId: string | null\n\n setSelectedDate(date: string): void\n select(id: string | null): void\n\n fetchDay(date?: string): Promise<void>\n fetchRange(from: string, to: string, query?: ReservationQuery): Promise<void>\n fetchConfig(): Promise<void>\n fetchSalao(): Promise<void>\n\n create(input: CreateReservationInput): Promise<Reservation | null>\n update(id: string, data: Partial<CreateReservationInput>): Promise<void>\n setStatus(id: string, status: ReservationStatus): Promise<void>\n seat(reservationId: string, tableId: string, guests?: number): Promise<void>\n remove(id: string): Promise<void>\n\n saveRule(rule: Partial<CapacityRule> & { id?: string }): Promise<void>\n deleteRule(id: string): Promise<void>\n saveException(ex: Partial<CapacityException> & { id?: string }): Promise<void>\n deleteException(id: string): Promise<void>\n saveSettings(settings: ReservationSettings): Promise<void>\n}\n\nfunction todayISO(): string {\n const d = new Date()\n return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`\n}\n\nexport function createReservationsStore(provider: ReservationsDataProvider): StoreApi<ReservationsUIState> {\n return createStore<ReservationsUIState>((set, get) => ({\n selectedDate: todayISO(),\n\n slots: [],\n slotsLoading: false,\n slotsError: null,\n\n dayReservations: [],\n dayLoading: false,\n\n reservations: [],\n listLoading: false,\n\n summary: null,\n\n rules: [],\n exceptions: [],\n settings: null,\n configLoading: false,\n\n zones: [],\n tables: [],\n\n selectedId: null,\n\n setSelectedDate(date: string) {\n set({ selectedDate: date })\n void get().fetchDay(date)\n },\n\n select(id) { set({ selectedId: id }) },\n\n async fetchDay(date?: string) {\n const day = date ?? get().selectedDate\n set({ slotsLoading: true, dayLoading: true, slotsError: null })\n // Three independent reads, settled independently: a broken capacity\n // function must not take the day's reservation list down with it. That is\n // exactly how the V1 loses the whole screen to one failing RPC.\n const [slots, rows, summary] = await Promise.allSettled([\n provider.getDayCapacity(day),\n provider.getReservations({ from: day, to: day }),\n provider.getSummary(day),\n ])\n set({\n slots: slots.status === 'fulfilled' ? slots.value : [],\n slotsError: slots.status === 'rejected' ? String(slots.reason?.message ?? slots.reason) : null,\n slotsLoading: false,\n dayReservations: rows.status === 'fulfilled' ? rows.value : [],\n dayLoading: false,\n summary: summary.status === 'fulfilled' ? summary.value : null,\n })\n },\n\n async fetchRange(from: string, to: string, query?: ReservationQuery) {\n set({ listLoading: true })\n try {\n set({ reservations: await provider.getReservations({ ...query, from, to }) })\n } catch (e: any) {\n toast.error(e?.message ?? 'Não foi possível carregar as reservas')\n } finally {\n set({ listLoading: false })\n }\n },\n\n async fetchConfig() {\n set({ configLoading: true })\n const [rules, exceptions, settings] = await Promise.allSettled([\n provider.getCapacityRules(),\n provider.getCapacityExceptions(),\n provider.getSettings(),\n ])\n set({\n rules: rules.status === 'fulfilled' ? rules.value : [],\n exceptions: exceptions.status === 'fulfilled' ? exceptions.value : [],\n settings: settings.status === 'fulfilled' ? settings.value : null,\n configLoading: false,\n })\n },\n\n async fetchSalao() {\n const [zones, tables] = await Promise.allSettled([provider.getZones(), provider.getTables()])\n set({\n zones: zones.status === 'fulfilled' ? zones.value : [],\n tables: tables.status === 'fulfilled' ? tables.value : [],\n })\n },\n\n async create(input) {\n try {\n const row = await provider.createReservation(input)\n toast.success('Reserva registrada')\n await get().fetchDay(input.reservedOn)\n return row\n } catch (e: any) {\n toast.error(e?.message ?? 'Não foi possível registrar a reserva')\n return null\n }\n },\n\n async update(id, data) {\n try {\n await provider.updateReservation(id, data)\n toast.success('Reserva atualizada')\n await get().fetchDay()\n } catch (e: any) {\n toast.error(e?.message ?? 'Não foi possível atualizar a reserva')\n }\n },\n\n async setStatus(id, status) {\n try {\n await provider.setStatus(id, status)\n await get().fetchDay()\n } catch (e: any) {\n toast.error(e?.message ?? 'Não foi possível mudar o estado')\n }\n },\n\n async seat(reservationId, tableId, guests) {\n try {\n const row = await provider.seatReservation({ reservationId, tableId, guests })\n // Say which comanda opened, not just \"ok\": the whole point of seating\n // here rather than in the floor plan is that the party becomes a\n // comanda, and reception has to be able to name it to the waiter.\n toast.success(row.orderReference\n ? `Mesa ${row.tableNumber} aberta — comanda ${row.orderReference}`\n : `Mesa ${row.tableNumber} ocupada`)\n await Promise.all([get().fetchDay(), get().fetchSalao()])\n } catch (e: any) {\n toast.error(e?.message ?? 'Não foi possível acomodar')\n }\n },\n\n async remove(id) {\n try {\n await provider.deleteReservation(id)\n toast.success('Reserva excluída')\n set({ selectedId: null })\n await get().fetchDay()\n } catch (e: any) {\n toast.error(e?.message ?? 'Não foi possível excluir')\n }\n },\n\n async saveRule(rule) {\n try {\n await provider.saveCapacityRule(rule)\n toast.success('Regra salva')\n await Promise.all([get().fetchConfig(), get().fetchDay()])\n } catch (e: any) {\n toast.error(e?.message ?? 'Não foi possível salvar a regra')\n }\n },\n\n async deleteRule(id) {\n try {\n await provider.deleteCapacityRule(id)\n await Promise.all([get().fetchConfig(), get().fetchDay()])\n } catch (e: any) {\n toast.error(e?.message ?? 'Não foi possível excluir a regra')\n }\n },\n\n async saveException(ex) {\n try {\n await provider.saveCapacityException(ex)\n toast.success('Exceção salva')\n await Promise.all([get().fetchConfig(), get().fetchDay()])\n } catch (e: any) {\n toast.error(e?.message ?? 'Não foi possível salvar a exceção')\n }\n },\n\n async deleteException(id) {\n try {\n await provider.deleteCapacityException(id)\n await Promise.all([get().fetchConfig(), get().fetchDay()])\n } catch (e: any) {\n toast.error(e?.message ?? 'Não foi possível excluir a exceção')\n }\n },\n\n async saveSettings(settings) {\n try {\n set({ settings: await provider.saveSettings(settings) })\n toast.success('Configurações salvas')\n } catch (e: any) {\n toast.error(e?.message ?? 'Não foi possível salvar')\n }\n },\n }))\n}\n","export const en: Record<string, string> = {\n 'reservations.page.title': 'Reservations',\n 'reservations.page.subtitle': 'Tables held for later',\n 'reservations.action.new': 'New reservation',\n 'reservations.status.pending': 'Pending',\n 'reservations.status.confirmed': 'Confirmed',\n 'reservations.status.seated': 'Seated',\n 'reservations.status.no_show': 'No show',\n 'reservations.status.cancelled': 'Cancelled',\n}\n","export const ptBR: Record<string, string> = {\n 'reservations.page.title': 'Reservas',\n 'reservations.page.subtitle': 'Mesas guardadas por horário',\n 'reservations.action.new': 'Nova reserva',\n 'reservations.status.pending': 'Pendente',\n 'reservations.status.confirmed': 'Confirmada',\n 'reservations.status.seated': 'Acomodada',\n 'reservations.status.no_show': 'Não compareceu',\n 'reservations.status.cancelled': 'Cancelada',\n}\n","import { en } from './en'\nimport { ptBR } from './pt-BR'\n\nexport const reservationsLocales: Record<string, Record<string, string>> = { en, 'pt-BR': ptBR }\n","// ---------------------------------------------------------------------------\n// Reservations Plugin — pure TypeScript types.\n//\n// A reservation spends the SEATS OF A ROOM inside a time window. That is the\n// whole difference from `plugin-agenda`, which spends a professional's time —\n// and the reason this plugin exists instead of a `bookingKind`. See\n// src/migrations/001_reservations.sql for the long version.\n// ---------------------------------------------------------------------------\n\n// ============================================================\n// ENUMS / LITERALS\n// ============================================================\n\n/**\n * The V1's five states, same words (`reservas/FLOW.md`, *O vocabulário*):\n * Pendente · Confirmada · Acomodada · Não compareceu · Cancelada.\n *\n * `seated` is the one that does work: it is where the party becomes a comanda.\n */\nexport type ReservationStatus = 'pending' | 'confirmed' | 'seated' | 'no_show' | 'cancelled'\n\nexport const RESERVATION_STATUSES: ReservationStatus[] = [\n 'pending', 'confirmed', 'seated', 'no_show', 'cancelled',\n]\n\n/**\n * How the house counts its lotação.\n *\n * `no_duration` is the V1 default, and its legend is the clearest statement of\n * the model: *\"a capacidade é o teto de pessoas que pode iniciar dentro da\n * faixa, sem rolagem entre faixas\"* — a reservation spends the slot it STARTS\n * in, and nothing spills into the next one.\n */\nexport type CapacityMode = 'fixed_duration' | 'per_slot_duration' | 'no_duration'\n\nexport const CAPACITY_MODES: CapacityMode[] = ['fixed_duration', 'per_slot_duration', 'no_duration']\n\n/** The V1's list, kept whole — it is what reception actually asks on the phone. */\nexport type Occasion =\n | 'birthday' | 'date' | 'business' | 'wedding' | 'graduation' | 'other'\n\nexport const OCCASIONS: Occasion[] = ['birthday', 'date', 'business', 'wedding', 'graduation', 'other']\n\n// ============================================================\n// CORE ENTITIES\n// ============================================================\n\n/** A reservation — `plg_reservations`, read through `v_reservations`. */\nexport interface Reservation {\n id: string\n /** The client record, when the guest is one. A reservation taken over the\n * phone from a stranger still has a name and a number — hence `guestName`. */\n personId?: string\n guestName: string\n phone?: string\n email?: string\n zoneId?: string\n zoneName?: string\n zoneColor?: string\n tableId?: string\n tableNumber?: number\n /** ISO date, no time. The day the guests are coming. */\n reservedOn: string\n /** \"HH:MM\". */\n startTime: string\n endTime?: string\n partySize: number\n occasion?: Occasion\n notes?: string\n status: ReservationStatus\n /** The comanda this reservation opened when it was seated. The join the V1\n * never made — see the migration. */\n orderId?: string\n orderReference?: string\n seatedAt?: string\n tenantId: string\n createdAt: string\n updatedAt: string\n}\n\n/** One line of the weekly grid — `plg_reservations_capacity_rules`. */\nexport interface CapacityRule {\n id: string\n /** The praça. Undefined = the house as a whole, for a one-room restaurant. */\n zoneId?: string\n zoneName?: string\n capacity: number\n startTime: string\n endTime: string\n /** 0=Sunday..6=Saturday, matching Date#getDay. */\n weekdays: number[]\n /** Only read in `per_slot_duration` mode. */\n durationMinutes?: number\n isActive: boolean\n tenantId: string\n}\n\n/** What overrides the grid — `plg_reservations_capacity_exceptions`. */\nexport interface CapacityException {\n id: string\n zoneId?: string\n zoneName?: string\n startsOn: string\n endsOn: string\n startTime?: string\n endTime?: string\n /** Zero closes the zone for those days without deleting the weekly grid. */\n capacity: number\n reason?: string\n tenantId: string\n}\n\n/** The policy — one row per tenant. */\nexport interface ReservationSettings {\n capacityMode: CapacityMode\n defaultDurationMinutes: number\n /** The V1 asks for this in MINUTES and the maximum in DAYS, in the same pair\n * of fields. Hours here, and the form writes the equivalent beside it. */\n minAdvanceHours: number\n maxAdvanceDays: number\n autoConfirm: boolean\n requirePhone: boolean\n requireEmail: boolean\n}\n\n/**\n * One window of one day, with what is left in it.\n *\n * The whole reason the screen exists. The V1's equivalent answered \"Nenhuma\n * grade configurada\" on every date tested with three rules loaded (V1-041), and\n * its reservation form never asked for availability at all.\n */\nexport interface DaySlot {\n zoneId?: string\n zoneName?: string\n zoneColor?: string\n startTime: string\n endTime: string\n capacity: number\n booked: number\n remaining: number\n /** True when an exception produced this window instead of the weekly grid. */\n isException: boolean\n}\n\n/** A praça, as this plugin needs it. Read from `plugin-tables`' own zones —\n * the capacity is per praça, not per a cadastro of its own. */\nexport interface ReservationZone {\n id: string\n name: string\n color?: string\n}\n\n/** A mesa, for the optional \"amarrar a reserva a uma mesa\" field and for\n * seating. Only the four things this plugin shows. */\nexport interface ReservationTable {\n id: string\n number: number\n name?: string\n seats: number\n zoneId?: string\n /** A mesa with a comanda open on it cannot receive a party. */\n isOccupied: boolean\n}\n\n// ============================================================\n// INPUT TYPES\n// ============================================================\n\nexport interface CreateReservationInput {\n personId?: string\n guestName: string\n phone?: string\n email?: string\n zoneId?: string\n tableId?: string\n reservedOn: string\n startTime: string\n endTime?: string\n partySize: number\n occasion?: Occasion\n notes?: string\n status?: ReservationStatus\n}\n\nexport interface ReservationQuery {\n from?: string\n to?: string\n status?: ReservationStatus | ReservationStatus[]\n zoneId?: string\n search?: string\n}\n\n/** Seating is a write in two places, so it is one call. */\nexport interface SeatReservationInput {\n reservationId: string\n tableId: string\n /** Defaults to the reservation's `partySize` — the party that shows up is not\n * always the party that booked, and reception corrects it here. */\n guests?: number\n}\n\n// ============================================================\n// AGGREGATION\n// ============================================================\n\nexport interface ReservationsSummary {\n /** Reservations for the day being looked at, by state. */\n total: number\n pending: number\n confirmed: number\n seated: number\n noShow: number\n cancelled: number\n /** People, not reservations — the number the kitchen plans against. */\n expectedGuests: number\n}\n","// AUTO-GENERATED from 001_reservations.sql — regenerate with scripts/embed-migrations.mjs\n// SQL files are the source of truth; this inline copy lets the manifest declare\n// migrations as data. Do not edit by hand — run the embed script instead.\n\nexport const MIGRATION_001_RESERVATIONS = `-- plugin-reservations — a mesa guardada para mais tarde.\n--\n-- WHY THIS IS NOT THE AGENDA. \\`plugin-agenda\\` schedules a PERSON's time: a\n-- column per professional, services with durations, an assignee. A restaurant\n-- reservation has neither professional nor service — it spends the SEATS OF A\n-- ROOM inside a time window. resto-saas shipped \\`createAgendaPlugin({\n-- bookingKind: 'reservation' })\\` with the labels swapped, and the screen came\n-- out with nine staff columns over the word \"Reservas\". A booking kind cannot\n-- change which resource is scarce.\n--\n-- The V1 (~/dev/beautyplace/docs/v1-guide/restaurante/reservas) models this\n-- correctly and we keep its model — local × faixa × dia da semana, with\n-- exceptions that override the weekly grid — with three deliberate changes,\n-- each written where it happens below.\n--\n-- Idempotent.\n\n-- ---------------------------------------------------------------------------\n-- Policy — one row per tenant.\n-- ---------------------------------------------------------------------------\ncreate table if not exists public.plg_reservations_settings (\n tenant_id uuid primary key references public.tenants(id) on delete cascade,\n -- V1's three modes, same words. \\`no_duration\\` is the V1 default and the one\n -- its own legend explains best: \"a capacidade é o teto de pessoas que pode\n -- iniciar dentro da faixa, sem rolagem entre faixas\" — the reservation spends\n -- the slot it STARTS in.\n capacity_mode text not null default 'no_duration'\n check (capacity_mode in ('fixed_duration','per_slot_duration','no_duration')),\n default_duration_minutes integer not null default 120 check (default_duration_minutes > 0),\n -- CHANGE 2 of 3: the V1 asks for minimum notice in MINUTES (1440) and maximum\n -- in DAYS (90), in the same pair of fields. Both are hours/days here and the\n -- UI writes the equivalent out beside them.\n min_advance_hours integer not null default 24 check (min_advance_hours >= 0),\n max_advance_days integer not null default 90 check (max_advance_days > 0),\n auto_confirm boolean not null default false,\n require_phone boolean not null default true,\n require_email boolean not null default false,\n created_at timestamptz not null default now(),\n updated_at timestamptz not null default now()\n);\n\n-- ---------------------------------------------------------------------------\n-- The weekly grid — one row per zone × window × set of weekdays.\n-- ---------------------------------------------------------------------------\ncreate table if not exists public.plg_reservations_capacity_rules (\n id uuid primary key default gen_random_uuid(),\n tenant_id uuid not null references public.tenants(id) on delete cascade,\n -- CHANGE 1 of 3: capacity is per PRAÇA, not per a cadastro of its own.\n --\n -- The V1 splits these: capacity lives on \\`service_locations\\` (Cadastros →\n -- Locais Operacionais) while the mesa lives on \\`restaurant_sections\\` (the\n -- Salão screen). Two cadastros with similar names, and its own document says\n -- \"nada na tela avisa\" — whoever registered the praças does not find those\n -- names when configuring the lotação. We already own zones with mesas inside\n -- them; a third cadastro would re-import the confusion and buy nothing.\n --\n -- Nullable = the house as a whole, for a restaurant with one room.\n zone_id uuid references public.plg_tables_zones(id) on delete cascade,\n capacity integer not null check (capacity > 0),\n start_time time not null,\n end_time time not null,\n -- 0=Sunday..6=Saturday, matching Date#getDay and plugin-menu's availability.\n weekdays smallint[] not null default '{0,1,2,3,4,5,6}',\n -- Only read in \\`per_slot_duration\\` mode; null falls back to the default.\n duration_minutes integer check (duration_minutes is null or duration_minutes > 0),\n is_active boolean not null default true,\n created_at timestamptz not null default now(),\n updated_at timestamptz not null default now(),\n check (end_time > start_time)\n);\n\n-- ---------------------------------------------------------------------------\n-- Exceptions — \"Exceções sobrepõem a grade semanal para o(s) dia(s) cobertos\n-- no mesmo local.\" (V1, literal). A row with capacity 0 closes the zone.\n-- ---------------------------------------------------------------------------\ncreate table if not exists public.plg_reservations_capacity_exceptions (\n id uuid primary key default gen_random_uuid(),\n tenant_id uuid not null references public.tenants(id) on delete cascade,\n zone_id uuid references public.plg_tables_zones(id) on delete cascade,\n starts_on date not null,\n ends_on date not null,\n -- Null start/end = the whole day. Zero capacity = closed.\n start_time time,\n end_time time,\n capacity integer not null default 0 check (capacity >= 0),\n reason text,\n created_at timestamptz not null default now(),\n updated_at timestamptz not null default now(),\n check (ends_on >= starts_on)\n);\n\n-- ---------------------------------------------------------------------------\n-- The reservations.\n-- ---------------------------------------------------------------------------\ncreate table if not exists public.plg_reservations (\n id uuid primary key default gen_random_uuid(),\n tenant_id uuid not null references public.tenants(id) on delete cascade,\n person_id uuid references public.people(id) on delete set null,\n -- Denormalised on purpose: a reservation taken over the phone from someone\n -- who is not a client yet still has a name and a number to call back.\n guest_name text not null,\n phone text,\n email text,\n zone_id uuid references public.plg_tables_zones(id) on delete set null,\n table_id uuid references public.plg_tables_tables(id) on delete set null,\n reserved_on date not null,\n start_time time not null,\n end_time time,\n party_size integer not null check (party_size > 0),\n occasion text,\n notes text,\n -- V1's five states, same words: Pendente · Confirmada · Acomodada ·\n -- Não compareceu · Cancelada.\n status text not null default 'pending'\n check (status in ('pending','confirmed','seated','no_show','cancelled')),\n -- CHANGE 3 of 3: \\`seated\\` opens the mesa.\n --\n -- In the V1, reservation and comanda are separate universes — marking\n -- Acomodada creates no comanda at all, and the night's money never knows a\n -- reservation happened. Here \\`seated\\` is the moment the party becomes a\n -- comanda, and this column is the join. Written by the app, not a trigger:\n -- opening a comanda is the tables plugin's job and it numbers the order.\n order_id uuid references public.orders(id) on delete set null,\n seated_at timestamptz,\n created_at timestamptz not null default now(),\n updated_at timestamptz not null default now()\n);\n\ncreate index if not exists plg_reservations_day_idx\n on public.plg_reservations (tenant_id, reserved_on, start_time);\ncreate index if not exists plg_reservations_zone_day_idx\n on public.plg_reservations (tenant_id, zone_id, reserved_on);\ncreate index if not exists plg_reservations_rules_zone_idx\n on public.plg_reservations_capacity_rules (tenant_id, zone_id);\ncreate index if not exists plg_reservations_exceptions_day_idx\n on public.plg_reservations_capacity_exceptions (tenant_id, starts_on, ends_on);\n\ndo $$ begin\n create trigger plg_reservations_settings_updated_at before update on public.plg_reservations_settings\n for each row execute function public.handle_updated_at();\nexception when duplicate_object then null; end $$;\ndo $$ begin\n create trigger plg_reservations_rules_updated_at before update on public.plg_reservations_capacity_rules\n for each row execute function public.handle_updated_at();\nexception when duplicate_object then null; end $$;\ndo $$ begin\n create trigger plg_reservations_exceptions_updated_at before update on public.plg_reservations_capacity_exceptions\n for each row execute function public.handle_updated_at();\nexception when duplicate_object then null; end $$;\ndo $$ begin\n create trigger plg_reservations_updated_at before update on public.plg_reservations\n for each row execute function public.handle_updated_at();\nexception when duplicate_object then null; end $$;\n\n-- ---------------------------------------------------------------------------\n-- RLS — the ACTIVE account, never the union.\n--\n-- \\`user_tenant_ids()\\` honours only a signed JWT claim; switching workspace\n-- happens through the \\`x-fayz-tenant\\` header, so it does not see the switch and\n-- answers with the UNION of the caller's accounts. plugin-tables learned this\n-- the hard way — Artorius drew Papa Léguas' mesas. \\`app.current_tenant_id()\\`\n-- reads the header and validates it against app.memberships: it chooses among\n-- accounts you already belong to and can never widen.\n-- ---------------------------------------------------------------------------\nalter table public.plg_reservations_settings enable row level security;\nalter table public.plg_reservations_capacity_rules enable row level security;\nalter table public.plg_reservations_capacity_exceptions enable row level security;\nalter table public.plg_reservations enable row level security;\n\ndo $$\ndeclare t text;\nbegin\n foreach t in array array['plg_reservations_settings','plg_reservations_capacity_rules',\n 'plg_reservations_capacity_exceptions','plg_reservations'] loop\n execute format('drop policy if exists %I on public.%I', t || '_select', t);\n execute format('drop policy if exists %I on public.%I', t || '_insert', t);\n execute format('drop policy if exists %I on public.%I', t || '_update', t);\n execute format('drop policy if exists %I on public.%I', t || '_delete', t);\n execute format('create policy %I on public.%I for select using (tenant_id = (select app.current_tenant_id()))', t || '_select', t);\n execute format('create policy %I on public.%I for insert with check (tenant_id = (select app.current_tenant_id()))', t || '_insert', t);\n execute format('create policy %I on public.%I for update using (tenant_id = (select app.current_tenant_id()))', t || '_update', t);\n execute format('create policy %I on public.%I for delete using (tenant_id = (select app.current_tenant_id()))', t || '_delete', t);\n execute format('grant select, insert, update, delete on public.%I to authenticated', t);\n end loop;\nend $$;\n\n-- ---------------------------------------------------------------------------\n-- The reservation with the names already resolved. The list and the calendar\n-- read this, so nobody joins four tables in TypeScript to render a row.\n-- ---------------------------------------------------------------------------\ncreate or replace view public.v_reservations with (security_invoker = true) as\nselect\n r.id, r.tenant_id, r.person_id, r.guest_name, r.phone, r.email,\n r.zone_id, z.name as zone_name, z.color as zone_color,\n r.table_id, t.number as table_number,\n r.reserved_on, r.start_time, r.end_time, r.party_size,\n r.occasion, r.notes, r.status, r.order_id, r.seated_at,\n o.reference_number as order_reference,\n r.created_at, r.updated_at\nfrom public.plg_reservations r\nleft join public.plg_tables_zones z on z.id = r.zone_id\nleft join public.plg_tables_tables t on t.id = r.table_id\nleft join public.orders o on o.id = r.order_id;\n\ngrant select on public.v_reservations to authenticated;\n\n-- ---------------------------------------------------------------------------\n-- The slots of one day, with what is left in each.\n--\n-- THIS IS THE FUNCTION THE V1 NEVER GOT RIGHT. With three rules covering all\n-- seven weekdays, its \"Capacidade do dia\" answered \"Nenhuma grade configurada\"\n-- on every date tested (V1-041), and its reservation form never called the\n-- availability function at all — the lotação check, if it existed, did not\n-- happen while anyone was deciding. Both are the reason this screen exists.\n--\n-- Returns one row per zone × window that applies to \\`p_date\\`, with the seats\n-- already spent by non-cancelled reservations STARTING inside that window —\n-- which is what \"sem rolagem entre faixas\" means in the V1's own legend.\n--\n-- Exceptions OVERRIDE, they do not add: a zone with an exception covering the\n-- date returns the exception's windows and none of the weekly ones. A capacity\n-- of 0 therefore closes the zone for the day without deleting the grid.\n-- ---------------------------------------------------------------------------\ncreate or replace function public.reservations_day_capacity(p_date date)\nreturns table (\n zone_id uuid,\n zone_name text,\n zone_color text,\n start_time time,\n end_time time,\n capacity integer,\n booked integer,\n remaining integer,\n is_exception boolean\n)\nlanguage sql\nstable\nsecurity invoker\nset search_path = public\nas $$\n with tenant as (select app.current_tenant_id() as id),\n -- Which zones had their day overridden. Checked per zone, so a holiday in the\n -- Varanda does not silence the grid of the Salão.\n overridden as (\n select distinct e.zone_id\n from public.plg_reservations_capacity_exceptions e, tenant\n where e.tenant_id = tenant.id\n and p_date between e.starts_on and e.ends_on\n ),\n slots as (\n select e.zone_id, e.start_time, e.end_time, e.capacity, true as is_exception\n from public.plg_reservations_capacity_exceptions e, tenant\n where e.tenant_id = tenant.id\n and p_date between e.starts_on and e.ends_on\n and e.capacity > 0\n -- A whole-day exception still has to draw SOMETHING, so it borrows the\n -- house's widest window rather than a made-up one.\n and coalesce(e.start_time, time '00:00') < coalesce(e.end_time, time '23:59')\n union all\n select r.zone_id, r.start_time, r.end_time, r.capacity, false\n from public.plg_reservations_capacity_rules r, tenant\n where r.tenant_id = tenant.id\n and r.is_active\n -- extract(dow) is 0=Sunday..6=Saturday, the same axis \\`weekdays\\` uses.\n and extract(dow from p_date)::smallint = any (r.weekdays)\n and (r.zone_id is null or r.zone_id not in (select o.zone_id from overridden o where o.zone_id is not null))\n )\n select\n s.zone_id,\n z.name as zone_name,\n z.color as zone_color,\n coalesce(s.start_time, time '00:00') as start_time,\n coalesce(s.end_time, time '23:59') as end_time,\n s.capacity,\n coalesce(b.booked, 0)::integer as booked,\n greatest(s.capacity - coalesce(b.booked, 0), 0)::integer as remaining,\n s.is_exception\n from slots s\n left join public.plg_tables_zones z on z.id = s.zone_id\n left join lateral (\n select sum(v.party_size)::integer as booked\n from public.plg_reservations v, tenant\n where v.tenant_id = tenant.id\n and v.reserved_on = p_date\n and v.status <> 'cancelled'\n and (s.zone_id is null or v.zone_id is not distinct from s.zone_id)\n -- The reservation spends the window it STARTS in.\n and v.start_time >= coalesce(s.start_time, time '00:00')\n and v.start_time < coalesce(s.end_time, time '23:59')\n ) b on true\n order by coalesce(s.start_time, time '00:00'), z.name nulls first;\n$$;\n\ngrant execute on function public.reservations_day_capacity(date) to authenticated;\n`\n\nexport const MIGRATIONS: Array<{ id: string; sql: string }> = [\n { id: \"001_reservations\", sql: MIGRATION_001_RESERVATIONS },\n]\n","import React from 'react'\nimport type { PluginManifest, PluginScope, VerticalId, EntityDef } from '@fayz-ai/core'\nimport type { EntityLookup } from '@fayz-ai/admin'\nimport type { ReservationsDataProvider } from './data/types'\nimport { createMockReservationsProvider } from './data/mock'\nimport { createReservationsStore } from './store'\nimport { reservationsLocales } from './locales'\nimport type { ResolvedReservationsConfig, ReservationsPluginLabels, ReservationStatusOption, OccasionOption } from './context'\n\nconst ReservationsPage = React.lazy(() =>\n import('./views/ReservationsPage').then((m) => ({ default: m.ReservationsPage })))\nconst ReservationsSettingsPage = React.lazy(() =>\n import('./views/ReservationsPage').then((m) => ({ default: m.ReservationsSettingsPage })))\n\n// ---------------------------------------------------------------------------\n// Defaults — the V1's vocabulary, value for value.\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_LABELS: ReservationsPluginLabels = {\n pageTitle: 'Reservas',\n pageSubtitle: 'Mesas guardadas por horário',\n newReservation: 'Nova reserva',\n}\n\n/**\n * The five states the V1 shows, with the colours the rest of the SDK uses for\n * the same meanings — pending is amber, done is green, refused is red. Fed to\n * `DotBadge` in @fayz-ai/ui, the same pill the agenda draws its statuses with.\n */\nconst DEFAULT_STATUSES: ReservationStatusOption[] = [\n { value: 'pending', label: 'Pendente', color: '#f59e0b' },\n { value: 'confirmed', label: 'Confirmada', color: '#3b82f6' },\n { value: 'seated', label: 'Acomodada', color: '#22c55e' },\n { value: 'no_show', label: 'Não compareceu', color: '#ef4444' },\n { value: 'cancelled', label: 'Cancelada', color: '#6b7280' },\n]\n\nconst DEFAULT_OCCASIONS: OccasionOption[] = [\n { value: 'birthday', label: 'Aniversário' },\n { value: 'date', label: 'Namoro' },\n { value: 'business', label: 'Negócios' },\n { value: 'wedding', label: 'Casamento' },\n { value: 'graduation', label: 'Formatura' },\n { value: 'other', label: 'Outro' },\n]\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface ReservationsPluginOptions {\n labels?: Partial<ReservationsPluginLabels>\n statuses?: ReservationStatusOption[]\n occasions?: OccasionOption[]\n dayWindow?: { start: string; end: string }\n navPosition?: number\n navSection?: 'main' | 'secondary' | 'settings'\n scope?: PluginScope\n verticalId?: VerticalId\n dataProvider?: ReservationsDataProvider\n /** Ver ResolvedReservationsConfig: quem reservou e uma pessoa cadastrada. */\n clientKind?: string\n contactLookup?: EntityLookup\n clientEntityDef?: EntityDef\n}\n\nfunction resolveConfig(options?: ReservationsPluginOptions): ResolvedReservationsConfig {\n return {\n labels: { ...DEFAULT_LABELS, ...options?.labels },\n statuses: options?.statuses ?? DEFAULT_STATUSES,\n occasions: options?.occasions ?? DEFAULT_OCCASIONS,\n dayWindow: options?.dayWindow ?? { start: '11:00', end: '23:59' },\n clientKind: options?.clientKind ?? 'customer',\n contactLookup: options?.contactLookup,\n clientEntityDef: options?.clientEntityDef,\n }\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Reservations — the seats of a room, held for a time window.\n *\n * NOT `createAgendaPlugin({ bookingKind: 'reservation' })`, which is what\n * resto-saas shipped before this and which drew nine professional columns under\n * the word \"Reservas\". The agenda schedules a PERSON's time; a restaurant\n * reservation spends a ROOM's capacity. A booking kind renames the axis; it\n * cannot change which resource is scarce.\n *\n * What the two genuinely share is drawn from @fayz-ai/ui — `MiniCalendar` and\n * `DotBadge`, both lifted out of plugin-agenda when this plugin needed them.\n */\nexport function createReservationsPlugin(options?: ReservationsPluginOptions): PluginManifest {\n const config = resolveConfig(options)\n const provider = options?.dataProvider ?? createMockReservationsProvider()\n const store = createReservationsStore(provider)\n\n const PageComponent: React.FC<any> = () =>\n React.createElement(React.Suspense, { fallback: null },\n React.createElement(ReservationsPage, { config, provider, store }))\n\n const SettingsComponent: React.FC<any> = () =>\n React.createElement(React.Suspense, { fallback: null },\n React.createElement(ReservationsSettingsPage, { config, provider, store }))\n\n return {\n id: 'reservations',\n defaultAgentRole: 'operations',\n name: config.labels.pageTitle,\n icon: 'CalendarClock',\n version: '1.0.0',\n scope: options?.scope ?? 'vertical',\n verticalId: options?.verticalId,\n defaultEnabled: true,\n // Dependência DURA, e o comentário que estava aqui dizia o contrário.\n //\n // A intenção era boa — \"uma casa sem planta de salão ainda aceita reservas,\n // numa grade da casa inteira; as praças só afinam a grade\" — mas o schema\n // nunca a sustentou: `plg_reservations_capacity`, `_capacity_exceptions` e\n // `plg_reservations` têm FK para `plg_tables_zones`/`_tables`, e as views\n // fazem join nelas. Sem o plugin de mesas instalado a migração não aplica,\n // então a promessa de opcionalidade falhava no primeiro `apply`, não numa\n // tela vazia.\n //\n // Declarar é o que torna a ordem da corrente (ver packages/db/chain.json)\n // uma consequência do manifesto em vez de uma coincidência de nomes.\n // Tornar a dependência de fato opcional é outro trabalho: exigiria trocar\n // as FKs por um evento `zone.deleted` do dono e as views por joins\n // tolerantes — e é isso, não um comentário, que reabriria a porta.\n dependencies: ['tables'],\n navigation: [\n {\n section: options?.navSection ?? 'main',\n position: options?.navPosition ?? 13,\n label: config.labels.pageTitle,\n route: '/reservations',\n icon: 'CalendarClock',\n permission: { feature: 'reservations', action: 'read' as const },\n },\n ],\n routes: [\n {\n path: '/reservations',\n component: PageComponent,\n permission: { feature: 'reservations', action: 'read' as const },\n },\n ],\n widgets: [],\n aiTools: [\n {\n id: 'reservations.availability',\n name: 'getReservationAvailability',\n description: 'How many seats are still free in each time window of a given day.',\n icon: 'CalendarClock',\n mode: 'read' as const,\n category: 'Reservations',\n parameters: {\n type: 'object' as const,\n properties: {\n date: { type: 'string' as const, description: 'ISO date (YYYY-MM-DD)' },\n },\n required: ['date'],\n },\n suggestions: [\n { label: 'Tenho mesa para 6 pessoas sexta à noite?' },\n { label: 'Quantas pessoas esperamos hoje?' },\n ],\n },\n {\n id: 'reservations.book',\n name: 'createReservation',\n description: 'Registers a reservation for a party on a date and time.',\n icon: 'CalendarPlus',\n mode: 'persist' as const,\n category: 'Reservations',\n parameters: {\n type: 'object' as const,\n properties: {\n guestName: { type: 'string' as const },\n date: { type: 'string' as const, description: 'ISO date (YYYY-MM-DD)' },\n startTime: { type: 'string' as const, description: 'HH:MM' },\n partySize: { type: 'number' as const },\n phone: { type: 'string' as const },\n },\n required: ['guestName', 'date', 'startTime', 'partySize'],\n },\n permission: { feature: 'reservations', action: 'create' as const },\n },\n ],\n settings: [\n {\n id: 'reservations',\n label: config.labels.pageTitle,\n icon: 'CalendarClock',\n component: SettingsComponent,\n order: 22,\n // Reading the grid is not the same as writing it: reception opens this\n // to see why a window is closed; only a manager changes the lotação.\n permission: { feature: 'reservations', action: 'read' as const },\n },\n ],\n locales: reservationsLocales,\n }\n}\n\nexport type { ReservationsDataProvider } from './data/types'\nexport { createMockReservationsProvider } from './data/mock'\nexport {\n createCoreReservationsProvider,\n DEFAULT_SETTINGS,\n type CoreReservationsProviderOptions,\n type CoreReservationsWriteOptions,\n} from './data/core-supabase'\nexport type { ResolvedReservationsConfig, ReservationsPluginLabels, ReservationStatusOption, OccasionOption } from './context'\nexport type {\n Reservation, ReservationStatus, CapacityMode, CapacityRule, CapacityException,\n ReservationSettings, DaySlot, ReservationZone, ReservationTable, Occasion,\n CreateReservationInput, ReservationQuery, SeatReservationInput, ReservationsSummary,\n} from './types'\nexport { RESERVATION_STATUSES, CAPACITY_MODES, OCCASIONS } from './types'\nexport { MIGRATIONS as reservationsMigrations } from './migrations'\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/locales/en.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,EAAE,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CASrC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/locales/index.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAyB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pt-BR.d.ts","sourceRoot":"","sources":["../../src/locales/pt-BR.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CASvC,CAAA"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const MIGRATION_001_RESERVATIONS = "-- plugin-reservations \u2014 a mesa guardada para mais tarde.\n--\n-- WHY THIS IS NOT THE AGENDA. `plugin-agenda` schedules a PERSON's time: a\n-- column per professional, services with durations, an assignee. A restaurant\n-- reservation has neither professional nor service \u2014 it spends the SEATS OF A\n-- ROOM inside a time window. resto-saas shipped `createAgendaPlugin({\n-- bookingKind: 'reservation' })` with the labels swapped, and the screen came\n-- out with nine staff columns over the word \"Reservas\". A booking kind cannot\n-- change which resource is scarce.\n--\n-- The V1 (~/dev/beautyplace/docs/v1-guide/restaurante/reservas) models this\n-- correctly and we keep its model \u2014 local \u00D7 faixa \u00D7 dia da semana, with\n-- exceptions that override the weekly grid \u2014 with three deliberate changes,\n-- each written where it happens below.\n--\n-- Idempotent.\n\n-- ---------------------------------------------------------------------------\n-- Policy \u2014 one row per tenant.\n-- ---------------------------------------------------------------------------\ncreate table if not exists public.plg_reservations_settings (\n tenant_id uuid primary key references public.tenants(id) on delete cascade,\n -- V1's three modes, same words. `no_duration` is the V1 default and the one\n -- its own legend explains best: \"a capacidade \u00E9 o teto de pessoas que pode\n -- iniciar dentro da faixa, sem rolagem entre faixas\" \u2014 the reservation spends\n -- the slot it STARTS in.\n capacity_mode text not null default 'no_duration'\n check (capacity_mode in ('fixed_duration','per_slot_duration','no_duration')),\n default_duration_minutes integer not null default 120 check (default_duration_minutes > 0),\n -- CHANGE 2 of 3: the V1 asks for minimum notice in MINUTES (1440) and maximum\n -- in DAYS (90), in the same pair of fields. Both are hours/days here and the\n -- UI writes the equivalent out beside them.\n min_advance_hours integer not null default 24 check (min_advance_hours >= 0),\n max_advance_days integer not null default 90 check (max_advance_days > 0),\n auto_confirm boolean not null default false,\n require_phone boolean not null default true,\n require_email boolean not null default false,\n created_at timestamptz not null default now(),\n updated_at timestamptz not null default now()\n);\n\n-- ---------------------------------------------------------------------------\n-- The weekly grid \u2014 one row per zone \u00D7 window \u00D7 set of weekdays.\n-- ---------------------------------------------------------------------------\ncreate table if not exists public.plg_reservations_capacity_rules (\n id uuid primary key default gen_random_uuid(),\n tenant_id uuid not null references public.tenants(id) on delete cascade,\n -- CHANGE 1 of 3: capacity is per PRA\u00C7A, not per a cadastro of its own.\n --\n -- The V1 splits these: capacity lives on `service_locations` (Cadastros \u2192\n -- Locais Operacionais) while the mesa lives on `restaurant_sections` (the\n -- Sal\u00E3o screen). Two cadastros with similar names, and its own document says\n -- \"nada na tela avisa\" \u2014 whoever registered the pra\u00E7as does not find those\n -- names when configuring the lota\u00E7\u00E3o. We already own zones with mesas inside\n -- them; a third cadastro would re-import the confusion and buy nothing.\n --\n -- Nullable = the house as a whole, for a restaurant with one room.\n zone_id uuid references public.plg_tables_zones(id) on delete cascade,\n capacity integer not null check (capacity > 0),\n start_time time not null,\n end_time time not null,\n -- 0=Sunday..6=Saturday, matching Date#getDay and plugin-menu's availability.\n weekdays smallint[] not null default '{0,1,2,3,4,5,6}',\n -- Only read in `per_slot_duration` mode; null falls back to the default.\n duration_minutes integer check (duration_minutes is null or duration_minutes > 0),\n is_active boolean not null default true,\n created_at timestamptz not null default now(),\n updated_at timestamptz not null default now(),\n check (end_time > start_time)\n);\n\n-- ---------------------------------------------------------------------------\n-- Exceptions \u2014 \"Exce\u00E7\u00F5es sobrep\u00F5em a grade semanal para o(s) dia(s) cobertos\n-- no mesmo local.\" (V1, literal). A row with capacity 0 closes the zone.\n-- ---------------------------------------------------------------------------\ncreate table if not exists public.plg_reservations_capacity_exceptions (\n id uuid primary key default gen_random_uuid(),\n tenant_id uuid not null references public.tenants(id) on delete cascade,\n zone_id uuid references public.plg_tables_zones(id) on delete cascade,\n starts_on date not null,\n ends_on date not null,\n -- Null start/end = the whole day. Zero capacity = closed.\n start_time time,\n end_time time,\n capacity integer not null default 0 check (capacity >= 0),\n reason text,\n created_at timestamptz not null default now(),\n updated_at timestamptz not null default now(),\n check (ends_on >= starts_on)\n);\n\n-- ---------------------------------------------------------------------------\n-- The reservations.\n-- ---------------------------------------------------------------------------\ncreate table if not exists public.plg_reservations (\n id uuid primary key default gen_random_uuid(),\n tenant_id uuid not null references public.tenants(id) on delete cascade,\n person_id uuid references public.people(id) on delete set null,\n -- Denormalised on purpose: a reservation taken over the phone from someone\n -- who is not a client yet still has a name and a number to call back.\n guest_name text not null,\n phone text,\n email text,\n zone_id uuid references public.plg_tables_zones(id) on delete set null,\n table_id uuid references public.plg_tables_tables(id) on delete set null,\n reserved_on date not null,\n start_time time not null,\n end_time time,\n party_size integer not null check (party_size > 0),\n occasion text,\n notes text,\n -- V1's five states, same words: Pendente \u00B7 Confirmada \u00B7 Acomodada \u00B7\n -- N\u00E3o compareceu \u00B7 Cancelada.\n status text not null default 'pending'\n check (status in ('pending','confirmed','seated','no_show','cancelled')),\n -- CHANGE 3 of 3: `seated` opens the mesa.\n --\n -- In the V1, reservation and comanda are separate universes \u2014 marking\n -- Acomodada creates no comanda at all, and the night's money never knows a\n -- reservation happened. Here `seated` is the moment the party becomes a\n -- comanda, and this column is the join. Written by the app, not a trigger:\n -- opening a comanda is the tables plugin's job and it numbers the order.\n order_id uuid references public.orders(id) on delete set null,\n seated_at timestamptz,\n created_at timestamptz not null default now(),\n updated_at timestamptz not null default now()\n);\n\ncreate index if not exists plg_reservations_day_idx\n on public.plg_reservations (tenant_id, reserved_on, start_time);\ncreate index if not exists plg_reservations_zone_day_idx\n on public.plg_reservations (tenant_id, zone_id, reserved_on);\ncreate index if not exists plg_reservations_rules_zone_idx\n on public.plg_reservations_capacity_rules (tenant_id, zone_id);\ncreate index if not exists plg_reservations_exceptions_day_idx\n on public.plg_reservations_capacity_exceptions (tenant_id, starts_on, ends_on);\n\ndo $$ begin\n create trigger plg_reservations_settings_updated_at before update on public.plg_reservations_settings\n for each row execute function public.handle_updated_at();\nexception when duplicate_object then null; end $$;\ndo $$ begin\n create trigger plg_reservations_rules_updated_at before update on public.plg_reservations_capacity_rules\n for each row execute function public.handle_updated_at();\nexception when duplicate_object then null; end $$;\ndo $$ begin\n create trigger plg_reservations_exceptions_updated_at before update on public.plg_reservations_capacity_exceptions\n for each row execute function public.handle_updated_at();\nexception when duplicate_object then null; end $$;\ndo $$ begin\n create trigger plg_reservations_updated_at before update on public.plg_reservations\n for each row execute function public.handle_updated_at();\nexception when duplicate_object then null; end $$;\n\n-- ---------------------------------------------------------------------------\n-- RLS \u2014 the ACTIVE account, never the union.\n--\n-- `user_tenant_ids()` honours only a signed JWT claim; switching workspace\n-- happens through the `x-fayz-tenant` header, so it does not see the switch and\n-- answers with the UNION of the caller's accounts. plugin-tables learned this\n-- the hard way \u2014 Artorius drew Papa L\u00E9guas' mesas. `app.current_tenant_id()`\n-- reads the header and validates it against app.memberships: it chooses among\n-- accounts you already belong to and can never widen.\n-- ---------------------------------------------------------------------------\nalter table public.plg_reservations_settings enable row level security;\nalter table public.plg_reservations_capacity_rules enable row level security;\nalter table public.plg_reservations_capacity_exceptions enable row level security;\nalter table public.plg_reservations enable row level security;\n\ndo $$\ndeclare t text;\nbegin\n foreach t in array array['plg_reservations_settings','plg_reservations_capacity_rules',\n 'plg_reservations_capacity_exceptions','plg_reservations'] loop\n execute format('drop policy if exists %I on public.%I', t || '_select', t);\n execute format('drop policy if exists %I on public.%I', t || '_insert', t);\n execute format('drop policy if exists %I on public.%I', t || '_update', t);\n execute format('drop policy if exists %I on public.%I', t || '_delete', t);\n execute format('create policy %I on public.%I for select using (tenant_id = (select app.current_tenant_id()))', t || '_select', t);\n execute format('create policy %I on public.%I for insert with check (tenant_id = (select app.current_tenant_id()))', t || '_insert', t);\n execute format('create policy %I on public.%I for update using (tenant_id = (select app.current_tenant_id()))', t || '_update', t);\n execute format('create policy %I on public.%I for delete using (tenant_id = (select app.current_tenant_id()))', t || '_delete', t);\n execute format('grant select, insert, update, delete on public.%I to authenticated', t);\n end loop;\nend $$;\n\n-- ---------------------------------------------------------------------------\n-- The reservation with the names already resolved. The list and the calendar\n-- read this, so nobody joins four tables in TypeScript to render a row.\n-- ---------------------------------------------------------------------------\ncreate or replace view public.v_reservations with (security_invoker = true) as\nselect\n r.id, r.tenant_id, r.person_id, r.guest_name, r.phone, r.email,\n r.zone_id, z.name as zone_name, z.color as zone_color,\n r.table_id, t.number as table_number,\n r.reserved_on, r.start_time, r.end_time, r.party_size,\n r.occasion, r.notes, r.status, r.order_id, r.seated_at,\n o.reference_number as order_reference,\n r.created_at, r.updated_at\nfrom public.plg_reservations r\nleft join public.plg_tables_zones z on z.id = r.zone_id\nleft join public.plg_tables_tables t on t.id = r.table_id\nleft join public.orders o on o.id = r.order_id;\n\ngrant select on public.v_reservations to authenticated;\n\n-- ---------------------------------------------------------------------------\n-- The slots of one day, with what is left in each.\n--\n-- THIS IS THE FUNCTION THE V1 NEVER GOT RIGHT. With three rules covering all\n-- seven weekdays, its \"Capacidade do dia\" answered \"Nenhuma grade configurada\"\n-- on every date tested (V1-041), and its reservation form never called the\n-- availability function at all \u2014 the lota\u00E7\u00E3o check, if it existed, did not\n-- happen while anyone was deciding. Both are the reason this screen exists.\n--\n-- Returns one row per zone \u00D7 window that applies to `p_date`, with the seats\n-- already spent by non-cancelled reservations STARTING inside that window \u2014\n-- which is what \"sem rolagem entre faixas\" means in the V1's own legend.\n--\n-- Exceptions OVERRIDE, they do not add: a zone with an exception covering the\n-- date returns the exception's windows and none of the weekly ones. A capacity\n-- of 0 therefore closes the zone for the day without deleting the grid.\n-- ---------------------------------------------------------------------------\ncreate or replace function public.reservations_day_capacity(p_date date)\nreturns table (\n zone_id uuid,\n zone_name text,\n zone_color text,\n start_time time,\n end_time time,\n capacity integer,\n booked integer,\n remaining integer,\n is_exception boolean\n)\nlanguage sql\nstable\nsecurity invoker\nset search_path = public\nas $$\n with tenant as (select app.current_tenant_id() as id),\n -- Which zones had their day overridden. Checked per zone, so a holiday in the\n -- Varanda does not silence the grid of the Sal\u00E3o.\n overridden as (\n select distinct e.zone_id\n from public.plg_reservations_capacity_exceptions e, tenant\n where e.tenant_id = tenant.id\n and p_date between e.starts_on and e.ends_on\n ),\n slots as (\n select e.zone_id, e.start_time, e.end_time, e.capacity, true as is_exception\n from public.plg_reservations_capacity_exceptions e, tenant\n where e.tenant_id = tenant.id\n and p_date between e.starts_on and e.ends_on\n and e.capacity > 0\n -- A whole-day exception still has to draw SOMETHING, so it borrows the\n -- house's widest window rather than a made-up one.\n and coalesce(e.start_time, time '00:00') < coalesce(e.end_time, time '23:59')\n union all\n select r.zone_id, r.start_time, r.end_time, r.capacity, false\n from public.plg_reservations_capacity_rules r, tenant\n where r.tenant_id = tenant.id\n and r.is_active\n -- extract(dow) is 0=Sunday..6=Saturday, the same axis `weekdays` uses.\n and extract(dow from p_date)::smallint = any (r.weekdays)\n and (r.zone_id is null or r.zone_id not in (select o.zone_id from overridden o where o.zone_id is not null))\n )\n select\n s.zone_id,\n z.name as zone_name,\n z.color as zone_color,\n coalesce(s.start_time, time '00:00') as start_time,\n coalesce(s.end_time, time '23:59') as end_time,\n s.capacity,\n coalesce(b.booked, 0)::integer as booked,\n greatest(s.capacity - coalesce(b.booked, 0), 0)::integer as remaining,\n s.is_exception\n from slots s\n left join public.plg_tables_zones z on z.id = s.zone_id\n left join lateral (\n select sum(v.party_size)::integer as booked\n from public.plg_reservations v, tenant\n where v.tenant_id = tenant.id\n and v.reserved_on = p_date\n and v.status <> 'cancelled'\n and (s.zone_id is null or v.zone_id is not distinct from s.zone_id)\n -- The reservation spends the window it STARTS in.\n and v.start_time >= coalesce(s.start_time, time '00:00')\n and v.start_time < coalesce(s.end_time, time '23:59')\n ) b on true\n order by coalesce(s.start_time, time '00:00'), z.name nulls first;\n$$;\n\ngrant execute on function public.reservations_day_capacity(date) to authenticated;\n";
|
|
2
|
+
export declare const MIGRATIONS: Array<{
|
|
3
|
+
id: string;
|
|
4
|
+
sql: string;
|
|
5
|
+
}>;
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/migrations/index.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,0BAA0B,gifAsStC,CAAA;AAED,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAEzD,CAAA"}
|
package/dist/store.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type StoreApi } from 'zustand/vanilla';
|
|
2
|
+
import type { ReservationsDataProvider } from './data/types';
|
|
3
|
+
import type { Reservation, CapacityRule, CapacityException, ReservationSettings, DaySlot, ReservationZone, ReservationTable, ReservationStatus, CreateReservationInput, ReservationQuery, ReservationsSummary } from './types';
|
|
4
|
+
export interface ReservationsUIState {
|
|
5
|
+
/** The day the service view is looking at, as `YYYY-MM-DD` local. */
|
|
6
|
+
selectedDate: string;
|
|
7
|
+
slots: DaySlot[];
|
|
8
|
+
slotsLoading: boolean;
|
|
9
|
+
/** The grid answered nothing for this day. Distinct from "still loading" so
|
|
10
|
+
* the screen can say WHICH of the two it is — the V1 could not, and its
|
|
11
|
+
* "Nenhuma grade configurada" was really a database error (V1-041). */
|
|
12
|
+
slotsError: string | null;
|
|
13
|
+
dayReservations: Reservation[];
|
|
14
|
+
dayLoading: boolean;
|
|
15
|
+
/** The wider list, for the Lista tab and the month markers. */
|
|
16
|
+
reservations: Reservation[];
|
|
17
|
+
listLoading: boolean;
|
|
18
|
+
summary: ReservationsSummary | null;
|
|
19
|
+
rules: CapacityRule[];
|
|
20
|
+
exceptions: CapacityException[];
|
|
21
|
+
settings: ReservationSettings | null;
|
|
22
|
+
configLoading: boolean;
|
|
23
|
+
zones: ReservationZone[];
|
|
24
|
+
tables: ReservationTable[];
|
|
25
|
+
selectedId: string | null;
|
|
26
|
+
setSelectedDate(date: string): void;
|
|
27
|
+
select(id: string | null): void;
|
|
28
|
+
fetchDay(date?: string): Promise<void>;
|
|
29
|
+
fetchRange(from: string, to: string, query?: ReservationQuery): Promise<void>;
|
|
30
|
+
fetchConfig(): Promise<void>;
|
|
31
|
+
fetchSalao(): Promise<void>;
|
|
32
|
+
create(input: CreateReservationInput): Promise<Reservation | null>;
|
|
33
|
+
update(id: string, data: Partial<CreateReservationInput>): Promise<void>;
|
|
34
|
+
setStatus(id: string, status: ReservationStatus): Promise<void>;
|
|
35
|
+
seat(reservationId: string, tableId: string, guests?: number): Promise<void>;
|
|
36
|
+
remove(id: string): Promise<void>;
|
|
37
|
+
saveRule(rule: Partial<CapacityRule> & {
|
|
38
|
+
id?: string;
|
|
39
|
+
}): Promise<void>;
|
|
40
|
+
deleteRule(id: string): Promise<void>;
|
|
41
|
+
saveException(ex: Partial<CapacityException> & {
|
|
42
|
+
id?: string;
|
|
43
|
+
}): Promise<void>;
|
|
44
|
+
deleteException(id: string): Promise<void>;
|
|
45
|
+
saveSettings(settings: ReservationSettings): Promise<void>;
|
|
46
|
+
}
|
|
47
|
+
export declare function createReservationsStore(provider: ReservationsDataProvider): StoreApi<ReservationsUIState>;
|
|
48
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAE5D,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAA;AAC5D,OAAO,KAAK,EACV,WAAW,EAAE,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EACjE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,iBAAiB,EAC7D,sBAAsB,EAAE,gBAAgB,EAAE,mBAAmB,EAC9D,MAAM,SAAS,CAAA;AAEhB,MAAM,WAAW,mBAAmB;IAClC,qEAAqE;IACrE,YAAY,EAAE,MAAM,CAAA;IAEpB,KAAK,EAAE,OAAO,EAAE,CAAA;IAChB,YAAY,EAAE,OAAO,CAAA;IACrB;;4EAEwE;IACxE,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IAEzB,eAAe,EAAE,WAAW,EAAE,CAAA;IAC9B,UAAU,EAAE,OAAO,CAAA;IAEnB,+DAA+D;IAC/D,YAAY,EAAE,WAAW,EAAE,CAAA;IAC3B,WAAW,EAAE,OAAO,CAAA;IAEpB,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAAA;IAEnC,KAAK,EAAE,YAAY,EAAE,CAAA;IACrB,UAAU,EAAE,iBAAiB,EAAE,CAAA;IAC/B,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAA;IACpC,aAAa,EAAE,OAAO,CAAA;IAEtB,KAAK,EAAE,eAAe,EAAE,CAAA;IACxB,MAAM,EAAE,gBAAgB,EAAE,CAAA;IAE1B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IAEzB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAA;IAE/B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACtC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7E,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAE3B,MAAM,CAAC,KAAK,EAAE,sBAAsB,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAA;IAClE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,sBAAsB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACxE,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/D,IAAI,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5E,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEjC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG;QAAE,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACtE,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,aAAa,CAAC,EAAE,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG;QAAE,EAAE,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9E,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1C,YAAY,CAAC,QAAQ,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3D;AAOD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,wBAAwB,GAAG,QAAQ,CAAC,mBAAmB,CAAC,CAgMzG"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The V1's five states, same words (`reservas/FLOW.md`, *O vocabulário*):
|
|
3
|
+
* Pendente · Confirmada · Acomodada · Não compareceu · Cancelada.
|
|
4
|
+
*
|
|
5
|
+
* `seated` is the one that does work: it is where the party becomes a comanda.
|
|
6
|
+
*/
|
|
7
|
+
export type ReservationStatus = 'pending' | 'confirmed' | 'seated' | 'no_show' | 'cancelled';
|
|
8
|
+
export declare const RESERVATION_STATUSES: ReservationStatus[];
|
|
9
|
+
/**
|
|
10
|
+
* How the house counts its lotação.
|
|
11
|
+
*
|
|
12
|
+
* `no_duration` is the V1 default, and its legend is the clearest statement of
|
|
13
|
+
* the model: *"a capacidade é o teto de pessoas que pode iniciar dentro da
|
|
14
|
+
* faixa, sem rolagem entre faixas"* — a reservation spends the slot it STARTS
|
|
15
|
+
* in, and nothing spills into the next one.
|
|
16
|
+
*/
|
|
17
|
+
export type CapacityMode = 'fixed_duration' | 'per_slot_duration' | 'no_duration';
|
|
18
|
+
export declare const CAPACITY_MODES: CapacityMode[];
|
|
19
|
+
/** The V1's list, kept whole — it is what reception actually asks on the phone. */
|
|
20
|
+
export type Occasion = 'birthday' | 'date' | 'business' | 'wedding' | 'graduation' | 'other';
|
|
21
|
+
export declare const OCCASIONS: Occasion[];
|
|
22
|
+
/** A reservation — `plg_reservations`, read through `v_reservations`. */
|
|
23
|
+
export interface Reservation {
|
|
24
|
+
id: string;
|
|
25
|
+
/** The client record, when the guest is one. A reservation taken over the
|
|
26
|
+
* phone from a stranger still has a name and a number — hence `guestName`. */
|
|
27
|
+
personId?: string;
|
|
28
|
+
guestName: string;
|
|
29
|
+
phone?: string;
|
|
30
|
+
email?: string;
|
|
31
|
+
zoneId?: string;
|
|
32
|
+
zoneName?: string;
|
|
33
|
+
zoneColor?: string;
|
|
34
|
+
tableId?: string;
|
|
35
|
+
tableNumber?: number;
|
|
36
|
+
/** ISO date, no time. The day the guests are coming. */
|
|
37
|
+
reservedOn: string;
|
|
38
|
+
/** "HH:MM". */
|
|
39
|
+
startTime: string;
|
|
40
|
+
endTime?: string;
|
|
41
|
+
partySize: number;
|
|
42
|
+
occasion?: Occasion;
|
|
43
|
+
notes?: string;
|
|
44
|
+
status: ReservationStatus;
|
|
45
|
+
/** The comanda this reservation opened when it was seated. The join the V1
|
|
46
|
+
* never made — see the migration. */
|
|
47
|
+
orderId?: string;
|
|
48
|
+
orderReference?: string;
|
|
49
|
+
seatedAt?: string;
|
|
50
|
+
tenantId: string;
|
|
51
|
+
createdAt: string;
|
|
52
|
+
updatedAt: string;
|
|
53
|
+
}
|
|
54
|
+
/** One line of the weekly grid — `plg_reservations_capacity_rules`. */
|
|
55
|
+
export interface CapacityRule {
|
|
56
|
+
id: string;
|
|
57
|
+
/** The praça. Undefined = the house as a whole, for a one-room restaurant. */
|
|
58
|
+
zoneId?: string;
|
|
59
|
+
zoneName?: string;
|
|
60
|
+
capacity: number;
|
|
61
|
+
startTime: string;
|
|
62
|
+
endTime: string;
|
|
63
|
+
/** 0=Sunday..6=Saturday, matching Date#getDay. */
|
|
64
|
+
weekdays: number[];
|
|
65
|
+
/** Only read in `per_slot_duration` mode. */
|
|
66
|
+
durationMinutes?: number;
|
|
67
|
+
isActive: boolean;
|
|
68
|
+
tenantId: string;
|
|
69
|
+
}
|
|
70
|
+
/** What overrides the grid — `plg_reservations_capacity_exceptions`. */
|
|
71
|
+
export interface CapacityException {
|
|
72
|
+
id: string;
|
|
73
|
+
zoneId?: string;
|
|
74
|
+
zoneName?: string;
|
|
75
|
+
startsOn: string;
|
|
76
|
+
endsOn: string;
|
|
77
|
+
startTime?: string;
|
|
78
|
+
endTime?: string;
|
|
79
|
+
/** Zero closes the zone for those days without deleting the weekly grid. */
|
|
80
|
+
capacity: number;
|
|
81
|
+
reason?: string;
|
|
82
|
+
tenantId: string;
|
|
83
|
+
}
|
|
84
|
+
/** The policy — one row per tenant. */
|
|
85
|
+
export interface ReservationSettings {
|
|
86
|
+
capacityMode: CapacityMode;
|
|
87
|
+
defaultDurationMinutes: number;
|
|
88
|
+
/** The V1 asks for this in MINUTES and the maximum in DAYS, in the same pair
|
|
89
|
+
* of fields. Hours here, and the form writes the equivalent beside it. */
|
|
90
|
+
minAdvanceHours: number;
|
|
91
|
+
maxAdvanceDays: number;
|
|
92
|
+
autoConfirm: boolean;
|
|
93
|
+
requirePhone: boolean;
|
|
94
|
+
requireEmail: boolean;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* One window of one day, with what is left in it.
|
|
98
|
+
*
|
|
99
|
+
* The whole reason the screen exists. The V1's equivalent answered "Nenhuma
|
|
100
|
+
* grade configurada" on every date tested with three rules loaded (V1-041), and
|
|
101
|
+
* its reservation form never asked for availability at all.
|
|
102
|
+
*/
|
|
103
|
+
export interface DaySlot {
|
|
104
|
+
zoneId?: string;
|
|
105
|
+
zoneName?: string;
|
|
106
|
+
zoneColor?: string;
|
|
107
|
+
startTime: string;
|
|
108
|
+
endTime: string;
|
|
109
|
+
capacity: number;
|
|
110
|
+
booked: number;
|
|
111
|
+
remaining: number;
|
|
112
|
+
/** True when an exception produced this window instead of the weekly grid. */
|
|
113
|
+
isException: boolean;
|
|
114
|
+
}
|
|
115
|
+
/** A praça, as this plugin needs it. Read from `plugin-tables`' own zones —
|
|
116
|
+
* the capacity is per praça, not per a cadastro of its own. */
|
|
117
|
+
export interface ReservationZone {
|
|
118
|
+
id: string;
|
|
119
|
+
name: string;
|
|
120
|
+
color?: string;
|
|
121
|
+
}
|
|
122
|
+
/** A mesa, for the optional "amarrar a reserva a uma mesa" field and for
|
|
123
|
+
* seating. Only the four things this plugin shows. */
|
|
124
|
+
export interface ReservationTable {
|
|
125
|
+
id: string;
|
|
126
|
+
number: number;
|
|
127
|
+
name?: string;
|
|
128
|
+
seats: number;
|
|
129
|
+
zoneId?: string;
|
|
130
|
+
/** A mesa with a comanda open on it cannot receive a party. */
|
|
131
|
+
isOccupied: boolean;
|
|
132
|
+
}
|
|
133
|
+
export interface CreateReservationInput {
|
|
134
|
+
personId?: string;
|
|
135
|
+
guestName: string;
|
|
136
|
+
phone?: string;
|
|
137
|
+
email?: string;
|
|
138
|
+
zoneId?: string;
|
|
139
|
+
tableId?: string;
|
|
140
|
+
reservedOn: string;
|
|
141
|
+
startTime: string;
|
|
142
|
+
endTime?: string;
|
|
143
|
+
partySize: number;
|
|
144
|
+
occasion?: Occasion;
|
|
145
|
+
notes?: string;
|
|
146
|
+
status?: ReservationStatus;
|
|
147
|
+
}
|
|
148
|
+
export interface ReservationQuery {
|
|
149
|
+
from?: string;
|
|
150
|
+
to?: string;
|
|
151
|
+
status?: ReservationStatus | ReservationStatus[];
|
|
152
|
+
zoneId?: string;
|
|
153
|
+
search?: string;
|
|
154
|
+
}
|
|
155
|
+
/** Seating is a write in two places, so it is one call. */
|
|
156
|
+
export interface SeatReservationInput {
|
|
157
|
+
reservationId: string;
|
|
158
|
+
tableId: string;
|
|
159
|
+
/** Defaults to the reservation's `partySize` — the party that shows up is not
|
|
160
|
+
* always the party that booked, and reception corrects it here. */
|
|
161
|
+
guests?: number;
|
|
162
|
+
}
|
|
163
|
+
export interface ReservationsSummary {
|
|
164
|
+
/** Reservations for the day being looked at, by state. */
|
|
165
|
+
total: number;
|
|
166
|
+
pending: number;
|
|
167
|
+
confirmed: number;
|
|
168
|
+
seated: number;
|
|
169
|
+
noShow: number;
|
|
170
|
+
cancelled: number;
|
|
171
|
+
/** People, not reservations — the number the kitchen plans against. */
|
|
172
|
+
expectedGuests: number;
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CapacitySettingsView.d.ts","sourceRoot":"","sources":["../../src/views/CapacitySettingsView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAA;AA0ClD,wBAAgB,oBAAoB,sBAoGnC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReservationsListView.d.ts","sourceRoot":"","sources":["../../src/views/ReservationsListView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoD,MAAM,OAAO,CAAA;AAUxE;yCACyC;AACzC,wBAAgB,oBAAoB,sBA+HnC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { StoreApi } from 'zustand/vanilla';
|
|
3
|
+
import { type ResolvedReservationsConfig } from '../context';
|
|
4
|
+
import type { ReservationsDataProvider } from '../data/types';
|
|
5
|
+
import type { ReservationsUIState } from '../store';
|
|
6
|
+
/**
|
|
7
|
+
* Two tabs, not the V1's four.
|
|
8
|
+
*
|
|
9
|
+
* The V1 has Calendário · Capacidade do dia · Lista de reservas · Configurações.
|
|
10
|
+
* The first two answer the same question at two zooms and are merged here — the
|
|
11
|
+
* month is the picker beside the day, so choosing a date does not cost a tab
|
|
12
|
+
* switch. Configurações moved out of the screen entirely: it is settings, and
|
|
13
|
+
* the rail is what a restaurant opens with the salão full.
|
|
14
|
+
*/
|
|
15
|
+
export declare function ReservationsPage({ config, provider, store }: {
|
|
16
|
+
config: ResolvedReservationsConfig;
|
|
17
|
+
provider: ReservationsDataProvider;
|
|
18
|
+
store: StoreApi<ReservationsUIState>;
|
|
19
|
+
}): React.JSX.Element;
|
|
20
|
+
/** The settings tab. Same context, so it reads the same store the screen does
|
|
21
|
+
* — saving a rule there refreshes the day here. */
|
|
22
|
+
export declare function ReservationsSettingsPage({ config, provider, store }: {
|
|
23
|
+
config: ResolvedReservationsConfig;
|
|
24
|
+
provider: ReservationsDataProvider;
|
|
25
|
+
store: StoreApi<ReservationsUIState>;
|
|
26
|
+
}): React.JSX.Element;
|
|
27
|
+
//# sourceMappingURL=ReservationsPage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReservationsPage.d.ts","sourceRoot":"","sources":["../../src/views/ReservationsPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmB,MAAM,OAAO,CAAA;AACvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAG/C,OAAO,EAA+B,KAAK,0BAA0B,EAAE,MAAM,YAAY,CAAA;AAIzF,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAA;AAC7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAInD;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAC5D,MAAM,EAAE,0BAA0B,CAAA;IAClC,QAAQ,EAAE,wBAAwB,CAAA;IAClC,KAAK,EAAE,QAAQ,CAAC,mBAAmB,CAAC,CAAA;CACrC,qBAsBA;AAED;oDACoD;AACpD,wBAAgB,wBAAwB,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IACpE,MAAM,EAAE,0BAA0B,CAAA;IAClC,QAAQ,EAAE,wBAAwB,CAAA;IAClC,KAAK,EAAE,QAAQ,CAAC,mBAAmB,CAAC,CAAA;CACrC,qBAMA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* The service screen: the night, one day at a time.
|
|
4
|
+
*
|
|
5
|
+
* Two columns, filters parked on the left — the shape the SDK's own UX ruler
|
|
6
|
+
* asks for: a bar over the list pushes the rows down on every touch and the
|
|
7
|
+
* person loses the line they were reading. Reception works this screen standing
|
|
8
|
+
* up with a phone in one hand.
|
|
9
|
+
*
|
|
10
|
+
* What is deliberately NOT here: a column per professional. That is the agenda,
|
|
11
|
+
* and it is what `/agenda` labelled "Reservas" was drawing — nine staff columns
|
|
12
|
+
* over a screen about how full the room is.
|
|
13
|
+
*/
|
|
14
|
+
export declare function ServiceDayView(): React.JSX.Element;
|
|
15
|
+
//# sourceMappingURL=ServiceDayView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ServiceDayView.d.ts","sourceRoot":"","sources":["../../src/views/ServiceDayView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAuC,MAAM,OAAO,CAAA;AAc3D;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,sBA+K7B"}
|