@fayz-ai/plugin-menu 0.9.0-next.1 → 0.9.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/README.md +3 -3
- package/dist/{MenuPage-WOI5IELV.js → MenuPage-ZNKKQJKD.js} +4 -4
- package/dist/{MenuPage-WOI5IELV.js.map → MenuPage-ZNKKQJKD.js.map} +1 -1
- package/dist/{MenuContext.d.ts → context.d.ts} +2 -2
- package/dist/context.d.ts.map +1 -0
- package/dist/data/registries.d.ts.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/{MenuPage.d.ts → views/MenuPage.d.ts} +3 -3
- package/dist/views/MenuPage.d.ts.map +1 -0
- package/package.json +6 -8
- package/dist/MenuContext.d.ts.map +0 -1
- package/dist/MenuPage.d.ts.map +0 -1
- package/dist/registries.d.ts.map +0 -1
- package/src/MenuContext.tsx +0 -40
- package/src/MenuPage.tsx +0 -21
- package/src/data/mock.ts +0 -289
- package/src/data/platform.ts +0 -429
- package/src/data/types.ts +0 -33
- package/src/index.ts +0 -191
- package/src/locales/en.ts +0 -64
- package/src/locales/index.ts +0 -4
- package/src/locales/pt-BR.ts +0 -64
- package/src/registries.ts +0 -84
- package/src/store.ts +0 -161
- package/src/types.ts +0 -145
- package/src/views/MenuManagerView.tsx +0 -694
- /package/dist/{registries.d.ts → data/registries.d.ts} +0 -0
package/src/locales/en.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
export const en: Record<string, string> = {
|
|
2
|
-
'menu.title': 'Menu',
|
|
3
|
-
'menu.nav.manager': 'Menu',
|
|
4
|
-
'menu.nav.categories': 'Categories',
|
|
5
|
-
'menu.nav.items': 'Items',
|
|
6
|
-
'menu.nav.modifiers': 'Modifiers',
|
|
7
|
-
'menu.manager.title': 'Menu Manager',
|
|
8
|
-
'menu.manager.subtitle': 'Manage your menu items and categories',
|
|
9
|
-
'menu.manager.search': 'Search menu...',
|
|
10
|
-
'menu.manager.allCategories': 'All Categories',
|
|
11
|
-
'menu.manager.newItem': 'New Item',
|
|
12
|
-
'menu.manager.noItems': 'No menu items yet',
|
|
13
|
-
'menu.manager.noItemsDesc': 'Add your first menu item to get started',
|
|
14
|
-
'menu.manager.addFirst': 'Add first item',
|
|
15
|
-
'menu.manager.available': 'Available',
|
|
16
|
-
'menu.manager.soldOut': 'Sold Out',
|
|
17
|
-
'menu.manager.hidden': 'Hidden',
|
|
18
|
-
'menu.manager.pos': 'POS',
|
|
19
|
-
'menu.manager.delivery': 'Delivery',
|
|
20
|
-
'menu.manager.featured': 'Featured',
|
|
21
|
-
'menu.manager.prepTime': 'Prep time',
|
|
22
|
-
'menu.manager.min': 'min',
|
|
23
|
-
'menu.manager.addCategory': 'Add Category',
|
|
24
|
-
'menu.manager.addProduct': 'Add Product',
|
|
25
|
-
'menu.manager.item': 'Item',
|
|
26
|
-
'menu.manager.price': 'Price',
|
|
27
|
-
'menu.manager.deliveryPrice': 'Delivery $',
|
|
28
|
-
'menu.manager.itemsCount': '{{count}} items',
|
|
29
|
-
'menu.manager.noResults': 'No categories or items match your search.',
|
|
30
|
-
'menu.manager.noResultsDesc': 'Try a different search term or category filter.',
|
|
31
|
-
'menu.itemForm.newTitle': 'New Menu Item',
|
|
32
|
-
'menu.itemForm.editTitle': 'Edit Menu Item',
|
|
33
|
-
'menu.itemForm.name': 'Item name',
|
|
34
|
-
'menu.itemForm.description': 'Description',
|
|
35
|
-
'menu.itemForm.price': 'Price',
|
|
36
|
-
'menu.itemForm.cost': 'Cost',
|
|
37
|
-
'menu.itemForm.category': 'Category',
|
|
38
|
-
'menu.itemForm.prepTime': 'Prep time (min)',
|
|
39
|
-
'menu.itemForm.image': 'Image URL',
|
|
40
|
-
'menu.itemForm.allergens': 'Allergens',
|
|
41
|
-
'menu.itemForm.dietaryTags': 'Dietary tags',
|
|
42
|
-
'menu.itemForm.availableForPos': 'Available for POS',
|
|
43
|
-
'menu.itemForm.availableForDelivery': 'Available for Delivery',
|
|
44
|
-
'menu.itemForm.deliveryPrice': 'Delivery price',
|
|
45
|
-
'menu.itemForm.isFeatured': 'Featured item',
|
|
46
|
-
'menu.itemForm.save': 'Save',
|
|
47
|
-
'menu.itemForm.cancel': 'Cancel',
|
|
48
|
-
'menu.itemForm.saving': 'Saving...',
|
|
49
|
-
'menu.categories.title': 'Categories',
|
|
50
|
-
'menu.categories.newCategory': 'New Category',
|
|
51
|
-
'menu.categories.name': 'Category name',
|
|
52
|
-
'menu.settings.title': 'Menu Settings',
|
|
53
|
-
'menu.settings.general': 'General',
|
|
54
|
-
'menu.settings.taxRate': 'Default tax rate',
|
|
55
|
-
'menu.settings.currency': 'Currency',
|
|
56
|
-
'menu.form.categoryName': 'Category name',
|
|
57
|
-
'menu.form.itemName': 'Item name',
|
|
58
|
-
'menu.form.description': 'Description',
|
|
59
|
-
'menu.form.category': 'Category',
|
|
60
|
-
'menu.form.uncategorized': 'Uncategorized',
|
|
61
|
-
'menu.form.optional': 'optional',
|
|
62
|
-
'menu.form.save': 'Save',
|
|
63
|
-
'menu.form.cancel': 'Cancel',
|
|
64
|
-
}
|
package/src/locales/index.ts
DELETED
package/src/locales/pt-BR.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
export const ptBR: Record<string, string> = {
|
|
2
|
-
'menu.title': 'Cardápio',
|
|
3
|
-
'menu.nav.manager': 'Cardápio',
|
|
4
|
-
'menu.nav.categories': 'Categorias',
|
|
5
|
-
'menu.nav.items': 'Itens',
|
|
6
|
-
'menu.nav.modifiers': 'Modificadores',
|
|
7
|
-
'menu.manager.title': 'Gerenciar Cardápio',
|
|
8
|
-
'menu.manager.subtitle': 'Gerencie itens e categorias do cardápio',
|
|
9
|
-
'menu.manager.search': 'Buscar no cardápio...',
|
|
10
|
-
'menu.manager.allCategories': 'Todas as Categorias',
|
|
11
|
-
'menu.manager.newItem': 'Novo Item',
|
|
12
|
-
'menu.manager.noItems': 'Nenhum item no cardápio',
|
|
13
|
-
'menu.manager.noItemsDesc': 'Adicione o primeiro item para começar',
|
|
14
|
-
'menu.manager.addFirst': 'Adicionar primeiro item',
|
|
15
|
-
'menu.manager.available': 'Disponível',
|
|
16
|
-
'menu.manager.soldOut': 'Esgotado',
|
|
17
|
-
'menu.manager.hidden': 'Oculto',
|
|
18
|
-
'menu.manager.pos': 'PDV',
|
|
19
|
-
'menu.manager.delivery': 'Delivery',
|
|
20
|
-
'menu.manager.featured': 'Destaque',
|
|
21
|
-
'menu.manager.prepTime': 'Tempo de preparo',
|
|
22
|
-
'menu.manager.min': 'min',
|
|
23
|
-
'menu.manager.addCategory': 'Adicionar Categoria',
|
|
24
|
-
'menu.manager.addProduct': 'Adicionar Produto',
|
|
25
|
-
'menu.manager.item': 'Item',
|
|
26
|
-
'menu.manager.price': 'Preço',
|
|
27
|
-
'menu.manager.deliveryPrice': 'Delivery R$',
|
|
28
|
-
'menu.manager.itemsCount': '{{count}} itens',
|
|
29
|
-
'menu.manager.noResults': 'Nenhuma categoria ou item encontrado.',
|
|
30
|
-
'menu.manager.noResultsDesc': 'Tente um termo diferente ou filtro de categoria.',
|
|
31
|
-
'menu.itemForm.newTitle': 'Novo Item do Cardápio',
|
|
32
|
-
'menu.itemForm.editTitle': 'Editar Item do Cardápio',
|
|
33
|
-
'menu.itemForm.name': 'Nome do item',
|
|
34
|
-
'menu.itemForm.description': 'Descrição',
|
|
35
|
-
'menu.itemForm.price': 'Preço',
|
|
36
|
-
'menu.itemForm.cost': 'Custo',
|
|
37
|
-
'menu.itemForm.category': 'Categoria',
|
|
38
|
-
'menu.itemForm.prepTime': 'Tempo de preparo (min)',
|
|
39
|
-
'menu.itemForm.image': 'URL da imagem',
|
|
40
|
-
'menu.itemForm.allergens': 'Alérgenos',
|
|
41
|
-
'menu.itemForm.dietaryTags': 'Tags dietéticas',
|
|
42
|
-
'menu.itemForm.availableForPos': 'Disponível no PDV',
|
|
43
|
-
'menu.itemForm.availableForDelivery': 'Disponível para Delivery',
|
|
44
|
-
'menu.itemForm.deliveryPrice': 'Preço delivery',
|
|
45
|
-
'menu.itemForm.isFeatured': 'Item em destaque',
|
|
46
|
-
'menu.itemForm.save': 'Salvar',
|
|
47
|
-
'menu.itemForm.cancel': 'Cancelar',
|
|
48
|
-
'menu.itemForm.saving': 'Salvando...',
|
|
49
|
-
'menu.categories.title': 'Categorias',
|
|
50
|
-
'menu.categories.newCategory': 'Nova Categoria',
|
|
51
|
-
'menu.categories.name': 'Nome da categoria',
|
|
52
|
-
'menu.settings.title': 'Configurações do Cardápio',
|
|
53
|
-
'menu.settings.general': 'Geral',
|
|
54
|
-
'menu.settings.taxRate': 'Taxa padrão',
|
|
55
|
-
'menu.settings.currency': 'Moeda',
|
|
56
|
-
'menu.form.categoryName': 'Nome da categoria',
|
|
57
|
-
'menu.form.itemName': 'Nome do item',
|
|
58
|
-
'menu.form.description': 'Descrição',
|
|
59
|
-
'menu.form.category': 'Categoria',
|
|
60
|
-
'menu.form.uncategorized': 'Sem categoria',
|
|
61
|
-
'menu.form.optional': 'opcional',
|
|
62
|
-
'menu.form.save': 'Salvar',
|
|
63
|
-
'menu.form.cancel': 'Cancelar',
|
|
64
|
-
}
|
package/src/registries.ts
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import type { PluginRegistryDef } from '@fayz-ai/core'
|
|
2
|
-
import type { EntityDef } from '@fayz-ai/core'
|
|
3
|
-
|
|
4
|
-
const allergenEntity: EntityDef = {
|
|
5
|
-
name: 'Allergen',
|
|
6
|
-
namePlural: 'Allergens',
|
|
7
|
-
icon: 'AlertTriangle',
|
|
8
|
-
displayField: 'name',
|
|
9
|
-
defaultSort: 'name',
|
|
10
|
-
fields: [
|
|
11
|
-
{ key: 'name', label: 'Name', type: 'text', required: true, showInTable: true },
|
|
12
|
-
{ key: 'icon', label: 'Icon', type: 'text', showInTable: true },
|
|
13
|
-
{ key: 'isActive', label: 'Active', type: 'boolean', showInTable: true, defaultValue: true },
|
|
14
|
-
],
|
|
15
|
-
data: { table: 'menu_allergens', tenantScoped: true },
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const dietaryTagEntity: EntityDef = {
|
|
19
|
-
name: 'Dietary Tag',
|
|
20
|
-
namePlural: 'Dietary Tags',
|
|
21
|
-
icon: 'Leaf',
|
|
22
|
-
displayField: 'name',
|
|
23
|
-
defaultSort: 'name',
|
|
24
|
-
fields: [
|
|
25
|
-
{ key: 'name', label: 'Name', type: 'text', required: true, showInTable: true },
|
|
26
|
-
{ key: 'color', label: 'Color', type: 'text', showInTable: true },
|
|
27
|
-
{ key: 'isActive', label: 'Active', type: 'boolean', showInTable: true, defaultValue: true },
|
|
28
|
-
],
|
|
29
|
-
data: { table: 'menu_dietary_tags', tenantScoped: true },
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const modifierGroupEntity: EntityDef = {
|
|
33
|
-
name: 'Modifier Group',
|
|
34
|
-
namePlural: 'Modifier Groups',
|
|
35
|
-
icon: 'ListPlus',
|
|
36
|
-
displayField: 'name',
|
|
37
|
-
defaultSort: 'name',
|
|
38
|
-
fields: [
|
|
39
|
-
{ key: 'name', label: 'Name', type: 'text', required: true, showInTable: true },
|
|
40
|
-
{ key: 'minSelections', label: 'Min Selections', type: 'number', showInTable: true, defaultValue: 0 },
|
|
41
|
-
{ key: 'maxSelections', label: 'Max Selections', type: 'number', showInTable: true, defaultValue: 1 },
|
|
42
|
-
{ key: 'isRequired', label: 'Required', type: 'boolean', showInTable: true, defaultValue: false },
|
|
43
|
-
],
|
|
44
|
-
data: { table: 'menu_modifier_groups', tenantScoped: true },
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export const menuRegistries: PluginRegistryDef[] = [
|
|
48
|
-
{
|
|
49
|
-
id: 'allergens',
|
|
50
|
-
entity: allergenEntity,
|
|
51
|
-
icon: 'AlertTriangle',
|
|
52
|
-
description: 'Allergen types for menu items',
|
|
53
|
-
display: 'table',
|
|
54
|
-
readOnly: true,
|
|
55
|
-
seedData: [
|
|
56
|
-
{ id: 'a-gluten', name: 'Gluten', icon: '🌾', isActive: true },
|
|
57
|
-
{ id: 'a-dairy', name: 'Dairy', icon: '🥛', isActive: true },
|
|
58
|
-
{ id: 'a-nuts', name: 'Nuts', icon: '🥜', isActive: true },
|
|
59
|
-
{ id: 'a-shellfish', name: 'Shellfish', icon: '🦐', isActive: true },
|
|
60
|
-
{ id: 'a-eggs', name: 'Eggs', icon: '🥚', isActive: true },
|
|
61
|
-
{ id: 'a-soy', name: 'Soy', icon: '🫘', isActive: true },
|
|
62
|
-
],
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
id: 'dietary-tags',
|
|
66
|
-
entity: dietaryTagEntity,
|
|
67
|
-
icon: 'Leaf',
|
|
68
|
-
description: 'Dietary tags (vegan, vegetarian, etc.)',
|
|
69
|
-
display: 'table',
|
|
70
|
-
readOnly: true,
|
|
71
|
-
seedData: [
|
|
72
|
-
{ id: 'dt-vegan', name: 'Vegan', color: 'green', isActive: true },
|
|
73
|
-
{ id: 'dt-vegetarian', name: 'Vegetarian', color: 'lime', isActive: true },
|
|
74
|
-
{ id: 'dt-gf', name: 'Gluten Free', color: 'amber', isActive: true },
|
|
75
|
-
],
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
id: 'modifier-groups',
|
|
79
|
-
entity: modifierGroupEntity,
|
|
80
|
-
icon: 'ListPlus',
|
|
81
|
-
description: 'Modifier groups for item customization',
|
|
82
|
-
display: 'table',
|
|
83
|
-
},
|
|
84
|
-
]
|
package/src/store.ts
DELETED
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import { createStore, type StoreApi } from 'zustand/vanilla'
|
|
2
|
-
import { dedup } from '@fayz-ai/saas'
|
|
3
|
-
import { toast } from 'sonner'
|
|
4
|
-
import type { MenuDataProvider } from './data/types'
|
|
5
|
-
import type {
|
|
6
|
-
MenuCategory, MenuItem, ModifierGroup, MenuSummary,
|
|
7
|
-
MenuItemQuery,
|
|
8
|
-
CreateMenuItemInput, UpdateMenuItemInput, CreateMenuCategoryInput,
|
|
9
|
-
} from './types'
|
|
10
|
-
|
|
11
|
-
// ---------------------------------------------------------------------------
|
|
12
|
-
// Store state
|
|
13
|
-
// ---------------------------------------------------------------------------
|
|
14
|
-
|
|
15
|
-
export interface MenuUIState {
|
|
16
|
-
// Data cache
|
|
17
|
-
categories: MenuCategory[]
|
|
18
|
-
categoriesLoading: boolean
|
|
19
|
-
|
|
20
|
-
menuItems: MenuItem[]
|
|
21
|
-
menuItemsTotal: number
|
|
22
|
-
menuItemsLoading: boolean
|
|
23
|
-
menuItemQuery: MenuItemQuery
|
|
24
|
-
|
|
25
|
-
modifierGroups: ModifierGroup[]
|
|
26
|
-
modifiersLoading: boolean
|
|
27
|
-
|
|
28
|
-
summary: MenuSummary | null
|
|
29
|
-
summaryLoading: boolean
|
|
30
|
-
|
|
31
|
-
// Actions
|
|
32
|
-
fetchCategories(): Promise<void>
|
|
33
|
-
fetchMenuItems(query: MenuItemQuery): Promise<void>
|
|
34
|
-
fetchModifierGroups(): Promise<void>
|
|
35
|
-
fetchSummary(): Promise<void>
|
|
36
|
-
createMenuItem(input: CreateMenuItemInput): Promise<MenuItem>
|
|
37
|
-
updateMenuItem(id: string, data: UpdateMenuItemInput): Promise<MenuItem>
|
|
38
|
-
deleteMenuItem(id: string): Promise<void>
|
|
39
|
-
toggleAvailability(id: string, field: string, value: any): Promise<void>
|
|
40
|
-
createCategory(input: CreateMenuCategoryInput): Promise<MenuCategory>
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// ---------------------------------------------------------------------------
|
|
44
|
-
// Store factory
|
|
45
|
-
// ---------------------------------------------------------------------------
|
|
46
|
-
|
|
47
|
-
export function createMenuStore(provider: MenuDataProvider): StoreApi<MenuUIState> {
|
|
48
|
-
return createStore<MenuUIState>((set, get) => ({
|
|
49
|
-
categories: [],
|
|
50
|
-
categoriesLoading: false,
|
|
51
|
-
|
|
52
|
-
menuItems: [],
|
|
53
|
-
menuItemsTotal: 0,
|
|
54
|
-
menuItemsLoading: false,
|
|
55
|
-
menuItemQuery: {},
|
|
56
|
-
|
|
57
|
-
modifierGroups: [],
|
|
58
|
-
modifiersLoading: false,
|
|
59
|
-
|
|
60
|
-
summary: null,
|
|
61
|
-
summaryLoading: false,
|
|
62
|
-
|
|
63
|
-
async fetchCategories() {
|
|
64
|
-
return dedup('menu:categories', async () => {
|
|
65
|
-
set({ categoriesLoading: true })
|
|
66
|
-
const categories = await provider.getCategories()
|
|
67
|
-
set({ categories, categoriesLoading: false })
|
|
68
|
-
})
|
|
69
|
-
},
|
|
70
|
-
|
|
71
|
-
async fetchMenuItems(query) {
|
|
72
|
-
return dedup('menu:items:' + JSON.stringify(query), async () => {
|
|
73
|
-
set({ menuItemsLoading: true, menuItemQuery: query })
|
|
74
|
-
const result = await provider.getMenuItems(query)
|
|
75
|
-
set({ menuItems: result.data, menuItemsTotal: result.total, menuItemsLoading: false })
|
|
76
|
-
})
|
|
77
|
-
},
|
|
78
|
-
|
|
79
|
-
async fetchModifierGroups() {
|
|
80
|
-
return dedup('menu:modifiers', async () => {
|
|
81
|
-
set({ modifiersLoading: true })
|
|
82
|
-
const modifierGroups = await provider.getModifierGroups()
|
|
83
|
-
set({ modifierGroups, modifiersLoading: false })
|
|
84
|
-
})
|
|
85
|
-
},
|
|
86
|
-
|
|
87
|
-
async fetchSummary() {
|
|
88
|
-
return dedup('menu:summary', async () => {
|
|
89
|
-
set({ summaryLoading: true })
|
|
90
|
-
const summary = await provider.getSummary()
|
|
91
|
-
set({ summary, summaryLoading: false })
|
|
92
|
-
})
|
|
93
|
-
},
|
|
94
|
-
|
|
95
|
-
async createMenuItem(input) {
|
|
96
|
-
try {
|
|
97
|
-
const item = await provider.createMenuItem(input)
|
|
98
|
-
const query = get().menuItemQuery
|
|
99
|
-
const [result, summary] = await Promise.all([provider.getMenuItems(query), provider.getSummary()])
|
|
100
|
-
set({ menuItems: result.data, menuItemsTotal: result.total, summary })
|
|
101
|
-
toast.success('Menu item created')
|
|
102
|
-
return item
|
|
103
|
-
} catch (err: any) {
|
|
104
|
-
toast.error('Failed to create menu item', { description: err?.message })
|
|
105
|
-
throw err
|
|
106
|
-
}
|
|
107
|
-
},
|
|
108
|
-
|
|
109
|
-
async updateMenuItem(id, data) {
|
|
110
|
-
try {
|
|
111
|
-
const item = await provider.updateMenuItem(id, data)
|
|
112
|
-
const query = get().menuItemQuery
|
|
113
|
-
const result = await provider.getMenuItems(query)
|
|
114
|
-
set({ menuItems: result.data, menuItemsTotal: result.total })
|
|
115
|
-
toast.success('Menu item updated')
|
|
116
|
-
return item
|
|
117
|
-
} catch (err: any) {
|
|
118
|
-
toast.error('Failed to update menu item', { description: err?.message })
|
|
119
|
-
throw err
|
|
120
|
-
}
|
|
121
|
-
},
|
|
122
|
-
|
|
123
|
-
async deleteMenuItem(id) {
|
|
124
|
-
try {
|
|
125
|
-
await provider.deleteMenuItem(id)
|
|
126
|
-
const query = get().menuItemQuery
|
|
127
|
-
const [result, summary] = await Promise.all([provider.getMenuItems(query), provider.getSummary()])
|
|
128
|
-
set({ menuItems: result.data, menuItemsTotal: result.total, summary })
|
|
129
|
-
toast.success('Menu item deleted')
|
|
130
|
-
} catch (err: any) {
|
|
131
|
-
toast.error('Failed to delete menu item', { description: err?.message })
|
|
132
|
-
throw err
|
|
133
|
-
}
|
|
134
|
-
},
|
|
135
|
-
|
|
136
|
-
async toggleAvailability(id, field, value) {
|
|
137
|
-
try {
|
|
138
|
-
await provider.toggleAvailability(id, field as any, value)
|
|
139
|
-
const query = get().menuItemQuery
|
|
140
|
-
const result = await provider.getMenuItems(query)
|
|
141
|
-
set({ menuItems: result.data, menuItemsTotal: result.total })
|
|
142
|
-
} catch (err: any) {
|
|
143
|
-
toast.error('Failed to update availability', { description: err?.message })
|
|
144
|
-
throw err
|
|
145
|
-
}
|
|
146
|
-
},
|
|
147
|
-
|
|
148
|
-
async createCategory(input) {
|
|
149
|
-
try {
|
|
150
|
-
const category = await provider.createCategory(input)
|
|
151
|
-
const categories = await provider.getCategories()
|
|
152
|
-
set({ categories })
|
|
153
|
-
toast.success('Category created')
|
|
154
|
-
return category
|
|
155
|
-
} catch (err: any) {
|
|
156
|
-
toast.error('Failed to create category', { description: err?.message })
|
|
157
|
-
throw err
|
|
158
|
-
}
|
|
159
|
-
},
|
|
160
|
-
}))
|
|
161
|
-
}
|
package/src/types.ts
DELETED
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
// ---------------------------------------------------------------------------
|
|
2
|
-
// Menu Plugin — Pure TypeScript types
|
|
3
|
-
// ---------------------------------------------------------------------------
|
|
4
|
-
|
|
5
|
-
// ============================================================
|
|
6
|
-
// ENUMS / LITERALS
|
|
7
|
-
// ============================================================
|
|
8
|
-
|
|
9
|
-
export type MenuItemStatus = 'available' | 'sold_out' | 'hidden'
|
|
10
|
-
|
|
11
|
-
// ============================================================
|
|
12
|
-
// CORE ENTITIES
|
|
13
|
-
// ============================================================
|
|
14
|
-
|
|
15
|
-
/** Menu category — maps to public.categories (kind='menu_category') */
|
|
16
|
-
export interface MenuCategory {
|
|
17
|
-
id: string
|
|
18
|
-
name: string
|
|
19
|
-
parentId?: string
|
|
20
|
-
icon?: string
|
|
21
|
-
color?: string
|
|
22
|
-
sortOrder: number
|
|
23
|
-
isActive: boolean
|
|
24
|
-
itemCount?: number
|
|
25
|
-
tenantId: string
|
|
26
|
-
createdAt: string
|
|
27
|
-
updatedAt: string
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/** Menu item — public.products + public.menu_items extension */
|
|
31
|
-
export interface MenuItem {
|
|
32
|
-
id: string
|
|
33
|
-
name: string
|
|
34
|
-
description?: string
|
|
35
|
-
price: number
|
|
36
|
-
cost?: number
|
|
37
|
-
currency: string
|
|
38
|
-
sku?: string
|
|
39
|
-
imageUrl?: string
|
|
40
|
-
categoryId?: string
|
|
41
|
-
categoryName?: string
|
|
42
|
-
status: MenuItemStatus
|
|
43
|
-
isActive: boolean
|
|
44
|
-
// Extension fields
|
|
45
|
-
prepTimeMinutes?: number
|
|
46
|
-
allergens?: string[]
|
|
47
|
-
dietaryTags?: string[]
|
|
48
|
-
availableForPos: boolean
|
|
49
|
-
availableForDelivery: boolean
|
|
50
|
-
deliveryPrice?: number
|
|
51
|
-
sortOrder: number
|
|
52
|
-
isFeatured: boolean
|
|
53
|
-
modifierGroupIds?: string[]
|
|
54
|
-
metadata?: Record<string, unknown>
|
|
55
|
-
tenantId: string
|
|
56
|
-
createdAt: string
|
|
57
|
-
updatedAt: string
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export interface ModifierGroup {
|
|
61
|
-
id: string
|
|
62
|
-
name: string
|
|
63
|
-
minSelections: number
|
|
64
|
-
maxSelections: number
|
|
65
|
-
isRequired: boolean
|
|
66
|
-
sortOrder: number
|
|
67
|
-
items: ModifierItem[]
|
|
68
|
-
tenantId: string
|
|
69
|
-
createdAt: string
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export interface ModifierItem {
|
|
73
|
-
id: string
|
|
74
|
-
groupId: string
|
|
75
|
-
name: string
|
|
76
|
-
priceAdjustment: number
|
|
77
|
-
isActive: boolean
|
|
78
|
-
sortOrder: number
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// ============================================================
|
|
82
|
-
// INPUT TYPES
|
|
83
|
-
// ============================================================
|
|
84
|
-
|
|
85
|
-
export interface CreateMenuItemInput {
|
|
86
|
-
name: string
|
|
87
|
-
description?: string
|
|
88
|
-
price: number
|
|
89
|
-
cost?: number
|
|
90
|
-
imageUrl?: string
|
|
91
|
-
categoryId?: string
|
|
92
|
-
status?: MenuItemStatus
|
|
93
|
-
prepTimeMinutes?: number
|
|
94
|
-
allergens?: string[]
|
|
95
|
-
dietaryTags?: string[]
|
|
96
|
-
availableForPos?: boolean
|
|
97
|
-
availableForDelivery?: boolean
|
|
98
|
-
deliveryPrice?: number
|
|
99
|
-
isFeatured?: boolean
|
|
100
|
-
modifierGroupIds?: string[]
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export interface UpdateMenuItemInput extends Partial<CreateMenuItemInput> {}
|
|
104
|
-
|
|
105
|
-
export interface CreateMenuCategoryInput {
|
|
106
|
-
name: string
|
|
107
|
-
parentId?: string
|
|
108
|
-
icon?: string
|
|
109
|
-
color?: string
|
|
110
|
-
sortOrder?: number
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// ============================================================
|
|
114
|
-
// QUERY TYPES
|
|
115
|
-
// ============================================================
|
|
116
|
-
|
|
117
|
-
export interface MenuItemQuery {
|
|
118
|
-
categoryId?: string
|
|
119
|
-
status?: MenuItemStatus | MenuItemStatus[]
|
|
120
|
-
search?: string
|
|
121
|
-
availableForPos?: boolean
|
|
122
|
-
availableForDelivery?: boolean
|
|
123
|
-
isFeatured?: boolean
|
|
124
|
-
page?: number
|
|
125
|
-
pageSize?: number
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export interface PaginatedResult<T> {
|
|
129
|
-
data: T[]
|
|
130
|
-
total: number
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
// ============================================================
|
|
134
|
-
// AGGREGATION
|
|
135
|
-
// ============================================================
|
|
136
|
-
|
|
137
|
-
export interface MenuSummary {
|
|
138
|
-
totalItems: number
|
|
139
|
-
availableItems: number
|
|
140
|
-
soldOutItems: number
|
|
141
|
-
hiddenItems: number
|
|
142
|
-
categoryCount: number
|
|
143
|
-
averagePrice: number
|
|
144
|
-
featuredCount: number
|
|
145
|
-
}
|