@fayz-ai/plugin-shop 0.8.1 → 0.8.4
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 → ShopPage-JP27MZS2.js} +232 -285
- package/dist/ShopPage-JP27MZS2.js.map +1 -0
- package/dist/{ShopPage-JF2SQBKO.cjs → ShopPage-NK6FSPJ5.cjs} +230 -283
- package/dist/ShopPage-NK6FSPJ5.cjs.map +1 -0
- package/dist/index.cjs +253 -25
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +248 -20
- package/dist/index.js.map +1 -1
- package/dist/views/ChannelsPage.d.ts +7 -0
- package/dist/views/ChannelsPage.d.ts.map +1 -0
- package/dist/views/OrderDetailView.d.ts +1 -1
- package/dist/views/OrderDetailView.d.ts.map +1 -1
- package/dist/views/discountEntity.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/ShopPage.tsx +1 -1
- package/src/index.ts +47 -2
- package/src/views/ChannelsPage.tsx +274 -0
- package/src/views/OrderDetailView.tsx +205 -461
- package/src/views/discountEntity.tsx +7 -0
- package/dist/ShopPage-HCLXMN7Q.js.map +0 -1
- package/dist/ShopPage-JF2SQBKO.cjs.map +0 -1
|
@@ -34,49 +34,9 @@ function shopCustomerLookup(provider) {
|
|
|
34
34
|
}
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
|
-
var RECEIVABLE_LABEL = {
|
|
38
|
-
open: "Em aberto",
|
|
39
|
-
partial: "Parcialmente recebido",
|
|
40
|
-
paid: "Recebido",
|
|
41
|
-
overdue: "Vencido",
|
|
42
|
-
cancelled: "Cancelado"
|
|
43
|
-
};
|
|
44
|
-
var RECEIVABLE_TONE = {
|
|
45
|
-
open: "bg-blue-100 text-blue-800",
|
|
46
|
-
partial: "bg-yellow-100 text-yellow-800",
|
|
47
|
-
paid: "bg-emerald-100 text-emerald-800",
|
|
48
|
-
overdue: "bg-red-100 text-red-700",
|
|
49
|
-
cancelled: "bg-gray-100 text-gray-700"
|
|
50
|
-
};
|
|
51
|
-
var SHIPMENT_LABEL = {
|
|
52
|
-
pending: "Aguardando coleta",
|
|
53
|
-
in_transit: "Em tr\xE2nsito",
|
|
54
|
-
delivered: "Entregue",
|
|
55
|
-
failed: "Falhou",
|
|
56
|
-
returned: "Devolvido",
|
|
57
|
-
cancelled: "Cancelado"
|
|
58
|
-
};
|
|
59
37
|
var money = (v, currency2 = "BRL") => new Intl.NumberFormat("pt-BR", { style: "currency", currency: currency2 }).format(Number(v) || 0);
|
|
60
|
-
var dateTime = (iso) => new Intl.DateTimeFormat("pt-BR", {
|
|
61
|
-
|
|
62
|
-
month: "2-digit",
|
|
63
|
-
year: "numeric",
|
|
64
|
-
hour: "2-digit",
|
|
65
|
-
minute: "2-digit"
|
|
66
|
-
}).format(new Date(iso));
|
|
67
|
-
var TONE = {
|
|
68
|
-
paid: "bg-emerald-100 text-emerald-800",
|
|
69
|
-
pending: "bg-yellow-100 text-yellow-800",
|
|
70
|
-
refunded: "bg-orange-100 text-orange-700",
|
|
71
|
-
partially_refunded: "bg-orange-100 text-orange-700",
|
|
72
|
-
voided: "bg-gray-100 text-gray-700",
|
|
73
|
-
fulfilled: "bg-emerald-100 text-emerald-800",
|
|
74
|
-
unfulfilled: "bg-gray-100 text-gray-700",
|
|
75
|
-
partially_fulfilled: "bg-blue-100 text-blue-800",
|
|
76
|
-
open: "bg-blue-100 text-blue-800",
|
|
77
|
-
cancelled: "bg-red-100 text-red-700",
|
|
78
|
-
archived: "bg-gray-100 text-gray-700"
|
|
79
|
-
};
|
|
38
|
+
var dateTime = (iso) => new Intl.DateTimeFormat("pt-BR", { day: "2-digit", month: "2-digit", year: "numeric", hour: "2-digit", minute: "2-digit" }).format(new Date(iso));
|
|
39
|
+
var dateOnly = (iso) => new Date(iso).toLocaleDateString("pt-BR");
|
|
80
40
|
var PAYMENT_LABEL = {
|
|
81
41
|
pix: "Pix",
|
|
82
42
|
credit_card: "Cart\xE3o de cr\xE9dito",
|
|
@@ -98,85 +58,89 @@ var LABEL = {
|
|
|
98
58
|
cancelled: "Cancelado",
|
|
99
59
|
archived: "Arquivado"
|
|
100
60
|
};
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
61
|
+
var RECEIVABLE_LABEL = {
|
|
62
|
+
open: "Em aberto",
|
|
63
|
+
partial: "Parcialmente recebido",
|
|
64
|
+
paid: "Recebido",
|
|
65
|
+
overdue: "Vencido",
|
|
66
|
+
cancelled: "Cancelado"
|
|
67
|
+
};
|
|
68
|
+
var SHIPMENT_LABEL = {
|
|
69
|
+
pending: "Aguardando coleta",
|
|
70
|
+
in_transit: "Em tr\xE2nsito",
|
|
71
|
+
delivered: "Entregue",
|
|
72
|
+
failed: "Falhou",
|
|
73
|
+
returned: "Devolvido",
|
|
74
|
+
cancelled: "Cancelado"
|
|
75
|
+
};
|
|
76
|
+
function toneOf(value) {
|
|
77
|
+
switch (value) {
|
|
78
|
+
case "paid":
|
|
79
|
+
case "fulfilled":
|
|
80
|
+
case "delivered":
|
|
81
|
+
return "success";
|
|
82
|
+
case "pending":
|
|
83
|
+
case "partial":
|
|
84
|
+
case "partially_fulfilled":
|
|
85
|
+
case "open":
|
|
86
|
+
case "in_transit":
|
|
87
|
+
return "warning";
|
|
88
|
+
case "refunded":
|
|
89
|
+
case "partially_refunded":
|
|
90
|
+
case "voided":
|
|
91
|
+
case "cancelled":
|
|
92
|
+
case "overdue":
|
|
93
|
+
case "failed":
|
|
94
|
+
case "returned":
|
|
95
|
+
return "destructive";
|
|
96
|
+
default:
|
|
97
|
+
return "muted";
|
|
98
|
+
}
|
|
110
99
|
}
|
|
111
|
-
function
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
100
|
+
function InlineBadge({ value }) {
|
|
101
|
+
const tone = toneOf(value);
|
|
102
|
+
const cls = {
|
|
103
|
+
success: "bg-emerald-100 text-emerald-800",
|
|
104
|
+
warning: "bg-amber-100 text-amber-800",
|
|
105
|
+
destructive: "bg-red-100 text-red-700",
|
|
106
|
+
info: "bg-sky-100 text-sky-800",
|
|
107
|
+
muted: "bg-muted text-muted-foreground"
|
|
108
|
+
};
|
|
109
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: `inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${cls[tone]}`, children: LABEL[value] ?? value });
|
|
116
110
|
}
|
|
117
111
|
function deliveryFromNotes(notes) {
|
|
118
112
|
if (!notes) return null;
|
|
119
113
|
const match = notes.match(/entrega:\s*(.+)/i);
|
|
120
114
|
return (match?.[1] ?? "").trim() || null;
|
|
121
115
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
]
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", "aria-busy": "true", "aria-live": "polite", children: [
|
|
130
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-4 w-20" }),
|
|
131
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-3", children: [
|
|
132
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-8 w-48" }),
|
|
133
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-5 w-20 rounded-full" }),
|
|
134
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-5 w-24 rounded-full" }),
|
|
135
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-4 w-32" })
|
|
136
|
-
] }),
|
|
137
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid gap-4 lg:grid-cols-3", children: [
|
|
138
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4 lg:col-span-2", children: [
|
|
139
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Card, { children: /* @__PURE__ */ jsxRuntime.jsxs(ui.CardContent, { className: "pt-4", children: [
|
|
140
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-4 w-16" }),
|
|
141
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "mt-1.5 h-3 w-24" }),
|
|
142
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-3 divide-y", children: Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3 py-2", children: [
|
|
143
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-10 w-10 shrink-0 rounded" }),
|
|
144
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1 space-y-1.5", children: [
|
|
145
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-3.5 w-2/5" }),
|
|
146
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-2.5 w-20" })
|
|
147
|
-
] }),
|
|
148
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-3 w-24" }),
|
|
149
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Skeleton, { className: "h-3 w-16" })
|
|
150
|
-
] }, i)) })
|
|
151
|
-
] }) }),
|
|
152
|
-
/* @__PURE__ */ jsxRuntime.jsx(BlockSkeleton, { rows: 6 })
|
|
153
|
-
] }),
|
|
154
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-4", children: [
|
|
155
|
-
/* @__PURE__ */ jsxRuntime.jsx(BlockSkeleton, { rows: 2 }),
|
|
156
|
-
/* @__PURE__ */ jsxRuntime.jsx(BlockSkeleton, { rows: 4 }),
|
|
157
|
-
/* @__PURE__ */ jsxRuntime.jsx(BlockSkeleton, { rows: 3 })
|
|
158
|
-
] })
|
|
159
|
-
] })
|
|
160
|
-
] });
|
|
161
|
-
}
|
|
162
|
-
function OrderDetailView({
|
|
163
|
-
orderId,
|
|
164
|
-
provider,
|
|
165
|
-
onBack
|
|
166
|
-
}) {
|
|
167
|
-
const [order, setOrder] = react.useState(null);
|
|
168
|
-
const [shipments, setShipments] = react.useState([]);
|
|
169
|
-
const [loading, setLoading] = react.useState(true);
|
|
116
|
+
var shopOrderCache = /* @__PURE__ */ new Map();
|
|
117
|
+
var shopShipmentsCache = /* @__PURE__ */ new Map();
|
|
118
|
+
var shopReceivableCache = /* @__PURE__ */ new Map();
|
|
119
|
+
function OrderDetailView({ orderId, provider, onBack }) {
|
|
120
|
+
const [order, setOrder] = react.useState(() => shopOrderCache.get(orderId) ?? null);
|
|
121
|
+
const [shipments, setShipments] = react.useState(() => shopShipmentsCache.get(orderId) ?? []);
|
|
122
|
+
const [loading, setLoading] = react.useState(() => !shopOrderCache.has(orderId));
|
|
170
123
|
const [error, setError] = react.useState(null);
|
|
171
124
|
const [confirming, setConfirming] = react.useState(false);
|
|
172
125
|
const [confirmError, setConfirmError] = react.useState(null);
|
|
173
|
-
const [receivable, setReceivable] = react.useState(null);
|
|
126
|
+
const [receivable, setReceivable] = react.useState(() => shopReceivableCache.get(orderId) ?? null);
|
|
174
127
|
react.useEffect(() => {
|
|
175
128
|
let cancelled = false;
|
|
129
|
+
const cached = shopOrderCache.get(orderId);
|
|
130
|
+
if (cached) {
|
|
131
|
+
setOrder(cached);
|
|
132
|
+
setLoading(false);
|
|
133
|
+
return () => {
|
|
134
|
+
cancelled = true;
|
|
135
|
+
};
|
|
136
|
+
}
|
|
176
137
|
setLoading(true);
|
|
177
138
|
setError(null);
|
|
178
139
|
provider().getOrder(orderId).then((o) => {
|
|
179
|
-
if (!cancelled)
|
|
140
|
+
if (!cancelled) {
|
|
141
|
+
if (o) shopOrderCache.set(orderId, o);
|
|
142
|
+
setOrder(o);
|
|
143
|
+
}
|
|
180
144
|
}).catch((err) => {
|
|
181
145
|
if (!cancelled) setError(err instanceof Error ? err.message : String(err));
|
|
182
146
|
}).finally(() => {
|
|
@@ -190,219 +154,202 @@ function OrderDetailView({
|
|
|
190
154
|
let cancelled = false;
|
|
191
155
|
const db = core.getSupabaseClientOptional();
|
|
192
156
|
if (!db) return;
|
|
193
|
-
|
|
194
|
-
|
|
157
|
+
if (shopShipmentsCache.has(orderId)) return () => {
|
|
158
|
+
cancelled = true;
|
|
159
|
+
};
|
|
160
|
+
db.from("fulfillments").select("*").eq("order_id", orderId).order("created_at", { ascending: false }).then(({ data: data2 }) => {
|
|
161
|
+
if (!cancelled) {
|
|
162
|
+
shopShipmentsCache.set(orderId, data2 ?? []);
|
|
163
|
+
setShipments(data2 ?? []);
|
|
164
|
+
}
|
|
195
165
|
});
|
|
196
166
|
return () => {
|
|
197
167
|
cancelled = true;
|
|
198
168
|
};
|
|
199
169
|
}, [orderId]);
|
|
200
|
-
if (loading) return /* @__PURE__ */ jsxRuntime.jsx(OrderDetailSkeleton, {});
|
|
201
|
-
if (error) {
|
|
202
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-800", children: [
|
|
203
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium", children: "N\xE3o foi poss\xEDvel carregar o pedido." }),
|
|
204
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-red-700", children: error })
|
|
205
|
-
] });
|
|
206
|
-
}
|
|
207
|
-
if (!order) return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-12 text-center text-sm text-muted-foreground", children: "Pedido n\xE3o encontrado." });
|
|
208
|
-
const delivery = deliveryFromNotes(order.notes);
|
|
209
|
-
const addr = order.shippingAddress;
|
|
210
170
|
react.useEffect(() => {
|
|
211
171
|
let cancelled = false;
|
|
212
172
|
const db = core.getSupabaseClientOptional();
|
|
213
173
|
if (!db) return;
|
|
174
|
+
if (shopReceivableCache.has(orderId)) {
|
|
175
|
+
setReceivable(shopReceivableCache.get(orderId) ?? null);
|
|
176
|
+
return () => {
|
|
177
|
+
cancelled = true;
|
|
178
|
+
};
|
|
179
|
+
}
|
|
214
180
|
void (async () => {
|
|
215
181
|
const [balance, bills] = await Promise.all([
|
|
216
182
|
db.from("v_invoice_balances").select("*").eq("invoice_id", orderId).maybeSingle(),
|
|
217
183
|
db.from("plg_financial_movements").select("*").eq("invoice_id", orderId).eq("movement_kind", "bill").order("installment_number", { ascending: true })
|
|
218
184
|
]);
|
|
219
185
|
if (cancelled || !balance?.data) return;
|
|
220
|
-
|
|
186
|
+
const rec = { balance: balance.data, bills: bills?.data ?? [] };
|
|
187
|
+
shopReceivableCache.set(orderId, rec);
|
|
188
|
+
setReceivable(rec);
|
|
221
189
|
})();
|
|
222
190
|
return () => {
|
|
223
191
|
cancelled = true;
|
|
224
192
|
};
|
|
225
193
|
}, [orderId, confirming]);
|
|
194
|
+
if (loading) return /* @__PURE__ */ jsxRuntime.jsx(saas.OrderDetailSkeleton, {});
|
|
195
|
+
if (error) {
|
|
196
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-lg border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-800", children: [
|
|
197
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium", children: "N\xE3o foi poss\xEDvel carregar o pedido." }),
|
|
198
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-red-700", children: error })
|
|
199
|
+
] });
|
|
200
|
+
}
|
|
201
|
+
if (!order) return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-12 text-center text-sm text-muted-foreground", children: "Pedido n\xE3o encontrado." });
|
|
202
|
+
const cur = order.currency;
|
|
203
|
+
const delivery = deliveryFromNotes(order.notes);
|
|
204
|
+
const addr = order.shippingAddress;
|
|
226
205
|
async function registerReceipt() {
|
|
227
206
|
if (!order) return;
|
|
207
|
+
shopReceivableCache.delete(order.id);
|
|
228
208
|
setConfirming(true);
|
|
229
209
|
setConfirmError(null);
|
|
230
210
|
try {
|
|
231
|
-
const
|
|
232
|
-
if (
|
|
233
|
-
|
|
211
|
+
const fresh = await provider().confirmPayment?.(order.id) ?? await provider().getOrder(order.id);
|
|
212
|
+
if (fresh) {
|
|
213
|
+
shopOrderCache.set(order.id, fresh);
|
|
214
|
+
setOrder(fresh);
|
|
215
|
+
}
|
|
234
216
|
} catch (err) {
|
|
235
217
|
setConfirmError(err instanceof Error ? err.message : String(err));
|
|
236
218
|
} finally {
|
|
237
219
|
setConfirming(false);
|
|
238
220
|
}
|
|
239
221
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
222
|
+
const installments = receivable && receivable.bills.length > 1 ? receivable.bills.map((b) => ({
|
|
223
|
+
number: b.installment_number ?? 0,
|
|
224
|
+
amount: `${money(Number(b.paid_amount ?? 0), cur)} / ${money(Number(b.amount), cur)}`,
|
|
225
|
+
status: RECEIVABLE_LABEL[b.status] ?? b.status,
|
|
226
|
+
statusTone: toneOf(b.status),
|
|
227
|
+
dueDate: `vence ${dateOnly(b.due_date)}`
|
|
228
|
+
})) : [];
|
|
229
|
+
const data = {
|
|
230
|
+
title: `Pedido #${order.orderNumber}`,
|
|
231
|
+
subtitle: dateTime(order.createdAt),
|
|
232
|
+
badges: [
|
|
233
|
+
{ label: LABEL[order.financialStatus] ?? order.financialStatus, tone: toneOf(order.financialStatus) },
|
|
234
|
+
{ label: LABEL[order.fulfillmentStatus] ?? order.fulfillmentStatus, tone: toneOf(order.fulfillmentStatus) }
|
|
235
|
+
],
|
|
236
|
+
customer: { name: order.customerName, email: order.customerEmail },
|
|
237
|
+
customerNode: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1 text-sm", children: [
|
|
238
|
+
order.customerId ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
239
|
+
saas.PersonLink,
|
|
240
|
+
{
|
|
241
|
+
personId: order.customerId,
|
|
242
|
+
name: order.customerName ?? order.customerEmail ?? "Cliente",
|
|
243
|
+
lookup: shopCustomerLookup(provider),
|
|
244
|
+
profileHref: `#/customers/${order.customerId}`,
|
|
245
|
+
className: "font-medium"
|
|
246
|
+
}
|
|
247
|
+
) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: "font-medium", children: order.customerName ?? "\u2014" }),
|
|
248
|
+
order.customerEmail && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: order.customerEmail }),
|
|
249
|
+
!order.customerId && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Compra sem cadastro \u2014 n\xE3o h\xE1 ficha de cliente para abrir." })
|
|
254
250
|
] }),
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
251
|
+
items: order.items.map((it) => ({
|
|
252
|
+
id: it.id,
|
|
253
|
+
name: it.name,
|
|
254
|
+
description: it.sku,
|
|
255
|
+
imageUrl: it.imageUrl,
|
|
256
|
+
quantity: it.quantity,
|
|
257
|
+
unitPrice: money(it.unitPrice, cur),
|
|
258
|
+
total: money(it.total, cur)
|
|
259
|
+
})),
|
|
260
|
+
totals: [
|
|
261
|
+
{ label: "Subtotal", value: money(order.subtotal, cur) },
|
|
262
|
+
...order.discountTotal > 0 ? [{ label: `Desconto${order.discountCode ? ` (${order.discountCode})` : ""}`, value: `\u2212 ${money(order.discountTotal, cur)}`, muted: true }] : [],
|
|
263
|
+
{ label: "Entrega", value: money(order.shippingTotal, cur) },
|
|
264
|
+
{ label: "Impostos", value: money(order.taxTotal, cur) },
|
|
265
|
+
{ label: "Total", value: money(order.total, cur), strong: true }
|
|
266
|
+
],
|
|
267
|
+
paymentMethod: order.paymentMethodKind ? PAYMENT_LABEL[order.paymentMethodKind] ?? order.paymentMethodKind : void 0,
|
|
268
|
+
paidAt: order.paidAt ? dateTime(order.paidAt) : void 0,
|
|
269
|
+
receivable: receivable ? {
|
|
270
|
+
referenceNumber: receivable.balance.reference_number ?? void 0,
|
|
271
|
+
statusBadge: { label: RECEIVABLE_LABEL[receivable.balance.status] ?? receivable.balance.status, tone: toneOf(receivable.balance.status) },
|
|
272
|
+
rows: [
|
|
273
|
+
{ label: "Faturado", value: money(receivable.balance.amount, cur) },
|
|
274
|
+
{ label: "Recebido", value: money(receivable.balance.paid, cur) },
|
|
275
|
+
{ label: "Saldo", value: money(receivable.balance.balance, cur), strong: true }
|
|
276
|
+
],
|
|
277
|
+
installments,
|
|
278
|
+
actions: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
279
|
+
receivable.balance.balance > 0 && receivable.balance.status !== "cancelled" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
280
|
+
"button",
|
|
281
|
+
{
|
|
282
|
+
type: "button",
|
|
283
|
+
onClick: registerReceipt,
|
|
284
|
+
disabled: confirming,
|
|
285
|
+
"data-testid": "order-register-receipt",
|
|
286
|
+
className: "rounded-md bg-primary px-3 py-1.5 text-sm font-medium text-primary-foreground transition hover:opacity-90 disabled:opacity-60",
|
|
287
|
+
children: confirming ? "Registrando\u2026" : "Registrar recebimento"
|
|
288
|
+
}
|
|
289
|
+
),
|
|
288
290
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
289
|
-
|
|
291
|
+
"button",
|
|
290
292
|
{
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-mono font-semibold", children: receivable.balance.reference_number ?? "\u2014" }),
|
|
296
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: `inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${RECEIVABLE_TONE[receivable.balance.status] ?? RECEIVABLE_TONE.open}`, children: RECEIVABLE_LABEL[receivable.balance.status] ?? receivable.balance.status })
|
|
297
|
-
] }),
|
|
298
|
-
/* @__PURE__ */ jsxRuntime.jsx(Row, { label: "Faturado", value: money(receivable.balance.amount, order.currency) }),
|
|
299
|
-
/* @__PURE__ */ jsxRuntime.jsx(Row, { label: "Recebido", value: money(receivable.balance.paid, order.currency) }),
|
|
300
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 border-t pt-2", children: /* @__PURE__ */ jsxRuntime.jsx(Row, { label: "Saldo", value: money(receivable.balance.balance, order.currency), strong: true }) }),
|
|
301
|
-
receivable.bills.length > 1 && /* @__PURE__ */ jsxRuntime.jsx("ul", { className: "mt-3 space-y-1 border-t pt-2 text-xs", children: receivable.bills.map((bill) => /* @__PURE__ */ jsxRuntime.jsxs("li", { className: "flex items-baseline justify-between gap-3", children: [
|
|
302
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-muted-foreground", children: [
|
|
303
|
-
"Parcela ",
|
|
304
|
-
bill.installment_number,
|
|
305
|
-
" \xB7 vence ",
|
|
306
|
-
new Date(bill.due_date).toLocaleDateString("pt-BR")
|
|
307
|
-
] }),
|
|
308
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "tabular-nums", children: [
|
|
309
|
-
money(Number(bill.paid_amount ?? 0), order.currency),
|
|
310
|
-
" / ",
|
|
311
|
-
money(Number(bill.amount), order.currency)
|
|
312
|
-
] })
|
|
313
|
-
] }, bill.id)) }),
|
|
314
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-4 flex flex-wrap gap-2", children: [
|
|
315
|
-
receivable.balance.balance > 0 && receivable.balance.status !== "cancelled" && /* @__PURE__ */ jsxRuntime.jsx(
|
|
316
|
-
"button",
|
|
317
|
-
{
|
|
318
|
-
type: "button",
|
|
319
|
-
onClick: registerReceipt,
|
|
320
|
-
disabled: confirming,
|
|
321
|
-
"data-testid": "order-register-receipt",
|
|
322
|
-
className: "rounded-md bg-primary px-3 py-1.5 text-sm font-medium text-primary-foreground transition hover:opacity-90 disabled:opacity-60",
|
|
323
|
-
children: confirming ? "Registrando\u2026" : "Registrar recebimento"
|
|
324
|
-
}
|
|
325
|
-
),
|
|
326
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
327
|
-
"button",
|
|
328
|
-
{
|
|
329
|
-
type: "button",
|
|
330
|
-
onClick: () => saas.adminNavigateTo("/financial"),
|
|
331
|
-
className: "rounded-md border px-3 py-1.5 text-sm font-medium transition hover:bg-muted",
|
|
332
|
-
children: "Abrir no Financeiro"
|
|
333
|
-
}
|
|
334
|
-
)
|
|
335
|
-
] }),
|
|
336
|
-
confirmError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 rounded-md border border-red-200 bg-red-50 px-3 py-2 text-xs text-red-800", children: confirmError })
|
|
337
|
-
] })
|
|
293
|
+
type: "button",
|
|
294
|
+
onClick: () => saas.adminNavigateTo("/financial"),
|
|
295
|
+
className: "rounded-md border px-3 py-1.5 text-sm font-medium transition hover:bg-muted",
|
|
296
|
+
children: "Abrir no Financeiro"
|
|
338
297
|
}
|
|
339
|
-
)
|
|
298
|
+
),
|
|
299
|
+
confirmError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-2 w-full rounded-md border border-red-200 bg-red-50 px-3 py-2 text-xs text-red-800", children: confirmError })
|
|
340
300
|
] }),
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
!order.customerId && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Compra sem cadastro \u2014 n\xE3o h\xE1 ficha de cliente para abrir." })
|
|
355
|
-
] }) }),
|
|
356
|
-
/* @__PURE__ */ jsxRuntime.jsx(Block, { title: "Entrega", hint: "O que a log\xEDstica precisa", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 text-sm", children: [
|
|
357
|
-
addr ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-0.5", children: [
|
|
358
|
-
/* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
|
|
359
|
-
[addr.street, addr.number].filter(Boolean).join(", "),
|
|
360
|
-
addr.complement ? ` \u2014 ${addr.complement}` : ""
|
|
361
|
-
] }),
|
|
362
|
-
addr.district && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: addr.district }),
|
|
363
|
-
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-muted-foreground", children: [
|
|
364
|
-
[addr.city, addr.state].filter((v) => v && v !== "\u2014").join("/"),
|
|
365
|
-
addr.postal_code ? ` \xB7 ${addr.postal_code}` : ""
|
|
366
|
-
] }),
|
|
367
|
-
(addr.recipient || addr.phone) && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: [addr.recipient, addr.phone].filter(Boolean).join(" \xB7 ") })
|
|
368
|
-
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
369
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: delivery ? "" : "text-muted-foreground", children: delivery ?? "Nenhum endere\xE7o registrado neste pedido." }),
|
|
370
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "Pedido anterior ao endere\xE7o estruturado \u2014 s\xF3 existe o texto livre das observa\xE7\xF5es, sem CEP, n\xFAmero ou bairro separ\xE1veis." })
|
|
301
|
+
emptyLabel: "Sem conta a receber para este pedido."
|
|
302
|
+
} : { rows: [], installments: [], emptyLabel: "Sem conta a receber para este pedido." },
|
|
303
|
+
extraSections: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
304
|
+
/* @__PURE__ */ jsxRuntime.jsx(saas.OrderDetailBlock, { title: "Entrega", hint: "O que a log\xEDstica precisa", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2 text-sm", children: [
|
|
305
|
+
addr ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-0.5", children: [
|
|
306
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
|
|
307
|
+
[addr.street, addr.number].filter(Boolean).join(", "),
|
|
308
|
+
addr.complement ? ` \u2014 ${addr.complement}` : ""
|
|
309
|
+
] }),
|
|
310
|
+
addr.district && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-muted-foreground", children: addr.district }),
|
|
311
|
+
/* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-muted-foreground", children: [
|
|
312
|
+
[addr.city, addr.state].filter((v) => v && v !== "\u2014").join("/"),
|
|
313
|
+
addr.postal_code ? ` \xB7 ${addr.postal_code}` : ""
|
|
371
314
|
] }),
|
|
372
|
-
/* @__PURE__ */ jsxRuntime.
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
315
|
+
(addr.recipient || addr.phone) && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: [addr.recipient, addr.phone].filter(Boolean).join(" \xB7 ") })
|
|
316
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsx("p", { className: delivery ? "" : "text-muted-foreground", children: delivery ?? "Nenhum endere\xE7o registrado neste pedido." }),
|
|
317
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-t pt-2", children: [
|
|
318
|
+
/* @__PURE__ */ jsxRuntime.jsx(saas.OrderDetailRow, { label: "Status", value: /* @__PURE__ */ jsxRuntime.jsx(InlineBadge, { value: order.fulfillmentStatus }) }),
|
|
319
|
+
shipments.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: "Nenhum envio registrado." }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2 space-y-2", children: shipments.map((s) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-md border px-2 py-1.5", children: [
|
|
320
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
321
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium", children: [s.carrier, s.service].filter(Boolean).join(" \xB7 ") || "Envio" }),
|
|
322
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] text-muted-foreground", children: SHIPMENT_LABEL[s.status] ?? s.status })
|
|
323
|
+
] }),
|
|
324
|
+
s.tracking_code && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "mt-0.5 font-mono text-xs", children: s.tracking_url ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: s.tracking_url, target: "_blank", rel: "noreferrer", className: "text-primary hover:underline", children: s.tracking_code }) : s.tracking_code }),
|
|
325
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-1 space-y-0.5 text-[11px] text-muted-foreground", children: [
|
|
326
|
+
s.shipped_at && /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
|
|
327
|
+
"Despachado em ",
|
|
328
|
+
dateTime(s.shipped_at)
|
|
378
329
|
] }),
|
|
379
|
-
s.
|
|
380
|
-
|
|
381
|
-
s.
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
s.
|
|
386
|
-
"Previs\xE3o: ",
|
|
387
|
-
dateTime(s.estimated_delivery_at)
|
|
388
|
-
] }),
|
|
389
|
-
s.delivered_at && /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
|
|
390
|
-
"Entregue em ",
|
|
391
|
-
dateTime(s.delivered_at)
|
|
392
|
-
] })
|
|
330
|
+
s.estimated_delivery_at && /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
|
|
331
|
+
"Previs\xE3o: ",
|
|
332
|
+
dateTime(s.estimated_delivery_at)
|
|
333
|
+
] }),
|
|
334
|
+
s.delivered_at && /* @__PURE__ */ jsxRuntime.jsxs("p", { children: [
|
|
335
|
+
"Entregue em ",
|
|
336
|
+
dateTime(s.delivered_at)
|
|
393
337
|
] })
|
|
394
|
-
] }
|
|
395
|
-
] })
|
|
396
|
-
] })
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
] })
|
|
405
|
-
|
|
338
|
+
] })
|
|
339
|
+
] }, s.id)) })
|
|
340
|
+
] })
|
|
341
|
+
] }) }),
|
|
342
|
+
/* @__PURE__ */ jsxRuntime.jsx(saas.OrderDetailBlock, { title: "Hist\xF3rico", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-1 text-sm", children: [
|
|
343
|
+
/* @__PURE__ */ jsxRuntime.jsx(saas.OrderDetailRow, { label: "Criado", value: dateTime(order.createdAt) }),
|
|
344
|
+
/* @__PURE__ */ jsxRuntime.jsx(saas.OrderDetailRow, { label: "Atualizado", value: dateTime(order.updatedAt) }),
|
|
345
|
+
/* @__PURE__ */ jsxRuntime.jsx(saas.OrderDetailRow, { label: "Situa\xE7\xE3o", value: /* @__PURE__ */ jsxRuntime.jsx(InlineBadge, { value: order.status }) })
|
|
346
|
+
] }) }),
|
|
347
|
+
order.notes && /* @__PURE__ */ jsxRuntime.jsx(saas.OrderDetailBlock, { title: "Observa\xE7\xF5es", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "whitespace-pre-wrap text-sm text-muted-foreground", children: order.notes }) })
|
|
348
|
+
] }),
|
|
349
|
+
onBack,
|
|
350
|
+
backLabel: "Pedidos"
|
|
351
|
+
};
|
|
352
|
+
return /* @__PURE__ */ jsxRuntime.jsx(saas.OrderDetailView, { ...data });
|
|
406
353
|
}
|
|
407
354
|
function currency(value, code = "BRL", locale = "pt-BR") {
|
|
408
355
|
return new Intl.NumberFormat(locale, { style: "currency", currency: code }).format(value);
|
|
@@ -557,7 +504,7 @@ function OrdersTab({ provider }) {
|
|
|
557
504
|
personId: id,
|
|
558
505
|
name: label,
|
|
559
506
|
lookup: shopCustomerLookup(() => resolveShopProvider(provider)),
|
|
560
|
-
profileHref: `#/
|
|
507
|
+
profileHref: `#/customers/${id}`
|
|
561
508
|
}
|
|
562
509
|
);
|
|
563
510
|
}
|
|
@@ -741,5 +688,5 @@ var ShopPage = ({ provider, section }) => {
|
|
|
741
688
|
ShopPage.displayName = "ShopPage";
|
|
742
689
|
|
|
743
690
|
exports.ShopPage = ShopPage;
|
|
744
|
-
//# sourceMappingURL=ShopPage-
|
|
745
|
-
//# sourceMappingURL=ShopPage-
|
|
691
|
+
//# sourceMappingURL=ShopPage-NK6FSPJ5.cjs.map
|
|
692
|
+
//# sourceMappingURL=ShopPage-NK6FSPJ5.cjs.map
|