@fayz-ai/plugin-shop 0.2.5 → 0.8.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/dist/ShopPage-HCLXMN7Q.js +743 -0
- package/dist/ShopPage-HCLXMN7Q.js.map +1 -0
- package/dist/ShopPage-JF2SQBKO.cjs +745 -0
- package/dist/ShopPage-JF2SQBKO.cjs.map +1 -0
- package/dist/ShopPage.d.ts +23 -1
- package/dist/ShopPage.d.ts.map +1 -1
- package/dist/data/customerDataProvider.d.ts +5 -0
- package/dist/data/customerDataProvider.d.ts.map +1 -0
- package/dist/data/discountDataProvider.d.ts +5 -0
- package/dist/data/discountDataProvider.d.ts.map +1 -0
- package/dist/data/productDataProvider.d.ts +6 -0
- package/dist/data/productDataProvider.d.ts.map +1 -0
- package/dist/data/shared.d.ts +12 -0
- package/dist/data/shared.d.ts.map +1 -0
- package/dist/data/shippingZoneDataProvider.d.ts +13 -0
- package/dist/data/shippingZoneDataProvider.d.ts.map +1 -0
- package/dist/index.cjs +986 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +987 -27
- package/dist/index.js.map +1 -1
- package/dist/views/OrderDetailView.d.ts +10 -0
- package/dist/views/OrderDetailView.d.ts.map +1 -0
- package/dist/views/ProductImagesTab.d.ts +19 -0
- package/dist/views/ProductImagesTab.d.ts.map +1 -0
- package/dist/views/customerEntity.d.ts +4 -0
- package/dist/views/customerEntity.d.ts.map +1 -0
- package/dist/views/customerLookup.d.ts +22 -0
- package/dist/views/customerLookup.d.ts.map +1 -0
- package/dist/views/discountEntity.d.ts +4 -0
- package/dist/views/discountEntity.d.ts.map +1 -0
- package/dist/views/productEntity.d.ts +6 -0
- package/dist/views/productEntity.d.ts.map +1 -0
- package/dist/views/shippingZoneEntity.d.ts +4 -0
- package/dist/views/shippingZoneEntity.d.ts.map +1 -0
- package/package.json +8 -5
- package/src/ShopPage.tsx +156 -54
- package/src/data/customerDataProvider.ts +31 -0
- package/src/data/discountDataProvider.ts +42 -0
- package/src/data/productDataProvider.ts +54 -0
- package/src/data/shared.ts +42 -0
- package/src/data/shippingZoneDataProvider.ts +49 -0
- package/src/index.ts +104 -12
- package/src/views/OrderDetailView.tsx +575 -0
- package/src/views/ProductImagesTab.tsx +183 -0
- package/src/views/customerEntity.tsx +110 -0
- package/src/views/customerLookup.ts +31 -0
- package/src/views/discountEntity.tsx +137 -0
- package/src/views/productEntity.tsx +229 -0
- package/src/views/shippingZoneEntity.tsx +123 -0
- package/dist/ShopPage-65PPVKBD.js +0 -271
- package/dist/ShopPage-65PPVKBD.js.map +0 -1
- package/dist/ShopPage-PG5GKOZU.cjs +0 -273
- package/dist/ShopPage-PG5GKOZU.cjs.map +0 -1
package/src/index.ts
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import type { PluginManifest, PluginScope, VerticalId } from '@fayz-ai/core'
|
|
3
|
-
import { setShopTenantResolver } from '@fayz-ai/shop'
|
|
4
|
-
import { useOrganizationStore } from '@fayz-ai/saas'
|
|
3
|
+
import { setShopTenantResolver, getShopProvider } from '@fayz-ai/shop'
|
|
4
|
+
import { useOrganizationStore, createCrudPage, registerEntityPath } from '@fayz-ai/saas'
|
|
5
|
+
import { buildShopProductEntity } from './views/productEntity'
|
|
6
|
+
import { buildShopCustomerEntity } from './views/customerEntity'
|
|
7
|
+
import { buildShopDiscountEntity } from './views/discountEntity'
|
|
8
|
+
import { buildShopShippingZoneEntity } from './views/shippingZoneEntity'
|
|
9
|
+
import { createShopProductDataProvider } from './data/productDataProvider'
|
|
10
|
+
import { createShopCustomerDataProvider } from './data/customerDataProvider'
|
|
11
|
+
import { createShopDiscountDataProvider } from './data/discountDataProvider'
|
|
12
|
+
import { createShopShippingZoneDataProvider } from './data/shippingZoneDataProvider'
|
|
5
13
|
import type { ShopProviderResolver } from './ShopPage'
|
|
6
14
|
import { ShopSettings } from './components/ShopSettings'
|
|
7
15
|
|
|
@@ -15,6 +23,8 @@ export interface ShopPluginOptions {
|
|
|
15
23
|
navPosition?: number
|
|
16
24
|
navSection?: 'main' | 'secondary' | 'settings'
|
|
17
25
|
navLabel?: string
|
|
26
|
+
/** Override the accordion child labels (Produtos / Pedidos / Clientes / Descontos). */
|
|
27
|
+
sectionLabels?: Partial<Record<'products' | 'orders' | 'customers' | 'discounts' | 'shipping', string>>
|
|
18
28
|
scope?: PluginScope
|
|
19
29
|
verticalId?: VerticalId
|
|
20
30
|
currency?: { code?: string; locale?: string; symbol?: string }
|
|
@@ -32,13 +42,76 @@ export function createShopPlugin(options?: ShopPluginOptions): PluginManifest {
|
|
|
32
42
|
// provider when they want SDK-owned data access instead of the global runtime.
|
|
33
43
|
setShopTenantResolver(() => useOrganizationStore.getState().currentOrg?.id)
|
|
34
44
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
45
|
+
// Teach the shared person-path registry where a SHOP customer lives. The
|
|
46
|
+
// built-in map ships veterinary defaults (customer → /registry/tutors), so
|
|
47
|
+
// without this PersonLink would resolve a shop customer to the wrong module.
|
|
48
|
+
registerEntityPath('shop_customer', '/shop/customers')
|
|
49
|
+
|
|
50
|
+
type ShopSection = 'products' | 'orders' | 'customers' | 'discounts' | 'shipping'
|
|
51
|
+
|
|
52
|
+
// One component per section so each gets its own route. The shell nests any
|
|
53
|
+
// entry whose route is a sub-path of another (same rule the courses modules
|
|
54
|
+
// use), so /shop/products … /shop/discounts render as an accordion under
|
|
55
|
+
// "Loja" instead of one link with everything hidden behind tabs.
|
|
56
|
+
const pageFor = (section?: ShopSection): React.ComponentType<unknown> => {
|
|
57
|
+
const Wrapped: React.ComponentType<unknown> = () =>
|
|
58
|
+
React.createElement(React.Suspense, { fallback: null },
|
|
59
|
+
React.createElement(
|
|
60
|
+
ShopPage as React.ComponentType<{ provider?: ShopProviderResolver; section?: ShopSection }>,
|
|
61
|
+
{ provider: options?.provider, section },
|
|
62
|
+
)
|
|
63
|
+
)
|
|
64
|
+
Wrapped.displayName = section ? `ShopPage:${section}` : 'ShopPageWrapper'
|
|
65
|
+
return Wrapped
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Products, customers and discounts all get the full generic CRUD (list +
|
|
69
|
+
// form + detail + delete) from their EntityDef, rather than three bespoke
|
|
70
|
+
// read-only tables. Orders stay on the custom page: an order is not a CRUD
|
|
71
|
+
// record — it needs fulfilment, refunds and a line-item view, which is its
|
|
72
|
+
// own screen.
|
|
73
|
+
const resolveProvider = () =>
|
|
74
|
+
typeof options?.provider === 'function'
|
|
75
|
+
? options.provider()
|
|
76
|
+
: options?.provider ?? getShopProvider()
|
|
77
|
+
|
|
78
|
+
const ProductsCrudPage = createCrudPage(buildShopProductEntity(curr.code, resolveProvider), {
|
|
79
|
+
dataProvider: createShopProductDataProvider(resolveProvider),
|
|
80
|
+
feature: 'shop',
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
const CustomersCrudPage = createCrudPage(buildShopCustomerEntity(), {
|
|
84
|
+
dataProvider: createShopCustomerDataProvider(resolveProvider),
|
|
85
|
+
feature: 'shop',
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
const DiscountsCrudPage = createCrudPage(buildShopDiscountEntity(), {
|
|
89
|
+
dataProvider: createShopDiscountDataProvider(resolveProvider),
|
|
90
|
+
feature: 'shop',
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
const ShippingZonesCrudPage = createCrudPage(buildShopShippingZoneEntity(curr.code), {
|
|
94
|
+
dataProvider: createShopShippingZoneDataProvider(resolveProvider),
|
|
95
|
+
feature: 'shop',
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
const CRUD_PAGES: Partial<Record<ShopSection, React.ComponentType<unknown>>> = {
|
|
99
|
+
products: ProductsCrudPage as React.ComponentType<unknown>,
|
|
100
|
+
customers: CustomersCrudPage as React.ComponentType<unknown>,
|
|
101
|
+
discounts: DiscountsCrudPage as React.ComponentType<unknown>,
|
|
102
|
+
shipping: ShippingZonesCrudPage as React.ComponentType<unknown>,
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const SECTIONS: Array<{ id: ShopSection; label: string; icon: string }> = [
|
|
106
|
+
{ id: 'products', label: options?.sectionLabels?.products ?? 'Produtos', icon: 'Package' },
|
|
107
|
+
{ id: 'orders', label: options?.sectionLabels?.orders ?? 'Pedidos', icon: 'ShoppingCart' },
|
|
108
|
+
{ id: 'customers', label: options?.sectionLabels?.customers ?? 'Clientes', icon: 'Users' },
|
|
109
|
+
{ id: 'discounts', label: options?.sectionLabels?.discounts ?? 'Descontos', icon: 'Tag' },
|
|
110
|
+
{ id: 'shipping', label: options?.sectionLabels?.shipping ?? 'Entrega', icon: 'Truck' },
|
|
111
|
+
]
|
|
112
|
+
|
|
113
|
+
const navSection = options?.navSection ?? 'main'
|
|
114
|
+
const navPosition = options?.navPosition ?? 6
|
|
42
115
|
|
|
43
116
|
return {
|
|
44
117
|
id: 'shop',
|
|
@@ -47,24 +120,43 @@ export function createShopPlugin(options?: ShopPluginOptions): PluginManifest {
|
|
|
47
120
|
version: '1.0.0',
|
|
48
121
|
scope: options?.scope ?? 'vertical',
|
|
49
122
|
verticalId: options?.verticalId,
|
|
123
|
+
// Storefront/commerce-operator-console surface — targets the ecommerce
|
|
124
|
+
// Panel world, not a saas admin app.
|
|
125
|
+
scaffolds: ['ecommerce'],
|
|
50
126
|
defaultEnabled: true,
|
|
51
127
|
dependencies: [],
|
|
52
128
|
navigation: [
|
|
53
129
|
{
|
|
54
|
-
section:
|
|
55
|
-
position:
|
|
130
|
+
section: navSection,
|
|
131
|
+
position: navPosition,
|
|
56
132
|
label: options?.navLabel ?? 'Shop',
|
|
57
133
|
route: '/shop',
|
|
58
134
|
icon: 'ShoppingBag',
|
|
59
135
|
permission: { feature: 'shop', action: 'read' as const },
|
|
136
|
+
// "Loja" and "Produtos" are the same screen — don't list both.
|
|
137
|
+
indexChild: false,
|
|
60
138
|
},
|
|
139
|
+
...SECTIONS.map((s, i) => ({
|
|
140
|
+
section: navSection,
|
|
141
|
+
position: navPosition + i + 1,
|
|
142
|
+
label: s.label,
|
|
143
|
+
route: `/shop/${s.id}`,
|
|
144
|
+
icon: s.icon,
|
|
145
|
+
permission: { feature: 'shop', action: 'read' as const },
|
|
146
|
+
})),
|
|
61
147
|
],
|
|
62
148
|
routes: [
|
|
63
149
|
{
|
|
150
|
+
// Kept so existing links to /shop still resolve; renders the tabbed page.
|
|
64
151
|
path: '/shop',
|
|
65
|
-
component:
|
|
152
|
+
component: pageFor(),
|
|
66
153
|
permission: { feature: 'shop', action: 'read' as const },
|
|
67
154
|
},
|
|
155
|
+
...SECTIONS.map((s) => ({
|
|
156
|
+
path: `/shop/${s.id}`,
|
|
157
|
+
component: CRUD_PAGES[s.id] ?? pageFor(s.id),
|
|
158
|
+
permission: { feature: 'shop', action: 'read' as const },
|
|
159
|
+
})),
|
|
68
160
|
],
|
|
69
161
|
widgets: [],
|
|
70
162
|
aiTools: [
|