@fayz-ai/plugin-shop 0.2.0

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.
@@ -0,0 +1,273 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+ var ui = require('@fayz-ai/ui');
5
+ var shop = require('@fayz-ai/shop');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+
8
+ // src/ShopPage.tsx
9
+ function currency(value, code = "BRL", locale = "pt-BR") {
10
+ return new Intl.NumberFormat(locale, { style: "currency", currency: code }).format(value);
11
+ }
12
+ function badge(label, color) {
13
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className: `inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium ${color}`, children: label });
14
+ }
15
+ var statusColors = {
16
+ active: "bg-emerald-100 text-emerald-800",
17
+ draft: "bg-gray-100 text-gray-700",
18
+ archived: "bg-orange-100 text-orange-700",
19
+ open: "bg-blue-100 text-blue-800",
20
+ cancelled: "bg-red-100 text-red-700",
21
+ paid: "bg-emerald-100 text-emerald-800",
22
+ pending: "bg-yellow-100 text-yellow-800",
23
+ fulfilled: "bg-emerald-100 text-emerald-800",
24
+ unfulfilled: "bg-gray-100 text-gray-700",
25
+ "partially_fulfilled": "bg-blue-100 text-blue-800"
26
+ };
27
+ function resolveShopProvider(provider) {
28
+ return typeof provider === "function" ? provider() : provider ?? shop.getShopProvider();
29
+ }
30
+ function ProductsTab({ provider }) {
31
+ const [products, setProducts] = react.useState([]);
32
+ const [loading, setLoading] = react.useState(true);
33
+ const [search, setSearch] = react.useState("");
34
+ const load = react.useCallback(async (opts) => {
35
+ setLoading(true);
36
+ try {
37
+ const data = await resolveShopProvider(provider).listProducts(opts);
38
+ setProducts(data);
39
+ } finally {
40
+ setLoading(false);
41
+ }
42
+ }, [provider]);
43
+ react.useEffect(() => {
44
+ load();
45
+ }, [load]);
46
+ const handleSearch = (e) => {
47
+ const q = e.target.value;
48
+ setSearch(q);
49
+ load(q ? { search: q } : void 0);
50
+ };
51
+ const columns = react.useMemo(() => [
52
+ { accessorKey: "name", header: "Produto", cell: ({ getValue }) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: getValue() }) },
53
+ { accessorKey: "sku", header: "SKU", cell: ({ getValue }) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: getValue() ?? "\u2014" }) },
54
+ {
55
+ accessorKey: "price",
56
+ header: () => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-right", children: "Pre\xE7o" }),
57
+ cell: ({ getValue, row }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: currency(getValue(), row.original.currency) })
58
+ },
59
+ {
60
+ accessorKey: "inventoryCount",
61
+ header: () => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-right", children: "Estoque" }),
62
+ cell: ({ getValue }) => {
63
+ const count = getValue();
64
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: count === 0 ? "text-red-600 font-medium" : "", children: count }) });
65
+ }
66
+ },
67
+ {
68
+ accessorKey: "status",
69
+ header: "Status",
70
+ cell: ({ getValue }) => {
71
+ const status = getValue();
72
+ return badge(status, statusColors[status] ?? "bg-gray-100 text-gray-700");
73
+ }
74
+ }
75
+ ], []);
76
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
77
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-4", children: [
78
+ /* @__PURE__ */ jsxRuntime.jsx(
79
+ "input",
80
+ {
81
+ type: "search",
82
+ value: search,
83
+ onChange: handleSearch,
84
+ placeholder: "Buscar produtos...",
85
+ className: "border rounded-lg px-3 py-2 text-sm w-64 focus:outline-none focus:ring-2 focus:ring-primary/50"
86
+ }
87
+ ),
88
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm text-muted-foreground", children: [
89
+ products.length,
90
+ " produtos"
91
+ ] })
92
+ ] }),
93
+ loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-12 text-center text-sm text-muted-foreground", children: "Carregando..." }) : /* @__PURE__ */ jsxRuntime.jsx(
94
+ ui.DataTable,
95
+ {
96
+ columns,
97
+ data: products,
98
+ variant: "card",
99
+ emptyMessage: "Nenhum produto encontrado."
100
+ }
101
+ )
102
+ ] });
103
+ }
104
+ function OrdersTab({ provider }) {
105
+ const [orders, setOrders] = react.useState([]);
106
+ const [loading, setLoading] = react.useState(true);
107
+ react.useEffect(() => {
108
+ resolveShopProvider(provider).listOrders({ limit: 50 }).then(setOrders).finally(() => setLoading(false));
109
+ }, [provider]);
110
+ const columns = react.useMemo(() => [
111
+ { accessorKey: "orderNumber", header: "Pedido", cell: ({ getValue }) => /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
112
+ "#",
113
+ getValue()
114
+ ] }) },
115
+ {
116
+ id: "customer",
117
+ accessorFn: (o) => o.customerName ?? o.customerEmail ?? "\u2014",
118
+ header: "Cliente",
119
+ cell: ({ getValue }) => /* @__PURE__ */ jsxRuntime.jsx("span", { children: getValue() })
120
+ },
121
+ {
122
+ accessorKey: "total",
123
+ header: () => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-right", children: "Total" }),
124
+ cell: ({ getValue, row }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right font-medium", children: currency(getValue(), row.original.currency) })
125
+ },
126
+ {
127
+ accessorKey: "financialStatus",
128
+ header: "Pagamento",
129
+ cell: ({ getValue }) => {
130
+ const status = getValue();
131
+ return badge(status, statusColors[status] ?? "bg-gray-100 text-gray-700");
132
+ }
133
+ },
134
+ {
135
+ accessorKey: "fulfillmentStatus",
136
+ header: "Entrega",
137
+ cell: ({ getValue }) => {
138
+ const status = getValue();
139
+ return badge(status, statusColors[status] ?? "bg-gray-100 text-gray-700");
140
+ }
141
+ },
142
+ {
143
+ accessorKey: "createdAt",
144
+ header: "Data",
145
+ cell: ({ getValue }) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: new Date(getValue()).toLocaleDateString("pt-BR") })
146
+ }
147
+ ], []);
148
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { children: loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-12 text-center text-sm text-muted-foreground", children: "Carregando..." }) : /* @__PURE__ */ jsxRuntime.jsx(
149
+ ui.DataTable,
150
+ {
151
+ columns,
152
+ data: orders,
153
+ variant: "card",
154
+ emptyMessage: "Nenhum pedido ainda."
155
+ }
156
+ ) });
157
+ }
158
+ function CustomersTab({ provider }) {
159
+ const [customers, setCustomers] = react.useState([]);
160
+ const [loading, setLoading] = react.useState(true);
161
+ react.useEffect(() => {
162
+ resolveShopProvider(provider).listCustomers({ limit: 50 }).then(setCustomers).finally(() => setLoading(false));
163
+ }, [provider]);
164
+ const columns = react.useMemo(() => [
165
+ {
166
+ id: "name",
167
+ accessorFn: (c) => `${c.firstName} ${c.lastName}`,
168
+ header: "Nome",
169
+ cell: ({ row }) => /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-medium", children: [
170
+ row.original.firstName,
171
+ " ",
172
+ row.original.lastName
173
+ ] })
174
+ },
175
+ { accessorKey: "email", header: "Email", cell: ({ getValue }) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: getValue() ?? "\u2014" }) },
176
+ { accessorKey: "phone", header: "Telefone", cell: ({ getValue }) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: getValue() ?? "\u2014" }) },
177
+ {
178
+ accessorKey: "ordersCount",
179
+ header: () => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-right", children: "Pedidos" }),
180
+ cell: ({ getValue }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: getValue() })
181
+ },
182
+ {
183
+ accessorKey: "totalSpent",
184
+ header: () => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-right", children: "Total Gasto" }),
185
+ cell: ({ getValue }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: currency(getValue()) })
186
+ }
187
+ ], []);
188
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { children: loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-12 text-center text-sm text-muted-foreground", children: "Carregando..." }) : /* @__PURE__ */ jsxRuntime.jsx(
189
+ ui.DataTable,
190
+ {
191
+ columns,
192
+ data: customers,
193
+ variant: "card",
194
+ emptyMessage: "Nenhum cliente ainda."
195
+ }
196
+ ) });
197
+ }
198
+ function DiscountsTab({ provider }) {
199
+ const [discounts, setDiscounts] = react.useState([]);
200
+ const [loading, setLoading] = react.useState(true);
201
+ react.useEffect(() => {
202
+ resolveShopProvider(provider).listDiscounts({ limit: 50 }).then(setDiscounts).finally(() => setLoading(false));
203
+ }, [provider]);
204
+ const columns = react.useMemo(() => [
205
+ { accessorKey: "title", header: "T\xEDtulo", cell: ({ getValue }) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium", children: getValue() }) },
206
+ { accessorKey: "code", header: "C\xF3digo", cell: ({ getValue }) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono text-sm", children: getValue() ?? "\u2014" }) },
207
+ { accessorKey: "type", header: "Tipo", cell: ({ getValue }) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-muted-foreground", children: getValue() }) },
208
+ {
209
+ accessorKey: "value",
210
+ header: () => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-right", children: "Valor" }),
211
+ cell: ({ row }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-right", children: row.original.type === "percentage" ? `${row.original.value}%` : currency(row.original.value) })
212
+ },
213
+ {
214
+ id: "usos",
215
+ accessorKey: "timesUsed",
216
+ header: () => /* @__PURE__ */ jsxRuntime.jsx("span", { className: "block text-right", children: "Usos" }),
217
+ cell: ({ row }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-right", children: [
218
+ row.original.timesUsed,
219
+ row.original.usageLimit ? ` / ${row.original.usageLimit}` : ""
220
+ ] })
221
+ },
222
+ {
223
+ accessorKey: "status",
224
+ header: "Status",
225
+ cell: ({ getValue }) => {
226
+ const status = getValue();
227
+ return badge(status, statusColors[status] ?? "bg-gray-100 text-gray-700");
228
+ }
229
+ }
230
+ ], []);
231
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { children: loading ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-12 text-center text-sm text-muted-foreground", children: "Carregando..." }) : /* @__PURE__ */ jsxRuntime.jsx(
232
+ ui.DataTable,
233
+ {
234
+ columns,
235
+ data: discounts,
236
+ variant: "card",
237
+ emptyMessage: "Nenhum desconto cadastrado."
238
+ }
239
+ ) });
240
+ }
241
+ var TABS = [
242
+ { id: "products", label: "Produtos" },
243
+ { id: "orders", label: "Pedidos" },
244
+ { id: "customers", label: "Clientes" },
245
+ { id: "discounts", label: "Descontos" }
246
+ ];
247
+ var ShopPage = ({ provider }) => {
248
+ const [tab, setTab] = react.useState("products");
249
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 max-w-7xl mx-auto", children: [
250
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6", children: [
251
+ /* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-2xl font-semibold", children: "Loja" }),
252
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground mt-1", children: "Gerencie produtos, pedidos, clientes e descontos." })
253
+ ] }),
254
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-b mb-6", children: /* @__PURE__ */ jsxRuntime.jsx("nav", { className: "flex gap-1", children: TABS.map((t) => /* @__PURE__ */ jsxRuntime.jsx(
255
+ "button",
256
+ {
257
+ onClick: () => setTab(t.id),
258
+ className: `px-4 py-2 text-sm font-medium border-b-2 transition-colors ${tab === t.id ? "border-primary text-primary" : "border-transparent text-muted-foreground hover:text-foreground"}`,
259
+ children: t.label
260
+ },
261
+ t.id
262
+ )) }) }),
263
+ tab === "products" && /* @__PURE__ */ jsxRuntime.jsx(ProductsTab, { provider }),
264
+ tab === "orders" && /* @__PURE__ */ jsxRuntime.jsx(OrdersTab, { provider }),
265
+ tab === "customers" && /* @__PURE__ */ jsxRuntime.jsx(CustomersTab, { provider }),
266
+ tab === "discounts" && /* @__PURE__ */ jsxRuntime.jsx(DiscountsTab, { provider })
267
+ ] });
268
+ };
269
+ ShopPage.displayName = "ShopPage";
270
+
271
+ exports.ShopPage = ShopPage;
272
+ //# sourceMappingURL=ShopPage-PG5GKOZU.cjs.map
273
+ //# sourceMappingURL=ShopPage-PG5GKOZU.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ShopPage.tsx"],"names":["getShopProvider","useState","useCallback","useEffect","useMemo","jsx","jsxs","DataTable"],"mappings":"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","file":"ShopPage-PG5GKOZU.cjs","sourcesContent":["import React, { useEffect, useState, useCallback, useMemo } from 'react'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport { DataTable } from '@fayz-ai/ui'\nimport { getShopProvider } from '@fayz-ai/shop'\nimport type { Product, Order, ShopCustomer, Discount, ListProductsOptions, ShopProvider } from '@fayz-ai/shop'\n\nexport type ShopProviderResolver = ShopProvider | (() => ShopProvider)\n\nexport interface ShopPageProps {\n provider?: ShopProviderResolver\n}\n\n// ---------------------------------------------------------------------------\n// Shared helpers\n// ---------------------------------------------------------------------------\n\nfunction currency(value: number, code = 'BRL', locale = 'pt-BR') {\n return new Intl.NumberFormat(locale, { style: 'currency', currency: code }).format(value)\n}\n\nfunction badge(label: string, color: string) {\n return (\n <span className={`inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium ${color}`}>\n {label}\n </span>\n )\n}\n\nconst statusColors: Record<string, string> = {\n active: 'bg-emerald-100 text-emerald-800',\n draft: 'bg-gray-100 text-gray-700',\n archived: 'bg-orange-100 text-orange-700',\n open: 'bg-blue-100 text-blue-800',\n cancelled: 'bg-red-100 text-red-700',\n paid: 'bg-emerald-100 text-emerald-800',\n pending: 'bg-yellow-100 text-yellow-800',\n fulfilled: 'bg-emerald-100 text-emerald-800',\n unfulfilled: 'bg-gray-100 text-gray-700',\n 'partially_fulfilled': 'bg-blue-100 text-blue-800',\n}\n\nfunction resolveShopProvider(provider?: ShopProviderResolver): ShopProvider {\n return typeof provider === 'function' ? provider() : provider ?? getShopProvider()\n}\n\n// ---------------------------------------------------------------------------\n// Products tab\n// ---------------------------------------------------------------------------\n\nfunction ProductsTab({ provider }: ShopPageProps) {\n const [products, setProducts] = useState<Product[]>([])\n const [loading, setLoading] = useState(true)\n const [search, setSearch] = useState('')\n\n const load = useCallback(async (opts?: ListProductsOptions) => {\n setLoading(true)\n try {\n const data = await resolveShopProvider(provider).listProducts(opts)\n setProducts(data)\n } finally {\n setLoading(false)\n }\n }, [provider])\n\n useEffect(() => { load() }, [load])\n\n const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {\n const q = e.target.value\n setSearch(q)\n load(q ? { search: q } : undefined)\n }\n\n const columns = useMemo<ColumnDef<Product, any>[]>(() => [\n { accessorKey: 'name', header: 'Produto', cell: ({ getValue }) => <span className=\"font-medium\">{getValue() as string}</span> },\n { accessorKey: 'sku', header: 'SKU', cell: ({ getValue }) => <span className=\"text-muted-foreground\">{(getValue() as string | undefined) ?? '—'}</span> },\n {\n accessorKey: 'price', header: () => <span className=\"block text-right\">Preço</span>,\n cell: ({ getValue, row }) => <div className=\"text-right\">{currency(getValue() as number, row.original.currency)}</div>,\n },\n {\n accessorKey: 'inventoryCount', header: () => <span className=\"block text-right\">Estoque</span>,\n cell: ({ getValue }) => {\n const count = getValue() as number\n return <div className=\"text-right\"><span className={count === 0 ? 'text-red-600 font-medium' : ''}>{count}</span></div>\n },\n },\n {\n accessorKey: 'status', header: 'Status',\n cell: ({ getValue }) => {\n const status = getValue() as string\n return badge(status, statusColors[status] ?? 'bg-gray-100 text-gray-700')\n },\n },\n ], [])\n\n return (\n <div>\n <div className=\"flex items-center justify-between mb-4\">\n <input\n type=\"search\" value={search} onChange={handleSearch}\n placeholder=\"Buscar produtos...\"\n className=\"border rounded-lg px-3 py-2 text-sm w-64 focus:outline-none focus:ring-2 focus:ring-primary/50\"\n />\n <span className=\"text-sm text-muted-foreground\">{products.length} produtos</span>\n </div>\n\n {loading ? (\n <div className=\"py-12 text-center text-sm text-muted-foreground\">Carregando...</div>\n ) : (\n <DataTable\n columns={columns}\n data={products}\n variant=\"card\"\n emptyMessage=\"Nenhum produto encontrado.\"\n />\n )}\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Orders tab\n// ---------------------------------------------------------------------------\n\nfunction OrdersTab({ provider }: ShopPageProps) {\n const [orders, setOrders] = useState<Order[]>([])\n const [loading, setLoading] = useState(true)\n\n useEffect(() => {\n resolveShopProvider(provider).listOrders({ limit: 50 }).then(setOrders).finally(() => setLoading(false))\n }, [provider])\n\n const columns = useMemo<ColumnDef<Order, any>[]>(() => [\n { accessorKey: 'orderNumber', header: 'Pedido', cell: ({ getValue }) => <span className=\"font-medium\">#{getValue() as string}</span> },\n {\n id: 'customer', accessorFn: (o) => o.customerName ?? o.customerEmail ?? '—', header: 'Cliente',\n cell: ({ getValue }) => <span>{getValue() as string}</span>,\n },\n {\n accessorKey: 'total', header: () => <span className=\"block text-right\">Total</span>,\n cell: ({ getValue, row }) => <div className=\"text-right font-medium\">{currency(getValue() as number, row.original.currency)}</div>,\n },\n {\n accessorKey: 'financialStatus', header: 'Pagamento',\n cell: ({ getValue }) => {\n const status = getValue() as string\n return badge(status, statusColors[status] ?? 'bg-gray-100 text-gray-700')\n },\n },\n {\n accessorKey: 'fulfillmentStatus', header: 'Entrega',\n cell: ({ getValue }) => {\n const status = getValue() as string\n return badge(status, statusColors[status] ?? 'bg-gray-100 text-gray-700')\n },\n },\n {\n accessorKey: 'createdAt', header: 'Data',\n cell: ({ getValue }) => <span className=\"text-muted-foreground\">{new Date(getValue() as string).toLocaleDateString('pt-BR')}</span>,\n },\n ], [])\n\n return (\n <div>\n {loading ? (\n <div className=\"py-12 text-center text-sm text-muted-foreground\">Carregando...</div>\n ) : (\n <DataTable\n columns={columns}\n data={orders}\n variant=\"card\"\n emptyMessage=\"Nenhum pedido ainda.\"\n />\n )}\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Customers tab\n// ---------------------------------------------------------------------------\n\nfunction CustomersTab({ provider }: ShopPageProps) {\n const [customers, setCustomers] = useState<ShopCustomer[]>([])\n const [loading, setLoading] = useState(true)\n\n useEffect(() => {\n resolveShopProvider(provider).listCustomers({ limit: 50 }).then(setCustomers).finally(() => setLoading(false))\n }, [provider])\n\n const columns = useMemo<ColumnDef<ShopCustomer, any>[]>(() => [\n {\n id: 'name', accessorFn: (c) => `${c.firstName} ${c.lastName}`, header: 'Nome',\n cell: ({ row }) => <span className=\"font-medium\">{row.original.firstName} {row.original.lastName}</span>,\n },\n { accessorKey: 'email', header: 'Email', cell: ({ getValue }) => <span className=\"text-muted-foreground\">{(getValue() as string | undefined) ?? '—'}</span> },\n { accessorKey: 'phone', header: 'Telefone', cell: ({ getValue }) => <span className=\"text-muted-foreground\">{(getValue() as string | undefined) ?? '—'}</span> },\n {\n accessorKey: 'ordersCount', header: () => <span className=\"block text-right\">Pedidos</span>,\n cell: ({ getValue }) => <div className=\"text-right\">{getValue() as number}</div>,\n },\n {\n accessorKey: 'totalSpent', header: () => <span className=\"block text-right\">Total Gasto</span>,\n cell: ({ getValue }) => <div className=\"text-right\">{currency(getValue() as number)}</div>,\n },\n ], [])\n\n return (\n <div>\n {loading ? (\n <div className=\"py-12 text-center text-sm text-muted-foreground\">Carregando...</div>\n ) : (\n <DataTable\n columns={columns}\n data={customers}\n variant=\"card\"\n emptyMessage=\"Nenhum cliente ainda.\"\n />\n )}\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Discounts tab\n// ---------------------------------------------------------------------------\n\nfunction DiscountsTab({ provider }: ShopPageProps) {\n const [discounts, setDiscounts] = useState<Discount[]>([])\n const [loading, setLoading] = useState(true)\n\n useEffect(() => {\n resolveShopProvider(provider).listDiscounts({ limit: 50 }).then(setDiscounts).finally(() => setLoading(false))\n }, [provider])\n\n const columns = useMemo<ColumnDef<Discount, any>[]>(() => [\n { accessorKey: 'title', header: 'Título', cell: ({ getValue }) => <span className=\"font-medium\">{getValue() as string}</span> },\n { accessorKey: 'code', header: 'Código', cell: ({ getValue }) => <span className=\"font-mono text-sm\">{(getValue() as string | undefined) ?? '—'}</span> },\n { accessorKey: 'type', header: 'Tipo', cell: ({ getValue }) => <span className=\"text-muted-foreground\">{getValue() as string}</span> },\n {\n accessorKey: 'value', header: () => <span className=\"block text-right\">Valor</span>,\n cell: ({ row }) => <div className=\"text-right\">{row.original.type === 'percentage' ? `${row.original.value}%` : currency(row.original.value)}</div>,\n },\n {\n id: 'usos', accessorKey: 'timesUsed', header: () => <span className=\"block text-right\">Usos</span>,\n cell: ({ row }) => <div className=\"text-right\">{row.original.timesUsed}{row.original.usageLimit ? ` / ${row.original.usageLimit}` : ''}</div>,\n },\n {\n accessorKey: 'status', header: 'Status',\n cell: ({ getValue }) => {\n const status = getValue() as string\n return badge(status, statusColors[status] ?? 'bg-gray-100 text-gray-700')\n },\n },\n ], [])\n\n return (\n <div>\n {loading ? (\n <div className=\"py-12 text-center text-sm text-muted-foreground\">Carregando...</div>\n ) : (\n <DataTable\n columns={columns}\n data={discounts}\n variant=\"card\"\n emptyMessage=\"Nenhum desconto cadastrado.\"\n />\n )}\n </div>\n )\n}\n\n// ---------------------------------------------------------------------------\n// Main page\n// ---------------------------------------------------------------------------\n\nconst TABS = [\n { id: 'products', label: 'Produtos' },\n { id: 'orders', label: 'Pedidos' },\n { id: 'customers', label: 'Clientes' },\n { id: 'discounts', label: 'Descontos' },\n] as const\n\ntype TabId = typeof TABS[number]['id']\n\nexport const ShopPage: React.FC<ShopPageProps> = ({ provider }) => {\n const [tab, setTab] = useState<TabId>('products')\n\n return (\n <div className=\"p-6 max-w-7xl mx-auto\">\n <div className=\"mb-6\">\n <h1 className=\"text-2xl font-semibold\">Loja</h1>\n <p className=\"text-muted-foreground mt-1\">Gerencie produtos, pedidos, clientes e descontos.</p>\n </div>\n\n {/* Tabs */}\n <div className=\"border-b mb-6\">\n <nav className=\"flex gap-1\">\n {TABS.map(t => (\n <button\n key={t.id}\n onClick={() => setTab(t.id)}\n className={`px-4 py-2 text-sm font-medium border-b-2 transition-colors ${\n tab === t.id\n ? 'border-primary text-primary'\n : 'border-transparent text-muted-foreground hover:text-foreground'\n }`}\n >\n {t.label}\n </button>\n ))}\n </nav>\n </div>\n\n {tab === 'products' && <ProductsTab provider={provider} />}\n {tab === 'orders' && <OrdersTab provider={provider} />}\n {tab === 'customers' && <CustomersTab provider={provider} />}\n {tab === 'discounts' && <DiscountsTab provider={provider} />}\n </div>\n )\n}\n\nShopPage.displayName = 'ShopPage'\n"]}
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import type { ShopProvider } from '@fayz-ai/shop';
3
+ export type ShopProviderResolver = ShopProvider | (() => ShopProvider);
4
+ export interface ShopPageProps {
5
+ provider?: ShopProviderResolver;
6
+ }
7
+ export declare const ShopPage: React.FC<ShopPageProps>;
8
+ //# sourceMappingURL=ShopPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShopPage.d.ts","sourceRoot":"","sources":["../src/ShopPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoD,MAAM,OAAO,CAAA;AAIxE,OAAO,KAAK,EAA+D,YAAY,EAAE,MAAM,eAAe,CAAA;AAE9G,MAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG,CAAC,MAAM,YAAY,CAAC,CAAA;AAEtE,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,oBAAoB,CAAA;CAChC;AAmRD,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAmC5C,CAAA"}
package/dist/index.cjs ADDED
@@ -0,0 +1,119 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+ var shop = require('@fayz-ai/shop');
5
+ var saas = require('@fayz-ai/saas');
6
+
7
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
+
9
+ var React__default = /*#__PURE__*/_interopDefault(React);
10
+
11
+ // src/index.ts
12
+ var ShopPage = React__default.default.lazy(() => import('./ShopPage-PG5GKOZU.cjs').then((m) => ({ default: m.ShopPage })));
13
+ function createShopPlugin(options) {
14
+ const curr = { code: "BRL", symbol: "R$", ...options?.currency };
15
+ shop.setShopTenantResolver(() => saas.useOrganizationStore.getState().currentOrg?.id);
16
+ const PageComponent = () => React__default.default.createElement(
17
+ React__default.default.Suspense,
18
+ { fallback: null },
19
+ React__default.default.createElement(ShopPage, {
20
+ provider: options?.provider
21
+ })
22
+ );
23
+ PageComponent.displayName = "ShopPageWrapper";
24
+ return {
25
+ id: "shop",
26
+ name: options?.navLabel ?? "Shop",
27
+ icon: "ShoppingBag",
28
+ version: "1.0.0",
29
+ scope: options?.scope ?? "vertical",
30
+ verticalId: options?.verticalId,
31
+ defaultEnabled: true,
32
+ dependencies: [],
33
+ navigation: [
34
+ {
35
+ section: options?.navSection ?? "main",
36
+ position: options?.navPosition ?? 6,
37
+ label: options?.navLabel ?? "Shop",
38
+ route: "/shop",
39
+ icon: "ShoppingBag",
40
+ permission: { feature: "shop", action: "read" }
41
+ }
42
+ ],
43
+ routes: [
44
+ {
45
+ path: "/shop",
46
+ component: PageComponent,
47
+ permission: { feature: "shop", action: "read" }
48
+ }
49
+ ],
50
+ widgets: [],
51
+ aiTools: [
52
+ {
53
+ id: "shop.list-products",
54
+ name: "listProducts",
55
+ description: "Lists products in the shop catalog.",
56
+ icon: "Package",
57
+ mode: "read",
58
+ category: "Shop",
59
+ parameters: {
60
+ type: "object",
61
+ properties: {
62
+ search: { type: "string", description: "Filter by name" },
63
+ status: { type: "string", enum: ["draft", "active", "archived"] }
64
+ }
65
+ },
66
+ suggestions: [
67
+ { label: "What products are available?" },
68
+ { label: "Which products are out of stock?" }
69
+ ]
70
+ },
71
+ {
72
+ id: "shop.list-orders",
73
+ name: "listOrders",
74
+ description: "Lists recent shop orders.",
75
+ icon: "ShoppingCart",
76
+ mode: "read",
77
+ category: "Shop",
78
+ parameters: {
79
+ type: "object",
80
+ properties: {
81
+ financialStatus: { type: "string", enum: ["pending", "paid", "refunded", "voided"] },
82
+ fulfillmentStatus: { type: "string", enum: ["unfulfilled", "partially_fulfilled", "fulfilled"] }
83
+ }
84
+ },
85
+ suggestions: [
86
+ { label: "Show me pending orders" },
87
+ { label: "How many orders were paid today?" }
88
+ ]
89
+ }
90
+ ],
91
+ settings: [
92
+ {
93
+ id: "shop",
94
+ label: "Shop",
95
+ icon: "ShoppingBag",
96
+ component: (() => {
97
+ const ShopSettingsTab = () => React__default.default.createElement(
98
+ "div",
99
+ { className: "p-4 space-y-2" },
100
+ React__default.default.createElement("h2", { className: "text-lg font-semibold" }, "Configura\xE7\xF5es da Loja"),
101
+ React__default.default.createElement(
102
+ "p",
103
+ { className: "text-sm text-muted-foreground" },
104
+ `Moeda: ${curr.symbol} (${curr.code})`
105
+ )
106
+ );
107
+ ShopSettingsTab.displayName = "ShopSettingsTab";
108
+ return ShopSettingsTab;
109
+ })(),
110
+ order: 30,
111
+ permission: { feature: "shop", action: "read" }
112
+ }
113
+ ]
114
+ };
115
+ }
116
+
117
+ exports.createShopPlugin = createShopPlugin;
118
+ //# sourceMappingURL=index.cjs.map
119
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"names":["React","setShopTenantResolver","useOrganizationStore"],"mappings":"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","file":"index.cjs","sourcesContent":["import React from 'react'\nimport type { PluginManifest, PluginScope, VerticalId } from '@fayz-ai/core'\nimport { setShopTenantResolver } from '@fayz-ai/shop'\nimport { useOrganizationStore } from '@fayz-ai/saas'\nimport type { ShopProviderResolver } from './ShopPage'\n\nconst ShopPage = React.lazy(() => import('./ShopPage').then((m) => ({ default: m.ShopPage })))\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface ShopPluginOptions {\n navPosition?: number\n navSection?: 'main' | 'secondary' | 'settings'\n navLabel?: string\n scope?: PluginScope\n verticalId?: VerticalId\n currency?: { code?: string; locale?: string; symbol?: string }\n provider?: ShopProviderResolver\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createShopPlugin(options?: ShopPluginOptions): PluginManifest {\n const curr = { code: 'BRL', locale: 'pt-BR', symbol: 'R$', ...options?.currency }\n\n // Scope fallback shop queries to the active organization. Apps can inject a\n // provider when they want SDK-owned data access instead of the global runtime.\n setShopTenantResolver(() => useOrganizationStore.getState().currentOrg?.id)\n\n const PageComponent: React.ComponentType<unknown> = () =>\n React.createElement(React.Suspense, { fallback: null },\n React.createElement(ShopPage as React.ComponentType<{ provider?: ShopProviderResolver }>, {\n provider: options?.provider,\n })\n )\n PageComponent.displayName = 'ShopPageWrapper'\n\n return {\n id: 'shop',\n name: options?.navLabel ?? 'Shop',\n icon: 'ShoppingBag',\n version: '1.0.0',\n scope: options?.scope ?? 'vertical',\n verticalId: options?.verticalId,\n defaultEnabled: true,\n dependencies: [],\n navigation: [\n {\n section: options?.navSection ?? 'main',\n position: options?.navPosition ?? 6,\n label: options?.navLabel ?? 'Shop',\n route: '/shop',\n icon: 'ShoppingBag',\n permission: { feature: 'shop', action: 'read' as const },\n },\n ],\n routes: [\n {\n path: '/shop',\n component: PageComponent,\n permission: { feature: 'shop', action: 'read' as const },\n },\n ],\n widgets: [],\n aiTools: [\n {\n id: 'shop.list-products',\n name: 'listProducts',\n description: 'Lists products in the shop catalog.',\n icon: 'Package',\n mode: 'read' as const,\n category: 'Shop',\n parameters: {\n type: 'object' as const,\n properties: {\n search: { type: 'string' as const, description: 'Filter by name' },\n status: { type: 'string' as const, enum: ['draft', 'active', 'archived'] },\n },\n },\n suggestions: [\n { label: 'What products are available?' },\n { label: 'Which products are out of stock?' },\n ],\n },\n {\n id: 'shop.list-orders',\n name: 'listOrders',\n description: 'Lists recent shop orders.',\n icon: 'ShoppingCart',\n mode: 'read' as const,\n category: 'Shop',\n parameters: {\n type: 'object' as const,\n properties: {\n financialStatus: { type: 'string' as const, enum: ['pending', 'paid', 'refunded', 'voided'] },\n fulfillmentStatus: { type: 'string' as const, enum: ['unfulfilled', 'partially_fulfilled', 'fulfilled'] },\n },\n },\n suggestions: [\n { label: 'Show me pending orders' },\n { label: 'How many orders were paid today?' },\n ],\n },\n ],\n settings: [\n {\n id: 'shop',\n label: 'Shop',\n icon: 'ShoppingBag',\n component: (() => {\n const ShopSettingsTab: React.ComponentType<unknown> = () =>\n React.createElement('div', { className: 'p-4 space-y-2' },\n React.createElement('h2', { className: 'text-lg font-semibold' }, 'Configurações da Loja'),\n React.createElement('p', { className: 'text-sm text-muted-foreground' },\n `Moeda: ${curr.symbol} (${curr.code})`\n )\n )\n ShopSettingsTab.displayName = 'ShopSettingsTab'\n return ShopSettingsTab\n })(),\n order: 30,\n permission: { feature: 'shop', action: 'read' as const },\n },\n ],\n }\n}\n\n// Re-export shop types so consumer apps only need @fayz-ai/plugin-shop\nexport type {\n Product, Order, ShopCustomer, Discount, Category,\n CreateProductInput, UpdateProductInput, ListProductsOptions,\n CreateOrderInput, UpdateOrderInput, ListOrdersOptions,\n} from '@fayz-ai/shop'\n"]}
@@ -0,0 +1,18 @@
1
+ import type { PluginManifest, PluginScope, VerticalId } from '@fayz-ai/core';
2
+ import type { ShopProviderResolver } from './ShopPage';
3
+ export interface ShopPluginOptions {
4
+ navPosition?: number;
5
+ navSection?: 'main' | 'secondary' | 'settings';
6
+ navLabel?: string;
7
+ scope?: PluginScope;
8
+ verticalId?: VerticalId;
9
+ currency?: {
10
+ code?: string;
11
+ locale?: string;
12
+ symbol?: string;
13
+ };
14
+ provider?: ShopProviderResolver;
15
+ }
16
+ export declare function createShopPlugin(options?: ShopPluginOptions): PluginManifest;
17
+ export type { Product, Order, ShopCustomer, Discount, Category, CreateProductInput, UpdateProductInput, ListProductsOptions, CreateOrderInput, UpdateOrderInput, ListOrdersOptions, } from '@fayz-ai/shop';
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAG5E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAQtD,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,CAAA;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,QAAQ,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAC9D,QAAQ,CAAC,EAAE,oBAAoB,CAAA;CAChC;AAMD,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,cAAc,CAuG5E;AAGD,YAAY,EACV,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,EAChD,kBAAkB,EAAE,kBAAkB,EAAE,mBAAmB,EAC3D,gBAAgB,EAAE,gBAAgB,EAAE,iBAAiB,GACtD,MAAM,eAAe,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,113 @@
1
+ import React from 'react';
2
+ import { setShopTenantResolver } from '@fayz-ai/shop';
3
+ import { useOrganizationStore } from '@fayz-ai/saas';
4
+
5
+ // src/index.ts
6
+ var ShopPage = React.lazy(() => import('./ShopPage-65PPVKBD.js').then((m) => ({ default: m.ShopPage })));
7
+ function createShopPlugin(options) {
8
+ const curr = { code: "BRL", symbol: "R$", ...options?.currency };
9
+ setShopTenantResolver(() => useOrganizationStore.getState().currentOrg?.id);
10
+ const PageComponent = () => React.createElement(
11
+ React.Suspense,
12
+ { fallback: null },
13
+ React.createElement(ShopPage, {
14
+ provider: options?.provider
15
+ })
16
+ );
17
+ PageComponent.displayName = "ShopPageWrapper";
18
+ return {
19
+ id: "shop",
20
+ name: options?.navLabel ?? "Shop",
21
+ icon: "ShoppingBag",
22
+ version: "1.0.0",
23
+ scope: options?.scope ?? "vertical",
24
+ verticalId: options?.verticalId,
25
+ defaultEnabled: true,
26
+ dependencies: [],
27
+ navigation: [
28
+ {
29
+ section: options?.navSection ?? "main",
30
+ position: options?.navPosition ?? 6,
31
+ label: options?.navLabel ?? "Shop",
32
+ route: "/shop",
33
+ icon: "ShoppingBag",
34
+ permission: { feature: "shop", action: "read" }
35
+ }
36
+ ],
37
+ routes: [
38
+ {
39
+ path: "/shop",
40
+ component: PageComponent,
41
+ permission: { feature: "shop", action: "read" }
42
+ }
43
+ ],
44
+ widgets: [],
45
+ aiTools: [
46
+ {
47
+ id: "shop.list-products",
48
+ name: "listProducts",
49
+ description: "Lists products in the shop catalog.",
50
+ icon: "Package",
51
+ mode: "read",
52
+ category: "Shop",
53
+ parameters: {
54
+ type: "object",
55
+ properties: {
56
+ search: { type: "string", description: "Filter by name" },
57
+ status: { type: "string", enum: ["draft", "active", "archived"] }
58
+ }
59
+ },
60
+ suggestions: [
61
+ { label: "What products are available?" },
62
+ { label: "Which products are out of stock?" }
63
+ ]
64
+ },
65
+ {
66
+ id: "shop.list-orders",
67
+ name: "listOrders",
68
+ description: "Lists recent shop orders.",
69
+ icon: "ShoppingCart",
70
+ mode: "read",
71
+ category: "Shop",
72
+ parameters: {
73
+ type: "object",
74
+ properties: {
75
+ financialStatus: { type: "string", enum: ["pending", "paid", "refunded", "voided"] },
76
+ fulfillmentStatus: { type: "string", enum: ["unfulfilled", "partially_fulfilled", "fulfilled"] }
77
+ }
78
+ },
79
+ suggestions: [
80
+ { label: "Show me pending orders" },
81
+ { label: "How many orders were paid today?" }
82
+ ]
83
+ }
84
+ ],
85
+ settings: [
86
+ {
87
+ id: "shop",
88
+ label: "Shop",
89
+ icon: "ShoppingBag",
90
+ component: (() => {
91
+ const ShopSettingsTab = () => React.createElement(
92
+ "div",
93
+ { className: "p-4 space-y-2" },
94
+ React.createElement("h2", { className: "text-lg font-semibold" }, "Configura\xE7\xF5es da Loja"),
95
+ React.createElement(
96
+ "p",
97
+ { className: "text-sm text-muted-foreground" },
98
+ `Moeda: ${curr.symbol} (${curr.code})`
99
+ )
100
+ );
101
+ ShopSettingsTab.displayName = "ShopSettingsTab";
102
+ return ShopSettingsTab;
103
+ })(),
104
+ order: 30,
105
+ permission: { feature: "shop", action: "read" }
106
+ }
107
+ ]
108
+ };
109
+ }
110
+
111
+ export { createShopPlugin };
112
+ //# sourceMappingURL=index.js.map
113
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import React from 'react'\nimport type { PluginManifest, PluginScope, VerticalId } from '@fayz-ai/core'\nimport { setShopTenantResolver } from '@fayz-ai/shop'\nimport { useOrganizationStore } from '@fayz-ai/saas'\nimport type { ShopProviderResolver } from './ShopPage'\n\nconst ShopPage = React.lazy(() => import('./ShopPage').then((m) => ({ default: m.ShopPage })))\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface ShopPluginOptions {\n navPosition?: number\n navSection?: 'main' | 'secondary' | 'settings'\n navLabel?: string\n scope?: PluginScope\n verticalId?: VerticalId\n currency?: { code?: string; locale?: string; symbol?: string }\n provider?: ShopProviderResolver\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createShopPlugin(options?: ShopPluginOptions): PluginManifest {\n const curr = { code: 'BRL', locale: 'pt-BR', symbol: 'R$', ...options?.currency }\n\n // Scope fallback shop queries to the active organization. Apps can inject a\n // provider when they want SDK-owned data access instead of the global runtime.\n setShopTenantResolver(() => useOrganizationStore.getState().currentOrg?.id)\n\n const PageComponent: React.ComponentType<unknown> = () =>\n React.createElement(React.Suspense, { fallback: null },\n React.createElement(ShopPage as React.ComponentType<{ provider?: ShopProviderResolver }>, {\n provider: options?.provider,\n })\n )\n PageComponent.displayName = 'ShopPageWrapper'\n\n return {\n id: 'shop',\n name: options?.navLabel ?? 'Shop',\n icon: 'ShoppingBag',\n version: '1.0.0',\n scope: options?.scope ?? 'vertical',\n verticalId: options?.verticalId,\n defaultEnabled: true,\n dependencies: [],\n navigation: [\n {\n section: options?.navSection ?? 'main',\n position: options?.navPosition ?? 6,\n label: options?.navLabel ?? 'Shop',\n route: '/shop',\n icon: 'ShoppingBag',\n permission: { feature: 'shop', action: 'read' as const },\n },\n ],\n routes: [\n {\n path: '/shop',\n component: PageComponent,\n permission: { feature: 'shop', action: 'read' as const },\n },\n ],\n widgets: [],\n aiTools: [\n {\n id: 'shop.list-products',\n name: 'listProducts',\n description: 'Lists products in the shop catalog.',\n icon: 'Package',\n mode: 'read' as const,\n category: 'Shop',\n parameters: {\n type: 'object' as const,\n properties: {\n search: { type: 'string' as const, description: 'Filter by name' },\n status: { type: 'string' as const, enum: ['draft', 'active', 'archived'] },\n },\n },\n suggestions: [\n { label: 'What products are available?' },\n { label: 'Which products are out of stock?' },\n ],\n },\n {\n id: 'shop.list-orders',\n name: 'listOrders',\n description: 'Lists recent shop orders.',\n icon: 'ShoppingCart',\n mode: 'read' as const,\n category: 'Shop',\n parameters: {\n type: 'object' as const,\n properties: {\n financialStatus: { type: 'string' as const, enum: ['pending', 'paid', 'refunded', 'voided'] },\n fulfillmentStatus: { type: 'string' as const, enum: ['unfulfilled', 'partially_fulfilled', 'fulfilled'] },\n },\n },\n suggestions: [\n { label: 'Show me pending orders' },\n { label: 'How many orders were paid today?' },\n ],\n },\n ],\n settings: [\n {\n id: 'shop',\n label: 'Shop',\n icon: 'ShoppingBag',\n component: (() => {\n const ShopSettingsTab: React.ComponentType<unknown> = () =>\n React.createElement('div', { className: 'p-4 space-y-2' },\n React.createElement('h2', { className: 'text-lg font-semibold' }, 'Configurações da Loja'),\n React.createElement('p', { className: 'text-sm text-muted-foreground' },\n `Moeda: ${curr.symbol} (${curr.code})`\n )\n )\n ShopSettingsTab.displayName = 'ShopSettingsTab'\n return ShopSettingsTab\n })(),\n order: 30,\n permission: { feature: 'shop', action: 'read' as const },\n },\n ],\n }\n}\n\n// Re-export shop types so consumer apps only need @fayz-ai/plugin-shop\nexport type {\n Product, Order, ShopCustomer, Discount, Category,\n CreateProductInput, UpdateProductInput, ListProductsOptions,\n CreateOrderInput, UpdateOrderInput, ListOrdersOptions,\n} from '@fayz-ai/shop'\n"]}