@cimplify/sdk 0.90.0 → 0.92.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.
- package/dist/advanced.d.mts +3 -3
- package/dist/advanced.d.ts +3 -3
- package/dist/advanced.js +20 -20
- package/dist/advanced.mjs +1 -1
- package/dist/{chunk-JVWFIFQ7.js → chunk-3MBMIEWT.js} +4 -4
- package/dist/{chunk-2UDEWILL.mjs → chunk-3XD2FVP4.mjs} +117 -35
- package/dist/{chunk-NGE37REW.mjs → chunk-54H2YYIW.mjs} +2 -2
- package/dist/{chunk-BN4V4ONE.js → chunk-DCRN67NO.js} +158 -73
- package/dist/{chunk-T7Z25EY4.js → chunk-HKN3YG76.js} +84 -0
- package/dist/{chunk-GHFDYM5K.js → chunk-IVJEUGWF.js} +10 -1
- package/dist/{chunk-KJP4U6L3.js → chunk-OAHSF542.js} +12 -0
- package/dist/{chunk-NNGKC3MM.mjs → chunk-PYBFTMHI.mjs} +12 -0
- package/dist/{chunk-OZDDHSIB.mjs → chunk-RRBY35TJ.mjs} +80 -1
- package/dist/{chunk-ZU4ZRYUR.mjs → chunk-T7LDBZZZ.mjs} +10 -1
- package/dist/{client-YiSelM7x.d.mts → client-BQbSKlHS.d.mts} +90 -11
- package/dist/{client-DMttx1xk.d.mts → client-Bw4HtLP1.d.mts} +2 -2
- package/dist/{client-CR1f94wY.d.ts → client-CeW3acve.d.ts} +90 -11
- package/dist/{client-CqpOcbin.d.ts → client-Otzv_rgP.d.ts} +2 -2
- package/dist/{index-DD9z396M.d.mts → index-CmIboQjl.d.mts} +3 -3
- package/dist/{index-CxTVu0HZ.d.ts → index-DgoRwz8l.d.ts} +3 -3
- package/dist/index.d.mts +49 -7
- package/dist/index.d.ts +49 -7
- package/dist/index.js +103 -83
- package/dist/index.mjs +5 -5
- package/dist/mock/cli.mjs +12 -0
- package/dist/mock/library.js +12 -0
- package/dist/mock/library.mjs +12 -0
- package/dist/mock/msw.js +12 -0
- package/dist/mock/msw.mjs +12 -0
- package/dist/{payment-5d8FTA1q.d.mts → payment-BFtLqiG2.d.mts} +1 -1
- package/dist/{payment-BX7ccIKY.d.ts → payment-Cq8FT1B6.d.ts} +1 -1
- package/dist/{price-DtfP_Xfq.d.ts → price-DaFXT-Lr.d.ts} +1 -1
- package/dist/{price-arl_4Rzn.d.mts → price-DleDWk_s.d.mts} +1 -1
- package/dist/{product-DZX4QuKS.d.ts → product-bZ8G5Z8D.d.mts} +38 -0
- package/dist/{product-DZX4QuKS.d.mts → product-bZ8G5Z8D.d.ts} +38 -0
- package/dist/react.d.mts +71 -6
- package/dist/react.d.ts +71 -6
- package/dist/react.js +466 -337
- package/dist/react.mjs +398 -272
- package/dist/{server-BceZMxcK.d.mts → server-D-iK-bNt.d.mts} +1 -1
- package/dist/{server-DoJGSC7L.d.ts → server-DwsY9hlX.d.ts} +1 -1
- package/dist/server.d.mts +4 -4
- package/dist/server.d.ts +4 -4
- package/dist/server.js +7 -7
- package/dist/server.mjs +2 -2
- package/dist/styles.css +1 -1
- package/dist/testing/msw.d.mts +2 -2
- package/dist/testing/msw.d.ts +2 -2
- package/dist/testing/msw.js +2 -2
- package/dist/testing/msw.mjs +1 -1
- package/dist/testing/suite.d.mts +6 -6
- package/dist/testing/suite.d.ts +6 -6
- package/dist/testing/suite.js +23 -23
- package/dist/testing/suite.mjs +4 -4
- package/dist/testing.d.mts +5 -5
- package/dist/testing.d.ts +5 -5
- package/dist/testing.js +79 -79
- package/dist/testing.mjs +5 -5
- package/dist/utils.d.mts +4 -4
- package/dist/utils.d.ts +4 -4
- package/package.json +1 -1
- package/registry/booking-page.json +1 -1
- package/registry/chat-widget.json +1 -1
- package/registry/customer-input-fields.json +1 -1
- package/registry/date-slot-picker.json +1 -1
- package/registry/product-customizer.json +1 -1
- package/registry/rental-service-card.json +1 -1
package/dist/react.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var chunkHKN3YG76_js = require('./chunk-HKN3YG76.js');
|
|
5
5
|
var chunkXREIZ56K_js = require('./chunk-XREIZ56K.js');
|
|
6
|
-
var
|
|
7
|
-
var
|
|
6
|
+
var chunkDCRN67NO_js = require('./chunk-DCRN67NO.js');
|
|
7
|
+
var chunkIVJEUGWF_js = require('./chunk-IVJEUGWF.js');
|
|
8
8
|
var chunkPTPOQVXS_js = require('./chunk-PTPOQVXS.js');
|
|
9
9
|
var chunkAETVRBKI_js = require('./chunk-AETVRBKI.js');
|
|
10
10
|
require('./chunk-OWW5GUSB.js');
|
|
@@ -747,6 +747,7 @@ function mapServerCart(serverCart, fallbackCurrency) {
|
|
|
747
747
|
scheduledStart: item.scheduled_start || void 0,
|
|
748
748
|
scheduledEnd: item.scheduled_end || void 0,
|
|
749
749
|
staffId: item.staff_id || void 0,
|
|
750
|
+
units: item.units || void 0,
|
|
750
751
|
lineType: item.line_type,
|
|
751
752
|
confirmationCode: item.confirmation_code || void 0,
|
|
752
753
|
serviceStatus: item.service_status || void 0,
|
|
@@ -805,7 +806,7 @@ async function syncFromServer(entry) {
|
|
|
805
806
|
return next;
|
|
806
807
|
}
|
|
807
808
|
function emitMutationError(entry, operation, opId, idempotencyKey, error) {
|
|
808
|
-
entry.client.events.emit(
|
|
809
|
+
entry.client.events.emit(chunkDCRN67NO_js.MUTATION_ERROR, {
|
|
809
810
|
service: "cart",
|
|
810
811
|
operation,
|
|
811
812
|
opId,
|
|
@@ -845,6 +846,12 @@ function getOrCreateStore(params) {
|
|
|
845
846
|
syncTail: Promise.resolve(),
|
|
846
847
|
failedOpRemovers: /* @__PURE__ */ new Set()
|
|
847
848
|
};
|
|
849
|
+
client.events.on(chunkDCRN67NO_js.SESSION_CLAIMED, () => {
|
|
850
|
+
if (entry.initialized) void syncFromServer(entry);
|
|
851
|
+
});
|
|
852
|
+
client.events.on(chunkDCRN67NO_js.SESSION_CLEARED, () => {
|
|
853
|
+
if (entry.initialized) void syncFromServer(entry);
|
|
854
|
+
});
|
|
848
855
|
cartStores.set(storeKey, entry);
|
|
849
856
|
return entry;
|
|
850
857
|
}
|
|
@@ -903,7 +910,8 @@ async function performAddItem(entry, product, quantity, options) {
|
|
|
903
910
|
specialInstructions: normalizedOptions.specialInstructions,
|
|
904
911
|
scheduledStart: normalizedOptions.scheduledStart,
|
|
905
912
|
scheduledEnd: normalizedOptions.scheduledEnd,
|
|
906
|
-
staffId: normalizedOptions.staffId
|
|
913
|
+
staffId: normalizedOptions.staffId,
|
|
914
|
+
units: normalizedOptions.units
|
|
907
915
|
});
|
|
908
916
|
const idempotencyKey = `idem_${typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : `${Date.now()}_${Math.random().toString(36).slice(2, 10)}`}`;
|
|
909
917
|
const patch = { kind: "add_item", tempItem, lineKey };
|
|
@@ -925,6 +933,7 @@ async function performAddItem(entry, product, quantity, options) {
|
|
|
925
933
|
scheduled_end: normalizedOptions.scheduledEnd,
|
|
926
934
|
staff_id: normalizedOptions.staffId,
|
|
927
935
|
resource_id: normalizedOptions.resourceId,
|
|
936
|
+
units: normalizedOptions.units,
|
|
928
937
|
customer_inputs: normalizedOptions.customerInputs
|
|
929
938
|
},
|
|
930
939
|
{ idempotencyKey }
|
|
@@ -1136,7 +1145,7 @@ var DEFAULT_COUNTRY = "US";
|
|
|
1136
1145
|
function createDefaultClient() {
|
|
1137
1146
|
const processRef = globalThis.process;
|
|
1138
1147
|
const envPublicKey = processRef?.env?.NEXT_PUBLIC_CIMPLIFY_PUBLIC_KEY || "";
|
|
1139
|
-
return
|
|
1148
|
+
return chunkDCRN67NO_js.createCimplifyClient({ publicKey: envPublicKey });
|
|
1140
1149
|
}
|
|
1141
1150
|
function getStoredLocationId() {
|
|
1142
1151
|
if (typeof window === "undefined" || !window.localStorage) {
|
|
@@ -1289,7 +1298,7 @@ function CimplifyProvider({
|
|
|
1289
1298
|
const apiCredentials = resolvedClient.getCredentialsMode() === "include" ? "use-credentials" : "anonymous";
|
|
1290
1299
|
preconnectOrigin(resolvedClient.getBaseUrl(), apiCredentials);
|
|
1291
1300
|
preconnectOrigin(resolvedClient.getLinkApiUrl(), apiCredentials);
|
|
1292
|
-
preconnectOrigin(
|
|
1301
|
+
preconnectOrigin(chunkHKN3YG76_js.DEFAULT_CDN_BASE_URL);
|
|
1293
1302
|
}
|
|
1294
1303
|
const setCurrentLocation = React14.useCallback(
|
|
1295
1304
|
(location) => {
|
|
@@ -3448,7 +3457,7 @@ function CimplifySignInButton({
|
|
|
3448
3457
|
const onClick = async () => {
|
|
3449
3458
|
if (busy || disabled || !signInOpts.clientId) return;
|
|
3450
3459
|
setBusy(true);
|
|
3451
|
-
await
|
|
3460
|
+
await chunkIVJEUGWF_js.startSignIn({
|
|
3452
3461
|
...signInOpts,
|
|
3453
3462
|
onSuccess: () => {
|
|
3454
3463
|
setBusy(false);
|
|
@@ -5478,14 +5487,24 @@ function useServices(options = {}) {
|
|
|
5478
5487
|
}
|
|
5479
5488
|
|
|
5480
5489
|
// src/react/hooks/use-available-slots.ts
|
|
5490
|
+
function narrowingUnits(units) {
|
|
5491
|
+
return units != null && units > 1 ? units : void 0;
|
|
5492
|
+
}
|
|
5481
5493
|
var slotsQuery = createCachedQuery({
|
|
5482
5494
|
name: "useAvailableSlots",
|
|
5483
|
-
key: (client, options) => cacheKey(
|
|
5495
|
+
key: (client, options) => cacheKey(
|
|
5496
|
+
client.getPublicKey(),
|
|
5497
|
+
options.serviceId,
|
|
5498
|
+
options.date,
|
|
5499
|
+
options.participantCount,
|
|
5500
|
+
narrowingUnits(options.units)
|
|
5501
|
+
),
|
|
5484
5502
|
fetch: async (client, options) => {
|
|
5485
5503
|
const result = await client.scheduling.getAvailableSlots({
|
|
5486
5504
|
service_id: options.serviceId,
|
|
5487
5505
|
date: options.date,
|
|
5488
|
-
participant_count: options.participantCount
|
|
5506
|
+
participant_count: options.participantCount,
|
|
5507
|
+
units: narrowingUnits(options.units)
|
|
5489
5508
|
});
|
|
5490
5509
|
if (!result.ok) throw result.error;
|
|
5491
5510
|
return result.value;
|
|
@@ -5502,6 +5521,9 @@ function useAvailableSlots(serviceId, date, options = {}) {
|
|
|
5502
5521
|
}
|
|
5503
5522
|
|
|
5504
5523
|
// src/react/hooks/use-service-availability.ts
|
|
5524
|
+
function narrowingUnits2(units) {
|
|
5525
|
+
return units != null && units > 1 ? units : void 0;
|
|
5526
|
+
}
|
|
5505
5527
|
var serviceAvailabilityQuery = createCachedQuery({
|
|
5506
5528
|
name: "useServiceAvailability",
|
|
5507
5529
|
key: (client, options) => cacheKey(
|
|
@@ -5509,7 +5531,8 @@ var serviceAvailabilityQuery = createCachedQuery({
|
|
|
5509
5531
|
options.serviceId,
|
|
5510
5532
|
options.startDate,
|
|
5511
5533
|
options.endDate,
|
|
5512
|
-
options.participantCount
|
|
5534
|
+
options.participantCount,
|
|
5535
|
+
narrowingUnits2(options.units)
|
|
5513
5536
|
),
|
|
5514
5537
|
fetch: async (client, options) => {
|
|
5515
5538
|
const result = await client.scheduling.getServiceAvailability({
|
|
@@ -5517,7 +5540,8 @@ var serviceAvailabilityQuery = createCachedQuery({
|
|
|
5517
5540
|
start_date: options.startDate,
|
|
5518
5541
|
end_date: options.endDate,
|
|
5519
5542
|
location_id: options.locationId,
|
|
5520
|
-
participant_count: options.participantCount
|
|
5543
|
+
participant_count: options.participantCount,
|
|
5544
|
+
units: narrowingUnits2(options.units)
|
|
5521
5545
|
});
|
|
5522
5546
|
if (!result.ok) throw result.error;
|
|
5523
5547
|
return result.value.availability;
|
|
@@ -5901,6 +5925,9 @@ function useChat(options = {}) {
|
|
|
5901
5925
|
const [awaitingReply, setAwaitingReply] = React14.useState(false);
|
|
5902
5926
|
const [seenAt, setSeenAt] = React14.useState(null);
|
|
5903
5927
|
const [mayHaveOlder, setMayHaveOlder] = React14.useState(false);
|
|
5928
|
+
const [claimedAs, setClaimedAs] = React14.useState(
|
|
5929
|
+
() => client?.support.claimedCustomerName ?? null
|
|
5930
|
+
);
|
|
5904
5931
|
const pollRef = React14.useRef(null);
|
|
5905
5932
|
const lastActivityRef = React14.useRef(Date.now());
|
|
5906
5933
|
const openedRef = React14.useRef(false);
|
|
@@ -5912,6 +5939,7 @@ function useChat(options = {}) {
|
|
|
5912
5939
|
const aiEnabledRef = React14.useRef(false);
|
|
5913
5940
|
const humanRequestedRef = React14.useRef(false);
|
|
5914
5941
|
const awaitReplyTimerRef = React14.useRef(null);
|
|
5942
|
+
const claimUnsubRef = React14.useRef(null);
|
|
5915
5943
|
messagesRef.current = messages;
|
|
5916
5944
|
clientRef.current = client;
|
|
5917
5945
|
humanRequestedRef.current = humanRequested;
|
|
@@ -5972,6 +6000,17 @@ function useChat(options = {}) {
|
|
|
5972
6000
|
pollRef.current = null;
|
|
5973
6001
|
}
|
|
5974
6002
|
}, []);
|
|
6003
|
+
const resyncConversation = React14.useCallback(async () => {
|
|
6004
|
+
const c = clientRef.current;
|
|
6005
|
+
if (!c || !openedRef.current) return;
|
|
6006
|
+
const result = await c.support.openConversation();
|
|
6007
|
+
if (!result.ok) return;
|
|
6008
|
+
setMessages(result.value.messages);
|
|
6009
|
+
aiEnabledRef.current = result.value.conversation.ai_enabled;
|
|
6010
|
+
setHumanRequested(result.value.conversation.needs_human_review ?? false);
|
|
6011
|
+
setSeenAt(result.value.conversation.team_read_at ?? null);
|
|
6012
|
+
setMayHaveOlder(result.value.messages.length >= 50);
|
|
6013
|
+
}, []);
|
|
5975
6014
|
const connectWebSocket = React14.useCallback(() => {
|
|
5976
6015
|
const c = clientRef.current;
|
|
5977
6016
|
if (!c || typeof WebSocket === "undefined") {
|
|
@@ -6006,6 +6045,8 @@ function useChat(options = {}) {
|
|
|
6006
6045
|
if (latest && (!last || new Date(last.created_at).getTime() < new Date(latest).getTime())) {
|
|
6007
6046
|
fetchNewMessages();
|
|
6008
6047
|
}
|
|
6048
|
+
} else if (envelope.type === "rekey") {
|
|
6049
|
+
void resyncConversation();
|
|
6009
6050
|
}
|
|
6010
6051
|
} catch {
|
|
6011
6052
|
}
|
|
@@ -6025,12 +6066,57 @@ function useChat(options = {}) {
|
|
|
6025
6066
|
ws.onerror = () => {
|
|
6026
6067
|
};
|
|
6027
6068
|
wsRef.current = ws;
|
|
6028
|
-
}, [appendMessages, startPolling, stopPolling, fetchNewMessages]);
|
|
6069
|
+
}, [appendMessages, startPolling, stopPolling, fetchNewMessages, resyncConversation]);
|
|
6070
|
+
const resetConversation = React14.useCallback(() => {
|
|
6071
|
+
stopPolling();
|
|
6072
|
+
if (wsReconnectTimerRef.current) {
|
|
6073
|
+
clearTimeout(wsReconnectTimerRef.current);
|
|
6074
|
+
wsReconnectTimerRef.current = null;
|
|
6075
|
+
}
|
|
6076
|
+
if (wsRef.current) {
|
|
6077
|
+
wsRef.current.onclose = null;
|
|
6078
|
+
wsRef.current.close();
|
|
6079
|
+
wsRef.current = null;
|
|
6080
|
+
}
|
|
6081
|
+
wsReconnectAttemptRef.current = 0;
|
|
6082
|
+
openedRef.current = false;
|
|
6083
|
+
stopAwaitingReply();
|
|
6084
|
+
setMessages([]);
|
|
6085
|
+
setConversationOpened(false);
|
|
6086
|
+
setHumanRequested(false);
|
|
6087
|
+
setSeenAt(null);
|
|
6088
|
+
setMayHaveOlder(false);
|
|
6089
|
+
setError(null);
|
|
6090
|
+
setClaimedAs(null);
|
|
6091
|
+
}, [stopPolling, stopAwaitingReply]);
|
|
6092
|
+
const watchSessionClaims = React14.useCallback(() => {
|
|
6093
|
+
const c = clientRef.current;
|
|
6094
|
+
if (!c || claimUnsubRef.current) return;
|
|
6095
|
+
const unsubClaimed = c.events.on(chunkDCRN67NO_js.SESSION_CLAIMED, (event) => {
|
|
6096
|
+
setClaimedAs(event.customerName || null);
|
|
6097
|
+
if (!openedRef.current) return;
|
|
6098
|
+
connectWebSocket();
|
|
6099
|
+
void resyncConversation();
|
|
6100
|
+
});
|
|
6101
|
+
const unsubCleared = c.events.on(chunkDCRN67NO_js.SESSION_CLEARED, resetConversation);
|
|
6102
|
+
claimUnsubRef.current = () => {
|
|
6103
|
+
unsubClaimed();
|
|
6104
|
+
unsubCleared();
|
|
6105
|
+
};
|
|
6106
|
+
}, [connectWebSocket, resyncConversation, resetConversation]);
|
|
6107
|
+
const signOut = React14.useCallback(async () => {
|
|
6108
|
+
const c = clientRef.current;
|
|
6109
|
+
if (!c) return false;
|
|
6110
|
+
const result = await c.link.logout();
|
|
6111
|
+
return result.ok;
|
|
6112
|
+
}, []);
|
|
6029
6113
|
React14.useEffect(() => {
|
|
6030
6114
|
return () => {
|
|
6031
6115
|
if (pollRef.current) clearInterval(pollRef.current);
|
|
6032
6116
|
if (wsReconnectTimerRef.current) clearTimeout(wsReconnectTimerRef.current);
|
|
6033
6117
|
if (awaitReplyTimerRef.current) clearTimeout(awaitReplyTimerRef.current);
|
|
6118
|
+
claimUnsubRef.current?.();
|
|
6119
|
+
claimUnsubRef.current = null;
|
|
6034
6120
|
if (wsRef.current) {
|
|
6035
6121
|
wsRef.current.onclose = null;
|
|
6036
6122
|
wsRef.current.close();
|
|
@@ -6050,13 +6136,15 @@ function useChat(options = {}) {
|
|
|
6050
6136
|
setHumanRequested(result.value.conversation.needs_human_review ?? false);
|
|
6051
6137
|
setSeenAt(result.value.conversation.team_read_at ?? null);
|
|
6052
6138
|
setMayHaveOlder(result.value.messages.length >= 50);
|
|
6139
|
+
setClaimedAs(client.support.claimedCustomerName);
|
|
6053
6140
|
connectWebSocket();
|
|
6141
|
+
watchSessionClaims();
|
|
6054
6142
|
} else {
|
|
6055
6143
|
openedRef.current = false;
|
|
6056
6144
|
setError(result.error);
|
|
6057
6145
|
}
|
|
6058
6146
|
setIsLoading(false);
|
|
6059
|
-
}, [client, connectWebSocket]);
|
|
6147
|
+
}, [client, connectWebSocket, watchSessionClaims]);
|
|
6060
6148
|
const send = React14.useCallback(
|
|
6061
6149
|
async (content, opts) => {
|
|
6062
6150
|
const attachments = opts?.attachments ?? [];
|
|
@@ -6176,6 +6264,8 @@ function useChat(options = {}) {
|
|
|
6176
6264
|
awaitingReply,
|
|
6177
6265
|
seenAt,
|
|
6178
6266
|
mayHaveOlder,
|
|
6267
|
+
claimedAs,
|
|
6268
|
+
signOut,
|
|
6179
6269
|
send,
|
|
6180
6270
|
startConversation,
|
|
6181
6271
|
react,
|
|
@@ -6255,15 +6345,15 @@ function AuthElement({
|
|
|
6255
6345
|
}, [onReady, onAuthenticated, onError]);
|
|
6256
6346
|
React14.useEffect(() => {
|
|
6257
6347
|
if (!elements || !containerRef.current) return;
|
|
6258
|
-
const element = elements.create(
|
|
6348
|
+
const element = elements.create(chunkIVJEUGWF_js.ELEMENT_TYPES.AUTH, { prefillEmail });
|
|
6259
6349
|
elementRef.current = element;
|
|
6260
|
-
element.on(
|
|
6350
|
+
element.on(chunkIVJEUGWF_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
|
|
6261
6351
|
element.on(
|
|
6262
|
-
|
|
6352
|
+
chunkIVJEUGWF_js.EVENT_TYPES.AUTHENTICATED,
|
|
6263
6353
|
(data) => onAuthenticatedRef.current?.(data)
|
|
6264
6354
|
);
|
|
6265
6355
|
element.on(
|
|
6266
|
-
|
|
6356
|
+
chunkIVJEUGWF_js.EVENT_TYPES.ERROR,
|
|
6267
6357
|
(data) => onErrorRef.current?.(data)
|
|
6268
6358
|
);
|
|
6269
6359
|
element.mount(containerRef.current);
|
|
@@ -6292,15 +6382,15 @@ function AddressElement({
|
|
|
6292
6382
|
}, [onReady, onChange, onError]);
|
|
6293
6383
|
React14.useEffect(() => {
|
|
6294
6384
|
if (!elements || !containerRef.current) return;
|
|
6295
|
-
const element = elements.create(
|
|
6385
|
+
const element = elements.create(chunkIVJEUGWF_js.ELEMENT_TYPES.ADDRESS, { mode });
|
|
6296
6386
|
elementRef.current = element;
|
|
6297
|
-
element.on(
|
|
6387
|
+
element.on(chunkIVJEUGWF_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
|
|
6298
6388
|
element.on(
|
|
6299
|
-
|
|
6389
|
+
chunkIVJEUGWF_js.EVENT_TYPES.CHANGE,
|
|
6300
6390
|
(data) => onChangeRef.current?.(data)
|
|
6301
6391
|
);
|
|
6302
6392
|
element.on(
|
|
6303
|
-
|
|
6393
|
+
chunkIVJEUGWF_js.EVENT_TYPES.ERROR,
|
|
6304
6394
|
(data) => onErrorRef.current?.(data)
|
|
6305
6395
|
);
|
|
6306
6396
|
element.mount(containerRef.current);
|
|
@@ -6330,15 +6420,15 @@ function PaymentElement({
|
|
|
6330
6420
|
}, [onReady, onChange, onError]);
|
|
6331
6421
|
React14.useEffect(() => {
|
|
6332
6422
|
if (!elements || !containerRef.current) return;
|
|
6333
|
-
const element = elements.create(
|
|
6423
|
+
const element = elements.create(chunkIVJEUGWF_js.ELEMENT_TYPES.PAYMENT, { amount, currency });
|
|
6334
6424
|
elementRef.current = element;
|
|
6335
|
-
element.on(
|
|
6425
|
+
element.on(chunkIVJEUGWF_js.EVENT_TYPES.READY, () => onReadyRef.current?.());
|
|
6336
6426
|
element.on(
|
|
6337
|
-
|
|
6427
|
+
chunkIVJEUGWF_js.EVENT_TYPES.CHANGE,
|
|
6338
6428
|
(data) => onChangeRef.current?.(data)
|
|
6339
6429
|
);
|
|
6340
6430
|
element.on(
|
|
6341
|
-
|
|
6431
|
+
chunkIVJEUGWF_js.EVENT_TYPES.ERROR,
|
|
6342
6432
|
(data) => onErrorRef.current?.(data)
|
|
6343
6433
|
);
|
|
6344
6434
|
element.mount(containerRef.current);
|
|
@@ -6629,7 +6719,7 @@ function VariantSelector({
|
|
|
6629
6719
|
{
|
|
6630
6720
|
"data-cimplify-variant-name": true,
|
|
6631
6721
|
className: cn("flex-1 min-w-0 text-sm", classNames?.name),
|
|
6632
|
-
children:
|
|
6722
|
+
children: chunkHKN3YG76_js.getVariantDisplayName(variant, productName)
|
|
6633
6723
|
}
|
|
6634
6724
|
),
|
|
6635
6725
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-variant-pricing": true, className: cn("text-sm text-muted-foreground", classNames?.pricing), children: [
|
|
@@ -7910,6 +8000,177 @@ function VolumePricing({
|
|
|
7910
8000
|
}
|
|
7911
8001
|
);
|
|
7912
8002
|
}
|
|
8003
|
+
function createPlacesSessionToken() {
|
|
8004
|
+
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
8005
|
+
return crypto.randomUUID();
|
|
8006
|
+
}
|
|
8007
|
+
return `places_${Date.now()}_${Math.random().toString(16).slice(2)}`;
|
|
8008
|
+
}
|
|
8009
|
+
var MIN_QUERY_LENGTH = 3;
|
|
8010
|
+
var DEBOUNCE_MS = 300;
|
|
8011
|
+
var BLUR_CLOSE_MS = 120;
|
|
8012
|
+
function AddressAutocomplete({
|
|
8013
|
+
value,
|
|
8014
|
+
onSelect,
|
|
8015
|
+
onDirty,
|
|
8016
|
+
placeholder,
|
|
8017
|
+
required,
|
|
8018
|
+
autoFocus,
|
|
8019
|
+
id,
|
|
8020
|
+
className,
|
|
8021
|
+
classNames
|
|
8022
|
+
}) {
|
|
8023
|
+
const clientContext = useOptionalCimplifyClient();
|
|
8024
|
+
const [inputText, setInputText] = React14__default.default.useState(value?.formatted_address ?? "");
|
|
8025
|
+
const [suggestions, setSuggestions] = React14__default.default.useState([]);
|
|
8026
|
+
const [isOpen, setIsOpen] = React14__default.default.useState(false);
|
|
8027
|
+
const [highlightedIndex, setHighlightedIndex] = React14__default.default.useState(-1);
|
|
8028
|
+
const debounceRef = React14__default.default.useRef(null);
|
|
8029
|
+
const seqRef = React14__default.default.useRef(0);
|
|
8030
|
+
const sessionTokenRef = React14__default.default.useRef(createPlacesSessionToken());
|
|
8031
|
+
const blurTimeoutRef = React14__default.default.useRef(null);
|
|
8032
|
+
React14__default.default.useEffect(() => {
|
|
8033
|
+
return () => {
|
|
8034
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
8035
|
+
if (blurTimeoutRef.current) clearTimeout(blurTimeoutRef.current);
|
|
8036
|
+
seqRef.current += 1;
|
|
8037
|
+
};
|
|
8038
|
+
}, []);
|
|
8039
|
+
const fetchSuggestions = React14__default.default.useCallback(
|
|
8040
|
+
async (query) => {
|
|
8041
|
+
const client = clientContext?.client;
|
|
8042
|
+
if (!client || query.length < MIN_QUERY_LENGTH) {
|
|
8043
|
+
setSuggestions([]);
|
|
8044
|
+
setIsOpen(false);
|
|
8045
|
+
return;
|
|
8046
|
+
}
|
|
8047
|
+
const seq = ++seqRef.current;
|
|
8048
|
+
const result = await client.places.autocomplete(query, sessionTokenRef.current);
|
|
8049
|
+
if (seqRef.current !== seq) return;
|
|
8050
|
+
if (result.ok && result.value.predictions.length > 0) {
|
|
8051
|
+
setSuggestions(result.value.predictions);
|
|
8052
|
+
setHighlightedIndex(0);
|
|
8053
|
+
setIsOpen(true);
|
|
8054
|
+
} else {
|
|
8055
|
+
setSuggestions([]);
|
|
8056
|
+
setIsOpen(false);
|
|
8057
|
+
}
|
|
8058
|
+
},
|
|
8059
|
+
[clientContext]
|
|
8060
|
+
);
|
|
8061
|
+
const handleInputChange = (nextValue) => {
|
|
8062
|
+
setInputText(nextValue);
|
|
8063
|
+
onDirty?.();
|
|
8064
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
8065
|
+
debounceRef.current = setTimeout(() => void fetchSuggestions(nextValue.trim()), DEBOUNCE_MS);
|
|
8066
|
+
};
|
|
8067
|
+
const selectSuggestion = React14__default.default.useCallback(
|
|
8068
|
+
async (suggestion) => {
|
|
8069
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
8070
|
+
if (blurTimeoutRef.current) clearTimeout(blurTimeoutRef.current);
|
|
8071
|
+
const fallback = suggestion.description.split(",")[0]?.trim() || suggestion.description;
|
|
8072
|
+
setInputText(fallback);
|
|
8073
|
+
setSuggestions([]);
|
|
8074
|
+
setIsOpen(false);
|
|
8075
|
+
const client = clientContext?.client;
|
|
8076
|
+
if (!client) return;
|
|
8077
|
+
const result = await client.places.details(suggestion.place_id, sessionTokenRef.current);
|
|
8078
|
+
sessionTokenRef.current = createPlacesSessionToken();
|
|
8079
|
+
if (result.ok) {
|
|
8080
|
+
const d = result.value;
|
|
8081
|
+
const address = {
|
|
8082
|
+
formatted_address: d.formatted_address || fallback,
|
|
8083
|
+
street_address: d.street_address,
|
|
8084
|
+
apartment: d.apartment,
|
|
8085
|
+
city: d.city,
|
|
8086
|
+
region: d.region,
|
|
8087
|
+
postal_code: d.postal_code,
|
|
8088
|
+
country: d.country,
|
|
8089
|
+
latitude: d.latitude,
|
|
8090
|
+
longitude: d.longitude,
|
|
8091
|
+
place_id: d.place_id
|
|
8092
|
+
};
|
|
8093
|
+
setInputText(address.formatted_address);
|
|
8094
|
+
onSelect(address);
|
|
8095
|
+
}
|
|
8096
|
+
},
|
|
8097
|
+
[clientContext, onSelect]
|
|
8098
|
+
);
|
|
8099
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-address-autocomplete": true, className: cn("relative", className, classNames?.root), children: [
|
|
8100
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8101
|
+
"input",
|
|
8102
|
+
{
|
|
8103
|
+
id,
|
|
8104
|
+
type: "text",
|
|
8105
|
+
value: inputText,
|
|
8106
|
+
onChange: (e) => handleInputChange(e.target.value),
|
|
8107
|
+
onFocus: () => {
|
|
8108
|
+
if (suggestions.length > 0) setIsOpen(true);
|
|
8109
|
+
},
|
|
8110
|
+
onBlur: () => {
|
|
8111
|
+
blurTimeoutRef.current = setTimeout(() => setIsOpen(false), BLUR_CLOSE_MS);
|
|
8112
|
+
},
|
|
8113
|
+
onKeyDown: (e) => {
|
|
8114
|
+
if (e.key === "Escape") {
|
|
8115
|
+
setIsOpen(false);
|
|
8116
|
+
return;
|
|
8117
|
+
}
|
|
8118
|
+
if (!isOpen || suggestions.length === 0) return;
|
|
8119
|
+
if (e.key === "ArrowDown") {
|
|
8120
|
+
e.preventDefault();
|
|
8121
|
+
setHighlightedIndex((i) => i < suggestions.length - 1 ? i + 1 : 0);
|
|
8122
|
+
} else if (e.key === "ArrowUp") {
|
|
8123
|
+
e.preventDefault();
|
|
8124
|
+
setHighlightedIndex((i) => i > 0 ? i - 1 : suggestions.length - 1);
|
|
8125
|
+
} else if (e.key === "Enter" && highlightedIndex >= 0) {
|
|
8126
|
+
e.preventDefault();
|
|
8127
|
+
void selectSuggestion(suggestions[highlightedIndex]);
|
|
8128
|
+
}
|
|
8129
|
+
},
|
|
8130
|
+
placeholder: placeholder ?? "Search for an address...",
|
|
8131
|
+
required,
|
|
8132
|
+
autoFocus,
|
|
8133
|
+
autoComplete: "off",
|
|
8134
|
+
"aria-autocomplete": "list",
|
|
8135
|
+
"aria-expanded": isOpen && suggestions.length > 0,
|
|
8136
|
+
"data-cimplify-address-input": true,
|
|
8137
|
+
className: classNames?.input
|
|
8138
|
+
}
|
|
8139
|
+
),
|
|
8140
|
+
isOpen && suggestions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
8141
|
+
"div",
|
|
8142
|
+
{
|
|
8143
|
+
role: "listbox",
|
|
8144
|
+
"data-cimplify-address-list": true,
|
|
8145
|
+
className: cn(
|
|
8146
|
+
"absolute left-0 right-0 top-full z-20 mt-1 overflow-hidden rounded-md border border-border bg-background shadow-lg",
|
|
8147
|
+
classNames?.list
|
|
8148
|
+
),
|
|
8149
|
+
children: suggestions.map((s, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
8150
|
+
"button",
|
|
8151
|
+
{
|
|
8152
|
+
type: "button",
|
|
8153
|
+
role: "option",
|
|
8154
|
+
"aria-selected": i === highlightedIndex,
|
|
8155
|
+
onMouseDown: (e) => {
|
|
8156
|
+
e.preventDefault();
|
|
8157
|
+
void selectSuggestion(s);
|
|
8158
|
+
},
|
|
8159
|
+
"data-cimplify-address-option": true,
|
|
8160
|
+
className: cn(
|
|
8161
|
+
"block w-full px-3 py-2.5 text-left text-sm transition-colors",
|
|
8162
|
+
i === highlightedIndex ? "bg-muted text-foreground" : "text-foreground hover:bg-muted/70",
|
|
8163
|
+
classNames?.option,
|
|
8164
|
+
i === highlightedIndex && classNames?.activeOption
|
|
8165
|
+
),
|
|
8166
|
+
children: s.description
|
|
8167
|
+
},
|
|
8168
|
+
s.place_id
|
|
8169
|
+
))
|
|
8170
|
+
}
|
|
8171
|
+
)
|
|
8172
|
+
] });
|
|
8173
|
+
}
|
|
7913
8174
|
function parseValue(value) {
|
|
7914
8175
|
if (!value) return void 0;
|
|
7915
8176
|
const date = dateFns.parseISO(value);
|
|
@@ -8251,12 +8512,12 @@ function FieldInput({
|
|
|
8251
8512
|
classNames?.input
|
|
8252
8513
|
);
|
|
8253
8514
|
switch (field.field_type) {
|
|
8254
|
-
case
|
|
8255
|
-
case
|
|
8515
|
+
case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Text:
|
|
8516
|
+
case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Url:
|
|
8256
8517
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8257
8518
|
"input",
|
|
8258
8519
|
{
|
|
8259
|
-
type: field.field_type ===
|
|
8520
|
+
type: field.field_type === chunkHKN3YG76_js.INPUT_FIELD_TYPE.Url ? "url" : "text",
|
|
8260
8521
|
value: typeof value === "string" ? value : "",
|
|
8261
8522
|
onChange: (e) => onValueChange(e.target.value),
|
|
8262
8523
|
placeholder: field.placeholder,
|
|
@@ -8265,7 +8526,7 @@ function FieldInput({
|
|
|
8265
8526
|
className: inputClass
|
|
8266
8527
|
}
|
|
8267
8528
|
);
|
|
8268
|
-
case
|
|
8529
|
+
case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Textarea:
|
|
8269
8530
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8270
8531
|
"textarea",
|
|
8271
8532
|
{
|
|
@@ -8278,7 +8539,7 @@ function FieldInput({
|
|
|
8278
8539
|
className: cn(inputClass, "resize-none", classNames?.textarea)
|
|
8279
8540
|
}
|
|
8280
8541
|
);
|
|
8281
|
-
case
|
|
8542
|
+
case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Number:
|
|
8282
8543
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8283
8544
|
"input",
|
|
8284
8545
|
{
|
|
@@ -8292,7 +8553,7 @@ function FieldInput({
|
|
|
8292
8553
|
className: inputClass
|
|
8293
8554
|
}
|
|
8294
8555
|
);
|
|
8295
|
-
case
|
|
8556
|
+
case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Select:
|
|
8296
8557
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8297
8558
|
"select",
|
|
8298
8559
|
{
|
|
@@ -8306,7 +8567,7 @@ function FieldInput({
|
|
|
8306
8567
|
]
|
|
8307
8568
|
}
|
|
8308
8569
|
);
|
|
8309
|
-
case
|
|
8570
|
+
case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Radio:
|
|
8310
8571
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("space-y-2", classNames?.radioGroup), children: (field.options || []).map((opt) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8311
8572
|
"label",
|
|
8312
8573
|
{
|
|
@@ -8331,7 +8592,7 @@ function FieldInput({
|
|
|
8331
8592
|
},
|
|
8332
8593
|
opt
|
|
8333
8594
|
)) });
|
|
8334
|
-
case
|
|
8595
|
+
case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Checkbox:
|
|
8335
8596
|
return /* @__PURE__ */ jsxRuntime.jsxs("label", { className: cn("flex items-center gap-2 text-sm cursor-pointer", classNames?.checkboxLabel), children: [
|
|
8336
8597
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8337
8598
|
"input",
|
|
@@ -8344,7 +8605,7 @@ function FieldInput({
|
|
|
8344
8605
|
),
|
|
8345
8606
|
field.placeholder || field.name
|
|
8346
8607
|
] });
|
|
8347
|
-
case
|
|
8608
|
+
case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Color:
|
|
8348
8609
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8349
8610
|
"input",
|
|
8350
8611
|
{
|
|
@@ -8354,7 +8615,7 @@ function FieldInput({
|
|
|
8354
8615
|
className: cn("w-12 h-10 rounded-md border border-input cursor-pointer", classNames?.colorInput)
|
|
8355
8616
|
}
|
|
8356
8617
|
);
|
|
8357
|
-
case
|
|
8618
|
+
case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Date:
|
|
8358
8619
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8359
8620
|
DatePicker,
|
|
8360
8621
|
{
|
|
@@ -8365,8 +8626,8 @@ function FieldInput({
|
|
|
8365
8626
|
"aria-label": field.name
|
|
8366
8627
|
}
|
|
8367
8628
|
);
|
|
8368
|
-
case
|
|
8369
|
-
case
|
|
8629
|
+
case chunkHKN3YG76_js.INPUT_FIELD_TYPE.File:
|
|
8630
|
+
case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Image:
|
|
8370
8631
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8371
8632
|
FileUploadInput,
|
|
8372
8633
|
{
|
|
@@ -8377,7 +8638,7 @@ function FieldInput({
|
|
|
8377
8638
|
classNames
|
|
8378
8639
|
}
|
|
8379
8640
|
);
|
|
8380
|
-
case
|
|
8641
|
+
case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Email:
|
|
8381
8642
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8382
8643
|
"input",
|
|
8383
8644
|
{
|
|
@@ -8389,7 +8650,7 @@ function FieldInput({
|
|
|
8389
8650
|
className: inputClass
|
|
8390
8651
|
}
|
|
8391
8652
|
);
|
|
8392
|
-
case
|
|
8653
|
+
case chunkHKN3YG76_js.INPUT_FIELD_TYPE.DateTime: {
|
|
8393
8654
|
const stringValue = typeof value === "string" ? value : "";
|
|
8394
8655
|
const [datePart, timePartRaw] = stringValue.includes("T") ? stringValue.split("T", 2) : [stringValue, ""];
|
|
8395
8656
|
const timePart = (timePartRaw ?? "").slice(0, 5);
|
|
@@ -8428,7 +8689,7 @@ function FieldInput({
|
|
|
8428
8689
|
)
|
|
8429
8690
|
] });
|
|
8430
8691
|
}
|
|
8431
|
-
case
|
|
8692
|
+
case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Time:
|
|
8432
8693
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8433
8694
|
TimePicker,
|
|
8434
8695
|
{
|
|
@@ -8439,7 +8700,7 @@ function FieldInput({
|
|
|
8439
8700
|
"aria-label": field.name
|
|
8440
8701
|
}
|
|
8441
8702
|
);
|
|
8442
|
-
case
|
|
8703
|
+
case chunkHKN3YG76_js.INPUT_FIELD_TYPE.MultiSelect:
|
|
8443
8704
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8444
8705
|
MultiSelectInput,
|
|
8445
8706
|
{
|
|
@@ -8449,7 +8710,7 @@ function FieldInput({
|
|
|
8449
8710
|
classNames
|
|
8450
8711
|
}
|
|
8451
8712
|
);
|
|
8452
|
-
case
|
|
8713
|
+
case chunkHKN3YG76_js.INPUT_FIELD_TYPE.DateRange:
|
|
8453
8714
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8454
8715
|
DateRangeInput,
|
|
8455
8716
|
{
|
|
@@ -8459,7 +8720,7 @@ function FieldInput({
|
|
|
8459
8720
|
classNames
|
|
8460
8721
|
}
|
|
8461
8722
|
);
|
|
8462
|
-
case
|
|
8723
|
+
case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Address:
|
|
8463
8724
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8464
8725
|
AddressInput,
|
|
8465
8726
|
{
|
|
@@ -8470,7 +8731,7 @@ function FieldInput({
|
|
|
8470
8731
|
inputClass
|
|
8471
8732
|
}
|
|
8472
8733
|
);
|
|
8473
|
-
case
|
|
8734
|
+
case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Location:
|
|
8474
8735
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8475
8736
|
LocationInput,
|
|
8476
8737
|
{
|
|
@@ -8481,7 +8742,7 @@ function FieldInput({
|
|
|
8481
8742
|
inputClass
|
|
8482
8743
|
}
|
|
8483
8744
|
);
|
|
8484
|
-
case
|
|
8745
|
+
case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Phone:
|
|
8485
8746
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8486
8747
|
PhoneInput,
|
|
8487
8748
|
{
|
|
@@ -8492,7 +8753,7 @@ function FieldInput({
|
|
|
8492
8753
|
inputClass
|
|
8493
8754
|
}
|
|
8494
8755
|
);
|
|
8495
|
-
case
|
|
8756
|
+
case chunkHKN3YG76_js.INPUT_FIELD_TYPE.Signature:
|
|
8496
8757
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8497
8758
|
SignatureInput,
|
|
8498
8759
|
{
|
|
@@ -8525,7 +8786,7 @@ function FileUploadInput({
|
|
|
8525
8786
|
const [isUploading, setIsUploading] = React14__default.default.useState(false);
|
|
8526
8787
|
const fileUrl = typeof value === "string" ? value : void 0;
|
|
8527
8788
|
const acceptedFormats = field.validation?.accepted_formats;
|
|
8528
|
-
const accept = acceptedFormats ? acceptedFormats.map((f) => `.${f}`).join(",") : field.field_type ===
|
|
8789
|
+
const accept = acceptedFormats ? acceptedFormats.map((f) => `.${f}`).join(",") : field.field_type === chunkHKN3YG76_js.INPUT_FIELD_TYPE.Image ? "image/*" : void 0;
|
|
8529
8790
|
const handleFile = async (file) => {
|
|
8530
8791
|
if (!onFileUpload) return;
|
|
8531
8792
|
if (field.validation?.max_size_mb) {
|
|
@@ -8543,7 +8804,7 @@ function FileUploadInput({
|
|
|
8543
8804
|
}
|
|
8544
8805
|
};
|
|
8545
8806
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("space-y-2", classNames?.fileInput), children: fileUrl ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
|
|
8546
|
-
field.field_type ===
|
|
8807
|
+
field.field_type === chunkHKN3YG76_js.INPUT_FIELD_TYPE.Image && /* @__PURE__ */ jsxRuntime.jsx("img", { src: fileUrl, alt: "Uploaded", className: "w-16 h-16 object-cover rounded-md border border-border" }),
|
|
8547
8808
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-foreground truncate", children: fileUrl.split("/").pop() }) }),
|
|
8548
8809
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8549
8810
|
"button",
|
|
@@ -8569,7 +8830,7 @@ function FileUploadInput({
|
|
|
8569
8830
|
}
|
|
8570
8831
|
),
|
|
8571
8832
|
isUploading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Uploading..." }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
8572
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: field.placeholder || `Upload ${field.field_type ===
|
|
8833
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: field.placeholder || `Upload ${field.field_type === chunkHKN3YG76_js.INPUT_FIELD_TYPE.Image ? "image" : "file"}` }),
|
|
8573
8834
|
acceptedFormats && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground/60 mt-1", children: [
|
|
8574
8835
|
acceptedFormats.map((f) => f.toUpperCase()).join(", "),
|
|
8575
8836
|
field.validation?.max_size_mb && ` \xB7 Max ${field.validation.max_size_mb}MB`
|
|
@@ -8670,129 +8931,18 @@ function AddressInput({
|
|
|
8670
8931
|
classNames,
|
|
8671
8932
|
inputClass
|
|
8672
8933
|
}) {
|
|
8673
|
-
const clientContext = useOptionalCimplifyClient();
|
|
8674
8934
|
const addr = value && typeof value === "object" ? value : null;
|
|
8675
|
-
|
|
8676
|
-
const [suggestions, setSuggestions] = React14__default.default.useState([]);
|
|
8677
|
-
const [isOpen, setIsOpen] = React14__default.default.useState(false);
|
|
8678
|
-
const [highlightedIndex, setHighlightedIndex] = React14__default.default.useState(-1);
|
|
8679
|
-
const debounceRef = React14__default.default.useRef(null);
|
|
8680
|
-
const seqRef = React14__default.default.useRef(0);
|
|
8681
|
-
const sessionTokenRef = React14__default.default.useRef(createSessionToken());
|
|
8682
|
-
const blurTimeoutRef = React14__default.default.useRef(null);
|
|
8683
|
-
React14__default.default.useEffect(() => {
|
|
8684
|
-
return () => {
|
|
8685
|
-
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
8686
|
-
if (blurTimeoutRef.current) clearTimeout(blurTimeoutRef.current);
|
|
8687
|
-
seqRef.current += 1;
|
|
8688
|
-
};
|
|
8689
|
-
}, []);
|
|
8690
|
-
const fetchSuggestions = React14__default.default.useCallback(async (query) => {
|
|
8691
|
-
const client = clientContext?.client;
|
|
8692
|
-
if (!client || query.length < 3) {
|
|
8693
|
-
setSuggestions([]);
|
|
8694
|
-
setIsOpen(false);
|
|
8695
|
-
return;
|
|
8696
|
-
}
|
|
8697
|
-
const seq = ++seqRef.current;
|
|
8698
|
-
const result = await client.places.autocomplete(query, sessionTokenRef.current);
|
|
8699
|
-
if (seqRef.current !== seq) return;
|
|
8700
|
-
if (result.ok && result.value.predictions.length > 0) {
|
|
8701
|
-
setSuggestions(result.value.predictions);
|
|
8702
|
-
setHighlightedIndex(0);
|
|
8703
|
-
setIsOpen(true);
|
|
8704
|
-
} else {
|
|
8705
|
-
setSuggestions([]);
|
|
8706
|
-
setIsOpen(false);
|
|
8707
|
-
}
|
|
8708
|
-
}, [clientContext]);
|
|
8709
|
-
const handleInputChange = (nextValue) => {
|
|
8710
|
-
setInputText(nextValue);
|
|
8711
|
-
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
8712
|
-
debounceRef.current = setTimeout(() => void fetchSuggestions(nextValue.trim()), 300);
|
|
8713
|
-
};
|
|
8714
|
-
const selectSuggestion = React14__default.default.useCallback(async (suggestion) => {
|
|
8715
|
-
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
8716
|
-
if (blurTimeoutRef.current) clearTimeout(blurTimeoutRef.current);
|
|
8717
|
-
const fallback = suggestion.description.split(",")[0]?.trim() || suggestion.description;
|
|
8718
|
-
setInputText(fallback);
|
|
8719
|
-
setSuggestions([]);
|
|
8720
|
-
setIsOpen(false);
|
|
8721
|
-
const client = clientContext?.client;
|
|
8722
|
-
if (!client) return;
|
|
8723
|
-
const result = await client.places.details(suggestion.place_id, sessionTokenRef.current);
|
|
8724
|
-
sessionTokenRef.current = createSessionToken();
|
|
8725
|
-
if (result.ok) {
|
|
8726
|
-
const d = result.value;
|
|
8727
|
-
const addressValue = {
|
|
8728
|
-
formatted_address: d.formatted_address || fallback,
|
|
8729
|
-
street_address: d.street_address,
|
|
8730
|
-
apartment: d.apartment,
|
|
8731
|
-
city: d.city,
|
|
8732
|
-
region: d.region,
|
|
8733
|
-
postal_code: d.postal_code,
|
|
8734
|
-
country: d.country,
|
|
8735
|
-
latitude: d.latitude,
|
|
8736
|
-
longitude: d.longitude,
|
|
8737
|
-
place_id: d.place_id
|
|
8738
|
-
};
|
|
8739
|
-
setInputText(addressValue.formatted_address);
|
|
8740
|
-
onValueChange(addressValue);
|
|
8741
|
-
}
|
|
8742
|
-
}, [clientContext, onValueChange]);
|
|
8743
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-2 relative", classNames?.addressInput), children: [
|
|
8935
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("space-y-2", classNames?.addressInput), children: [
|
|
8744
8936
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8745
|
-
|
|
8937
|
+
AddressAutocomplete,
|
|
8746
8938
|
{
|
|
8747
|
-
|
|
8748
|
-
|
|
8749
|
-
onChange: (e) => handleInputChange(e.target.value),
|
|
8750
|
-
onFocus: () => {
|
|
8751
|
-
if (suggestions.length > 0) setIsOpen(true);
|
|
8752
|
-
},
|
|
8753
|
-
onBlur: () => {
|
|
8754
|
-
blurTimeoutRef.current = setTimeout(() => setIsOpen(false), 120);
|
|
8755
|
-
},
|
|
8756
|
-
onKeyDown: (e) => {
|
|
8757
|
-
if (e.key === "Escape") {
|
|
8758
|
-
setIsOpen(false);
|
|
8759
|
-
return;
|
|
8760
|
-
}
|
|
8761
|
-
if (!isOpen || suggestions.length === 0) return;
|
|
8762
|
-
if (e.key === "ArrowDown") {
|
|
8763
|
-
e.preventDefault();
|
|
8764
|
-
setHighlightedIndex((i) => i < suggestions.length - 1 ? i + 1 : 0);
|
|
8765
|
-
} else if (e.key === "ArrowUp") {
|
|
8766
|
-
e.preventDefault();
|
|
8767
|
-
setHighlightedIndex((i) => i > 0 ? i - 1 : suggestions.length - 1);
|
|
8768
|
-
} else if (e.key === "Enter" && highlightedIndex >= 0) {
|
|
8769
|
-
e.preventDefault();
|
|
8770
|
-
void selectSuggestion(suggestions[highlightedIndex]);
|
|
8771
|
-
}
|
|
8772
|
-
},
|
|
8939
|
+
value: addr,
|
|
8940
|
+
onSelect: onValueChange,
|
|
8773
8941
|
placeholder: field.placeholder || "Search for an address...",
|
|
8774
8942
|
required: field.is_required,
|
|
8775
|
-
|
|
8776
|
-
"aria-autocomplete": "list",
|
|
8777
|
-
"aria-expanded": isOpen && suggestions.length > 0,
|
|
8778
|
-
className: inputClass
|
|
8943
|
+
classNames: { input: inputClass }
|
|
8779
8944
|
}
|
|
8780
8945
|
),
|
|
8781
|
-
isOpen && suggestions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { role: "listbox", className: "absolute left-0 right-0 top-full z-20 mt-1 overflow-hidden rounded-md border border-border bg-background shadow-lg", children: suggestions.map((s, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
8782
|
-
"button",
|
|
8783
|
-
{
|
|
8784
|
-
type: "button",
|
|
8785
|
-
role: "option",
|
|
8786
|
-
"aria-selected": i === highlightedIndex,
|
|
8787
|
-
onMouseDown: (e) => {
|
|
8788
|
-
e.preventDefault();
|
|
8789
|
-
void selectSuggestion(s);
|
|
8790
|
-
},
|
|
8791
|
-
className: cn("block w-full px-3 py-2.5 text-left text-sm transition-colors", i === highlightedIndex ? "bg-muted text-foreground" : "text-foreground hover:bg-muted/70"),
|
|
8792
|
-
children: s.description
|
|
8793
|
-
},
|
|
8794
|
-
s.place_id
|
|
8795
|
-
)) }),
|
|
8796
8946
|
addr && /* @__PURE__ */ jsxRuntime.jsx(
|
|
8797
8947
|
"input",
|
|
8798
8948
|
{
|
|
@@ -8812,121 +8962,22 @@ function LocationInput({
|
|
|
8812
8962
|
classNames,
|
|
8813
8963
|
inputClass
|
|
8814
8964
|
}) {
|
|
8815
|
-
const clientContext = useOptionalCimplifyClient();
|
|
8816
8965
|
const loc = value && typeof value === "object" ? value : null;
|
|
8817
|
-
|
|
8818
|
-
const [suggestions, setSuggestions] = React14__default.default.useState([]);
|
|
8819
|
-
const [isOpen, setIsOpen] = React14__default.default.useState(false);
|
|
8820
|
-
const [highlightedIndex, setHighlightedIndex] = React14__default.default.useState(-1);
|
|
8821
|
-
const debounceRef = React14__default.default.useRef(null);
|
|
8822
|
-
const seqRef = React14__default.default.useRef(0);
|
|
8823
|
-
const sessionTokenRef = React14__default.default.useRef(createSessionToken());
|
|
8824
|
-
const blurTimeoutRef = React14__default.default.useRef(null);
|
|
8825
|
-
React14__default.default.useEffect(() => {
|
|
8826
|
-
return () => {
|
|
8827
|
-
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
8828
|
-
if (blurTimeoutRef.current) clearTimeout(blurTimeoutRef.current);
|
|
8829
|
-
seqRef.current += 1;
|
|
8830
|
-
};
|
|
8831
|
-
}, []);
|
|
8832
|
-
const fetchSuggestions = React14__default.default.useCallback(async (query) => {
|
|
8833
|
-
const client = clientContext?.client;
|
|
8834
|
-
if (!client || query.length < 3) {
|
|
8835
|
-
setSuggestions([]);
|
|
8836
|
-
setIsOpen(false);
|
|
8837
|
-
return;
|
|
8838
|
-
}
|
|
8839
|
-
const seq = ++seqRef.current;
|
|
8840
|
-
const result = await client.places.autocomplete(query, sessionTokenRef.current);
|
|
8841
|
-
if (seqRef.current !== seq) return;
|
|
8842
|
-
if (result.ok && result.value.predictions.length > 0) {
|
|
8843
|
-
setSuggestions(result.value.predictions);
|
|
8844
|
-
setHighlightedIndex(0);
|
|
8845
|
-
setIsOpen(true);
|
|
8846
|
-
} else {
|
|
8847
|
-
setSuggestions([]);
|
|
8848
|
-
setIsOpen(false);
|
|
8849
|
-
}
|
|
8850
|
-
}, [clientContext]);
|
|
8851
|
-
const handleInputChange = (nextValue) => {
|
|
8852
|
-
setInputText(nextValue);
|
|
8853
|
-
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
8854
|
-
debounceRef.current = setTimeout(() => void fetchSuggestions(nextValue.trim()), 300);
|
|
8855
|
-
};
|
|
8856
|
-
const selectSuggestion = React14__default.default.useCallback(async (suggestion) => {
|
|
8857
|
-
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
8858
|
-
if (blurTimeoutRef.current) clearTimeout(blurTimeoutRef.current);
|
|
8859
|
-
const label = suggestion.description.split(",")[0]?.trim() || suggestion.description;
|
|
8860
|
-
setInputText(label);
|
|
8861
|
-
setSuggestions([]);
|
|
8862
|
-
setIsOpen(false);
|
|
8863
|
-
const client = clientContext?.client;
|
|
8864
|
-
if (!client) return;
|
|
8865
|
-
const result = await client.places.details(suggestion.place_id, sessionTokenRef.current);
|
|
8866
|
-
sessionTokenRef.current = createSessionToken();
|
|
8867
|
-
if (result.ok) {
|
|
8868
|
-
const d = result.value;
|
|
8869
|
-
onValueChange({
|
|
8870
|
-
latitude: d.latitude,
|
|
8871
|
-
longitude: d.longitude,
|
|
8872
|
-
label: d.formatted_address || label
|
|
8873
|
-
});
|
|
8874
|
-
setInputText(d.formatted_address || label);
|
|
8875
|
-
}
|
|
8876
|
-
}, [clientContext, onValueChange]);
|
|
8877
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("relative", classNames?.locationInput), children: [
|
|
8966
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(classNames?.locationInput), children: [
|
|
8878
8967
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8879
|
-
|
|
8968
|
+
AddressAutocomplete,
|
|
8880
8969
|
{
|
|
8881
|
-
|
|
8882
|
-
|
|
8883
|
-
|
|
8884
|
-
|
|
8885
|
-
|
|
8886
|
-
},
|
|
8887
|
-
onBlur: () => {
|
|
8888
|
-
blurTimeoutRef.current = setTimeout(() => setIsOpen(false), 120);
|
|
8889
|
-
},
|
|
8890
|
-
onKeyDown: (e) => {
|
|
8891
|
-
if (e.key === "Escape") {
|
|
8892
|
-
setIsOpen(false);
|
|
8893
|
-
return;
|
|
8894
|
-
}
|
|
8895
|
-
if (!isOpen || suggestions.length === 0) return;
|
|
8896
|
-
if (e.key === "ArrowDown") {
|
|
8897
|
-
e.preventDefault();
|
|
8898
|
-
setHighlightedIndex((i) => i < suggestions.length - 1 ? i + 1 : 0);
|
|
8899
|
-
} else if (e.key === "ArrowUp") {
|
|
8900
|
-
e.preventDefault();
|
|
8901
|
-
setHighlightedIndex((i) => i > 0 ? i - 1 : suggestions.length - 1);
|
|
8902
|
-
} else if (e.key === "Enter" && highlightedIndex >= 0) {
|
|
8903
|
-
e.preventDefault();
|
|
8904
|
-
void selectSuggestion(suggestions[highlightedIndex]);
|
|
8905
|
-
}
|
|
8906
|
-
},
|
|
8970
|
+
value: loc ? { formatted_address: loc.label ?? "", latitude: loc.latitude, longitude: loc.longitude } : null,
|
|
8971
|
+
onSelect: (address) => onValueChange({
|
|
8972
|
+
latitude: address.latitude,
|
|
8973
|
+
longitude: address.longitude,
|
|
8974
|
+
label: address.formatted_address
|
|
8975
|
+
}),
|
|
8907
8976
|
placeholder: field.placeholder || "Search for a location...",
|
|
8908
8977
|
required: field.is_required,
|
|
8909
|
-
|
|
8910
|
-
"aria-autocomplete": "list",
|
|
8911
|
-
"aria-expanded": isOpen && suggestions.length > 0,
|
|
8912
|
-
className: inputClass
|
|
8978
|
+
classNames: { input: inputClass }
|
|
8913
8979
|
}
|
|
8914
8980
|
),
|
|
8915
|
-
isOpen && suggestions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { role: "listbox", className: "absolute left-0 right-0 top-full z-20 mt-1 overflow-hidden rounded-md border border-border bg-background shadow-lg", children: suggestions.map((s, i) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
8916
|
-
"button",
|
|
8917
|
-
{
|
|
8918
|
-
type: "button",
|
|
8919
|
-
role: "option",
|
|
8920
|
-
"aria-selected": i === highlightedIndex,
|
|
8921
|
-
onMouseDown: (e) => {
|
|
8922
|
-
e.preventDefault();
|
|
8923
|
-
void selectSuggestion(s);
|
|
8924
|
-
},
|
|
8925
|
-
className: cn("block w-full px-3 py-2.5 text-left text-sm transition-colors", i === highlightedIndex ? "bg-muted text-foreground" : "text-foreground hover:bg-muted/70"),
|
|
8926
|
-
children: s.description
|
|
8927
|
-
},
|
|
8928
|
-
s.place_id
|
|
8929
|
-
)) }),
|
|
8930
8981
|
loc && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-muted-foreground mt-1", children: [
|
|
8931
8982
|
loc.latitude.toFixed(4),
|
|
8932
8983
|
", ",
|
|
@@ -9057,12 +9108,6 @@ function SignatureInput({
|
|
|
9057
9108
|
!sig?.data_url && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: field.placeholder || "Draw your signature above" })
|
|
9058
9109
|
] });
|
|
9059
9110
|
}
|
|
9060
|
-
function createSessionToken() {
|
|
9061
|
-
if (typeof crypto !== "undefined" && crypto.randomUUID) {
|
|
9062
|
-
return crypto.randomUUID();
|
|
9063
|
-
}
|
|
9064
|
-
return `places_${Date.now()}_${Math.random().toString(16).slice(2)}`;
|
|
9065
|
-
}
|
|
9066
9111
|
function getTimeOfDay(timeStr) {
|
|
9067
9112
|
const hour = parseInt(timeStr.split("T").pop()?.split(":")[0] ?? timeStr.split(":")[0], 10);
|
|
9068
9113
|
if (hour < 12) return "morning";
|
|
@@ -9308,6 +9353,7 @@ function DateSlotPicker({
|
|
|
9308
9353
|
serviceId,
|
|
9309
9354
|
daysToShow = 7,
|
|
9310
9355
|
participantCount,
|
|
9356
|
+
units,
|
|
9311
9357
|
selectedSlot,
|
|
9312
9358
|
onSlotSelect,
|
|
9313
9359
|
availability: availabilityProp,
|
|
@@ -9342,6 +9388,7 @@ function DateSlotPicker({
|
|
|
9342
9388
|
dateRange.endDate,
|
|
9343
9389
|
{
|
|
9344
9390
|
participantCount,
|
|
9391
|
+
units,
|
|
9345
9392
|
enabled: availabilityProp === void 0
|
|
9346
9393
|
}
|
|
9347
9394
|
);
|
|
@@ -9499,6 +9546,7 @@ function ProductCustomizer({
|
|
|
9499
9546
|
const [specialInstructions, setSpecialInstructions] = React14.useState("");
|
|
9500
9547
|
const [selectedSlot, setSelectedSlot] = React14.useState(null);
|
|
9501
9548
|
const [selectedStaffId, setSelectedStaffId] = React14.useState(null);
|
|
9549
|
+
const [unitsCount, setUnitsCount] = React14.useState(1);
|
|
9502
9550
|
const cart = useCart();
|
|
9503
9551
|
const currency = chunkPTPOQVXS_js.getProductCurrency(product);
|
|
9504
9552
|
const productType = product.type || "product";
|
|
@@ -9506,6 +9554,7 @@ function ProductCustomizer({
|
|
|
9506
9554
|
const isBundle = productType === "bundle";
|
|
9507
9555
|
const isDigital = productType === "digital";
|
|
9508
9556
|
const isService = productType === "service";
|
|
9557
|
+
const offersUnits = isService && chunkHKN3YG76_js.isMultiDayService(product);
|
|
9509
9558
|
const isStandard = !isComposite && !isBundle;
|
|
9510
9559
|
const hasVariants = isStandard && product.variants && product.variants.length > 0;
|
|
9511
9560
|
const hasAddOns = isStandard && product.add_ons && product.add_ons.length > 0;
|
|
@@ -9527,6 +9576,7 @@ function ProductCustomizer({
|
|
|
9527
9576
|
setSpecialInstructions("");
|
|
9528
9577
|
setSelectedSlot(null);
|
|
9529
9578
|
setSelectedStaffId(null);
|
|
9579
|
+
setUnitsCount(1);
|
|
9530
9580
|
}, [product.id, product.min_order_quantity]);
|
|
9531
9581
|
const slotStaff = React14.useMemo(
|
|
9532
9582
|
() => (selectedSlot?.available_staff ?? []).map((member) => ({
|
|
@@ -9616,7 +9666,17 @@ function ProductCustomizer({
|
|
|
9616
9666
|
if (perUnit === void 0 || perUnit === null) return void 0;
|
|
9617
9667
|
return chunkPTPOQVXS_js.parsePrice(perUnit) * quantity;
|
|
9618
9668
|
}, [quote, quantity]);
|
|
9619
|
-
const displayTotalPrice =
|
|
9669
|
+
const displayTotalPrice = React14.useMemo(() => {
|
|
9670
|
+
const total = quotedTotalPrice ?? localTotalPrice;
|
|
9671
|
+
const multiplier = chunkHKN3YG76_js.serviceBillingMultiplier(product, {
|
|
9672
|
+
quantity,
|
|
9673
|
+
units: unitsCount,
|
|
9674
|
+
scheduledStart: selectedSlot?.start_time,
|
|
9675
|
+
scheduledEnd: selectedSlot?.end_time
|
|
9676
|
+
});
|
|
9677
|
+
if (multiplier === null) return total;
|
|
9678
|
+
return total / Math.max(1, quantity) * multiplier;
|
|
9679
|
+
}, [quotedTotalPrice, localTotalPrice, product, quantity, unitsCount, selectedSlot]);
|
|
9620
9680
|
const handleVariantChange = React14.useCallback(
|
|
9621
9681
|
(variantId, variant) => {
|
|
9622
9682
|
setSelectedVariantId(variantId);
|
|
@@ -9648,7 +9708,8 @@ function ProductCustomizer({
|
|
|
9648
9708
|
scheduledStart: selectedSlot.start_time,
|
|
9649
9709
|
scheduledEnd: selectedSlot.end_time,
|
|
9650
9710
|
staffId: selectedStaffId ?? selectedSlot.available_staff?.[0]?.staff_id,
|
|
9651
|
-
resourceId: selectedSlot.available_resources?.[0]?.resource_id
|
|
9711
|
+
resourceId: selectedSlot.available_resources?.[0]?.resource_id,
|
|
9712
|
+
units: unitsCount > 1 ? unitsCount : void 0
|
|
9652
9713
|
} : {},
|
|
9653
9714
|
customerInputs: Object.keys(customerInputValues).length > 0 ? Object.entries(customerInputValues).filter(([, v]) => v !== void 0 && v !== "").map(([fieldId, value]) => ({ field_id: fieldId, value })) : void 0,
|
|
9654
9715
|
specialInstructions: specialInstructions.trim() || void 0
|
|
@@ -9669,7 +9730,7 @@ function ProductCustomizer({
|
|
|
9669
9730
|
} finally {
|
|
9670
9731
|
setIsSubmitting(false);
|
|
9671
9732
|
}
|
|
9672
|
-
}, [product, quantity, selectedVariantId, selectedVariant, quoteId, normalizedAddOnOptionIds, selectedAddOnOptions, isComposite, compositeSelections, isBundle, bundleSelections, selectedBillingPlan, customerInputValues, specialInstructions, isService, selectedSlot, selectedStaffId, isSubmitting, onAddToCart, cart]);
|
|
9733
|
+
}, [product, quantity, selectedVariantId, selectedVariant, quoteId, normalizedAddOnOptionIds, selectedAddOnOptions, isComposite, compositeSelections, isBundle, bundleSelections, selectedBillingPlan, customerInputValues, specialInstructions, isService, selectedSlot, selectedStaffId, unitsCount, isSubmitting, onAddToCart, cart]);
|
|
9673
9734
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-customizer": true, className: cn("space-y-6", className, classNames?.root), children: [
|
|
9674
9735
|
isComposite && product.groups && product.composite_id && /* @__PURE__ */ jsxRuntime.jsx(
|
|
9675
9736
|
CompositeSelector,
|
|
@@ -9706,9 +9767,17 @@ function ProductCustomizer({
|
|
|
9706
9767
|
setSelectedStaffId(null);
|
|
9707
9768
|
},
|
|
9708
9769
|
participantCount: quantity,
|
|
9709
|
-
|
|
9770
|
+
units: offersUnits ? unitsCount : void 0,
|
|
9771
|
+
currency,
|
|
9772
|
+
schedulingMode: product.scheduling_mode ?? (offersUnits ? "multi_day" : "intraday"),
|
|
9773
|
+
durationUnit: product.duration_unit,
|
|
9774
|
+
durationValue: product.duration_value
|
|
9710
9775
|
}
|
|
9711
9776
|
),
|
|
9777
|
+
offersUnits && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-customizer-units": true, className: classNames?.units, children: [
|
|
9778
|
+
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-xs font-medium uppercase tracking-wider text-muted-foreground mb-3", children: "Units" }),
|
|
9779
|
+
/* @__PURE__ */ jsxRuntime.jsx(QuantitySelector, { value: unitsCount, onChange: setUnitsCount, min: 1 })
|
|
9780
|
+
] }),
|
|
9712
9781
|
isService && slotStaff.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-customizer-staff": true, children: [
|
|
9713
9782
|
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-xs font-medium uppercase tracking-wider text-muted-foreground mb-3", children: "Choose your specialist" }),
|
|
9714
9783
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -10313,7 +10382,7 @@ function CartLineItemRow({
|
|
|
10313
10382
|
const isOptimistic = item.isOptimistic === true;
|
|
10314
10383
|
const lineTotal = chunkPTPOQVXS_js.parsePrice(unitPrice) * item.quantity;
|
|
10315
10384
|
const imageUrl = item.product.image_url;
|
|
10316
|
-
const variantLabel2 = item.variant ?
|
|
10385
|
+
const variantLabel2 = item.variant ? chunkHKN3YG76_js.getVariantDisplayName(item.variant, item.product.name) : null;
|
|
10317
10386
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
10318
10387
|
"div",
|
|
10319
10388
|
{
|
|
@@ -10413,7 +10482,7 @@ function CartLineItemRow({
|
|
|
10413
10482
|
input.field_name,
|
|
10414
10483
|
":"
|
|
10415
10484
|
] }),
|
|
10416
|
-
/* @__PURE__ */ jsxRuntime.jsx("dd", { "data-cimplify-cart-input-value": true, className: "text-foreground m-0 truncate", children: input.field_type ===
|
|
10485
|
+
/* @__PURE__ */ jsxRuntime.jsx("dd", { "data-cimplify-cart-input-value": true, className: "text-foreground m-0 truncate", children: input.field_type === chunkHKN3YG76_js.INPUT_FIELD_TYPE.File || input.field_type === chunkHKN3YG76_js.INPUT_FIELD_TYPE.Image ? String(input.value).split("/").pop() || "Uploaded file" : String(input.value) })
|
|
10417
10486
|
] }, input.field_id)) }),
|
|
10418
10487
|
(item.lineType === "service" || item.product.type === "service") && item.scheduledStart && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-cart-service-info": true, className: cn("mt-1.5 flex items-center gap-1.5 text-xs text-muted-foreground", classNames?.serviceInfo), children: [
|
|
10419
10488
|
/* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-3.5 h-3.5 shrink-0", fill: "none", stroke: "currentColor", strokeWidth: "2", viewBox: "0 0 24 24", "aria-hidden": true, children: /* @__PURE__ */ jsxRuntime.jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", d: "M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
|
|
@@ -11298,7 +11367,7 @@ function FoodProductCard({
|
|
|
11298
11367
|
const tags = product.tags || [];
|
|
11299
11368
|
const isSignature = product.metadata?.is_signature === true;
|
|
11300
11369
|
const isNew = product.metadata?.is_new === true;
|
|
11301
|
-
const isComposite = product.type ===
|
|
11370
|
+
const isComposite = product.type === chunkHKN3YG76_js.PRODUCT_TYPE.Composite;
|
|
11302
11371
|
return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, className, children: [
|
|
11303
11372
|
/* @__PURE__ */ jsxRuntime.jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "square", renderImage, children: [
|
|
11304
11373
|
isSignature && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute top-3 left-3 inline-flex items-center gap-1 text-[11px] font-semibold tracking-wide bg-amber-50 text-amber-700 border border-amber-200/60 px-2 py-0.5 rounded-md", children: [
|
|
@@ -11762,18 +11831,18 @@ function RentalServiceCard({
|
|
|
11762
11831
|
const currency = chunkPTPOQVXS_js.getProductCurrency(product);
|
|
11763
11832
|
const hasDeposit = product.deposit_type && product.deposit_type !== "none" && product.deposit_amount;
|
|
11764
11833
|
const unit = product.duration_unit ? UNIT_LABELS2[product.duration_unit] || product.duration_unit : "day";
|
|
11834
|
+
const priceUnit = product.price_basis === "per_person" ? "guest" : product.price_basis === "flat" ? "" : unit;
|
|
11765
11835
|
const status = product.inventory_status;
|
|
11766
11836
|
return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, className, children: [
|
|
11767
11837
|
/* @__PURE__ */ jsxRuntime.jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "16/9", renderImage, children: [
|
|
11768
11838
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/50 to-transparent pointer-events-none" }),
|
|
11769
|
-
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute bottom-3 left-3 inline-flex items-center text-[12px] font-semibold px-2.5 py-1 rounded-lg bg-background/92 backdrop-blur-xl text-foreground shadow-sm", children: [
|
|
11839
|
+
priceUnit && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute bottom-3 left-3 inline-flex items-center text-[12px] font-semibold px-2.5 py-1 rounded-lg bg-background/92 backdrop-blur-xl text-foreground shadow-sm", children: [
|
|
11770
11840
|
"Per ",
|
|
11771
|
-
|
|
11841
|
+
priceUnit
|
|
11772
11842
|
] }),
|
|
11773
11843
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute bottom-3 right-3 text-white font-bold text-lg drop-shadow-sm", children: [
|
|
11774
11844
|
/* @__PURE__ */ jsxRuntime.jsx(Price, { amount: product.default_price, currency }),
|
|
11775
|
-
|
|
11776
|
-
unit
|
|
11845
|
+
priceUnit && `/${priceUnit}`
|
|
11777
11846
|
] }),
|
|
11778
11847
|
product.general_service_capacity != null && product.general_service_capacity > 1 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "absolute top-3 left-3 text-[11px] font-semibold tracking-wide bg-blue-50/90 text-blue-700 border border-blue-200/50 backdrop-blur px-2 py-0.5 rounded-md", children: [
|
|
11779
11848
|
"Up to ",
|
|
@@ -12065,36 +12134,36 @@ var BUILT_IN_CARDS = {
|
|
|
12065
12134
|
["composite" /* Composite */]: CompositeProductCard,
|
|
12066
12135
|
["subscription" /* Subscription */]: SubscriptionCard
|
|
12067
12136
|
};
|
|
12068
|
-
var RENTAL_UNITS = /* @__PURE__ */ new Set([
|
|
12069
|
-
var LEASE_UNITS = /* @__PURE__ */ new Set([
|
|
12137
|
+
var RENTAL_UNITS = /* @__PURE__ */ new Set([chunkHKN3YG76_js.DURATION_UNIT.Days, chunkHKN3YG76_js.DURATION_UNIT.Hours]);
|
|
12138
|
+
var LEASE_UNITS = /* @__PURE__ */ new Set([chunkHKN3YG76_js.DURATION_UNIT.Weeks, chunkHKN3YG76_js.DURATION_UNIT.Months, chunkHKN3YG76_js.DURATION_UNIT.Years]);
|
|
12070
12139
|
function resolveCardVariant(product) {
|
|
12071
|
-
if (product.type ===
|
|
12140
|
+
if (product.type === chunkHKN3YG76_js.PRODUCT_TYPE.Bundle) {
|
|
12072
12141
|
return "bundle" /* Bundle */;
|
|
12073
12142
|
}
|
|
12074
|
-
if (product.type ===
|
|
12143
|
+
if (product.type === chunkHKN3YG76_js.PRODUCT_TYPE.Composite) {
|
|
12075
12144
|
return "composite" /* Composite */;
|
|
12076
12145
|
}
|
|
12077
12146
|
if (product.quantity_pricing && product.quantity_pricing.length > 1) {
|
|
12078
12147
|
return "wholesale" /* Wholesale */;
|
|
12079
12148
|
}
|
|
12080
|
-
if (product.type ===
|
|
12149
|
+
if (product.type === chunkHKN3YG76_js.PRODUCT_TYPE.Digital) {
|
|
12081
12150
|
return "digital" /* Digital */;
|
|
12082
12151
|
}
|
|
12083
|
-
if (product.type ===
|
|
12152
|
+
if (product.type === chunkHKN3YG76_js.PRODUCT_TYPE.Service) {
|
|
12084
12153
|
switch (product.boundary_kind) {
|
|
12085
|
-
case
|
|
12154
|
+
case chunkHKN3YG76_js.BOUNDARY_KIND.CheckInOut:
|
|
12086
12155
|
return "accommodation" /* Accommodation */;
|
|
12087
|
-
case
|
|
12156
|
+
case chunkHKN3YG76_js.BOUNDARY_KIND.MoveInOut:
|
|
12088
12157
|
return "lease" /* Lease */;
|
|
12089
|
-
case
|
|
12090
|
-
case
|
|
12091
|
-
case
|
|
12158
|
+
case chunkHKN3YG76_js.BOUNDARY_KIND.PickupReturn:
|
|
12159
|
+
case chunkHKN3YG76_js.BOUNDARY_KIND.DeliveryCollection:
|
|
12160
|
+
case chunkHKN3YG76_js.BOUNDARY_KIND.AccessVacate:
|
|
12092
12161
|
return "rental" /* Rental */;
|
|
12093
12162
|
}
|
|
12094
12163
|
if (product.duration_unit && RENTAL_UNITS.has(product.duration_unit)) {
|
|
12095
12164
|
return "rental" /* Rental */;
|
|
12096
12165
|
}
|
|
12097
|
-
if (product.duration_unit ===
|
|
12166
|
+
if (product.duration_unit === chunkHKN3YG76_js.DURATION_UNIT.Nights) {
|
|
12098
12167
|
return "accommodation" /* Accommodation */;
|
|
12099
12168
|
}
|
|
12100
12169
|
if (product.duration_unit && LEASE_UNITS.has(product.duration_unit)) {
|
|
@@ -12105,10 +12174,10 @@ function resolveCardVariant(product) {
|
|
|
12105
12174
|
}
|
|
12106
12175
|
return "standard" /* Standard */;
|
|
12107
12176
|
}
|
|
12108
|
-
if (product.render_hint ===
|
|
12177
|
+
if (product.render_hint === chunkHKN3YG76_js.RENDER_HINT.Food) {
|
|
12109
12178
|
return "food" /* Food */;
|
|
12110
12179
|
}
|
|
12111
|
-
if (product.render_hint ===
|
|
12180
|
+
if (product.render_hint === chunkHKN3YG76_js.RENDER_HINT.Physical) {
|
|
12112
12181
|
return "retail" /* Retail */;
|
|
12113
12182
|
}
|
|
12114
12183
|
return "retail" /* Retail */;
|
|
@@ -12367,6 +12436,15 @@ function ProductGrid({
|
|
|
12367
12436
|
] });
|
|
12368
12437
|
}
|
|
12369
12438
|
|
|
12439
|
+
// src/react/utils/attachment.ts
|
|
12440
|
+
var IMAGE_EXTENSIONS = [".jpg", ".jpeg", ".png", ".webp", ".gif", ".bmp", ".svg"];
|
|
12441
|
+
function isImageAttachment(attachment) {
|
|
12442
|
+
if (attachment.mime_type?.startsWith("image/")) return true;
|
|
12443
|
+
if (attachment.mime_type) return false;
|
|
12444
|
+
const path = attachment.url.split("?")[0].split("#")[0].toLowerCase();
|
|
12445
|
+
return IMAGE_EXTENSIONS.some((extension) => path.endsWith(extension));
|
|
12446
|
+
}
|
|
12447
|
+
|
|
12370
12448
|
// src/react/utils/boundary-labels.ts
|
|
12371
12449
|
var PRESET_LABELS = {
|
|
12372
12450
|
check_in_out: { start: "Check-in", end: "Check-out" },
|
|
@@ -12376,14 +12454,14 @@ var PRESET_LABELS = {
|
|
|
12376
12454
|
move_in_out: { start: "Move-in", end: "Move-out" }
|
|
12377
12455
|
};
|
|
12378
12456
|
function defaultBoundaryKind(unit) {
|
|
12379
|
-
return unit ===
|
|
12457
|
+
return unit === chunkHKN3YG76_js.DURATION_UNIT.Nights ? chunkHKN3YG76_js.BOUNDARY_KIND.CheckInOut : chunkHKN3YG76_js.BOUNDARY_KIND.PickupReturn;
|
|
12380
12458
|
}
|
|
12381
12459
|
function resolveBoundaryKind(product) {
|
|
12382
12460
|
return product.boundary_kind ?? defaultBoundaryKind(product.duration_unit);
|
|
12383
12461
|
}
|
|
12384
12462
|
function getBoundaryLabels(product) {
|
|
12385
12463
|
const kind = resolveBoundaryKind(product);
|
|
12386
|
-
if (kind ===
|
|
12464
|
+
if (kind === chunkHKN3YG76_js.BOUNDARY_KIND.Custom) {
|
|
12387
12465
|
return {
|
|
12388
12466
|
start: product.boundary_start_label?.trim() || "Start",
|
|
12389
12467
|
end: product.boundary_end_label?.trim() || "End"
|
|
@@ -13548,6 +13626,7 @@ function BookingPage({
|
|
|
13548
13626
|
const [selectedDate, setSelectedDate] = React14.useState(null);
|
|
13549
13627
|
const [selectedStaffId, setSelectedStaffId] = React14.useState(null);
|
|
13550
13628
|
const [selectedResourceId, setSelectedResourceId] = React14.useState(null);
|
|
13629
|
+
const [bookingUnits, setBookingUnits] = React14.useState(1);
|
|
13551
13630
|
const [isSubmitting, setIsSubmitting] = React14.useState(false);
|
|
13552
13631
|
const [error, setError] = React14.useState(null);
|
|
13553
13632
|
const hasResourceStep = resources && resources.length > 0;
|
|
@@ -13641,7 +13720,8 @@ function BookingPage({
|
|
|
13641
13720
|
scheduledStart: selectedSlot.start_time,
|
|
13642
13721
|
scheduledEnd: selectedSlot.end_time,
|
|
13643
13722
|
staffId: selectedStaffId || void 0,
|
|
13644
|
-
resourceId: selectedResourceId || void 0
|
|
13723
|
+
resourceId: selectedResourceId || void 0,
|
|
13724
|
+
units: bookingUnits > 1 ? bookingUnits : void 0
|
|
13645
13725
|
});
|
|
13646
13726
|
onBooked?.(selectedSlot, selectedStaffId);
|
|
13647
13727
|
}
|
|
@@ -13737,6 +13817,31 @@ function BookingPage({
|
|
|
13737
13817
|
] }),
|
|
13738
13818
|
step === STEP.CONFIRM && selectedSlot && /* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-step": "confirm", className: classNames?.step, children: [
|
|
13739
13819
|
/* @__PURE__ */ jsxRuntime.jsx("h2", { "data-cimplify-booking-step-title": true, className: classNames?.stepTitle, children: "Confirm your booking" }),
|
|
13820
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-units": true, className: classNames?.summaryRow, children: [
|
|
13821
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Units" }),
|
|
13822
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-units-stepper": true, children: [
|
|
13823
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
13824
|
+
"button",
|
|
13825
|
+
{
|
|
13826
|
+
type: "button",
|
|
13827
|
+
"data-cimplify-booking-units-decrement": true,
|
|
13828
|
+
onClick: () => setBookingUnits((current) => Math.max(1, current - 1)),
|
|
13829
|
+
disabled: bookingUnits <= 1,
|
|
13830
|
+
children: "\u2212"
|
|
13831
|
+
}
|
|
13832
|
+
),
|
|
13833
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "data-cimplify-booking-units-value": true, children: bookingUnits }),
|
|
13834
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
13835
|
+
"button",
|
|
13836
|
+
{
|
|
13837
|
+
type: "button",
|
|
13838
|
+
"data-cimplify-booking-units-increment": true,
|
|
13839
|
+
onClick: () => setBookingUnits((current) => current + 1),
|
|
13840
|
+
children: "+"
|
|
13841
|
+
}
|
|
13842
|
+
)
|
|
13843
|
+
] })
|
|
13844
|
+
] }),
|
|
13740
13845
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary": true, className: classNames?.summary, children: [
|
|
13741
13846
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { "data-cimplify-booking-summary-row": true, className: classNames?.summaryRow, children: [
|
|
13742
13847
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "Service" }),
|
|
@@ -14444,7 +14549,7 @@ function DefaultProductLayout({
|
|
|
14444
14549
|
className
|
|
14445
14550
|
}) {
|
|
14446
14551
|
const [selectedVariantId, setSelectedVariantId] = React14__default.default.useState();
|
|
14447
|
-
const images =
|
|
14552
|
+
const images = chunkHKN3YG76_js.resolveGallery(product, selectedVariantId);
|
|
14448
14553
|
const currency = chunkPTPOQVXS_js.getProductCurrency(product);
|
|
14449
14554
|
const hasRange = product.quantity_pricing && product.quantity_pricing.length > 1 || product.variants && product.variants.length > 1;
|
|
14450
14555
|
const onSale = chunkPTPOQVXS_js.isOnSale(product);
|
|
@@ -15091,25 +15196,25 @@ function resolveTemplateKey(product) {
|
|
|
15091
15196
|
if (typeof metaTemplate === "string" && metaTemplate.trim()) {
|
|
15092
15197
|
return metaTemplate.trim();
|
|
15093
15198
|
}
|
|
15094
|
-
if (product.type ===
|
|
15199
|
+
if (product.type === chunkHKN3YG76_js.PRODUCT_TYPE.Bundle) {
|
|
15095
15200
|
return "bundle" /* Bundle */;
|
|
15096
15201
|
}
|
|
15097
|
-
if (product.type ===
|
|
15202
|
+
if (product.type === chunkHKN3YG76_js.PRODUCT_TYPE.Composite) {
|
|
15098
15203
|
return "composite" /* Composite */;
|
|
15099
15204
|
}
|
|
15100
15205
|
if (product.quantity_pricing && product.quantity_pricing.length > 1) {
|
|
15101
15206
|
return "wholesale" /* Wholesale */;
|
|
15102
15207
|
}
|
|
15103
|
-
if (product.type ===
|
|
15208
|
+
if (product.type === chunkHKN3YG76_js.PRODUCT_TYPE.Service) {
|
|
15104
15209
|
return "service" /* Service */;
|
|
15105
15210
|
}
|
|
15106
|
-
if (product.type ===
|
|
15211
|
+
if (product.type === chunkHKN3YG76_js.PRODUCT_TYPE.Digital) {
|
|
15107
15212
|
return "digital" /* Digital */;
|
|
15108
15213
|
}
|
|
15109
|
-
if (product.render_hint ===
|
|
15214
|
+
if (product.render_hint === chunkHKN3YG76_js.RENDER_HINT.Food) {
|
|
15110
15215
|
return "food" /* Food */;
|
|
15111
15216
|
}
|
|
15112
|
-
if (product.render_hint ===
|
|
15217
|
+
if (product.render_hint === chunkHKN3YG76_js.RENDER_HINT.Physical) {
|
|
15113
15218
|
return "physical" /* Physical */;
|
|
15114
15219
|
}
|
|
15115
15220
|
return "default" /* Default */;
|
|
@@ -16995,7 +17100,7 @@ function ChatWidget({
|
|
|
16995
17100
|
const context = useOptionalCimplifyClient();
|
|
16996
17101
|
const client = clientProp ?? context?.client;
|
|
16997
17102
|
const [open, setOpen] = React14.useState(defaultOpen);
|
|
16998
|
-
const [
|
|
17103
|
+
const [readCount, setReadCount] = React14.useState(0);
|
|
16999
17104
|
const {
|
|
17000
17105
|
messages,
|
|
17001
17106
|
isLoading,
|
|
@@ -17004,6 +17109,8 @@ function ChatWidget({
|
|
|
17004
17109
|
seenAt,
|
|
17005
17110
|
error,
|
|
17006
17111
|
isActive,
|
|
17112
|
+
claimedAs,
|
|
17113
|
+
signOut,
|
|
17007
17114
|
send,
|
|
17008
17115
|
react,
|
|
17009
17116
|
startConversation
|
|
@@ -17025,22 +17132,14 @@ function ChatWidget({
|
|
|
17025
17132
|
},
|
|
17026
17133
|
[client, send]
|
|
17027
17134
|
);
|
|
17028
|
-
const
|
|
17029
|
-
React14.useEffect(() => {
|
|
17030
|
-
if (!open && messages.length > prevCountRef.current) {
|
|
17031
|
-
const newMessages = messages.slice(prevCountRef.current);
|
|
17032
|
-
const incomingCount = newMessages.filter(
|
|
17033
|
-
(m) => m.sender_type !== "customer"
|
|
17034
|
-
).length;
|
|
17035
|
-
if (incomingCount > 0) setUnread((n) => n + incomingCount);
|
|
17036
|
-
}
|
|
17037
|
-
prevCountRef.current = messages.length;
|
|
17038
|
-
}, [messages, open]);
|
|
17135
|
+
const unread = open ? 0 : messages.slice(readCount).filter((m) => m.sender_type !== "customer").length;
|
|
17039
17136
|
const handleOpen = React14.useCallback(() => {
|
|
17040
17137
|
setOpen(true);
|
|
17041
|
-
setUnread(0);
|
|
17042
17138
|
}, []);
|
|
17043
|
-
const handleClose = React14.useCallback(() =>
|
|
17139
|
+
const handleClose = React14.useCallback(() => {
|
|
17140
|
+
setReadCount(messages.length);
|
|
17141
|
+
setOpen(false);
|
|
17142
|
+
}, [messages.length]);
|
|
17044
17143
|
const isLeft = position === "bottom-left";
|
|
17045
17144
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17046
17145
|
"div",
|
|
@@ -17076,6 +17175,8 @@ function ChatWidget({
|
|
|
17076
17175
|
error,
|
|
17077
17176
|
isActive,
|
|
17078
17177
|
isLeft,
|
|
17178
|
+
claimedAs,
|
|
17179
|
+
onSignOut: () => void signOut(),
|
|
17079
17180
|
onClose: handleClose,
|
|
17080
17181
|
onSend: send,
|
|
17081
17182
|
onReact: react,
|
|
@@ -17137,6 +17238,8 @@ function Panel({
|
|
|
17137
17238
|
error,
|
|
17138
17239
|
isActive,
|
|
17139
17240
|
isLeft,
|
|
17241
|
+
claimedAs,
|
|
17242
|
+
onSignOut,
|
|
17140
17243
|
onClose,
|
|
17141
17244
|
onSend,
|
|
17142
17245
|
onReact,
|
|
@@ -17160,6 +17263,8 @@ function Panel({
|
|
|
17160
17263
|
Header,
|
|
17161
17264
|
{
|
|
17162
17265
|
businessName,
|
|
17266
|
+
claimedAs,
|
|
17267
|
+
onSignOut,
|
|
17163
17268
|
onClose,
|
|
17164
17269
|
className: classNames?.header
|
|
17165
17270
|
}
|
|
@@ -17206,6 +17311,8 @@ function Panel({
|
|
|
17206
17311
|
}
|
|
17207
17312
|
function Header({
|
|
17208
17313
|
businessName,
|
|
17314
|
+
claimedAs,
|
|
17315
|
+
onSignOut,
|
|
17209
17316
|
onClose,
|
|
17210
17317
|
className
|
|
17211
17318
|
}) {
|
|
@@ -17220,7 +17327,22 @@ function Header({
|
|
|
17220
17327
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-9 w-9 flex-shrink-0 items-center justify-center rounded-[10px] bg-white/15", children: /* @__PURE__ */ jsxRuntime.jsx(ChatIcon, { className: "h-5 w-5" }) }),
|
|
17221
17328
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
17222
17329
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "truncate text-[15px] font-semibold leading-tight", children: businessName }),
|
|
17223
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1
|
|
17330
|
+
claimedAs ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1 truncate text-xs text-white/60", children: [
|
|
17331
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "truncate", children: [
|
|
17332
|
+
"Chatting as ",
|
|
17333
|
+
claimedAs
|
|
17334
|
+
] }),
|
|
17335
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", children: "\xB7" }),
|
|
17336
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17337
|
+
"button",
|
|
17338
|
+
{
|
|
17339
|
+
type: "button",
|
|
17340
|
+
onClick: onSignOut,
|
|
17341
|
+
className: "flex-shrink-0 underline underline-offset-2 hover:text-white",
|
|
17342
|
+
children: "Not you?"
|
|
17343
|
+
}
|
|
17344
|
+
)
|
|
17345
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5 text-xs text-white/60", children: [
|
|
17224
17346
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-[7px] w-[7px] flex-shrink-0 rounded-full bg-emerald-400" }),
|
|
17225
17347
|
"Online"
|
|
17226
17348
|
] })
|
|
@@ -17304,10 +17426,6 @@ function MessageList({
|
|
|
17304
17426
|
onReact,
|
|
17305
17427
|
className
|
|
17306
17428
|
}) {
|
|
17307
|
-
const bottomRef = React14.useRef(null);
|
|
17308
|
-
React14.useEffect(() => {
|
|
17309
|
-
bottomRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
17310
|
-
}, [messages.length, isSending]);
|
|
17311
17429
|
const { bubbles, reactionsByTarget } = partitionMessages(messages);
|
|
17312
17430
|
const seenMessageId = lastSeenCustomerMessageId(bubbles, seenAt);
|
|
17313
17431
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -17427,7 +17545,15 @@ function MessageList({
|
|
|
17427
17545
|
] }, msg.id);
|
|
17428
17546
|
}),
|
|
17429
17547
|
isSending && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mr-auto mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(TypingDots, {}) }),
|
|
17430
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17548
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17549
|
+
"div",
|
|
17550
|
+
{
|
|
17551
|
+
ref: (node) => {
|
|
17552
|
+
node?.scrollIntoView({ behavior: "smooth" });
|
|
17553
|
+
}
|
|
17554
|
+
},
|
|
17555
|
+
`${messages.length}:${isSending}`
|
|
17556
|
+
)
|
|
17431
17557
|
]
|
|
17432
17558
|
}
|
|
17433
17559
|
);
|
|
@@ -19476,7 +19602,7 @@ async function genUIFingerprint(manifest) {
|
|
|
19476
19602
|
|
|
19477
19603
|
Object.defineProperty(exports, "getVariantDisplayName", {
|
|
19478
19604
|
enumerable: true,
|
|
19479
|
-
get: function () { return
|
|
19605
|
+
get: function () { return chunkHKN3YG76_js.getVariantDisplayName; }
|
|
19480
19606
|
});
|
|
19481
19607
|
Object.defineProperty(exports, "messagePreview", {
|
|
19482
19608
|
enumerable: true,
|
|
@@ -19505,6 +19631,7 @@ exports.AccountSubscriptionsPage = AccountSubscriptionsPage;
|
|
|
19505
19631
|
exports.Ad = Ad;
|
|
19506
19632
|
exports.AdProvider = AdProvider;
|
|
19507
19633
|
exports.AddOnSelector = AddOnSelector;
|
|
19634
|
+
exports.AddressAutocomplete = AddressAutocomplete;
|
|
19508
19635
|
exports.AddressElement = AddressElement;
|
|
19509
19636
|
exports.AuthElement = AuthElement;
|
|
19510
19637
|
exports.AvailabilityBadge = AvailabilityBadge;
|
|
@@ -19668,12 +19795,14 @@ exports.WholesaleProductLayout = WholesaleProductLayout;
|
|
|
19668
19795
|
exports.WishlistButton = WishlistButton;
|
|
19669
19796
|
exports.clearOrdersCache = clearOrdersCache;
|
|
19670
19797
|
exports.cn = cn;
|
|
19798
|
+
exports.createPlacesSessionToken = createPlacesSessionToken;
|
|
19671
19799
|
exports.defaultBoundaryKind = defaultBoundaryKind;
|
|
19672
19800
|
exports.genUICatalog = genUICatalog;
|
|
19673
19801
|
exports.genUIFingerprint = genUIFingerprint;
|
|
19674
19802
|
exports.genUIManifest = genUIManifest;
|
|
19675
19803
|
exports.genUIManifestJson = genUIManifestJson;
|
|
19676
19804
|
exports.getBoundaryLabels = getBoundaryLabels;
|
|
19805
|
+
exports.isImageAttachment = isImageAttachment;
|
|
19677
19806
|
exports.isTerminalOrderStatus = isTerminalOrderStatus;
|
|
19678
19807
|
exports.parseGenUIProgram = parse;
|
|
19679
19808
|
exports.partitionMessages = partitionMessages;
|