@fayz-ai/plugin-tables 0.9.0 → 0.9.2

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.
@@ -1,348 +0,0 @@
1
- import { createFayzClient, type FayzClientOptions, type FayzTableFilter } from '@fayz-ai/sdk'
2
- import type {
3
- CreateTableInput,
4
- RestaurantTable,
5
- SeatGuestsInput,
6
- TableQuery,
7
- TableSession,
8
- TablesSummary,
9
- TableStatus,
10
- UpdateTableStatusInput,
11
- Zone,
12
- } from '../types'
13
- import type { TablesDataProvider } from './types'
14
-
15
- export interface FayzTablesProviderOptions extends FayzClientOptions {
16
- projectId?: string
17
- tableName?: string
18
- schema?: string
19
- runtime?: boolean
20
- /**
21
- * Active tenant id (or a getter) used to scope reads and stamp writes on the
22
- * restaurant_tables table. When omitted, scoping is left to runtime/RLS.
23
- */
24
- tenantId?: string | (() => string | undefined | null)
25
- }
26
-
27
- interface RestaurantTableRow {
28
- id: string
29
- tenant_id?: string | null
30
- name?: string | null
31
- number?: number | null
32
- seats?: number | null
33
- status?: TableStatus | null
34
- zone?: string | null
35
- zone_name?: string | null
36
- shape?: RestaurantTable['shape'] | null
37
- grid_col?: number | null
38
- grid_row?: number | null
39
- is_active?: boolean | null
40
- current_session_id?: string | null
41
- current_order_id?: string | null
42
- current_guests?: number | null
43
- current_waiter_name?: string | null
44
- current_elapsed_minutes?: number | null
45
- current_total?: number | null
46
- metadata?: Record<string, unknown> | null
47
- created_at?: string | null
48
- updated_at?: string | null
49
- }
50
-
51
- const DEFAULT_TABLE_NAME = 'restaurant_tables'
52
-
53
- function nowIso(): string {
54
- return new Date().toISOString()
55
- }
56
-
57
- function rowToTable(row: RestaurantTableRow): RestaurantTable {
58
- const number = row.number ?? 0
59
- const zone = row.zone ?? 'indoor'
60
- return {
61
- id: row.id,
62
- name: row.name ?? `Table ${number}`,
63
- number,
64
- seats: row.seats ?? 4,
65
- status: row.status ?? 'available',
66
- zone,
67
- zoneName: row.zone_name ?? zone,
68
- shape: row.shape ?? 'square',
69
- gridCol: row.grid_col ?? 0,
70
- gridRow: row.grid_row ?? 0,
71
- isActive: row.is_active ?? true,
72
- currentSessionId: row.current_session_id ?? undefined,
73
- currentOrderId: row.current_order_id ?? undefined,
74
- currentGuests: row.current_guests ?? undefined,
75
- currentWaiterName: row.current_waiter_name ?? undefined,
76
- currentElapsedMinutes: row.current_elapsed_minutes ?? undefined,
77
- currentTotal: row.current_total ?? undefined,
78
- metadata: row.metadata ?? {},
79
- tenantId: row.tenant_id ?? 'runtime-tenant',
80
- createdAt: row.created_at ?? nowIso(),
81
- updatedAt: row.updated_at ?? row.created_at ?? nowIso(),
82
- }
83
- }
84
-
85
- function tableCreatePayload(input: CreateTableInput): Record<string, unknown> {
86
- return {
87
- name: input.name,
88
- number: input.number,
89
- seats: input.seats,
90
- zone: input.zone,
91
- shape: input.shape ?? 'square',
92
- grid_col: input.gridCol ?? 0,
93
- grid_row: input.gridRow ?? 0,
94
- status: 'available',
95
- is_active: true,
96
- }
97
- }
98
-
99
- function tableUpdatePayload(data: Partial<RestaurantTable>): Record<string, unknown> {
100
- const payload: Record<string, unknown> = {}
101
- if (data.name !== undefined) payload.name = data.name
102
- if (data.number !== undefined) payload.number = data.number
103
- if (data.seats !== undefined) payload.seats = data.seats
104
- if (data.status !== undefined) payload.status = data.status
105
- if (data.zone !== undefined) payload.zone = data.zone
106
- if (data.zoneName !== undefined) payload.zone_name = data.zoneName
107
- if (data.shape !== undefined) payload.shape = data.shape
108
- if (data.gridCol !== undefined) payload.grid_col = data.gridCol
109
- if (data.gridRow !== undefined) payload.grid_row = data.gridRow
110
- if (data.isActive !== undefined) payload.is_active = data.isActive
111
- if (data.currentSessionId !== undefined) payload.current_session_id = data.currentSessionId
112
- if (data.currentOrderId !== undefined) payload.current_order_id = data.currentOrderId
113
- if (data.currentGuests !== undefined) payload.current_guests = data.currentGuests
114
- if (data.currentWaiterName !== undefined) payload.current_waiter_name = data.currentWaiterName
115
- if (data.currentElapsedMinutes !== undefined) payload.current_elapsed_minutes = data.currentElapsedMinutes
116
- if (data.currentTotal !== undefined) payload.current_total = data.currentTotal
117
- if (data.metadata !== undefined) payload.metadata = data.metadata
118
- return payload
119
- }
120
-
121
- function filtersFromQuery(query?: TableQuery): FayzTableFilter[] {
122
- const filters: FayzTableFilter[] = [{ column: 'is_active', operator: 'eq', value: true }]
123
- if (!query) return filters
124
- if (query.zone) filters.push({ column: 'zone', operator: 'eq', value: query.zone })
125
- if (query.status && !Array.isArray(query.status)) {
126
- filters.push({ column: 'status', operator: 'eq', value: query.status })
127
- }
128
- return filters
129
- }
130
-
131
- function matchesClientQuery(table: RestaurantTable, query?: TableQuery): boolean {
132
- if (!query) return true
133
- if (Array.isArray(query.status) && !query.status.includes(table.status)) return false
134
- if (query.search) {
135
- const search = query.search.toLowerCase()
136
- return table.name.toLowerCase().includes(search)
137
- || String(table.number).includes(search)
138
- || (table.zoneName?.toLowerCase().includes(search) ?? false)
139
- }
140
- return true
141
- }
142
-
143
- function summarize(tables: RestaurantTable[]): TablesSummary {
144
- const availableCount = tables.filter((table) => table.status === 'available').length
145
- const occupiedCount = tables.filter((table) => table.status === 'occupied').length
146
- const reservedCount = tables.filter((table) => table.status === 'reserved').length
147
- const cleaningCount = tables.filter((table) => table.status === 'cleaning').length
148
- const totalSeats = tables.reduce((sum, table) => sum + table.seats, 0)
149
- const occupiedSeats = tables
150
- .filter((table) => table.status === 'occupied')
151
- .reduce((sum, table) => sum + (table.currentGuests ?? table.seats), 0)
152
-
153
- return {
154
- totalTables: tables.length,
155
- availableCount,
156
- occupiedCount,
157
- reservedCount,
158
- cleaningCount,
159
- totalSeats,
160
- occupiedSeats,
161
- averageSessionMinutes: 0,
162
- }
163
- }
164
-
165
- export function createFayzTablesProvider(options: FayzTablesProviderOptions = {}): TablesDataProvider {
166
- const client = createFayzClient(options)
167
- const table = options.tableName ?? DEFAULT_TABLE_NAME
168
- const baseOptions = {
169
- projectId: options.projectId,
170
- table,
171
- schema: options.schema,
172
- runtime: options.runtime,
173
- }
174
-
175
- function resolveTenant(): string | undefined {
176
- const value = typeof options.tenantId === 'function' ? options.tenantId() : options.tenantId
177
- return value ?? undefined
178
- }
179
-
180
- function withTenant(filters: FayzTableFilter[]): FayzTableFilter[] {
181
- const tenantId = resolveTenant()
182
- return tenantId ? [{ column: 'tenant_id', operator: 'eq', value: tenantId }, ...filters] : filters
183
- }
184
-
185
- async function listTables(query?: TableQuery): Promise<RestaurantTable[]> {
186
- const response = await client.data.listRows<RestaurantTableRow>({
187
- ...baseOptions,
188
- filters: withTenant(filtersFromQuery(query)),
189
- sortColumn: 'number',
190
- sortDirection: 'asc',
191
- limit: 500,
192
- })
193
- return response.rows.map(rowToTable).filter((item) => matchesClientQuery(item, query))
194
- }
195
-
196
- async function getById(id: string): Promise<RestaurantTable | null> {
197
- const response = await client.data.listRows<RestaurantTableRow>({
198
- ...baseOptions,
199
- filters: withTenant([{ column: 'id', operator: 'eq', value: id }]),
200
- limit: 1,
201
- })
202
- return response.rows[0] ? rowToTable(response.rows[0]) : null
203
- }
204
-
205
- return {
206
- async getTables(query?: TableQuery) {
207
- return listTables(query)
208
- },
209
-
210
- async getTableById(id: string) {
211
- return getById(id)
212
- },
213
-
214
- async createTable(input: CreateTableInput) {
215
- const tenantId = resolveTenant()
216
- const row = await client.data.createRow<RestaurantTableRow>({
217
- ...baseOptions,
218
- row: tenantId ? { ...tableCreatePayload(input), tenant_id: tenantId } : tableCreatePayload(input),
219
- })
220
- return rowToTable(row)
221
- },
222
-
223
- async updateTable(id: string, data: Partial<RestaurantTable>) {
224
- const row = await client.data.updateRow<RestaurantTableRow>({
225
- ...baseOptions,
226
- primaryKeys: { id },
227
- row: tableUpdatePayload(data),
228
- })
229
- return rowToTable(row)
230
- },
231
-
232
- async deleteTable(id: string) {
233
- await client.data.deleteRows({ ...baseOptions, rows: [{ id }] })
234
- },
235
-
236
- async updateTableStatus(input: UpdateTableStatusInput) {
237
- return this.updateTable(input.tableId, { status: input.status })
238
- },
239
-
240
- async updateTablePositions(positions: Array<{ id: string; gridCol: number; gridRow: number }>) {
241
- await Promise.all(positions.map((position) => this.updateTable(position.id, {
242
- gridCol: position.gridCol,
243
- gridRow: position.gridRow,
244
- })))
245
- },
246
-
247
- async seatGuests(input: SeatGuestsInput) {
248
- const table = await this.updateTable(input.tableId, {
249
- status: 'occupied',
250
- currentGuests: input.guests,
251
- currentWaiterName: input.waiterId ? `Waiter ${input.waiterId}` : undefined,
252
- currentElapsedMinutes: 0,
253
- currentTotal: 0,
254
- })
255
- const session: TableSession = {
256
- id: table.currentSessionId ?? `runtime-session-${table.id}`,
257
- tableId: table.id,
258
- tableName: table.name,
259
- guests: input.guests,
260
- waiterId: input.waiterId,
261
- waiterName: table.currentWaiterName,
262
- seatedAt: nowIso(),
263
- status: 'active',
264
- notes: input.notes,
265
- tenantId: table.tenantId,
266
- createdAt: nowIso(),
267
- }
268
- return session
269
- },
270
-
271
- async closeSession(sessionId: string) {
272
- const tables = await listTables()
273
- const table = tables.find((item) => item.currentSessionId === sessionId)
274
- if (table) await this.updateTable(table.id, {
275
- status: 'cleaning',
276
- currentSessionId: undefined,
277
- currentOrderId: undefined,
278
- currentGuests: undefined,
279
- currentWaiterName: undefined,
280
- currentElapsedMinutes: undefined,
281
- currentTotal: undefined,
282
- })
283
- return {
284
- id: sessionId,
285
- tableId: table?.id ?? '',
286
- tableName: table?.name,
287
- guests: table?.currentGuests ?? 0,
288
- seatedAt: nowIso(),
289
- closedAt: nowIso(),
290
- status: 'closed',
291
- tenantId: table?.tenantId ?? 'runtime-tenant',
292
- createdAt: nowIso(),
293
- }
294
- },
295
-
296
- async getActiveSessions() {
297
- const tables = await listTables({ status: 'occupied' })
298
- return tables.map((table) => ({
299
- id: table.currentSessionId ?? `runtime-session-${table.id}`,
300
- tableId: table.id,
301
- tableName: table.name,
302
- guests: table.currentGuests ?? table.seats,
303
- waiterName: table.currentWaiterName,
304
- seatedAt: nowIso(),
305
- status: 'active' as const,
306
- tenantId: table.tenantId,
307
- createdAt: nowIso(),
308
- }))
309
- },
310
-
311
- async getSessionHistory() {
312
- return []
313
- },
314
-
315
- async getZones() {
316
- const tables = await listTables()
317
- const zones = new Map<string, Zone>()
318
- for (const table of tables) {
319
- if (zones.has(table.zone)) continue
320
- zones.set(table.zone, {
321
- id: table.zone,
322
- name: table.zoneName ?? table.zone,
323
- sortOrder: zones.size,
324
- isActive: true,
325
- tenantId: table.tenantId,
326
- createdAt: table.createdAt,
327
- })
328
- }
329
- return [...zones.values()]
330
- },
331
-
332
- async createZone() {
333
- throw new Error('Restaurant zone writes require a dedicated Fayz table/broker contract.')
334
- },
335
-
336
- async updateZone() {
337
- throw new Error('Restaurant zone writes require a dedicated Fayz table/broker contract.')
338
- },
339
-
340
- async deleteZone() {
341
- throw new Error('Restaurant zone writes require a dedicated Fayz table/broker contract.')
342
- },
343
-
344
- async getSummary() {
345
- return summarize(await listTables())
346
- },
347
- }
348
- }
package/src/data/types.ts DELETED
@@ -1,31 +0,0 @@
1
- import type {
2
- RestaurantTable, TableSession, Zone,
3
- CreateTableInput, SeatGuestsInput, UpdateTableStatusInput,
4
- TableQuery, TablesSummary,
5
- } from '../types'
6
-
7
- export interface TablesDataProvider {
8
- // Tables
9
- getTables(query?: TableQuery): Promise<RestaurantTable[]>
10
- getTableById(id: string): Promise<RestaurantTable | null>
11
- createTable(input: CreateTableInput): Promise<RestaurantTable>
12
- updateTable(id: string, data: Partial<RestaurantTable>): Promise<RestaurantTable>
13
- deleteTable(id: string): Promise<void>
14
- updateTableStatus(input: UpdateTableStatusInput): Promise<RestaurantTable>
15
- updateTablePositions(positions: Array<{ id: string; gridCol: number; gridRow: number }>): Promise<void>
16
-
17
- // Sessions
18
- seatGuests(input: SeatGuestsInput): Promise<TableSession>
19
- closeSession(sessionId: string): Promise<TableSession>
20
- getActiveSessions(): Promise<TableSession[]>
21
- getSessionHistory(tableId?: string): Promise<TableSession[]>
22
-
23
- // Zones
24
- getZones(): Promise<Zone[]>
25
- createZone(data: Partial<Zone>): Promise<Zone>
26
- updateZone(id: string, data: Partial<Zone>): Promise<Zone>
27
- deleteZone(id: string): Promise<void>
28
-
29
- // Summary
30
- getSummary(): Promise<TablesSummary>
31
- }
package/src/index.ts DELETED
@@ -1,179 +0,0 @@
1
- import React from 'react'
2
- import type { PluginManifest, PluginScope, VerticalId } from '@fayz-ai/core'
3
- import type { TablesDataProvider } from './data/types'
4
- import type { TableSession } from './types'
5
- import { createMockTablesProvider } from './data/mock'
6
- import { createTablesStore } from './store'
7
- import { tablesRegistries } from './registries'
8
- import { tablesLocales } from './locales'
9
- import { PluginSettingsPanel } from '@fayz-ai/saas'
10
-
11
- const TablesPage = React.lazy(() => import('./TablesPage').then((m) => ({ default: m.TablesPage })))
12
-
13
- // ---------------------------------------------------------------------------
14
- // Labels
15
- // ---------------------------------------------------------------------------
16
-
17
- export interface TablesPluginLabels {
18
- pageTitle: string
19
- floorPlan: string
20
- zones: string
21
- sessionHistory: string
22
- }
23
-
24
- const DEFAULT_LABELS: TablesPluginLabels = {
25
- pageTitle: 'Tables',
26
- floorPlan: 'Floor Plan',
27
- zones: 'Zones',
28
- sessionHistory: 'Session History',
29
- }
30
-
31
- // ---------------------------------------------------------------------------
32
- // Options
33
- // ---------------------------------------------------------------------------
34
-
35
- export interface TablesPluginOptions {
36
- modules?: {
37
- reservations?: boolean
38
- sessionHistory?: boolean
39
- }
40
- labels?: Partial<TablesPluginLabels>
41
- defaultZones?: Array<{ name: string; color?: string }>
42
- navPosition?: number
43
- navSection?: 'main' | 'secondary' | 'settings'
44
- scope?: PluginScope
45
- verticalId?: VerticalId
46
- dataProvider?: TablesDataProvider
47
- onTableSeated?: (session: TableSession) => Promise<string | undefined>
48
- onTableClosed?: (session: TableSession) => Promise<void>
49
- }
50
-
51
- // ---------------------------------------------------------------------------
52
- // Config resolver
53
- // ---------------------------------------------------------------------------
54
-
55
- function resolveConfig(options?: TablesPluginOptions) {
56
- return {
57
- modules: {
58
- reservations: options?.modules?.reservations === true,
59
- sessionHistory: options?.modules?.sessionHistory !== false,
60
- },
61
- labels: { ...DEFAULT_LABELS, ...options?.labels } as any,
62
- defaultZones: options?.defaultZones ?? [
63
- { name: 'Indoor', color: '#3b82f6' },
64
- { name: 'Outdoor', color: '#22c55e' },
65
- { name: 'Bar', color: '#f59e0b' },
66
- ],
67
- onTableSeated: options?.onTableSeated,
68
- onTableClosed: options?.onTableClosed,
69
- }
70
- }
71
-
72
- // ---------------------------------------------------------------------------
73
- // Factory
74
- // ---------------------------------------------------------------------------
75
-
76
- export function createTablesPlugin(options?: TablesPluginOptions): PluginManifest {
77
- const config = resolveConfig(options)
78
- const provider = options?.dataProvider ?? createMockTablesProvider()
79
- const store = createTablesStore(provider)
80
-
81
- const PageComponent: React.FC<any> = () =>
82
- React.createElement(React.Suspense, { fallback: null },
83
- React.createElement(TablesPage, { config, provider, store, registries: tablesRegistries })
84
- )
85
-
86
- return {
87
- id: 'tables',
88
- name: config.labels.pageTitle,
89
- icon: 'MapPin',
90
- version: '1.0.0',
91
- scope: options?.scope ?? 'vertical',
92
- verticalId: options?.verticalId,
93
- defaultEnabled: true,
94
- dependencies: [],
95
- navigation: [
96
- {
97
- section: options?.navSection ?? 'main',
98
- position: options?.navPosition ?? 4,
99
- label: config.labels.pageTitle,
100
- route: '/tables',
101
- icon: 'MapPin',
102
- permission: { feature: 'tables', action: 'read' as const },
103
- },
104
- ],
105
- routes: [
106
- {
107
- path: '/tables',
108
- component: PageComponent,
109
- permission: { feature: 'tables', action: 'read' as const },
110
- },
111
- ],
112
- widgets: [],
113
- aiTools: [
114
- {
115
- id: 'tables.availability',
116
- name: 'getTableAvailability',
117
- description: 'Returns which tables are available, occupied, reserved, or being cleaned.',
118
- icon: 'MapPin',
119
- mode: 'read' as const,
120
- category: 'Tables',
121
- parameters: {
122
- type: 'object' as const,
123
- properties: {
124
- zone: { type: 'string' as const, description: 'Filter by zone name' },
125
- status: { type: 'string' as const, enum: ['available', 'occupied', 'reserved', 'cleaning'] },
126
- },
127
- },
128
- suggestions: [
129
- { label: 'Which tables are available right now?' },
130
- { label: 'How many tables are occupied?' },
131
- ],
132
- },
133
- {
134
- id: 'tables.seat-guests',
135
- name: 'seatGuests',
136
- description: 'Seats guests at a specific table.',
137
- icon: 'UserPlus',
138
- mode: 'persist' as const,
139
- category: 'Tables',
140
- parameters: {
141
- type: 'object' as const,
142
- properties: {
143
- tableNumber: { type: 'number' as const, description: 'Table number' },
144
- guests: { type: 'number' as const, description: 'Number of guests' },
145
- },
146
- required: ['tableNumber', 'guests'],
147
- },
148
- permission: { feature: 'tables', action: 'edit' as const },
149
- },
150
- ],
151
- registries: tablesRegistries,
152
- settings: [
153
- {
154
- id: 'tables',
155
- label: config.labels.pageTitle,
156
- icon: 'MapPin',
157
- component: (() => {
158
- const TablesSettingsTab: React.ComponentType<unknown> = () =>
159
- React.createElement(PluginSettingsPanel, {
160
- title: 'Tables Settings',
161
- subtitle: 'Zones and floor plan configuration',
162
- registries: tablesRegistries,
163
- routeBase: '/settings/tables',
164
- })
165
- TablesSettingsTab.displayName = 'TablesSettingsTab'
166
- return TablesSettingsTab
167
- })(),
168
- order: 21,
169
- permission: { feature: 'tables', action: 'read' as const },
170
- },
171
- ],
172
- locales: tablesLocales,
173
- }
174
- }
175
-
176
- export type { TablesDataProvider } from './data/types'
177
- export { createFayzTablesProvider } from './data/platform'
178
- export type { FayzTablesProviderOptions } from './data/platform'
179
- export type { ResolvedTablesConfig } from './TablesContext'
package/src/locales/en.ts DELETED
@@ -1,45 +0,0 @@
1
- export const en: Record<string, string> = {
2
- 'tables.title': 'Tables',
3
- 'tables.nav.floorPlan': 'Floor Plan',
4
- 'tables.nav.zones': 'Zones',
5
- 'tables.nav.history': 'Session History',
6
- 'tables.floorPlan.title': 'Floor Plan',
7
- 'tables.floorPlan.subtitle': 'Manage table layout and seating',
8
- 'tables.floorPlan.available': 'Available',
9
- 'tables.floorPlan.occupied': 'Occupied',
10
- 'tables.floorPlan.reserved': 'Reserved',
11
- 'tables.floorPlan.cleaning': 'Cleaning',
12
- 'tables.floorPlan.seats': 'seats',
13
- 'tables.floorPlan.noTables': 'No tables configured',
14
- 'tables.floorPlan.noTablesDesc': 'Add your first table to get started',
15
- 'tables.floorPlan.addTable': 'Add Table',
16
- 'tables.floorPlan.occupiedOf': '{occupied} occupied, {available} available of {total} tables',
17
- 'tables.floorPlan.selectTable': 'Select a table',
18
- 'tables.floorPlan.selectTableDesc': 'Click on any table to see details and actions',
19
- 'tables.floorPlan.min': 'min',
20
- 'tables.floorPlan.zone': 'Zone',
21
- 'tables.floorPlan.order': 'Order',
22
- 'tables.floorPlan.checkIn': 'Check In',
23
- 'tables.detail.currentSession': 'Current Session',
24
- 'tables.detail.guests': 'Guests',
25
- 'tables.detail.waiter': 'Waiter',
26
- 'tables.detail.elapsed': 'Elapsed',
27
- 'tables.detail.total': 'Running Total',
28
- 'tables.detail.viewOrder': 'View Order',
29
- 'tables.detail.seatGuests': 'Seat Guests',
30
- 'tables.detail.closeTable': 'Close Table',
31
- 'tables.detail.markClean': 'Mark Ready',
32
- 'tables.detail.cancel': 'Cancel',
33
- 'tables.seat.title': 'Seat Guests',
34
- 'tables.seat.guestCount': 'Number of guests',
35
- 'tables.seat.waiter': 'Waiter',
36
- 'tables.seat.notes': 'Notes',
37
- 'tables.seat.confirm': 'Seat',
38
- 'tables.history.title': 'Session History',
39
- 'tables.history.table': 'Table',
40
- 'tables.history.guests': 'Guests',
41
- 'tables.history.waiter': 'Waiter',
42
- 'tables.history.duration': 'Duration',
43
- 'tables.history.noSessions': 'No session history yet',
44
- 'tables.settings.title': 'Tables Settings',
45
- }
@@ -1,4 +0,0 @@
1
- import { en } from './en'
2
- import { ptBR } from './pt-BR'
3
-
4
- export const tablesLocales: Record<string, Record<string, string>> = { en, 'pt-BR': ptBR }
@@ -1,45 +0,0 @@
1
- export const ptBR: Record<string, string> = {
2
- 'tables.title': 'Mesas',
3
- 'tables.nav.floorPlan': 'Mapa de Mesas',
4
- 'tables.nav.zones': 'Áreas',
5
- 'tables.nav.history': 'Histórico',
6
- 'tables.floorPlan.title': 'Mapa de Mesas',
7
- 'tables.floorPlan.subtitle': 'Gerencie o layout e a ocupação das mesas',
8
- 'tables.floorPlan.available': 'Disponível',
9
- 'tables.floorPlan.occupied': 'Ocupada',
10
- 'tables.floorPlan.reserved': 'Reservada',
11
- 'tables.floorPlan.cleaning': 'Limpeza',
12
- 'tables.floorPlan.seats': 'lugares',
13
- 'tables.floorPlan.noTables': 'Nenhuma mesa configurada',
14
- 'tables.floorPlan.noTablesDesc': 'Adicione a primeira mesa para começar',
15
- 'tables.floorPlan.addTable': 'Adicionar Mesa',
16
- 'tables.floorPlan.occupiedOf': '{occupied} ocupadas, {available} disponíveis de {total} mesas',
17
- 'tables.floorPlan.selectTable': 'Selecione uma mesa',
18
- 'tables.floorPlan.selectTableDesc': 'Clique em uma mesa para ver detalhes e ações',
19
- 'tables.floorPlan.min': 'min',
20
- 'tables.floorPlan.zone': 'Área',
21
- 'tables.floorPlan.order': 'Pedido',
22
- 'tables.floorPlan.checkIn': 'Check-in',
23
- 'tables.detail.currentSession': 'Sessão Atual',
24
- 'tables.detail.guests': 'Pessoas',
25
- 'tables.detail.waiter': 'Garçom',
26
- 'tables.detail.elapsed': 'Tempo',
27
- 'tables.detail.total': 'Total Parcial',
28
- 'tables.detail.viewOrder': 'Ver Pedido',
29
- 'tables.detail.seatGuests': 'Sentar Clientes',
30
- 'tables.detail.closeTable': 'Fechar Mesa',
31
- 'tables.detail.markClean': 'Marcar Pronta',
32
- 'tables.detail.cancel': 'Cancelar',
33
- 'tables.seat.title': 'Sentar Clientes',
34
- 'tables.seat.guestCount': 'Número de pessoas',
35
- 'tables.seat.waiter': 'Garçom',
36
- 'tables.seat.notes': 'Observações',
37
- 'tables.seat.confirm': 'Sentar',
38
- 'tables.history.title': 'Histórico de Sessões',
39
- 'tables.history.table': 'Mesa',
40
- 'tables.history.guests': 'Pessoas',
41
- 'tables.history.waiter': 'Garçom',
42
- 'tables.history.duration': 'Duração',
43
- 'tables.history.noSessions': 'Nenhum histórico de sessões',
44
- 'tables.settings.title': 'Configurações de Mesas',
45
- }
package/src/registries.ts DELETED
@@ -1,32 +0,0 @@
1
- import type { PluginRegistryDef } from '@fayz-ai/core'
2
- import type { EntityDef } from '@fayz-ai/core'
3
-
4
- const zoneEntity: EntityDef = {
5
- name: 'Zone',
6
- namePlural: 'Zones',
7
- icon: 'MapPin',
8
- displayField: 'name',
9
- defaultSort: 'sortOrder',
10
- fields: [
11
- { key: 'name', label: 'Name', type: 'text', required: true, showInTable: true },
12
- { key: 'color', label: 'Color', type: 'text', showInTable: true },
13
- { key: 'sortOrder', label: 'Order', type: 'number', showInTable: true, defaultValue: 0 },
14
- { key: 'isActive', label: 'Active', type: 'boolean', showInTable: true, defaultValue: true },
15
- ],
16
- data: { table: 'restaurant_zones', tenantScoped: true },
17
- }
18
-
19
- export const tablesRegistries: PluginRegistryDef[] = [
20
- {
21
- id: 'zones',
22
- entity: zoneEntity,
23
- icon: 'MapPin',
24
- description: 'Floor plan zones (indoor, outdoor, bar, etc.)',
25
- display: 'table',
26
- seedData: [
27
- { id: 'z-indoor', name: 'Indoor', color: '#3b82f6', sortOrder: 0, isActive: true },
28
- { id: 'z-outdoor', name: 'Outdoor', color: '#22c55e', sortOrder: 1, isActive: true },
29
- { id: 'z-bar', name: 'Bar', color: '#f59e0b', sortOrder: 2, isActive: true },
30
- ],
31
- },
32
- ]