@fayz-ai/plugin-shop 0.9.0 → 0.10.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.
Files changed (165) hide show
  1. package/README.md +4 -4
  2. package/dist/ShopPage-ZBJRNMKQ.js +2942 -0
  3. package/dist/ShopPage-ZBJRNMKQ.js.map +1 -0
  4. package/dist/analytics/cards.d.ts +3 -0
  5. package/dist/analytics/cards.d.ts.map +1 -0
  6. package/dist/chunk-EW4XJRA2.js +835 -0
  7. package/dist/chunk-EW4XJRA2.js.map +1 -0
  8. package/dist/data/categoryDataProvider.d.ts +5 -0
  9. package/dist/data/categoryDataProvider.d.ts.map +1 -0
  10. package/dist/data/collectionDataProvider.d.ts +5 -0
  11. package/dist/data/collectionDataProvider.d.ts.map +1 -0
  12. package/dist/data/customerGroupDataProvider.d.ts +5 -0
  13. package/dist/data/customerGroupDataProvider.d.ts.map +1 -0
  14. package/dist/data/customerSegmentDataProvider.d.ts +16 -0
  15. package/dist/data/customerSegmentDataProvider.d.ts.map +1 -0
  16. package/dist/data/giftCardDataProvider.d.ts +5 -0
  17. package/dist/data/giftCardDataProvider.d.ts.map +1 -0
  18. package/dist/data/registries.d.ts +53 -0
  19. package/dist/data/registries.d.ts.map +1 -0
  20. package/dist/data/registry-routes.d.ts +21 -0
  21. package/dist/data/registry-routes.d.ts.map +1 -0
  22. package/dist/data/shippingProfileDataProvider.d.ts +19 -0
  23. package/dist/data/shippingProfileDataProvider.d.ts.map +1 -0
  24. package/dist/data/stockLocationDataProvider.d.ts +13 -0
  25. package/dist/data/stockLocationDataProvider.d.ts.map +1 -0
  26. package/dist/index.d.ts +18 -3
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +5362 -418
  29. package/dist/index.js.map +1 -1
  30. package/dist/integrations/abacatepay/connectorDef.d.ts +41 -0
  31. package/dist/integrations/abacatepay/connectorDef.d.ts.map +1 -0
  32. package/dist/integrations/appmax/connectorDef.d.ts +28 -0
  33. package/dist/integrations/appmax/connectorDef.d.ts.map +1 -0
  34. package/dist/integrations/bling/connectorDef.d.ts +10 -0
  35. package/dist/integrations/bling/connectorDef.d.ts.map +1 -0
  36. package/dist/integrations/bling/data.d.ts +61 -0
  37. package/dist/integrations/bling/data.d.ts.map +1 -0
  38. package/dist/integrations/bling/inbound.d.ts +97 -0
  39. package/dist/integrations/bling/inbound.d.ts.map +1 -0
  40. package/dist/integrations/bling/index.d.ts +9 -0
  41. package/dist/integrations/bling/index.d.ts.map +1 -0
  42. package/dist/integrations/bling/limits.d.ts +33 -0
  43. package/dist/integrations/bling/limits.d.ts.map +1 -0
  44. package/dist/integrations/bling/mapping.d.ts +10 -0
  45. package/dist/integrations/bling/mapping.d.ts.map +1 -0
  46. package/dist/integrations/bling/sync.d.ts +70 -0
  47. package/dist/integrations/bling/sync.d.ts.map +1 -0
  48. package/dist/integrations/bling/types.d.ts +59 -0
  49. package/dist/integrations/bling/types.d.ts.map +1 -0
  50. package/dist/integrations/melhor-envio/connectorDef.d.ts +38 -0
  51. package/dist/integrations/melhor-envio/connectorDef.d.ts.map +1 -0
  52. package/dist/integrations/melhor-envio/labelProvider.d.ts +4 -0
  53. package/dist/integrations/melhor-envio/labelProvider.d.ts.map +1 -0
  54. package/dist/integrations/stripe-connect/connectorDef.d.ts +17 -0
  55. package/dist/integrations/stripe-connect/connectorDef.d.ts.map +1 -0
  56. package/dist/settings/CheckoutSettings.d.ts +17 -0
  57. package/dist/settings/CheckoutSettings.d.ts.map +1 -0
  58. package/dist/settings/ChoiceCards.d.ts +23 -0
  59. package/dist/settings/ChoiceCards.d.ts.map +1 -0
  60. package/dist/settings/FulfillmentSettings.d.ts +23 -0
  61. package/dist/settings/FulfillmentSettings.d.ts.map +1 -0
  62. package/dist/settings/HandlingSettings.d.ts +17 -0
  63. package/dist/settings/HandlingSettings.d.ts.map +1 -0
  64. package/dist/settings/PackagesSettings.d.ts +22 -0
  65. package/dist/settings/PackagesSettings.d.ts.map +1 -0
  66. package/dist/settings/PaymentProviderRow.d.ts +28 -0
  67. package/dist/settings/PaymentProviderRow.d.ts.map +1 -0
  68. package/dist/settings/PaymentsSettings.d.ts +7 -0
  69. package/dist/settings/PaymentsSettings.d.ts.map +1 -0
  70. package/dist/settings/SettingsState.d.ts +27 -0
  71. package/dist/settings/SettingsState.d.ts.map +1 -0
  72. package/dist/settings/ShippingSettings.d.ts +27 -0
  73. package/dist/settings/ShippingSettings.d.ts.map +1 -0
  74. package/dist/settings/StoreGeneralSettings.d.ts +19 -0
  75. package/dist/settings/StoreGeneralSettings.d.ts.map +1 -0
  76. package/dist/settings/error-message.d.ts +2 -0
  77. package/dist/settings/error-message.d.ts.map +1 -0
  78. package/dist/settings/index.d.ts +12 -0
  79. package/dist/settings/index.d.ts.map +1 -0
  80. package/dist/settings/payment-provider.d.ts +13 -0
  81. package/dist/settings/payment-provider.d.ts.map +1 -0
  82. package/dist/settings/useStoreSettings.d.ts +30 -0
  83. package/dist/settings/useStoreSettings.d.ts.map +1 -0
  84. package/dist/views/AgencySelect.d.ts +17 -0
  85. package/dist/views/AgencySelect.d.ts.map +1 -0
  86. package/dist/views/ChannelsPage.d.ts +1 -1
  87. package/dist/views/ChannelsPage.d.ts.map +1 -1
  88. package/dist/views/ContentPage.d.ts +7 -0
  89. package/dist/views/ContentPage.d.ts.map +1 -0
  90. package/dist/views/EmailTemplatePage.d.ts +9 -0
  91. package/dist/views/EmailTemplatePage.d.ts.map +1 -0
  92. package/dist/views/EmailsPage.d.ts +7 -0
  93. package/dist/views/EmailsPage.d.ts.map +1 -0
  94. package/dist/views/FulfillmentProviderSelect.d.ts +14 -0
  95. package/dist/views/FulfillmentProviderSelect.d.ts.map +1 -0
  96. package/dist/views/NewOrderCharge.d.ts +17 -0
  97. package/dist/views/NewOrderCharge.d.ts.map +1 -0
  98. package/dist/views/NewOrderPage.d.ts +9 -0
  99. package/dist/views/NewOrderPage.d.ts.map +1 -0
  100. package/dist/views/OrderDetailView.d.ts +2 -0
  101. package/dist/views/OrderDetailView.d.ts.map +1 -1
  102. package/dist/views/OrderPaymentDetail.d.ts +5 -0
  103. package/dist/views/OrderPaymentDetail.d.ts.map +1 -0
  104. package/dist/views/OrderProviderLinks.d.ts +5 -0
  105. package/dist/views/OrderProviderLinks.d.ts.map +1 -0
  106. package/dist/views/PackageSelect.d.ts +20 -0
  107. package/dist/views/PackageSelect.d.ts.map +1 -0
  108. package/dist/views/ProductImagesTab.d.ts.map +1 -1
  109. package/dist/views/ProductVariantsTab.d.ts +29 -0
  110. package/dist/views/ProductVariantsTab.d.ts.map +1 -0
  111. package/dist/views/SenderLocationModal.d.ts +20 -0
  112. package/dist/views/SenderLocationModal.d.ts.map +1 -0
  113. package/dist/views/ShipOrderForm.d.ts +10 -0
  114. package/dist/views/ShipOrderForm.d.ts.map +1 -0
  115. package/dist/views/ShipWithCarrier.d.ts +18 -0
  116. package/dist/views/ShipWithCarrier.d.ts.map +1 -0
  117. package/dist/views/ShipmentActions.d.ts +11 -0
  118. package/dist/views/ShipmentActions.d.ts.map +1 -0
  119. package/dist/views/ShippingProfileSelect.d.ts +13 -0
  120. package/dist/views/ShippingProfileSelect.d.ts.map +1 -0
  121. package/dist/views/ShopPage.d.ts.map +1 -0
  122. package/dist/views/categoryEntity.d.ts +4 -0
  123. package/dist/views/categoryEntity.d.ts.map +1 -0
  124. package/dist/views/collectionEntity.d.ts +4 -0
  125. package/dist/views/collectionEntity.d.ts.map +1 -0
  126. package/dist/views/customerEntity.d.ts.map +1 -1
  127. package/dist/views/customerGroupEntity.d.ts +4 -0
  128. package/dist/views/customerGroupEntity.d.ts.map +1 -0
  129. package/dist/views/customerSegmentEntity.d.ts +13 -0
  130. package/dist/views/customerSegmentEntity.d.ts.map +1 -0
  131. package/dist/views/eta-label.d.ts +6 -0
  132. package/dist/views/eta-label.d.ts.map +1 -0
  133. package/dist/views/giftCardEntity.d.ts +4 -0
  134. package/dist/views/giftCardEntity.d.ts.map +1 -0
  135. package/dist/views/media-links.d.ts +12 -0
  136. package/dist/views/media-links.d.ts.map +1 -0
  137. package/dist/views/new-order-rules.d.ts +55 -0
  138. package/dist/views/new-order-rules.d.ts.map +1 -0
  139. package/dist/views/order-actions.d.ts +4 -0
  140. package/dist/views/order-actions.d.ts.map +1 -0
  141. package/dist/views/productEntity.d.ts.map +1 -1
  142. package/dist/views/shippingZoneEntity.d.ts.map +1 -1
  143. package/package.json +11 -10
  144. package/dist/ShopPage-JP27MZS2.js +0 -690
  145. package/dist/ShopPage-JP27MZS2.js.map +0 -1
  146. package/dist/ShopPage.d.ts.map +0 -1
  147. package/dist/components/ShopSettings.d.ts +0 -15
  148. package/dist/components/ShopSettings.d.ts.map +0 -1
  149. package/src/ShopPage.tsx +0 -425
  150. package/src/components/ShopSettings.tsx +0 -108
  151. package/src/data/customerDataProvider.ts +0 -31
  152. package/src/data/discountDataProvider.ts +0 -42
  153. package/src/data/productDataProvider.ts +0 -54
  154. package/src/data/shared.ts +0 -42
  155. package/src/data/shippingZoneDataProvider.ts +0 -49
  156. package/src/index.ts +0 -270
  157. package/src/views/ChannelsPage.tsx +0 -274
  158. package/src/views/OrderDetailView.tsx +0 -319
  159. package/src/views/ProductImagesTab.tsx +0 -183
  160. package/src/views/customerEntity.tsx +0 -110
  161. package/src/views/customerLookup.ts +0 -31
  162. package/src/views/discountEntity.tsx +0 -144
  163. package/src/views/productEntity.tsx +0 -229
  164. package/src/views/shippingZoneEntity.tsx +0 -123
  165. /package/dist/{ShopPage.d.ts → views/ShopPage.d.ts} +0 -0
@@ -0,0 +1,835 @@
1
+ import React3, { useState, useEffect } from 'react';
2
+ import { Skeleton } from '@fayz-ai/ui';
3
+ import { RefreshCw, MapPin } from 'lucide-react';
4
+ import { OWN_FULFILLMENT, resolveShippingLabelProvider, getShopProvider } from '@fayz-ai/shop';
5
+ import { useConnectors } from '@fayz-ai/admin';
6
+ import { jsxs, jsx } from 'react/jsx-runtime';
7
+
8
+ // src/settings/error-message.ts
9
+ var RPC_REFUSAL = [
10
+ [/nothing left to fulfill/i, "N\xE3o h\xE1 itens pendentes neste pedido \u2014 tudo j\xE1 foi enviado."],
11
+ [/not a member of this store/i, "Sua conta n\xE3o tem permiss\xE3o para despachar pedidos desta loja."],
12
+ [/order not found/i, "Pedido n\xE3o encontrado."],
13
+ [/fulfillment not found/i, "Envio n\xE3o encontrado \u2014 recarregue a p\xE1gina."],
14
+ [/fulfillment was cancelled/i, "Este envio foi cancelado. Registre um novo envio."],
15
+ [/location does not belong to this store/i, "O local de estoque escolhido n\xE3o \xE9 desta loja."],
16
+ [/not pending/i, "N\xE3o h\xE1 cobran\xE7a em aberto para registrar neste pedido."],
17
+ [/not authorized to confirm payment/i, "Sua conta n\xE3o tem permiss\xE3o para registrar o pagamento deste pedido."]
18
+ ];
19
+ function errorMessage(error) {
20
+ const raw = rawMessage(error);
21
+ for (const [pattern, friendly] of RPC_REFUSAL) if (pattern.test(raw)) return friendly;
22
+ return raw;
23
+ }
24
+ function rawMessage(error) {
25
+ if (error instanceof Error) return error.message.trim() || "erro desconhecido";
26
+ if (error && typeof error === "object") {
27
+ const e = error;
28
+ const parts = [e.message, e.details, e.hint].filter(
29
+ (p) => typeof p === "string" && p.trim().length > 0
30
+ );
31
+ if (parts.length) return parts.join(" \u2014 ");
32
+ if (typeof e.code === "string" && e.code) return `erro ${e.code}`;
33
+ }
34
+ const text = String(error ?? "").trim();
35
+ return text && text !== "[object Object]" ? text : "erro desconhecido";
36
+ }
37
+ function AgencySelect({ value, onChange, values, provider }) {
38
+ const resolve2 = provider ?? (() => getShopProvider());
39
+ const { connectors } = useConnectors({ hostPluginId: "shop", includeGrants: false });
40
+ const carrier = React3.useMemo(() => resolveShippingLabelProvider({
41
+ connected: (connectors ?? []).filter((c) => c.state === "connected").map((c) => c.slug)
42
+ }), [connectors]);
43
+ const state = String(values?.state ?? "").trim().toUpperCase().slice(0, 2);
44
+ const city = String(values?.city ?? "").trim();
45
+ const [agencies, setAgencies] = useState(null);
46
+ const [loading, setLoading] = useState(false);
47
+ const [error, setError] = useState(null);
48
+ const chosen = value?.[carrier?.id ?? ""] ?? null;
49
+ async function load() {
50
+ if (!carrier) return;
51
+ setLoading(true);
52
+ setError(null);
53
+ try {
54
+ const found = await resolve2().listShippingAgencies?.({ state, city, carrier: carrier.id });
55
+ setAgencies(found ?? []);
56
+ } catch (err) {
57
+ setError(errorMessage(err));
58
+ } finally {
59
+ setLoading(false);
60
+ }
61
+ }
62
+ useEffect(() => {
63
+ if (!carrier || !state || agencies !== null) return;
64
+ void load();
65
+ }, [carrier, state]);
66
+ if (!carrier) return null;
67
+ function pick(agency) {
68
+ const next = { ...value ?? {} };
69
+ if (agency) next[carrier.id] = { id: agency.id, name: agency.name };
70
+ else delete next[carrier.id];
71
+ onChange(next);
72
+ }
73
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
74
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
75
+ /* @__PURE__ */ jsxs("p", { className: "text-xs text-muted-foreground", children: [
76
+ "Onde voc\xEA entrega os pacotes da ",
77
+ carrier.label,
78
+ ". Em branco, usamos a mais perto que aceite o servi\xE7o."
79
+ ] }),
80
+ state && /* @__PURE__ */ jsxs(
81
+ "button",
82
+ {
83
+ type: "button",
84
+ onClick: () => {
85
+ setAgencies(null);
86
+ void load();
87
+ },
88
+ disabled: loading,
89
+ "data-testid": "agency-reload",
90
+ className: "inline-flex items-center gap-1 text-xs text-muted-foreground transition hover:text-foreground",
91
+ children: [
92
+ /* @__PURE__ */ jsx(RefreshCw, { className: `h-3 w-3 ${loading ? "animate-spin" : ""}` }),
93
+ "Atualizar"
94
+ ]
95
+ }
96
+ )
97
+ ] }),
98
+ !state && /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: "Preencha a UF acima para listar as ag\xEAncias perto daqui." }),
99
+ chosen && /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2 rounded-md border bg-muted/30 p-2.5 text-sm", "data-testid": "agency-chosen", children: [
100
+ /* @__PURE__ */ jsx(MapPin, { className: "mt-0.5 h-4 w-4 shrink-0 text-muted-foreground" }),
101
+ /* @__PURE__ */ jsxs("span", { className: "min-w-0 flex-1", children: [
102
+ /* @__PURE__ */ jsx("span", { className: "block truncate font-medium", children: chosen.name ?? chosen.id }),
103
+ /* @__PURE__ */ jsxs("span", { className: "block text-xs text-muted-foreground", children: [
104
+ "Ag\xEAncia #",
105
+ chosen.id
106
+ ] })
107
+ ] }),
108
+ /* @__PURE__ */ jsx(
109
+ "button",
110
+ {
111
+ type: "button",
112
+ onClick: () => pick(null),
113
+ "data-testid": "agency-clear",
114
+ className: "text-xs text-muted-foreground underline-offset-2 hover:underline",
115
+ children: "Usar a mais pr\xF3xima"
116
+ }
117
+ )
118
+ ] }),
119
+ loading && agencies === null && /* @__PURE__ */ jsx("div", { className: "space-y-1.5", children: [0, 1, 2].map((row) => /* @__PURE__ */ jsxs("div", { className: "rounded-md border p-2.5", children: [
120
+ /* @__PURE__ */ jsx(Skeleton, { className: "h-3.5 w-48" }),
121
+ /* @__PURE__ */ jsx(Skeleton, { className: "mt-1.5 h-3 w-64" })
122
+ ] }, row)) }),
123
+ error && /* @__PURE__ */ jsx("p", { className: "rounded-md border border-red-200 bg-red-50 px-2.5 py-1.5 text-xs text-red-800", children: error }),
124
+ !chosen && agencies && agencies.length === 0 && !loading && /* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground", children: [
125
+ "A ",
126
+ carrier.label,
127
+ " n\xE3o listou ag\xEAncias para esta UF. O despacho segue sem escolher uma."
128
+ ] }),
129
+ !chosen && agencies && agencies.length > 0 && /* @__PURE__ */ jsx("ul", { className: "max-h-56 space-y-1.5 overflow-auto", "data-testid": "agency-options", children: agencies.map((agency) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
130
+ "button",
131
+ {
132
+ type: "button",
133
+ onClick: () => pick(agency),
134
+ className: "block w-full rounded-md border p-2.5 text-left text-sm transition hover:bg-muted/50",
135
+ children: [
136
+ /* @__PURE__ */ jsx("span", { className: "block truncate font-medium", children: agency.name }),
137
+ /* @__PURE__ */ jsx("span", { className: "block truncate text-xs text-muted-foreground", children: [agency.address, agency.city && `${agency.city}/${agency.state}`].filter(Boolean).join(" \xB7 ") })
138
+ ]
139
+ }
140
+ ) }, agency.id)) })
141
+ ] });
142
+ }
143
+
144
+ // src/views/eta-label.ts
145
+ function etaLabel(min, max) {
146
+ if (min == null && max == null) return "";
147
+ const from = Math.max(0, min ?? 0);
148
+ const to = Math.max(from, max ?? from);
149
+ if (to <= 0) return "no mesmo dia";
150
+ if (from <= 0) return to === 1 ? "em at\xE9 24h" : `em at\xE9 ${to} dias`;
151
+ if (from === to) return `em ${to} ${to === 1 ? "dia" : "dias"}`;
152
+ return `${from}\u2013${to} dias`;
153
+ }
154
+ var cep = (value) => {
155
+ const digits = String(value ?? "").replace(/\D/g, "").padStart(8, "0");
156
+ return `${digits.slice(0, 5)}-${digits.slice(5)}`;
157
+ };
158
+ function buildShopShippingZoneEntity(currency = "BRL") {
159
+ const money = (value) => value == null ? "\u2014" : new Intl.NumberFormat("pt-BR", { style: "currency", currency }).format(Number(value));
160
+ const fields = [
161
+ {
162
+ key: "name",
163
+ label: "Nome da zona",
164
+ type: "text",
165
+ required: true,
166
+ group: "zone",
167
+ placeholder: "Rio de Janeiro \u2014 capital",
168
+ hint: "Aparece para o cliente na hora de escolher a entrega.",
169
+ searchable: true,
170
+ showInTable: true,
171
+ sortable: true,
172
+ renderCell: (value, row) => row.excluded ? /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
173
+ /* @__PURE__ */ jsx("span", { className: "rounded-full bg-red-100 px-2 py-0.5 text-xs font-medium text-red-800", children: "n\xE3o entrego" }),
174
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground line-through", children: String(value ?? "") })
175
+ ] }) : /* @__PURE__ */ jsx("span", { children: String(value ?? "") })
176
+ },
177
+ {
178
+ // First in the form and not buried at the end: it changes what every field
179
+ // below it means. On an exclusion, price and prazo are ignored.
180
+ key: "excluded",
181
+ label: "N\xE3o entrego nesta faixa",
182
+ type: "boolean",
183
+ group: "zone",
184
+ hint: "Use para recusar uma regi\xE3o que uma zona mais ampla j\xE1 cobre. Vale para qualquer meio de entrega, inclusive transportadora, e o pedido \xE9 recusado no servidor.",
185
+ showInTable: false
186
+ },
187
+ {
188
+ key: "carrier",
189
+ label: "Transportadora",
190
+ type: "text",
191
+ group: "zone",
192
+ placeholder: "Correios, motoboy pr\xF3prio\u2026",
193
+ hint: "Opcional. Mostrado antes do nome da zona quando preenchido.",
194
+ showInTable: true
195
+ },
196
+ {
197
+ key: "postalFrom",
198
+ label: "CEP inicial",
199
+ type: "text",
200
+ required: true,
201
+ group: "zone",
202
+ placeholder: "20000-000",
203
+ hint: "In\xEDcio da faixa. Pode digitar com ou sem tra\xE7o.",
204
+ showInTable: true,
205
+ renderCell: (_v, row) => /* @__PURE__ */ jsxs("span", { className: "whitespace-nowrap font-mono text-xs", children: [
206
+ cep(row.postalFrom),
207
+ " \u2192 ",
208
+ cep(row.postalTo)
209
+ ] })
210
+ },
211
+ {
212
+ key: "postalTo",
213
+ label: "CEP final",
214
+ type: "text",
215
+ required: true,
216
+ group: "zone",
217
+ placeholder: "23799-999",
218
+ hint: "Fim da faixa, inclusive.",
219
+ showInTable: false
220
+ },
221
+ {
222
+ key: "rate",
223
+ label: "Valor do frete",
224
+ type: "number",
225
+ required: true,
226
+ group: "pricing",
227
+ hint: "Cobrado nos pedidos entregues nessa faixa.",
228
+ showInTable: true,
229
+ sortable: true,
230
+ renderCell: (value) => /* @__PURE__ */ jsx("span", { className: "tabular-nums", children: money(value) })
231
+ },
232
+ {
233
+ key: "freeAbove",
234
+ label: "Frete gr\xE1tis acima de",
235
+ type: "number",
236
+ group: "pricing",
237
+ hint: "Deixe vazio para nunca dar frete gr\xE1tis nessa zona. Vale mais que a regra geral da loja.",
238
+ showInTable: true,
239
+ renderCell: (value) => /* @__PURE__ */ jsx("span", { className: "tabular-nums", children: money(value) })
240
+ },
241
+ {
242
+ key: "etaMinDays",
243
+ label: "Prazo m\xEDnimo (dias)",
244
+ type: "number",
245
+ group: "delivery",
246
+ hint: '0 = no mesmo dia. Com m\xE1ximo 1, o cliente l\xEA "em at\xE9 24h".',
247
+ showInTable: false
248
+ },
249
+ {
250
+ key: "etaMaxDays",
251
+ label: "Prazo m\xE1ximo (dias)",
252
+ type: "number",
253
+ group: "delivery",
254
+ hint: "\xC9 o que o cliente v\xEA na p\xE1gina do produto.",
255
+ showInTable: true,
256
+ renderCell: (_v, row) => {
257
+ if (row.excluded) return /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "\u2014" });
258
+ const label = etaLabel(row.etaMinDays, row.etaMaxDays);
259
+ return label ? /* @__PURE__ */ jsx("span", { children: label }) : /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "\u2014" });
260
+ }
261
+ },
262
+ {
263
+ key: "active",
264
+ label: "Ativa",
265
+ type: "boolean",
266
+ group: "delivery",
267
+ hint: "Desativar para de cotar essa faixa sem apagar a configura\xE7\xE3o.",
268
+ showInTable: true,
269
+ renderCell: (value) => /* @__PURE__ */ jsx("span", { className: `rounded-full px-2 py-0.5 text-xs font-medium ${value ? "bg-emerald-100 text-emerald-800" : "bg-gray-100 text-gray-700"}`, children: value ? "Ativa" : "Inativa" })
270
+ },
271
+ {
272
+ key: "sortOrder",
273
+ label: "Ordem",
274
+ type: "number",
275
+ group: "delivery",
276
+ hint: "Desempate quando duas zonas custam o mesmo. Menor aparece primeiro.",
277
+ showInTable: false
278
+ }
279
+ ];
280
+ return {
281
+ name: "Zona de entrega",
282
+ // 'Zonas', não 'Entrega': o plural nomeia o CADASTRO, e ele aparece na
283
+ // migalha, no vazio da lista e na busca. Dizendo "Entrega" a tela lia
284
+ // "← Entrega / Entrega", "Nenhum(a) entrega ainda" e "Buscar entrega...".
285
+ namePlural: "Zonas",
286
+ icon: "Truck",
287
+ displayField: "name",
288
+ fields,
289
+ fieldGroups: [
290
+ {
291
+ id: "zone",
292
+ label: "Faixa de CEP",
293
+ columns: 2,
294
+ description: "Faixas podem se sobrepor: quando duas cobrem o mesmo CEP, o cliente paga a mais barata \u2014 e uma faixa marcada como \xABn\xE3o entrego\xBB vence todas as outras."
295
+ },
296
+ {
297
+ id: "pricing",
298
+ label: "Pre\xE7o",
299
+ columns: 2,
300
+ description: "O frete cobrado \xE9 recalculado no servidor a cada pedido, a partir daqui."
301
+ },
302
+ { id: "delivery", label: "Prazo e status", columns: 2 }
303
+ ],
304
+ facets: [
305
+ { field: "active", allLabel: "Todas" },
306
+ { field: "excluded", allLabel: "Todas" }
307
+ ]
308
+ };
309
+ }
310
+
311
+ // src/data/shared.ts
312
+ var resolve = (p) => typeof p === "function" ? p() : p;
313
+ function applyQuery(rows, query, facetKey) {
314
+ const prop = (row, key) => row[key];
315
+ let data = rows;
316
+ if (facetKey) {
317
+ const wanted = query.filters?.[facetKey];
318
+ if (wanted && wanted !== "all") data = data.filter((row) => prop(row, facetKey) === wanted);
319
+ }
320
+ if (query.sortBy) {
321
+ const dir = query.sortDir === "desc" ? -1 : 1;
322
+ const key = query.sortBy;
323
+ data = [...data].sort((a, b) => {
324
+ const av = prop(a, key);
325
+ const bv = prop(b, key);
326
+ if (typeof av === "number" && typeof bv === "number") return (av - bv) * dir;
327
+ return String(av ?? "").localeCompare(String(bv ?? ""), "pt-BR") * dir;
328
+ });
329
+ }
330
+ const total = data.length;
331
+ const page = query.page ?? 1;
332
+ const size = query.pageSize ?? total;
333
+ return { data: data.slice((page - 1) * size, page * size), total };
334
+ }
335
+
336
+ // src/data/shippingZoneDataProvider.ts
337
+ function createShopShippingZoneDataProvider(provider) {
338
+ const shop = () => {
339
+ const p = resolve(provider);
340
+ if (!p.listShippingZones) {
341
+ throw new Error("Este provider de loja n\xE3o suporta zonas de entrega.");
342
+ }
343
+ return p;
344
+ };
345
+ return {
346
+ async list(query) {
347
+ const rows = await shop().listShippingZones();
348
+ const term = query.search?.trim().toLowerCase();
349
+ const filtered = term ? rows.filter((z) => z.name.toLowerCase().includes(term) || (z.carrier ?? "").toLowerCase().includes(term)) : rows;
350
+ return applyQuery(filtered, query);
351
+ },
352
+ async create(data) {
353
+ return shop().createShippingZone(data);
354
+ },
355
+ async update(id, data) {
356
+ const { id: _id, tenantId: _tenant, ...patch } = data;
357
+ return shop().updateShippingZone(id, patch);
358
+ },
359
+ async remove(id) {
360
+ await shop().deleteShippingZone(id);
361
+ }
362
+ };
363
+ }
364
+
365
+ // src/data/shippingProfileDataProvider.ts
366
+ function gatewayChoiceOf(profile) {
367
+ if (profile.carrierQuotes === void 0) return "inherit";
368
+ return profile.carrierQuotes ? "allow" : "deny";
369
+ }
370
+ function carrierQuotesOf(choice) {
371
+ if (choice === "allow") return true;
372
+ if (choice === "deny") return false;
373
+ return void 0;
374
+ }
375
+ var withGateway = (profile) => ({ ...profile, gateway: gatewayChoiceOf(profile) });
376
+ function createShopShippingProfileDataProvider(provider) {
377
+ const shop = () => {
378
+ const p = resolve(provider);
379
+ if (!p.listShippingProfiles) {
380
+ throw new Error("Este provider de loja n\xE3o suporta perfis de entrega.");
381
+ }
382
+ return p;
383
+ };
384
+ const toInput2 = (data) => {
385
+ const { id: _id, tenantId: _tenant, gateway, ...rest } = data;
386
+ return {
387
+ ...rest,
388
+ // Only when the form rendered the select, so a partial patch cannot reset it.
389
+ ...gateway !== void 0 ? { carrierQuotes: carrierQuotesOf(gateway) } : {}
390
+ };
391
+ };
392
+ return {
393
+ async list(query) {
394
+ const rows = (await shop().listShippingProfiles()).map(withGateway);
395
+ const term = query.search?.trim().toLowerCase();
396
+ const filtered = term ? rows.filter((p) => p.name.toLowerCase().includes(term)) : rows;
397
+ return applyQuery(filtered, query);
398
+ },
399
+ async create(data) {
400
+ const input = toInput2(data);
401
+ return withGateway(await shop().createShippingProfile(input));
402
+ },
403
+ async update(id, data) {
404
+ return withGateway(await shop().updateShippingProfile(id, toInput2(data)));
405
+ },
406
+ async remove(id) {
407
+ await shop().deleteShippingProfile(id);
408
+ }
409
+ };
410
+ }
411
+
412
+ // src/data/stockLocationDataProvider.ts
413
+ function createShopStockLocationDataProvider(provider) {
414
+ const shop = () => {
415
+ const p = resolve(provider);
416
+ if (!p.listStockLocations) {
417
+ throw new Error("Este provider de loja n\xE3o suporta locais de estoque.");
418
+ }
419
+ return p;
420
+ };
421
+ return {
422
+ async list(query) {
423
+ const rows = await shop().listStockLocations();
424
+ const term = query.search?.trim().toLowerCase();
425
+ const filtered = term ? rows.filter((l) => l.name.toLowerCase().includes(term) || (l.city ?? "").toLowerCase().includes(term)) : rows;
426
+ return applyQuery(filtered, query);
427
+ },
428
+ async create(data) {
429
+ return shop().createStockLocation(toInput(data));
430
+ },
431
+ async update(id, data) {
432
+ return shop().updateStockLocation(id, toInput(data));
433
+ },
434
+ async remove(id) {
435
+ await shop().deleteStockLocation(id);
436
+ }
437
+ };
438
+ }
439
+ function toInput(data) {
440
+ const {
441
+ id: _id,
442
+ tenantId: _tenant,
443
+ createdAt: _created,
444
+ updatedAt: _updated,
445
+ ...rest
446
+ } = data;
447
+ return rest;
448
+ }
449
+ function FulfillmentProviderSelect({ value, onChange }) {
450
+ const { connectors } = useConnectors({ hostPluginId: "shop", includeGrants: false });
451
+ const carriers = React3.useMemo(
452
+ () => (connectors ?? []).filter((c) => c.category === "logistics" || c.category === "shipping"),
453
+ [connectors]
454
+ );
455
+ const chosen = carriers.find((c) => c.slug === value) ?? null;
456
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
457
+ /* @__PURE__ */ jsxs(
458
+ "select",
459
+ {
460
+ value: value ?? "",
461
+ onChange: (event) => onChange(event.target.value || null),
462
+ className: "flex h-9 w-full rounded-input border border-input bg-background px-3 py-1.5 text-sm shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
463
+ children: [
464
+ /* @__PURE__ */ jsx("option", { value: "", children: "Segue a decis\xE3o da loja" }),
465
+ /* @__PURE__ */ jsx("option", { value: OWN_FULFILLMENT, children: "Eu mesmo despacho \u2014 carro, motoboy, ag\xEAncia" }),
466
+ carriers.map((connector) => /* @__PURE__ */ jsxs("option", { value: connector.slug, children: [
467
+ connector.name,
468
+ connector.state === "ready" ? " \u2014 ainda n\xE3o conectado" : ""
469
+ ] }, connector.slug))
470
+ ]
471
+ }
472
+ ),
473
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: value === OWN_FULFILLMENT ? "Nenhum gateway \xE9 consultado para o que sai daqui." : chosen ? chosen.state === "ready" ? `Fica registrado. ${chosen.name} s\xF3 cota depois de conectado em Entrega.` : `${chosen.name} cota o frete do que sai daqui.` : "Usa o que estiver escolhido em Entrega \u2192 Quem calcula o frete." })
474
+ ] });
475
+ }
476
+ var SHIPPING_PROFILES_REGISTRY = "shipping-profiles";
477
+ var SHIPPING_ZONES_REGISTRY = "shipping-zones";
478
+ var PACKAGES_REGISTRY = "packages";
479
+ var LOCATIONS_REGISTRY = "locations";
480
+ function packageMeasureLabel(row) {
481
+ const dim = [row.heightCm, row.widthCm, row.lengthCm].map((v) => trim(Number(v) || 0));
482
+ const kg = trim((Number(row.emptyWeightGrams) || 0) / 1e3);
483
+ return `${dim.join(" \xD7 ")} cm, ${kg} kg`;
484
+ }
485
+ function trim(value) {
486
+ return String(Number(value.toFixed(2)));
487
+ }
488
+ var packageEntity = {
489
+ name: "Embalagem",
490
+ namePlural: "Embalagens",
491
+ icon: "Box",
492
+ displayField: "name",
493
+ defaultSort: "name",
494
+ defaultSortDir: "asc",
495
+ fields: [
496
+ {
497
+ key: "name",
498
+ label: "Nome",
499
+ type: "text",
500
+ required: true,
501
+ searchable: true,
502
+ showInTable: true,
503
+ placeholder: "Caixa P",
504
+ // Nome, medidas e o selo do padrão numa célula só: é o cartão do print
505
+ // desenhado com o que a tabela genérica já sabe renderizar, em vez de uma
506
+ // lista especial ao lado da lista que todo o resto do admin usa.
507
+ renderCell: (_v, row) => React3.createElement(
508
+ "div",
509
+ { className: "flex items-center gap-3" },
510
+ React3.createElement("span", {
511
+ className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-md bg-muted text-muted-foreground"
512
+ }, "\u25A2"),
513
+ React3.createElement(
514
+ "div",
515
+ { className: "min-w-0" },
516
+ React3.createElement(
517
+ "p",
518
+ { className: "flex items-center gap-2 truncate font-medium" },
519
+ row.name,
520
+ row.isDefault ? React3.createElement("span", {
521
+ className: "rounded-full bg-primary/10 px-2 py-0.5 text-[10px] font-medium text-primary"
522
+ }, "Padr\xE3o da loja") : null
523
+ ),
524
+ React3.createElement("p", { className: "text-xs text-muted-foreground" }, packageMeasureLabel(row))
525
+ )
526
+ )
527
+ },
528
+ {
529
+ key: "kind",
530
+ label: "Tipo",
531
+ type: "select",
532
+ group: "shape",
533
+ defaultValue: "box",
534
+ showInTable: false,
535
+ // Muda o preço na transportadora, não só o rótulo na tela: envelope e
536
+ // pacote mole têm tabela própria em vários serviços.
537
+ hint: "Envelope e pacote mole t\xEAm tabela de pre\xE7o pr\xF3pria em v\xE1rias transportadoras.",
538
+ options: [
539
+ { label: "Caixa", value: "box" },
540
+ { label: "Envelope", value: "envelope" },
541
+ { label: "Pacote mole", value: "soft" }
542
+ ]
543
+ },
544
+ { key: "heightCm", label: "Altura (cm)", type: "number", group: "shape", required: true, min: 0, placeholder: "4,2" },
545
+ { key: "widthCm", label: "Largura (cm)", type: "number", group: "shape", required: true, min: 0, placeholder: "13,7" },
546
+ { key: "lengthCm", label: "Comprimento (cm)", type: "number", group: "shape", required: true, min: 0, placeholder: "22" },
547
+ {
548
+ key: "emptyWeightGrams",
549
+ label: "Peso vazia (g)",
550
+ type: "number",
551
+ group: "shape",
552
+ min: 0,
553
+ defaultValue: 0,
554
+ // Zero é um valor legítimo e não «não preenchido»: um envelope pesa nada
555
+ // que mude a faixa, e a tela precisa saber dizer isso.
556
+ hint: "Quanto a embalagem pesa vazia. Zero \xE9 uma resposta \u2014 entra na conta do frete."
557
+ },
558
+ {
559
+ key: "isDefault",
560
+ label: "Padr\xE3o da loja",
561
+ type: "boolean",
562
+ group: "policy",
563
+ inlineToggle: true,
564
+ hint: "A caixa em que o pedido cai quando algum item n\xE3o tem medida. S\xF3 uma por loja."
565
+ },
566
+ { key: "active", label: "Ativa", type: "boolean", group: "policy", defaultValue: true, inlineToggle: true }
567
+ ],
568
+ fieldGroups: [
569
+ { id: "shape", label: "Medidas", description: "Medidas internas, em cent\xEDmetros.", columns: 3 },
570
+ { id: "policy", label: "Uso", columns: 2 }
571
+ ],
572
+ data: {
573
+ table: "plg_shop_packages",
574
+ tenantScoped: true
575
+ }
576
+ };
577
+ var packagesRegistry = {
578
+ id: PACKAGES_REGISTRY,
579
+ entity: packageEntity,
580
+ icon: "Box",
581
+ description: "Em que caixas a loja embala. A cota\xE7\xE3o escolhe a menor em que o pedido cabe e soma o peso dela vazia; quando o produto aponta uma embalagem, \xE9 ela que manda. Sem nenhuma cadastrada, o frete sai no piso da transportadora."
582
+ };
583
+ function buildShippingZonesRegistry(provider, currency = "BRL") {
584
+ return {
585
+ id: SHIPPING_ZONES_REGISTRY,
586
+ entity: buildShopShippingZoneEntity(currency),
587
+ icon: "MapPin",
588
+ description: "Faixas de CEP com pre\xE7o, prazo e frete gr\xE1tis pr\xF3prios. Um CEP fora de todas as zonas cai no pre\xE7o base; sem pre\xE7o base e sem zona que o cubra, o checkout diz que n\xE3o entrega ali.",
589
+ dataProvider: createShopShippingZoneDataProvider(provider)
590
+ };
591
+ }
592
+ function buildShippingProfilesRegistry(provider) {
593
+ const entity = {
594
+ name: "Perfil de entrega",
595
+ namePlural: "Perfis de entrega",
596
+ icon: "Layers",
597
+ displayField: "name",
598
+ defaultSort: "name",
599
+ defaultSortDir: "asc",
600
+ fields: [
601
+ {
602
+ key: "name",
603
+ label: "Nome",
604
+ type: "text",
605
+ required: true,
606
+ searchable: true,
607
+ showInTable: true,
608
+ placeholder: "Refrigerados",
609
+ hint: "Como voc\xEA chama esse grupo de produtos. Aparece na ficha do produto.",
610
+ renderCell: (_v, row) => React3.createElement(
611
+ "div",
612
+ { className: "min-w-0" },
613
+ React3.createElement(
614
+ "p",
615
+ { className: "flex items-center gap-2 truncate font-medium" },
616
+ row.name,
617
+ row.isDefault ? React3.createElement("span", {
618
+ className: "rounded-full bg-primary/10 px-2 py-0.5 text-[10px] font-medium text-primary"
619
+ }, "Geral") : null
620
+ ),
621
+ React3.createElement(
622
+ "p",
623
+ { className: "text-xs text-muted-foreground" },
624
+ row.gateway === "deny" ? "S\xF3 pelas suas zonas \u2014 transportadora n\xE3o cota" : row.gateway === "allow" ? "Transportadora pode cotar" : "Segue a decis\xE3o da loja"
625
+ )
626
+ )
627
+ },
628
+ {
629
+ key: "gateway",
630
+ label: "Transportadora",
631
+ type: "select",
632
+ defaultValue: "inherit",
633
+ showInTable: false,
634
+ hint: "Escolha \xABn\xE3o cota\xBB para produtos que s\xF3 saem pela sua pr\xF3pria entrega \u2014 refrigerados, fr\xE1geis, sob encomenda.",
635
+ options: [
636
+ { label: "Segue a decis\xE3o da loja", value: "inherit" },
637
+ { label: "Pode cotar", value: "allow" },
638
+ { label: "N\xE3o cota \u2014 s\xF3 minhas zonas", value: "deny" }
639
+ ]
640
+ },
641
+ {
642
+ key: "isDefault",
643
+ label: "\xC9 o perfil geral",
644
+ type: "boolean",
645
+ inlineToggle: true,
646
+ showInTable: false,
647
+ hint: "O perfil de todo produto que ningu\xE9m moveu. S\xF3 um por loja."
648
+ }
649
+ ],
650
+ data: {
651
+ table: "plg_shop_shipping_profiles",
652
+ tenantScoped: true
653
+ }
654
+ };
655
+ return {
656
+ id: SHIPPING_PROFILES_REGISTRY,
657
+ entity,
658
+ icon: "Layers",
659
+ description: "Grupos de produtos com zonas pr\xF3prias. Um produto sem perfil usa o geral. Um perfil com a transportadora desligada \xE9 como se diz \xABisto s\xF3 sai na minha entrega\xBB.",
660
+ dataProvider: createShopShippingProfileDataProvider(provider)
661
+ };
662
+ }
663
+ function buildStockLocationsRegistry(provider) {
664
+ const entity = {
665
+ name: "Local",
666
+ namePlural: "Locais",
667
+ icon: "Warehouse",
668
+ displayField: "name",
669
+ defaultSort: "name",
670
+ defaultSortDir: "asc",
671
+ fields: [
672
+ {
673
+ key: "name",
674
+ label: "Nome",
675
+ type: "text",
676
+ required: true,
677
+ searchable: true,
678
+ showInTable: true,
679
+ placeholder: "Estoque principal",
680
+ renderCell: (_v, row) => React3.createElement(
681
+ "div",
682
+ { className: "min-w-0" },
683
+ React3.createElement(
684
+ "p",
685
+ { className: "flex items-center gap-2 truncate font-medium" },
686
+ row.name,
687
+ row.isDefault ? React3.createElement("span", {
688
+ className: "rounded-full bg-primary/10 px-2 py-0.5 text-[10px] font-medium text-primary"
689
+ }, "Padr\xE3o") : null,
690
+ row.shipsOnline === false ? React3.createElement("span", {
691
+ className: "rounded-full bg-muted px-2 py-0.5 text-[10px] text-muted-foreground"
692
+ }, "N\xE3o despacha") : null
693
+ ),
694
+ React3.createElement(
695
+ "p",
696
+ { className: "text-xs text-muted-foreground" },
697
+ locationSummary(row)
698
+ )
699
+ )
700
+ },
701
+ {
702
+ key: "kind",
703
+ label: "Tipo",
704
+ type: "select",
705
+ group: "place",
706
+ defaultValue: "store",
707
+ hint: "Em tr\xE2nsito \xE9 estoque em movimento: existe, mas n\xE3o pode ser prometido a um comprador.",
708
+ options: [
709
+ { label: "Loja", value: "store" },
710
+ { label: "Dep\xF3sito", value: "warehouse" },
711
+ { label: "Em tr\xE2nsito", value: "transit" },
712
+ { label: "Virtual", value: "virtual" }
713
+ ]
714
+ },
715
+ {
716
+ key: "postalCode",
717
+ label: "CEP de origem",
718
+ type: "text",
719
+ group: "place",
720
+ required: false,
721
+ placeholder: "20000-000",
722
+ hint: "De onde o pacote sai. \xC9 este CEP que a transportadora usa para calcular o frete."
723
+ },
724
+ { key: "city", label: "Cidade", type: "text", group: "place" },
725
+ { key: "state", label: "UF", type: "text", group: "place" },
726
+ { key: "street", label: "Rua", type: "text", group: "place", span: 2, placeholder: "Rua Tal" },
727
+ // A carrier refuses a label whose sender is a postcode. These are what it
728
+ // asks for on top of one — filled once, printed on every etiqueta.
729
+ { key: "number", label: "N\xFAmero", type: "text", group: "place", placeholder: "123" },
730
+ { key: "district", label: "Bairro", type: "text", group: "place" },
731
+ { key: "complement", label: "Complemento", type: "text", group: "place", placeholder: "sala 4" },
732
+ // Goes printed on the label, and is what the carrier checks.
733
+ { key: "document", label: "CNPJ ou CPF do remetente", type: "text", group: "place" },
734
+ { key: "phone", label: "Telefone", type: "text", group: "place" },
735
+ { key: "email", label: "E-mail", type: "text", group: "place" },
736
+ {
737
+ key: "fulfillmentProvider",
738
+ label: "Quem despacha daqui",
739
+ type: "custom",
740
+ group: "dispatch",
741
+ span: 2,
742
+ showInTable: false,
743
+ renderInput: ({ value, onChange }) => React3.createElement(FulfillmentProviderSelect, {
744
+ value: value ?? null,
745
+ onChange
746
+ })
747
+ },
748
+ {
749
+ key: "carrierAgencies",
750
+ label: "Ag\xEAncia de postagem",
751
+ type: "custom",
752
+ group: "dispatch",
753
+ span: 2,
754
+ showInTable: false,
755
+ renderInput: ({ value, onChange, values }) => React3.createElement(AgencySelect, {
756
+ value,
757
+ onChange,
758
+ values,
759
+ provider: () => typeof provider === "function" ? provider() : provider
760
+ })
761
+ },
762
+ {
763
+ key: "shipsOnline",
764
+ label: "Despacha pedidos da loja",
765
+ type: "boolean",
766
+ group: "dispatch",
767
+ defaultValue: true,
768
+ inlineToggle: true,
769
+ hint: "Desligue para um local que s\xF3 guarda estoque."
770
+ },
771
+ {
772
+ key: "isSellable",
773
+ label: "Estoque vend\xE1vel",
774
+ type: "boolean",
775
+ group: "dispatch",
776
+ defaultValue: true,
777
+ inlineToggle: true,
778
+ hint: "O que est\xE1 aqui pode ser prometido a um comprador."
779
+ },
780
+ {
781
+ key: "isDefault",
782
+ label: "Local padr\xE3o",
783
+ type: "boolean",
784
+ group: "dispatch",
785
+ inlineToggle: true,
786
+ hint: "Onde o estoque cai quando ningu\xE9m escolhe. S\xF3 um por loja."
787
+ },
788
+ {
789
+ key: "status",
790
+ label: "Situa\xE7\xE3o",
791
+ type: "select",
792
+ group: "dispatch",
793
+ defaultValue: "active",
794
+ options: [
795
+ { label: "Ativo", value: "active" },
796
+ { label: "Arquivado", value: "archived" }
797
+ ]
798
+ }
799
+ ],
800
+ fieldGroups: [
801
+ { id: "place", label: "Onde \xE9", columns: 2 },
802
+ { id: "dispatch", label: "O que sai daqui", columns: 2 }
803
+ ],
804
+ data: {
805
+ table: "plg_shop_stock_locations",
806
+ tenantScoped: true
807
+ }
808
+ };
809
+ return {
810
+ id: LOCATIONS_REGISTRY,
811
+ entity,
812
+ icon: "Warehouse",
813
+ description: "De onde os pedidos saem. O CEP daqui \xE9 a origem que a transportadora usa para cotar o frete, e cada local pode ter seu pr\xF3prio despachante \u2014 ou seguir a decis\xE3o da loja.",
814
+ dataProvider: createShopStockLocationDataProvider(provider)
815
+ };
816
+ }
817
+ function locationSummary(row) {
818
+ const where = [row.city, row.state].filter(Boolean).join("/");
819
+ const cep2 = typeof row.postalCode === "string" && row.postalCode.length === 8 ? `${row.postalCode.slice(0, 5)}-${row.postalCode.slice(5)}` : null;
820
+ const who = row.fulfillmentProvider === OWN_FULFILLMENT ? "voc\xEA mesmo despacha" : typeof row.fulfillmentProvider === "string" && row.fulfillmentProvider ? row.fulfillmentProvider : null;
821
+ const parts = [where || null, cep2, who].filter(Boolean);
822
+ return parts.length ? parts.join(" \xB7 ") : "Sem endere\xE7o \u2014 a transportadora n\xE3o consegue cotar";
823
+ }
824
+ function buildShopRegistries(provider, currency = "BRL") {
825
+ return [
826
+ buildStockLocationsRegistry(provider),
827
+ buildShippingProfilesRegistry(provider),
828
+ buildShippingZonesRegistry(provider, currency),
829
+ packagesRegistry
830
+ ];
831
+ }
832
+
833
+ export { LOCATIONS_REGISTRY, PACKAGES_REGISTRY, SHIPPING_PROFILES_REGISTRY, SHIPPING_ZONES_REGISTRY, applyQuery, buildShopRegistries, buildStockLocationsRegistry, errorMessage, locationSummary, packageMeasureLabel, packagesRegistry, resolve };
834
+ //# sourceMappingURL=chunk-EW4XJRA2.js.map
835
+ //# sourceMappingURL=chunk-EW4XJRA2.js.map