@cimplify/sdk 0.97.0 → 0.98.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/{chunk-RRBY35TJ.mjs → chunk-4G5UWFC3.mjs} +7 -1
- package/dist/{chunk-HKN3YG76.js → chunk-QPRI2NII.js} +7 -0
- package/dist/index.js +22 -25
- package/dist/index.mjs +2 -8
- package/dist/react.d.mts +382 -261
- package/dist/react.d.ts +382 -261
- package/dist/react.js +696 -211
- package/dist/react.mjs +627 -161
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/registry/chat-widget.json +1 -1
package/dist/react.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
var
|
|
4
|
+
var chunkQPRI2NII_js = require('./chunk-QPRI2NII.js');
|
|
5
5
|
var chunkXREIZ56K_js = require('./chunk-XREIZ56K.js');
|
|
6
6
|
var chunkW5PH7SPK_js = require('./chunk-W5PH7SPK.js');
|
|
7
7
|
var chunkVEOAMBEX_js = require('./chunk-VEOAMBEX.js');
|
|
@@ -1298,7 +1298,7 @@ function CimplifyProvider({
|
|
|
1298
1298
|
const apiCredentials = resolvedClient.getCredentialsMode() === "include" ? "use-credentials" : "anonymous";
|
|
1299
1299
|
preconnectOrigin(resolvedClient.getBaseUrl(), apiCredentials);
|
|
1300
1300
|
preconnectOrigin(resolvedClient.getLinkApiUrl(), apiCredentials);
|
|
1301
|
-
preconnectOrigin(
|
|
1301
|
+
preconnectOrigin(chunkQPRI2NII_js.DEFAULT_CDN_BASE_URL);
|
|
1302
1302
|
}
|
|
1303
1303
|
const setCurrentLocation = React14.useCallback(
|
|
1304
1304
|
(location) => {
|
|
@@ -6810,7 +6810,7 @@ function VariantSelector({
|
|
|
6810
6810
|
{
|
|
6811
6811
|
"data-cimplify-variant-name": true,
|
|
6812
6812
|
className: cn("flex-1 min-w-0 text-sm", classNames?.name),
|
|
6813
|
-
children:
|
|
6813
|
+
children: chunkQPRI2NII_js.getVariantDisplayName(variant, productName)
|
|
6814
6814
|
}
|
|
6815
6815
|
),
|
|
6816
6816
|
/* @__PURE__ */ jsxRuntime.jsxs("span", { "data-cimplify-variant-pricing": true, className: cn("text-sm text-muted-foreground", classNames?.pricing), children: [
|
|
@@ -8603,12 +8603,12 @@ function FieldInput({
|
|
|
8603
8603
|
classNames?.input
|
|
8604
8604
|
);
|
|
8605
8605
|
switch (field.field_type) {
|
|
8606
|
-
case
|
|
8607
|
-
case
|
|
8606
|
+
case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Text:
|
|
8607
|
+
case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Url:
|
|
8608
8608
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8609
8609
|
"input",
|
|
8610
8610
|
{
|
|
8611
|
-
type: field.field_type ===
|
|
8611
|
+
type: field.field_type === chunkQPRI2NII_js.INPUT_FIELD_TYPE.Url ? "url" : "text",
|
|
8612
8612
|
value: typeof value === "string" ? value : "",
|
|
8613
8613
|
onChange: (e) => onValueChange(e.target.value),
|
|
8614
8614
|
placeholder: field.placeholder,
|
|
@@ -8617,7 +8617,7 @@ function FieldInput({
|
|
|
8617
8617
|
className: inputClass
|
|
8618
8618
|
}
|
|
8619
8619
|
);
|
|
8620
|
-
case
|
|
8620
|
+
case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Textarea:
|
|
8621
8621
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8622
8622
|
"textarea",
|
|
8623
8623
|
{
|
|
@@ -8630,7 +8630,7 @@ function FieldInput({
|
|
|
8630
8630
|
className: cn(inputClass, "resize-none", classNames?.textarea)
|
|
8631
8631
|
}
|
|
8632
8632
|
);
|
|
8633
|
-
case
|
|
8633
|
+
case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Number:
|
|
8634
8634
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8635
8635
|
"input",
|
|
8636
8636
|
{
|
|
@@ -8644,7 +8644,7 @@ function FieldInput({
|
|
|
8644
8644
|
className: inputClass
|
|
8645
8645
|
}
|
|
8646
8646
|
);
|
|
8647
|
-
case
|
|
8647
|
+
case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Select:
|
|
8648
8648
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8649
8649
|
"select",
|
|
8650
8650
|
{
|
|
@@ -8658,7 +8658,7 @@ function FieldInput({
|
|
|
8658
8658
|
]
|
|
8659
8659
|
}
|
|
8660
8660
|
);
|
|
8661
|
-
case
|
|
8661
|
+
case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Radio:
|
|
8662
8662
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("space-y-2", classNames?.radioGroup), children: (field.options || []).map((opt) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8663
8663
|
"label",
|
|
8664
8664
|
{
|
|
@@ -8683,7 +8683,7 @@ function FieldInput({
|
|
|
8683
8683
|
},
|
|
8684
8684
|
opt
|
|
8685
8685
|
)) });
|
|
8686
|
-
case
|
|
8686
|
+
case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Checkbox:
|
|
8687
8687
|
return /* @__PURE__ */ jsxRuntime.jsxs("label", { className: cn("flex items-center gap-2 text-sm cursor-pointer", classNames?.checkboxLabel), children: [
|
|
8688
8688
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8689
8689
|
"input",
|
|
@@ -8696,7 +8696,7 @@ function FieldInput({
|
|
|
8696
8696
|
),
|
|
8697
8697
|
field.placeholder || field.name
|
|
8698
8698
|
] });
|
|
8699
|
-
case
|
|
8699
|
+
case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Color:
|
|
8700
8700
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8701
8701
|
"input",
|
|
8702
8702
|
{
|
|
@@ -8706,7 +8706,7 @@ function FieldInput({
|
|
|
8706
8706
|
className: cn("w-12 h-10 rounded-md border border-input cursor-pointer", classNames?.colorInput)
|
|
8707
8707
|
}
|
|
8708
8708
|
);
|
|
8709
|
-
case
|
|
8709
|
+
case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Date:
|
|
8710
8710
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8711
8711
|
DatePicker,
|
|
8712
8712
|
{
|
|
@@ -8717,8 +8717,8 @@ function FieldInput({
|
|
|
8717
8717
|
"aria-label": field.name
|
|
8718
8718
|
}
|
|
8719
8719
|
);
|
|
8720
|
-
case
|
|
8721
|
-
case
|
|
8720
|
+
case chunkQPRI2NII_js.INPUT_FIELD_TYPE.File:
|
|
8721
|
+
case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Image:
|
|
8722
8722
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8723
8723
|
FileUploadInput,
|
|
8724
8724
|
{
|
|
@@ -8729,7 +8729,7 @@ function FieldInput({
|
|
|
8729
8729
|
classNames
|
|
8730
8730
|
}
|
|
8731
8731
|
);
|
|
8732
|
-
case
|
|
8732
|
+
case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Email:
|
|
8733
8733
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8734
8734
|
"input",
|
|
8735
8735
|
{
|
|
@@ -8741,7 +8741,7 @@ function FieldInput({
|
|
|
8741
8741
|
className: inputClass
|
|
8742
8742
|
}
|
|
8743
8743
|
);
|
|
8744
|
-
case
|
|
8744
|
+
case chunkQPRI2NII_js.INPUT_FIELD_TYPE.DateTime: {
|
|
8745
8745
|
const stringValue = typeof value === "string" ? value : "";
|
|
8746
8746
|
const [datePart, timePartRaw] = stringValue.includes("T") ? stringValue.split("T", 2) : [stringValue, ""];
|
|
8747
8747
|
const timePart = (timePartRaw ?? "").slice(0, 5);
|
|
@@ -8780,7 +8780,7 @@ function FieldInput({
|
|
|
8780
8780
|
)
|
|
8781
8781
|
] });
|
|
8782
8782
|
}
|
|
8783
|
-
case
|
|
8783
|
+
case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Time:
|
|
8784
8784
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8785
8785
|
TimePicker,
|
|
8786
8786
|
{
|
|
@@ -8791,7 +8791,7 @@ function FieldInput({
|
|
|
8791
8791
|
"aria-label": field.name
|
|
8792
8792
|
}
|
|
8793
8793
|
);
|
|
8794
|
-
case
|
|
8794
|
+
case chunkQPRI2NII_js.INPUT_FIELD_TYPE.MultiSelect:
|
|
8795
8795
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8796
8796
|
MultiSelectInput,
|
|
8797
8797
|
{
|
|
@@ -8801,7 +8801,7 @@ function FieldInput({
|
|
|
8801
8801
|
classNames
|
|
8802
8802
|
}
|
|
8803
8803
|
);
|
|
8804
|
-
case
|
|
8804
|
+
case chunkQPRI2NII_js.INPUT_FIELD_TYPE.DateRange:
|
|
8805
8805
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8806
8806
|
DateRangeInput,
|
|
8807
8807
|
{
|
|
@@ -8811,7 +8811,7 @@ function FieldInput({
|
|
|
8811
8811
|
classNames
|
|
8812
8812
|
}
|
|
8813
8813
|
);
|
|
8814
|
-
case
|
|
8814
|
+
case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Address:
|
|
8815
8815
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8816
8816
|
AddressInput,
|
|
8817
8817
|
{
|
|
@@ -8822,7 +8822,7 @@ function FieldInput({
|
|
|
8822
8822
|
inputClass
|
|
8823
8823
|
}
|
|
8824
8824
|
);
|
|
8825
|
-
case
|
|
8825
|
+
case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Location:
|
|
8826
8826
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8827
8827
|
LocationInput,
|
|
8828
8828
|
{
|
|
@@ -8833,7 +8833,7 @@ function FieldInput({
|
|
|
8833
8833
|
inputClass
|
|
8834
8834
|
}
|
|
8835
8835
|
);
|
|
8836
|
-
case
|
|
8836
|
+
case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Phone:
|
|
8837
8837
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8838
8838
|
PhoneInput,
|
|
8839
8839
|
{
|
|
@@ -8844,7 +8844,7 @@ function FieldInput({
|
|
|
8844
8844
|
inputClass
|
|
8845
8845
|
}
|
|
8846
8846
|
);
|
|
8847
|
-
case
|
|
8847
|
+
case chunkQPRI2NII_js.INPUT_FIELD_TYPE.Signature:
|
|
8848
8848
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8849
8849
|
SignatureInput,
|
|
8850
8850
|
{
|
|
@@ -8877,7 +8877,7 @@ function FileUploadInput({
|
|
|
8877
8877
|
const [isUploading, setIsUploading] = React14__default.default.useState(false);
|
|
8878
8878
|
const fileUrl = typeof value === "string" ? value : void 0;
|
|
8879
8879
|
const acceptedFormats = field.validation?.accepted_formats;
|
|
8880
|
-
const accept = acceptedFormats ? acceptedFormats.map((f) => `.${f}`).join(",") : field.field_type ===
|
|
8880
|
+
const accept = acceptedFormats ? acceptedFormats.map((f) => `.${f}`).join(",") : field.field_type === chunkQPRI2NII_js.INPUT_FIELD_TYPE.Image ? "image/*" : void 0;
|
|
8881
8881
|
const handleFile = async (file) => {
|
|
8882
8882
|
if (!onFileUpload) return;
|
|
8883
8883
|
if (field.validation?.max_size_mb) {
|
|
@@ -8895,7 +8895,7 @@ function FileUploadInput({
|
|
|
8895
8895
|
}
|
|
8896
8896
|
};
|
|
8897
8897
|
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: [
|
|
8898
|
-
field.field_type ===
|
|
8898
|
+
field.field_type === chunkQPRI2NII_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" }),
|
|
8899
8899
|
/* @__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() }) }),
|
|
8900
8900
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
8901
8901
|
"button",
|
|
@@ -8921,7 +8921,7 @@ function FileUploadInput({
|
|
|
8921
8921
|
}
|
|
8922
8922
|
),
|
|
8923
8923
|
isUploading ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: "Uploading..." }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
8924
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: field.placeholder || `Upload ${field.field_type ===
|
|
8924
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-muted-foreground", children: field.placeholder || `Upload ${field.field_type === chunkQPRI2NII_js.INPUT_FIELD_TYPE.Image ? "image" : "file"}` }),
|
|
8925
8925
|
acceptedFormats && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs text-muted-foreground/60 mt-1", children: [
|
|
8926
8926
|
acceptedFormats.map((f) => f.toUpperCase()).join(", "),
|
|
8927
8927
|
field.validation?.max_size_mb && ` \xB7 Max ${field.validation.max_size_mb}MB`
|
|
@@ -9655,7 +9655,7 @@ function ProductCustomizer({
|
|
|
9655
9655
|
const isBundle = productType === "bundle";
|
|
9656
9656
|
const isDigital = productType === "digital";
|
|
9657
9657
|
const isService = productType === "service";
|
|
9658
|
-
const offersUnits = isService &&
|
|
9658
|
+
const offersUnits = isService && chunkQPRI2NII_js.isMultiDayService(product);
|
|
9659
9659
|
const isStandard = !isComposite && !isBundle;
|
|
9660
9660
|
const hasVariants = isStandard && product.variants && product.variants.length > 0;
|
|
9661
9661
|
const hasAddOns = isStandard && product.add_ons && product.add_ons.length > 0;
|
|
@@ -9769,7 +9769,7 @@ function ProductCustomizer({
|
|
|
9769
9769
|
}, [quote, quantity]);
|
|
9770
9770
|
const displayTotalPrice = React14.useMemo(() => {
|
|
9771
9771
|
const total = quotedTotalPrice ?? localTotalPrice;
|
|
9772
|
-
const multiplier =
|
|
9772
|
+
const multiplier = chunkQPRI2NII_js.serviceBillingMultiplier(product, {
|
|
9773
9773
|
quantity,
|
|
9774
9774
|
units: unitsCount,
|
|
9775
9775
|
scheduledStart: selectedSlot?.start_time,
|
|
@@ -10483,7 +10483,7 @@ function CartLineItemRow({
|
|
|
10483
10483
|
const isOptimistic2 = item.isOptimistic === true;
|
|
10484
10484
|
const lineTotal = chunkPTPOQVXS_js.parsePrice(unitPrice) * item.quantity;
|
|
10485
10485
|
const imageUrl = item.product.image_url;
|
|
10486
|
-
const variantLabel2 = item.variant ?
|
|
10486
|
+
const variantLabel2 = item.variant ? chunkQPRI2NII_js.getVariantDisplayName(item.variant, item.product.name) : null;
|
|
10487
10487
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
10488
10488
|
"div",
|
|
10489
10489
|
{
|
|
@@ -10583,7 +10583,7 @@ function CartLineItemRow({
|
|
|
10583
10583
|
input.field_name,
|
|
10584
10584
|
":"
|
|
10585
10585
|
] }),
|
|
10586
|
-
/* @__PURE__ */ jsxRuntime.jsx("dd", { "data-cimplify-cart-input-value": true, className: "text-foreground m-0 truncate", children: input.field_type ===
|
|
10586
|
+
/* @__PURE__ */ jsxRuntime.jsx("dd", { "data-cimplify-cart-input-value": true, className: "text-foreground m-0 truncate", children: input.field_type === chunkQPRI2NII_js.INPUT_FIELD_TYPE.File || input.field_type === chunkQPRI2NII_js.INPUT_FIELD_TYPE.Image ? String(input.value).split("/").pop() || "Uploaded file" : String(input.value) })
|
|
10587
10587
|
] }, input.field_id)) }),
|
|
10588
10588
|
(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: [
|
|
10589
10589
|
/* @__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" }) }),
|
|
@@ -11468,7 +11468,7 @@ function FoodProductCard({
|
|
|
11468
11468
|
const tags = product.tags || [];
|
|
11469
11469
|
const isSignature = product.metadata?.is_signature === true;
|
|
11470
11470
|
const isNew = product.metadata?.is_new === true;
|
|
11471
|
-
const isComposite = product.type ===
|
|
11471
|
+
const isComposite = product.type === chunkQPRI2NII_js.PRODUCT_TYPE.Composite;
|
|
11472
11472
|
return /* @__PURE__ */ jsxRuntime.jsxs(CardShell, { product, renderLink, className, children: [
|
|
11473
11473
|
/* @__PURE__ */ jsxRuntime.jsxs(CardImage, { src: image, alt: product.name, aspectRatio: "square", renderImage, children: [
|
|
11474
11474
|
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: [
|
|
@@ -12235,36 +12235,36 @@ var BUILT_IN_CARDS = {
|
|
|
12235
12235
|
["composite" /* Composite */]: CompositeProductCard,
|
|
12236
12236
|
["subscription" /* Subscription */]: SubscriptionCard
|
|
12237
12237
|
};
|
|
12238
|
-
var RENTAL_UNITS = /* @__PURE__ */ new Set([
|
|
12239
|
-
var LEASE_UNITS = /* @__PURE__ */ new Set([
|
|
12238
|
+
var RENTAL_UNITS = /* @__PURE__ */ new Set([chunkQPRI2NII_js.DURATION_UNIT.Days, chunkQPRI2NII_js.DURATION_UNIT.Hours]);
|
|
12239
|
+
var LEASE_UNITS = /* @__PURE__ */ new Set([chunkQPRI2NII_js.DURATION_UNIT.Weeks, chunkQPRI2NII_js.DURATION_UNIT.Months, chunkQPRI2NII_js.DURATION_UNIT.Years]);
|
|
12240
12240
|
function resolveCardVariant(product) {
|
|
12241
|
-
if (product.type ===
|
|
12241
|
+
if (product.type === chunkQPRI2NII_js.PRODUCT_TYPE.Bundle) {
|
|
12242
12242
|
return "bundle" /* Bundle */;
|
|
12243
12243
|
}
|
|
12244
|
-
if (product.type ===
|
|
12244
|
+
if (product.type === chunkQPRI2NII_js.PRODUCT_TYPE.Composite) {
|
|
12245
12245
|
return "composite" /* Composite */;
|
|
12246
12246
|
}
|
|
12247
12247
|
if (product.quantity_pricing && product.quantity_pricing.length > 1) {
|
|
12248
12248
|
return "wholesale" /* Wholesale */;
|
|
12249
12249
|
}
|
|
12250
|
-
if (product.type ===
|
|
12250
|
+
if (product.type === chunkQPRI2NII_js.PRODUCT_TYPE.Digital) {
|
|
12251
12251
|
return "digital" /* Digital */;
|
|
12252
12252
|
}
|
|
12253
|
-
if (product.type ===
|
|
12253
|
+
if (product.type === chunkQPRI2NII_js.PRODUCT_TYPE.Service) {
|
|
12254
12254
|
switch (product.boundary_kind) {
|
|
12255
|
-
case
|
|
12255
|
+
case chunkQPRI2NII_js.BOUNDARY_KIND.CheckInOut:
|
|
12256
12256
|
return "accommodation" /* Accommodation */;
|
|
12257
|
-
case
|
|
12257
|
+
case chunkQPRI2NII_js.BOUNDARY_KIND.MoveInOut:
|
|
12258
12258
|
return "lease" /* Lease */;
|
|
12259
|
-
case
|
|
12260
|
-
case
|
|
12261
|
-
case
|
|
12259
|
+
case chunkQPRI2NII_js.BOUNDARY_KIND.PickupReturn:
|
|
12260
|
+
case chunkQPRI2NII_js.BOUNDARY_KIND.DeliveryCollection:
|
|
12261
|
+
case chunkQPRI2NII_js.BOUNDARY_KIND.AccessVacate:
|
|
12262
12262
|
return "rental" /* Rental */;
|
|
12263
12263
|
}
|
|
12264
12264
|
if (product.duration_unit && RENTAL_UNITS.has(product.duration_unit)) {
|
|
12265
12265
|
return "rental" /* Rental */;
|
|
12266
12266
|
}
|
|
12267
|
-
if (product.duration_unit ===
|
|
12267
|
+
if (product.duration_unit === chunkQPRI2NII_js.DURATION_UNIT.Nights) {
|
|
12268
12268
|
return "accommodation" /* Accommodation */;
|
|
12269
12269
|
}
|
|
12270
12270
|
if (product.duration_unit && LEASE_UNITS.has(product.duration_unit)) {
|
|
@@ -12275,10 +12275,10 @@ function resolveCardVariant(product) {
|
|
|
12275
12275
|
}
|
|
12276
12276
|
return "standard" /* Standard */;
|
|
12277
12277
|
}
|
|
12278
|
-
if (product.render_hint ===
|
|
12278
|
+
if (product.render_hint === chunkQPRI2NII_js.RENDER_HINT.Food) {
|
|
12279
12279
|
return "food" /* Food */;
|
|
12280
12280
|
}
|
|
12281
|
-
if (product.render_hint ===
|
|
12281
|
+
if (product.render_hint === chunkQPRI2NII_js.RENDER_HINT.Physical) {
|
|
12282
12282
|
return "retail" /* Retail */;
|
|
12283
12283
|
}
|
|
12284
12284
|
return "retail" /* Retail */;
|
|
@@ -12558,14 +12558,14 @@ var PRESET_LABELS = {
|
|
|
12558
12558
|
move_in_out: { start: "Move-in", end: "Move-out" }
|
|
12559
12559
|
};
|
|
12560
12560
|
function defaultBoundaryKind(unit) {
|
|
12561
|
-
return unit ===
|
|
12561
|
+
return unit === chunkQPRI2NII_js.DURATION_UNIT.Nights ? chunkQPRI2NII_js.BOUNDARY_KIND.CheckInOut : chunkQPRI2NII_js.BOUNDARY_KIND.PickupReturn;
|
|
12562
12562
|
}
|
|
12563
12563
|
function resolveBoundaryKind(product) {
|
|
12564
12564
|
return product.boundary_kind ?? defaultBoundaryKind(product.duration_unit);
|
|
12565
12565
|
}
|
|
12566
12566
|
function getBoundaryLabels(product) {
|
|
12567
12567
|
const kind = resolveBoundaryKind(product);
|
|
12568
|
-
if (kind ===
|
|
12568
|
+
if (kind === chunkQPRI2NII_js.BOUNDARY_KIND.Custom) {
|
|
12569
12569
|
return {
|
|
12570
12570
|
start: product.boundary_start_label?.trim() || "Start",
|
|
12571
12571
|
end: product.boundary_end_label?.trim() || "End"
|
|
@@ -14653,7 +14653,7 @@ function DefaultProductLayout({
|
|
|
14653
14653
|
className
|
|
14654
14654
|
}) {
|
|
14655
14655
|
const [selectedVariantId, setSelectedVariantId] = React14__default.default.useState();
|
|
14656
|
-
const images =
|
|
14656
|
+
const images = chunkQPRI2NII_js.resolveGallery(product, selectedVariantId);
|
|
14657
14657
|
const currency = chunkPTPOQVXS_js.getProductCurrency(product);
|
|
14658
14658
|
const hasRange = product.quantity_pricing && product.quantity_pricing.length > 1 || product.variants && product.variants.length > 1;
|
|
14659
14659
|
const onSale = chunkPTPOQVXS_js.isOnSale(product);
|
|
@@ -15300,25 +15300,25 @@ function resolveTemplateKey(product) {
|
|
|
15300
15300
|
if (typeof metaTemplate === "string" && metaTemplate.trim()) {
|
|
15301
15301
|
return metaTemplate.trim();
|
|
15302
15302
|
}
|
|
15303
|
-
if (product.type ===
|
|
15303
|
+
if (product.type === chunkQPRI2NII_js.PRODUCT_TYPE.Bundle) {
|
|
15304
15304
|
return "bundle" /* Bundle */;
|
|
15305
15305
|
}
|
|
15306
|
-
if (product.type ===
|
|
15306
|
+
if (product.type === chunkQPRI2NII_js.PRODUCT_TYPE.Composite) {
|
|
15307
15307
|
return "composite" /* Composite */;
|
|
15308
15308
|
}
|
|
15309
15309
|
if (product.quantity_pricing && product.quantity_pricing.length > 1) {
|
|
15310
15310
|
return "wholesale" /* Wholesale */;
|
|
15311
15311
|
}
|
|
15312
|
-
if (product.type ===
|
|
15312
|
+
if (product.type === chunkQPRI2NII_js.PRODUCT_TYPE.Service) {
|
|
15313
15313
|
return "service" /* Service */;
|
|
15314
15314
|
}
|
|
15315
|
-
if (product.type ===
|
|
15315
|
+
if (product.type === chunkQPRI2NII_js.PRODUCT_TYPE.Digital) {
|
|
15316
15316
|
return "digital" /* Digital */;
|
|
15317
15317
|
}
|
|
15318
|
-
if (product.render_hint ===
|
|
15318
|
+
if (product.render_hint === chunkQPRI2NII_js.RENDER_HINT.Food) {
|
|
15319
15319
|
return "food" /* Food */;
|
|
15320
15320
|
}
|
|
15321
|
-
if (product.render_hint ===
|
|
15321
|
+
if (product.render_hint === chunkQPRI2NII_js.RENDER_HINT.Physical) {
|
|
15322
15322
|
return "physical" /* Physical */;
|
|
15323
15323
|
}
|
|
15324
15324
|
return "default" /* Default */;
|
|
@@ -17170,12 +17170,582 @@ var ChatMarkdown = React14.memo(function ChatMarkdown2({
|
|
|
17170
17170
|
}
|
|
17171
17171
|
return /* @__PURE__ */ jsxRuntime.jsx(SettledMarkdown, { text, className });
|
|
17172
17172
|
});
|
|
17173
|
-
|
|
17174
|
-
|
|
17175
|
-
|
|
17173
|
+
|
|
17174
|
+
// src/react/chat-kit/motion.ts
|
|
17175
|
+
function prefersReducedMotion() {
|
|
17176
|
+
return typeof window !== "undefined" && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
17177
|
+
}
|
|
17178
|
+
function scrollBehavior() {
|
|
17179
|
+
return prefersReducedMotion() ? "auto" : "smooth";
|
|
17180
|
+
}
|
|
17181
|
+
function QuoteBlock({
|
|
17182
|
+
quote,
|
|
17183
|
+
inCustomerBubble,
|
|
17184
|
+
businessName,
|
|
17185
|
+
onMissing
|
|
17186
|
+
}) {
|
|
17187
|
+
const quotedIsCustomer = quote.sender_type === "customer";
|
|
17188
|
+
const jumpToOriginal = async () => {
|
|
17189
|
+
let original = document.getElementById(`chat-msg-${quote.id}`);
|
|
17190
|
+
if (!original && onMissing && await onMissing()) {
|
|
17191
|
+
original = document.getElementById(`chat-msg-${quote.id}`);
|
|
17192
|
+
}
|
|
17193
|
+
if (!original) return;
|
|
17194
|
+
original.scrollIntoView({ behavior: scrollBehavior(), block: "center" });
|
|
17195
|
+
original.classList.remove("animate-quote-flash");
|
|
17196
|
+
void original.offsetWidth;
|
|
17197
|
+
original.classList.add("animate-quote-flash");
|
|
17198
|
+
};
|
|
17199
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17200
|
+
"button",
|
|
17201
|
+
{
|
|
17202
|
+
type: "button",
|
|
17203
|
+
onClick: () => void jumpToOriginal(),
|
|
17204
|
+
className: cn(
|
|
17205
|
+
"flex w-full gap-2 rounded-[10px] px-2.5 py-1.5 text-left",
|
|
17206
|
+
inCustomerBubble ? "bg-primary-foreground/15" : "bg-background/70"
|
|
17207
|
+
),
|
|
17208
|
+
children: [
|
|
17209
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17210
|
+
"span",
|
|
17211
|
+
{
|
|
17212
|
+
className: cn(
|
|
17213
|
+
"w-[3px] shrink-0 self-stretch rounded-full",
|
|
17214
|
+
inCustomerBubble ? "bg-primary-foreground/50" : quotedIsCustomer ? "bg-primary" : "bg-muted-foreground/50"
|
|
17215
|
+
)
|
|
17216
|
+
}
|
|
17217
|
+
),
|
|
17218
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-col", children: [
|
|
17219
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17220
|
+
"span",
|
|
17221
|
+
{
|
|
17222
|
+
className: cn(
|
|
17223
|
+
"text-[11px] leading-4 font-semibold",
|
|
17224
|
+
inCustomerBubble ? "text-primary-foreground" : "text-foreground"
|
|
17225
|
+
),
|
|
17226
|
+
children: quotedIsCustomer ? "You" : businessName
|
|
17227
|
+
}
|
|
17228
|
+
),
|
|
17229
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17230
|
+
"span",
|
|
17231
|
+
{
|
|
17232
|
+
className: cn(
|
|
17233
|
+
"truncate text-xs leading-4",
|
|
17234
|
+
inCustomerBubble ? "text-primary-foreground/75" : "text-muted-foreground"
|
|
17235
|
+
),
|
|
17236
|
+
children: quote.preview
|
|
17237
|
+
}
|
|
17238
|
+
)
|
|
17239
|
+
] })
|
|
17240
|
+
]
|
|
17241
|
+
}
|
|
17242
|
+
);
|
|
17243
|
+
}
|
|
17244
|
+
var SWIPE_COMMIT_PX = 48;
|
|
17245
|
+
var SWIPE_ARM_PX = 10;
|
|
17246
|
+
var OVERDRAG_RATE = 0.25;
|
|
17247
|
+
var LONG_PRESS_MS = 450;
|
|
17248
|
+
var RETURN_TRANSITION = "transform 0.25s cubic-bezier(0.2, 0, 0, 1)";
|
|
17249
|
+
function swipeTravel(distance) {
|
|
17250
|
+
if (distance <= 0) return 0;
|
|
17251
|
+
if (distance <= SWIPE_COMMIT_PX) return distance;
|
|
17252
|
+
return SWIPE_COMMIT_PX + (distance - SWIPE_COMMIT_PX) * OVERDRAG_RATE;
|
|
17253
|
+
}
|
|
17254
|
+
function swipeCommitted(distance) {
|
|
17255
|
+
return distance >= SWIPE_COMMIT_PX;
|
|
17256
|
+
}
|
|
17257
|
+
function swipeProgress(distance) {
|
|
17258
|
+
return Math.min(Math.max(distance / SWIPE_COMMIT_PX, 0), 1);
|
|
17259
|
+
}
|
|
17260
|
+
function useSwipeReply({ onReply, onLongPress }) {
|
|
17261
|
+
const rowRef = React14.useRef(null);
|
|
17262
|
+
const glyphRef = React14.useRef(null);
|
|
17263
|
+
const gestureRef = React14.useRef(null);
|
|
17264
|
+
const suppressClickRef = React14.useRef(false);
|
|
17265
|
+
const optionsRef = React14.useRef({ onReply, onLongPress });
|
|
17266
|
+
optionsRef.current = { onReply, onLongPress };
|
|
17267
|
+
const settle = React14.useCallback((glyphVisible) => {
|
|
17268
|
+
const row = rowRef.current;
|
|
17269
|
+
const glyph = glyphRef.current;
|
|
17270
|
+
if (row) {
|
|
17271
|
+
row.style.transition = RETURN_TRANSITION;
|
|
17272
|
+
row.style.transform = "translateX(0px)";
|
|
17273
|
+
}
|
|
17274
|
+
if (glyph && !glyphVisible) {
|
|
17275
|
+
glyph.style.transition = "opacity 0.2s ease-out";
|
|
17276
|
+
glyph.style.opacity = "0";
|
|
17277
|
+
}
|
|
17278
|
+
}, []);
|
|
17279
|
+
const clearGesture = React14.useCallback(() => {
|
|
17280
|
+
const gesture = gestureRef.current;
|
|
17281
|
+
if (gesture?.longPressTimer) clearTimeout(gesture.longPressTimer);
|
|
17282
|
+
gestureRef.current = null;
|
|
17283
|
+
}, []);
|
|
17284
|
+
const onPointerDown = React14.useCallback((event) => {
|
|
17285
|
+
if (!event.isPrimary) return;
|
|
17286
|
+
suppressClickRef.current = false;
|
|
17287
|
+
gestureRef.current = {
|
|
17288
|
+
pointerId: event.pointerId,
|
|
17289
|
+
startX: event.clientX,
|
|
17290
|
+
startY: event.clientY,
|
|
17291
|
+
armed: false,
|
|
17292
|
+
distance: 0,
|
|
17293
|
+
longPressTimer: setTimeout(() => {
|
|
17294
|
+
gestureRef.current = null;
|
|
17295
|
+
suppressClickRef.current = true;
|
|
17296
|
+
optionsRef.current.onLongPress();
|
|
17297
|
+
}, LONG_PRESS_MS)
|
|
17298
|
+
};
|
|
17299
|
+
}, []);
|
|
17300
|
+
const onPointerMove = React14.useCallback((event) => {
|
|
17301
|
+
const gesture = gestureRef.current;
|
|
17302
|
+
if (!gesture || gesture.pointerId !== event.pointerId) return;
|
|
17303
|
+
const leftward = gesture.startX - event.clientX;
|
|
17304
|
+
const vertical = Math.abs(event.clientY - gesture.startY);
|
|
17305
|
+
if (!gesture.armed) {
|
|
17306
|
+
const scrolling = vertical > SWIPE_ARM_PX && vertical >= leftward;
|
|
17307
|
+
const rightward = leftward < -SWIPE_ARM_PX;
|
|
17308
|
+
if (scrolling || rightward) {
|
|
17309
|
+
clearGesture();
|
|
17310
|
+
return;
|
|
17311
|
+
}
|
|
17312
|
+
if (leftward <= SWIPE_ARM_PX || leftward <= vertical) return;
|
|
17313
|
+
if (prefersReducedMotion()) {
|
|
17314
|
+
clearGesture();
|
|
17315
|
+
return;
|
|
17316
|
+
}
|
|
17317
|
+
gesture.armed = true;
|
|
17318
|
+
if (gesture.longPressTimer) clearTimeout(gesture.longPressTimer);
|
|
17319
|
+
gesture.longPressTimer = null;
|
|
17320
|
+
event.currentTarget.setPointerCapture(event.pointerId);
|
|
17321
|
+
if (rowRef.current) rowRef.current.style.transition = "none";
|
|
17322
|
+
if (glyphRef.current) glyphRef.current.style.transition = "none";
|
|
17323
|
+
}
|
|
17324
|
+
gesture.distance = leftward;
|
|
17325
|
+
if (rowRef.current) {
|
|
17326
|
+
rowRef.current.style.transform = `translateX(-${swipeTravel(leftward)}px)`;
|
|
17327
|
+
}
|
|
17328
|
+
if (glyphRef.current) {
|
|
17329
|
+
glyphRef.current.style.opacity = String(swipeProgress(leftward));
|
|
17330
|
+
}
|
|
17331
|
+
}, [clearGesture]);
|
|
17332
|
+
const onPointerUp = React14.useCallback(
|
|
17333
|
+
(event) => {
|
|
17334
|
+
const gesture = gestureRef.current;
|
|
17335
|
+
if (!gesture || gesture.pointerId !== event.pointerId) return;
|
|
17336
|
+
const commit = gesture.armed && swipeCommitted(gesture.distance);
|
|
17337
|
+
const wasArmed = gesture.armed;
|
|
17338
|
+
clearGesture();
|
|
17339
|
+
if (wasArmed) {
|
|
17340
|
+
suppressClickRef.current = true;
|
|
17341
|
+
settle(false);
|
|
17342
|
+
}
|
|
17343
|
+
if (commit) optionsRef.current.onReply();
|
|
17344
|
+
},
|
|
17345
|
+
[clearGesture, settle]
|
|
17346
|
+
);
|
|
17347
|
+
const onPointerCancel = React14.useCallback(
|
|
17348
|
+
(event) => {
|
|
17349
|
+
const gesture = gestureRef.current;
|
|
17350
|
+
if (!gesture || gesture.pointerId !== event.pointerId) return;
|
|
17351
|
+
const wasArmed = gesture.armed;
|
|
17352
|
+
clearGesture();
|
|
17353
|
+
if (wasArmed) settle(false);
|
|
17354
|
+
},
|
|
17355
|
+
[clearGesture, settle]
|
|
17356
|
+
);
|
|
17357
|
+
const onClickCapture = React14.useCallback((event) => {
|
|
17358
|
+
if (!suppressClickRef.current) return;
|
|
17359
|
+
suppressClickRef.current = false;
|
|
17360
|
+
event.preventDefault();
|
|
17361
|
+
event.stopPropagation();
|
|
17362
|
+
}, []);
|
|
17363
|
+
return {
|
|
17364
|
+
rowRef,
|
|
17365
|
+
glyphRef,
|
|
17366
|
+
handlers: { onPointerDown, onPointerMove, onPointerUp, onPointerCancel, onClickCapture }
|
|
17367
|
+
};
|
|
17368
|
+
}
|
|
17369
|
+
var PROSE_CLASS = "[&_p]:my-0 [&_p+p]:mt-1.5 [&_ul]:my-1 [&_ul]:list-disc [&_ul]:pl-4 [&_ol]:my-1 [&_ol]:list-decimal [&_ol]:pl-4 [&_li]:my-0.5 [&_h1]:text-[15px] [&_h1]:font-bold [&_h2]:text-[15px] [&_h2]:font-bold [&_h3]:text-sm [&_h3]:font-semibold [&_hr]:my-2 [&_hr]:border-border [&_table]:my-1 [&_table]:w-full [&_th]:pb-1 [&_th]:text-left [&_th]:text-[11px] [&_th]:font-semibold [&_th]:uppercase [&_th]:text-muted-foreground [&_td]:border-b [&_td]:border-border/50 [&_td]:py-1 [&_td:last-child]:text-right [&_td:last-child]:font-semibold [&_td:last-child]:tabular-nums [&_tr:last-child_td]:border-b-0 [&_a]:underline [&_code]:rounded [&_code]:bg-muted [&_code]:px-1 [&_code]:text-[13px]";
|
|
17370
|
+
function bubbleShape(isCustomer, group) {
|
|
17371
|
+
if (!hasTail(group)) return "rounded-[18px]";
|
|
17372
|
+
return isCustomer ? "rounded-[18px] rounded-br-none" : "rounded-[18px] rounded-bl-none";
|
|
17373
|
+
}
|
|
17374
|
+
function hasTail(group) {
|
|
17375
|
+
return group === "single" || group === "last";
|
|
17376
|
+
}
|
|
17377
|
+
var TAIL_SWEEP = "M21 0 L21 5 C21 15 25 16 25 16 C20.93 16.43 16.84 14.94 13.96 11.96 C9 16 5 16 0 16";
|
|
17378
|
+
var TAIL_FILL = `${TAIL_SWEEP} Z`;
|
|
17379
|
+
var TAIL_NOTCH = "M25 16 C20.93 16.43 16.84 14.94 13.96 11.96 C9 16 5 16 0 16 Z";
|
|
17380
|
+
function BubbleTail({ isCustomer }) {
|
|
17381
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17382
|
+
"svg",
|
|
17383
|
+
{
|
|
17384
|
+
width: "25",
|
|
17385
|
+
height: "16",
|
|
17386
|
+
viewBox: "0 0 25 16",
|
|
17387
|
+
"aria-hidden": "true",
|
|
17388
|
+
className: cn(
|
|
17389
|
+
"absolute bottom-0",
|
|
17390
|
+
isCustomer ? "-right-[4px] fill-primary" : "-left-[4px] -scale-x-100 fill-background"
|
|
17391
|
+
),
|
|
17392
|
+
children: [
|
|
17393
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: TAIL_FILL }),
|
|
17394
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: TAIL_NOTCH, style: { fill: "var(--color-chat-canvas, var(--color-muted, #f3f5f3))" } }),
|
|
17395
|
+
!isCustomer && /* @__PURE__ */ jsxRuntime.jsx("path", { d: TAIL_SWEEP, fill: "none", strokeWidth: "1", className: "stroke-foreground/[0.07]" })
|
|
17396
|
+
]
|
|
17397
|
+
}
|
|
17398
|
+
);
|
|
17399
|
+
}
|
|
17400
|
+
function clockLabel(at) {
|
|
17401
|
+
const date = new Date(at);
|
|
17402
|
+
if (Number.isNaN(date.getTime())) return "";
|
|
17403
|
+
const hour = date.getHours() % 12 || 12;
|
|
17404
|
+
return `${hour}:${String(date.getMinutes()).padStart(2, "0")}`;
|
|
17405
|
+
}
|
|
17406
|
+
function DoubleTick() {
|
|
17407
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "15", height: "9", viewBox: "0 0 15 9", fill: "none", "aria-hidden": "true", children: [
|
|
17408
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M1 4.5L4 7.5L9.5 1.5", stroke: "currentColor", strokeWidth: "1.4", strokeLinecap: "round", strokeLinejoin: "round" }),
|
|
17409
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6.5 4.5L9.5 7.5L14 2.5", stroke: "currentColor", strokeWidth: "1.4", strokeLinecap: "round", strokeLinejoin: "round" })
|
|
17410
|
+
] });
|
|
17411
|
+
}
|
|
17412
|
+
function SendingClock() {
|
|
17413
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "11", height: "11", viewBox: "0 0 11 11", fill: "none", "aria-hidden": "true", children: [
|
|
17414
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "5.5", cy: "5.5", r: "4.5", stroke: "currentColor", strokeWidth: "1.2" }),
|
|
17415
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5.5 3v2.7l1.8 1", stroke: "currentColor", strokeWidth: "1.2", strokeLinecap: "round" })
|
|
17416
|
+
] });
|
|
17417
|
+
}
|
|
17418
|
+
function PaperclipIcon() {
|
|
17419
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
17420
|
+
"svg",
|
|
17421
|
+
{
|
|
17422
|
+
width: "14",
|
|
17423
|
+
height: "14",
|
|
17424
|
+
viewBox: "0 0 24 24",
|
|
17425
|
+
fill: "none",
|
|
17426
|
+
stroke: "currentColor",
|
|
17427
|
+
strokeWidth: "2",
|
|
17428
|
+
strokeLinecap: "round",
|
|
17429
|
+
strokeLinejoin: "round",
|
|
17430
|
+
"aria-hidden": "true",
|
|
17431
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48" })
|
|
17432
|
+
}
|
|
17433
|
+
);
|
|
17434
|
+
}
|
|
17435
|
+
function ReplyGlyph() {
|
|
17436
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17437
|
+
"svg",
|
|
17438
|
+
{
|
|
17439
|
+
width: "18",
|
|
17440
|
+
height: "18",
|
|
17441
|
+
viewBox: "0 0 24 24",
|
|
17442
|
+
fill: "none",
|
|
17443
|
+
stroke: "currentColor",
|
|
17444
|
+
strokeWidth: "2.2",
|
|
17445
|
+
strokeLinecap: "round",
|
|
17446
|
+
strokeLinejoin: "round",
|
|
17447
|
+
"aria-hidden": "true",
|
|
17448
|
+
children: [
|
|
17449
|
+
/* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "9 17 4 12 9 7" }),
|
|
17450
|
+
/* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 18v-2a4 4 0 0 0-4-4H4" })
|
|
17451
|
+
]
|
|
17452
|
+
}
|
|
17453
|
+
);
|
|
17454
|
+
}
|
|
17455
|
+
var DELIVERY_LABELS = {
|
|
17456
|
+
sending: "Sending",
|
|
17457
|
+
delivered: "Delivered",
|
|
17458
|
+
seen: "Seen"
|
|
17459
|
+
};
|
|
17460
|
+
function BubbleMeta({
|
|
17461
|
+
at,
|
|
17462
|
+
isCustomer,
|
|
17463
|
+
delivery
|
|
17464
|
+
}) {
|
|
17465
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17466
|
+
"span",
|
|
17467
|
+
{
|
|
17468
|
+
className: cn(
|
|
17469
|
+
"ml-auto flex shrink-0 items-center gap-[3px] self-end pb-px whitespace-nowrap",
|
|
17470
|
+
isCustomer ? "text-primary-foreground/70" : "text-muted-foreground"
|
|
17471
|
+
),
|
|
17472
|
+
children: [
|
|
17473
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10.5px] leading-[13px] font-medium", children: clockLabel(at) }),
|
|
17474
|
+
isCustomer && delivery && /* @__PURE__ */ jsxRuntime.jsx(
|
|
17475
|
+
"span",
|
|
17476
|
+
{
|
|
17477
|
+
role: "img",
|
|
17478
|
+
"aria-label": DELIVERY_LABELS[delivery],
|
|
17479
|
+
className: cn(
|
|
17480
|
+
"flex items-center text-primary-foreground",
|
|
17481
|
+
delivery !== "seen" && "opacity-55"
|
|
17482
|
+
),
|
|
17483
|
+
children: delivery === "sending" ? /* @__PURE__ */ jsxRuntime.jsx(SendingClock, {}) : /* @__PURE__ */ jsxRuntime.jsx(DoubleTick, {})
|
|
17484
|
+
}
|
|
17485
|
+
)
|
|
17486
|
+
]
|
|
17487
|
+
}
|
|
17488
|
+
);
|
|
17489
|
+
}
|
|
17490
|
+
function reactionPills(reactions) {
|
|
17491
|
+
const counts = /* @__PURE__ */ new Map();
|
|
17492
|
+
for (const reaction of reactions) {
|
|
17493
|
+
const emoji = reaction.content.trim();
|
|
17494
|
+
if (emoji) counts.set(emoji, (counts.get(emoji) ?? 0) + 1);
|
|
17495
|
+
}
|
|
17496
|
+
return [...counts.entries()].map(([emoji, count]) => ({ emoji, count }));
|
|
17497
|
+
}
|
|
17498
|
+
var MessageBubble = React14.memo(function MessageBubble2({
|
|
17499
|
+
message,
|
|
17500
|
+
reactions,
|
|
17501
|
+
businessName,
|
|
17502
|
+
group = "single",
|
|
17503
|
+
delivery,
|
|
17504
|
+
onReply,
|
|
17505
|
+
onLongPress,
|
|
17506
|
+
avatar,
|
|
17507
|
+
overlay,
|
|
17508
|
+
renderCards,
|
|
17509
|
+
renderProgram,
|
|
17510
|
+
onQuoteMiss
|
|
17511
|
+
}) {
|
|
17512
|
+
const showAvatar = group === "single" || group === "last";
|
|
17513
|
+
const isCustomer = message.sender_type === "customer";
|
|
17514
|
+
const isBusiness = !isCustomer;
|
|
17515
|
+
const segments = React14.useMemo(
|
|
17516
|
+
() => isCustomer ? [{ kind: "prose", text: message.content }] : chunkXREIZ56K_js.splitGenUIContent(message.content),
|
|
17517
|
+
[isCustomer, message.content]
|
|
17518
|
+
);
|
|
17519
|
+
const drawable = React14.useMemo(
|
|
17520
|
+
() => segments.filter(
|
|
17521
|
+
(segment) => segment.kind === "prose" && segment.text.trim() !== "" || segment.kind === "program" && renderProgram != null
|
|
17522
|
+
),
|
|
17523
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
17524
|
+
[segments, renderProgram != null]
|
|
17525
|
+
);
|
|
17526
|
+
const swipe = useSwipeReply({
|
|
17527
|
+
onReply: () => onReply(message),
|
|
17528
|
+
onLongPress: () => onLongPress?.(message)
|
|
17529
|
+
});
|
|
17530
|
+
const quote = message.reply_to ?? null;
|
|
17531
|
+
const pills = reactions ? reactionPills(reactions) : [];
|
|
17532
|
+
const cards = renderCards?.(message);
|
|
17533
|
+
const proseSegments = drawable.filter((segment) => segment.kind === "prose");
|
|
17534
|
+
const lastProseIndex = drawable.lastIndexOf(proseSegments[proseSegments.length - 1]);
|
|
17535
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { id: `chat-msg-${message.id}`, className: "relative rounded-xl", children: [
|
|
17536
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17537
|
+
"span",
|
|
17538
|
+
{
|
|
17539
|
+
ref: swipe.glyphRef,
|
|
17540
|
+
"aria-hidden": "true",
|
|
17541
|
+
className: "absolute top-1/2 right-1 -translate-y-1/2 text-muted-foreground opacity-0",
|
|
17542
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ReplyGlyph, {})
|
|
17543
|
+
}
|
|
17544
|
+
),
|
|
17545
|
+
overlay,
|
|
17546
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
17547
|
+
"div",
|
|
17548
|
+
{
|
|
17549
|
+
ref: swipe.rowRef,
|
|
17550
|
+
...swipe.handlers,
|
|
17551
|
+
onContextMenu: onLongPress ? (event) => {
|
|
17552
|
+
event.preventDefault();
|
|
17553
|
+
onLongPress(message);
|
|
17554
|
+
} : void 0,
|
|
17555
|
+
className: cn(
|
|
17556
|
+
"flex touch-pan-y flex-col gap-[3px] select-none [-webkit-touch-callout:none]",
|
|
17557
|
+
isCustomer ? "items-end" : "items-start"
|
|
17558
|
+
),
|
|
17559
|
+
children: [
|
|
17560
|
+
quote && drawable[0]?.kind !== "prose" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "max-w-[280px] rounded-[14px] border border-foreground/[0.07] bg-background p-1.5 shadow-[0_1px_1px_rgba(15,23,42,0.03)]", children: /* @__PURE__ */ jsxRuntime.jsx(QuoteBlock, { quote, inCustomerBubble: false, businessName, onMissing: onQuoteMiss }) }),
|
|
17561
|
+
message.attachments.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex max-w-[280px] flex-wrap gap-1.5", children: message.attachments.map((attachment, index) => {
|
|
17562
|
+
const url = safeAttachmentUrl(attachment.url);
|
|
17563
|
+
if (!url) return null;
|
|
17564
|
+
return isImageAttachment(attachment) ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: url, target: "_blank", rel: "noreferrer", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
17565
|
+
"img",
|
|
17566
|
+
{
|
|
17567
|
+
src: url,
|
|
17568
|
+
alt: attachment.filename ?? "Photo",
|
|
17569
|
+
loading: "lazy",
|
|
17570
|
+
className: "max-h-[240px] max-w-[240px] rounded-[16px] object-cover"
|
|
17571
|
+
}
|
|
17572
|
+
) }, index) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17573
|
+
"a",
|
|
17574
|
+
{
|
|
17575
|
+
href: url,
|
|
17576
|
+
target: "_blank",
|
|
17577
|
+
rel: "noreferrer",
|
|
17578
|
+
className: "flex items-center gap-2 rounded-[14px] border border-foreground/[0.07] bg-background px-3 py-2 text-[13px] font-medium text-foreground shadow-[0_1px_1px_rgba(15,23,42,0.03)]",
|
|
17579
|
+
children: [
|
|
17580
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 text-muted-foreground", children: /* @__PURE__ */ jsxRuntime.jsx(PaperclipIcon, {}) }),
|
|
17581
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "max-w-[200px] truncate", children: attachment.filename ?? "Attachment" })
|
|
17582
|
+
]
|
|
17583
|
+
},
|
|
17584
|
+
index
|
|
17585
|
+
);
|
|
17586
|
+
}) }),
|
|
17587
|
+
drawable.map(
|
|
17588
|
+
(segment, index) => segment.kind === "program" ? /* @__PURE__ */ jsxRuntime.jsx(React14__default.default.Fragment, { children: renderProgram?.(segment.source) }, index) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex max-w-full items-end gap-1.5", children: [
|
|
17589
|
+
isBusiness && avatar && /* @__PURE__ */ jsxRuntime.jsx(
|
|
17590
|
+
"span",
|
|
17591
|
+
{
|
|
17592
|
+
"aria-label": businessName,
|
|
17593
|
+
className: cn(
|
|
17594
|
+
"shrink-0",
|
|
17595
|
+
// One avatar per run, anchored to its last bubble.
|
|
17596
|
+
showAvatar && index === lastProseIndex ? "visible" : "invisible"
|
|
17597
|
+
),
|
|
17598
|
+
children: avatar
|
|
17599
|
+
}
|
|
17600
|
+
),
|
|
17601
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
17602
|
+
"div",
|
|
17603
|
+
{
|
|
17604
|
+
className: cn(
|
|
17605
|
+
"relative flex max-w-[280px] min-w-0 flex-col gap-1.5 py-2 pr-[11px] pl-3.5 text-[15px] leading-[21px] font-[450] break-words",
|
|
17606
|
+
bubbleShape(isCustomer, index === lastProseIndex ? group : "middle"),
|
|
17607
|
+
isCustomer ? "bg-primary text-primary-foreground" : "border border-foreground/[0.07] bg-background text-foreground shadow-[0_1px_1px_rgba(15,23,42,0.03)]"
|
|
17608
|
+
),
|
|
17609
|
+
children: [
|
|
17610
|
+
index === 0 && quote && /* @__PURE__ */ jsxRuntime.jsx(QuoteBlock, { quote, inCustomerBubble: isCustomer, businessName, onMissing: onQuoteMiss }),
|
|
17611
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-wrap items-end gap-x-2 gap-y-0.5", children: [
|
|
17612
|
+
isCustomer ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "whitespace-pre-wrap", children: segment.text }) : /* @__PURE__ */ jsxRuntime.jsx(ChatMarkdown, { text: segment.text, className: cn("min-w-0", PROSE_CLASS) }),
|
|
17613
|
+
index === lastProseIndex && /* @__PURE__ */ jsxRuntime.jsx(BubbleMeta, { at: message.created_at, isCustomer, delivery })
|
|
17614
|
+
] }),
|
|
17615
|
+
index === lastProseIndex && hasTail(group) && /* @__PURE__ */ jsxRuntime.jsx(BubbleTail, { isCustomer })
|
|
17616
|
+
]
|
|
17617
|
+
}
|
|
17618
|
+
)
|
|
17619
|
+
] }, index)
|
|
17620
|
+
),
|
|
17621
|
+
cards,
|
|
17622
|
+
pills.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
17623
|
+
"div",
|
|
17624
|
+
{
|
|
17625
|
+
className: cn(
|
|
17626
|
+
"z-[1] -mt-3 flex gap-1",
|
|
17627
|
+
// Overlap the bubble corner by ~9px, tucked inside the tail side.
|
|
17628
|
+
isCustomer ? "mr-2.5" : "ml-10"
|
|
17629
|
+
),
|
|
17630
|
+
children: pills.map((pill) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17631
|
+
"span",
|
|
17632
|
+
{
|
|
17633
|
+
className: "flex items-center gap-[3px] rounded-full border border-foreground/[0.08] bg-background px-[7px] py-[2px] shadow-[0_1px_3px_rgba(15,23,42,0.08)]",
|
|
17634
|
+
children: [
|
|
17635
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs leading-4", children: pill.emoji }),
|
|
17636
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[11px] leading-[13px] font-semibold text-muted-foreground", children: pill.count })
|
|
17637
|
+
]
|
|
17638
|
+
},
|
|
17639
|
+
pill.emoji
|
|
17640
|
+
))
|
|
17641
|
+
}
|
|
17642
|
+
)
|
|
17643
|
+
]
|
|
17644
|
+
}
|
|
17645
|
+
)
|
|
17646
|
+
] });
|
|
17647
|
+
});
|
|
17648
|
+
function Seam({
|
|
17649
|
+
label,
|
|
17650
|
+
variant = "line"
|
|
17651
|
+
}) {
|
|
17652
|
+
if (variant === "chip") {
|
|
17653
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center py-1.5", children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded-full border border-foreground/[0.06] bg-background px-3 py-1 text-[11px] leading-[14px] font-semibold tracking-[0.04em] text-muted-foreground uppercase shadow-[0_1px_2px_rgba(15,23,42,0.04)]", children: label }) });
|
|
17654
|
+
}
|
|
17655
|
+
const unread = variant === "unread";
|
|
17656
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2.5 py-1.5", children: [
|
|
17657
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17658
|
+
"span",
|
|
17659
|
+
{
|
|
17660
|
+
className: cn("h-px flex-1", unread ? "bg-primary/35" : "bg-foreground/[0.08]"),
|
|
17661
|
+
"aria-hidden": "true"
|
|
17662
|
+
}
|
|
17663
|
+
),
|
|
17664
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17665
|
+
"span",
|
|
17666
|
+
{
|
|
17667
|
+
className: cn(
|
|
17668
|
+
"whitespace-nowrap",
|
|
17669
|
+
unread ? "text-[11px] leading-[14px] font-semibold tracking-[0.04em] text-primary uppercase" : "text-[11.5px] leading-[15px] font-medium text-muted-foreground"
|
|
17670
|
+
),
|
|
17671
|
+
children: label
|
|
17672
|
+
}
|
|
17673
|
+
),
|
|
17674
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17675
|
+
"span",
|
|
17676
|
+
{
|
|
17677
|
+
className: cn("h-px flex-1", unread ? "bg-primary/35" : "bg-foreground/[0.08]"),
|
|
17678
|
+
"aria-hidden": "true"
|
|
17679
|
+
}
|
|
17680
|
+
)
|
|
17681
|
+
] });
|
|
17682
|
+
}
|
|
17683
|
+
|
|
17684
|
+
// src/react/chat-kit/timeline.ts
|
|
17685
|
+
function sameDay(a, b) {
|
|
17686
|
+
return new Date(a).toDateString() === new Date(b).toDateString();
|
|
17687
|
+
}
|
|
17688
|
+
function dayLabel(at) {
|
|
17689
|
+
const date = new Date(at);
|
|
17690
|
+
const today = /* @__PURE__ */ new Date();
|
|
17691
|
+
if (date.toDateString() === today.toDateString()) return "Today";
|
|
17692
|
+
const yesterday = new Date(today);
|
|
17693
|
+
yesterday.setDate(today.getDate() - 1);
|
|
17694
|
+
if (date.toDateString() === yesterday.toDateString()) return "Yesterday";
|
|
17695
|
+
return date.toLocaleDateString([], { weekday: "short", day: "numeric", month: "short" });
|
|
17696
|
+
}
|
|
17176
17697
|
function proseOf(content) {
|
|
17177
17698
|
return chunkXREIZ56K_js.splitGenUIContent(content).filter((segment) => segment.kind === "prose").map((segment) => segment.text).join("\n\n").trim();
|
|
17178
17699
|
}
|
|
17700
|
+
function hasProgram(content) {
|
|
17701
|
+
return chunkXREIZ56K_js.splitGenUIContent(content).some((segment) => segment.kind === "program");
|
|
17702
|
+
}
|
|
17703
|
+
function chatTimeline(messages, options = {}) {
|
|
17704
|
+
const { readAt = null, rendersPrograms = false } = options;
|
|
17705
|
+
const partitioned = partitionMessages(messages);
|
|
17706
|
+
const bubbles = partitioned.bubbles.filter(
|
|
17707
|
+
(message) => message.sender_type === "system" || message.attachments.length > 0 || chunkQPRI2NII_js.chatMessageCards(message).length > 0 || rendersPrograms && hasProgram(message.content) || (message.sender_type === "customer" ? message.content.trim() !== "" : proseOf(message.content) !== "")
|
|
17708
|
+
);
|
|
17709
|
+
let firstUnreadId;
|
|
17710
|
+
let unreadOnOpen = 0;
|
|
17711
|
+
if (readAt) {
|
|
17712
|
+
const readAtMs = new Date(readAt).getTime();
|
|
17713
|
+
for (const message of bubbles) {
|
|
17714
|
+
if (message.sender_type === "customer" || new Date(message.created_at).getTime() <= readAtMs)
|
|
17715
|
+
continue;
|
|
17716
|
+
firstUnreadId ?? (firstUnreadId = message.id);
|
|
17717
|
+
unreadOnOpen += 1;
|
|
17718
|
+
}
|
|
17719
|
+
}
|
|
17720
|
+
return {
|
|
17721
|
+
bubbles,
|
|
17722
|
+
reactionsByTarget: partitioned.reactionsByTarget,
|
|
17723
|
+
firstUnreadId,
|
|
17724
|
+
unreadOnOpen,
|
|
17725
|
+
firstAgentMessageId: bubbles.find((m) => m.sender_type === "agent")?.id
|
|
17726
|
+
};
|
|
17727
|
+
}
|
|
17728
|
+
function groupPosition(timeline, index) {
|
|
17729
|
+
const { bubbles, firstAgentMessageId, firstUnreadId } = timeline;
|
|
17730
|
+
const message = bubbles[index];
|
|
17731
|
+
const previous = bubbles[index - 1];
|
|
17732
|
+
const next = bubbles[index + 1];
|
|
17733
|
+
const startsRun = !previous || !sameDay(previous.created_at, message.created_at) || previous.sender_type !== message.sender_type || message.id === firstAgentMessageId || message.id === firstUnreadId || previous.sender_type === "system";
|
|
17734
|
+
const endsRun = !next || next.sender_type !== message.sender_type || next.sender_type === "system" || !sameDay(message.created_at, next.created_at);
|
|
17735
|
+
if (startsRun && endsRun) return "single";
|
|
17736
|
+
if (startsRun) return "first";
|
|
17737
|
+
if (endsRun) return "last";
|
|
17738
|
+
return "middle";
|
|
17739
|
+
}
|
|
17740
|
+
function deliveryState(message, timeline, seenAt, isOptimistic2) {
|
|
17741
|
+
if (message.sender_type !== "customer") return void 0;
|
|
17742
|
+
if (isOptimistic2(message)) return "sending";
|
|
17743
|
+
const seenCutoff = timeline.firstAgentMessageId ? seenAt : null;
|
|
17744
|
+
return seenCutoff && message.created_at <= seenCutoff ? "seen" : "delivered";
|
|
17745
|
+
}
|
|
17746
|
+
var MAX_ATTACHMENT_BYTES = 5 * 1024 * 1024;
|
|
17747
|
+
var KEEP_DISMISSED_KEY = "cimplify_keep_chat_dismissed";
|
|
17748
|
+
var AT_BOTTOM_SLACK_PX = 48;
|
|
17179
17749
|
function ChatWidget({
|
|
17180
17750
|
client: clientProp,
|
|
17181
17751
|
businessName = "Support",
|
|
@@ -17300,6 +17870,7 @@ function ChatWidget({
|
|
|
17300
17870
|
isSending,
|
|
17301
17871
|
isTyping: showTyping,
|
|
17302
17872
|
seenAt,
|
|
17873
|
+
readAt,
|
|
17303
17874
|
error: error ?? attachError,
|
|
17304
17875
|
isActive,
|
|
17305
17876
|
isLeft,
|
|
@@ -17371,6 +17942,7 @@ function Panel({
|
|
|
17371
17942
|
isSending,
|
|
17372
17943
|
isTyping,
|
|
17373
17944
|
seenAt,
|
|
17945
|
+
readAt,
|
|
17374
17946
|
error,
|
|
17375
17947
|
isActive,
|
|
17376
17948
|
isLeft,
|
|
@@ -17429,6 +18001,7 @@ function Panel({
|
|
|
17429
18001
|
isLoading,
|
|
17430
18002
|
isSending: isTyping,
|
|
17431
18003
|
seenAt,
|
|
18004
|
+
readAt,
|
|
17432
18005
|
humanRequested,
|
|
17433
18006
|
mayHaveOlder,
|
|
17434
18007
|
onReact,
|
|
@@ -17589,22 +18162,8 @@ function Welcome({
|
|
|
17589
18162
|
);
|
|
17590
18163
|
}
|
|
17591
18164
|
var QUICK_REACTIONS = ["\u{1F44D}", "\u2764\uFE0F"];
|
|
17592
|
-
function
|
|
17593
|
-
|
|
17594
|
-
for (let i = bubbles.length - 1; i >= 0; i--) {
|
|
17595
|
-
if (bubbles[i].sender_type !== "customer") continue;
|
|
17596
|
-
return bubbles[i].created_at <= seenAt ? bubbles[i].id : null;
|
|
17597
|
-
}
|
|
17598
|
-
return null;
|
|
17599
|
-
}
|
|
17600
|
-
function dayLabel(at) {
|
|
17601
|
-
const date = new Date(at);
|
|
17602
|
-
const today = /* @__PURE__ */ new Date();
|
|
17603
|
-
if (date.toDateString() === today.toDateString()) return "Today";
|
|
17604
|
-
const yesterday = new Date(today);
|
|
17605
|
-
yesterday.setDate(today.getDate() - 1);
|
|
17606
|
-
if (date.toDateString() === yesterday.toDateString()) return "Yesterday";
|
|
17607
|
-
return date.toLocaleDateString([], { weekday: "short", day: "numeric", month: "short" });
|
|
18165
|
+
function LetterAvatar({ name }) {
|
|
18166
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex size-6 items-center justify-center rounded-full bg-foreground text-[10px] font-bold text-background", children: name.charAt(0).toUpperCase() });
|
|
17608
18167
|
}
|
|
17609
18168
|
function MessageList({
|
|
17610
18169
|
messages,
|
|
@@ -17612,6 +18171,7 @@ function MessageList({
|
|
|
17612
18171
|
isLoading,
|
|
17613
18172
|
isSending,
|
|
17614
18173
|
seenAt,
|
|
18174
|
+
readAt,
|
|
17615
18175
|
humanRequested,
|
|
17616
18176
|
mayHaveOlder,
|
|
17617
18177
|
onReact,
|
|
@@ -17621,12 +18181,8 @@ function MessageList({
|
|
|
17621
18181
|
className
|
|
17622
18182
|
}) {
|
|
17623
18183
|
const scrolledUpRef = React14.useRef(false);
|
|
17624
|
-
const
|
|
17625
|
-
const bubbles =
|
|
17626
|
-
(m) => m.sender_type === "system" || m.attachments.length > 0 || (m.sender_type === "customer" ? m.content.trim() !== "" : proseOf(m.content) !== "")
|
|
17627
|
-
);
|
|
17628
|
-
const reactionsByTarget = partitioned.reactionsByTarget;
|
|
17629
|
-
const seenMessageId = lastSeenCustomerMessageId(bubbles, seenAt);
|
|
18184
|
+
const timeline = chatTimeline(messages, { readAt });
|
|
18185
|
+
const { bubbles, reactionsByTarget, firstUnreadId, unreadOnOpen, firstAgentMessageId } = timeline;
|
|
17630
18186
|
const lastBubble = bubbles[bubbles.length - 1];
|
|
17631
18187
|
const offerHuman = !humanRequested && lastBubble?.sender_type === "bot" && !isSending;
|
|
17632
18188
|
const handleScroll = (event) => {
|
|
@@ -17637,121 +18193,62 @@ function MessageList({
|
|
|
17637
18193
|
"div",
|
|
17638
18194
|
{
|
|
17639
18195
|
onScroll: handleScroll,
|
|
17640
|
-
|
|
17641
|
-
|
|
17642
|
-
className
|
|
17643
|
-
),
|
|
18196
|
+
style: { background: "var(--color-chat-canvas, var(--color-muted, #f3f5f3))" },
|
|
18197
|
+
className: cn("flex flex-1 flex-col gap-0.5 overflow-y-auto px-3.5 py-3.5", className),
|
|
17644
18198
|
children: [
|
|
17645
18199
|
isLoading && messages.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-1 items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(TypingDots, {}) }),
|
|
17646
|
-
mayHaveOlder && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center pb-
|
|
18200
|
+
mayHaveOlder && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex justify-center pb-1", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
17647
18201
|
"button",
|
|
17648
18202
|
{
|
|
17649
18203
|
type: "button",
|
|
17650
18204
|
onClick: onLoadOlder,
|
|
17651
|
-
className: "rounded-full border border-
|
|
18205
|
+
className: "rounded-full border border-foreground/[0.06] bg-background px-3.5 py-[7px] text-xs font-semibold text-muted-foreground shadow-[0_1px_2px_rgba(15,23,42,0.04)]",
|
|
17652
18206
|
children: "Show earlier messages"
|
|
17653
18207
|
}
|
|
17654
18208
|
) }),
|
|
17655
18209
|
bubbles.map((msg, i) => {
|
|
17656
|
-
const isCustomer = msg.sender_type === "customer";
|
|
17657
18210
|
const prev = bubbles[i - 1];
|
|
17658
|
-
const sameSenderAsPrev = prev?.sender_type === msg.sender_type;
|
|
17659
|
-
const optimistic = isOptimistic(msg);
|
|
17660
|
-
const reactions = reactionsByTarget.get(msg.id);
|
|
17661
18211
|
const newDay = !prev || !sameDay(prev.created_at, msg.created_at);
|
|
17662
|
-
|
|
17663
|
-
|
|
17664
|
-
|
|
17665
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
17666
|
-
|
|
17667
|
-
|
|
17668
|
-
|
|
17669
|
-
|
|
17670
|
-
|
|
17671
|
-
|
|
17672
|
-
|
|
17673
|
-
|
|
18212
|
+
const group = groupPosition(timeline, i);
|
|
18213
|
+
const startsRun = group === "single" || group === "first";
|
|
18214
|
+
const delivery = deliveryState(msg, timeline, seenAt, isOptimistic);
|
|
18215
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
18216
|
+
"div",
|
|
18217
|
+
{
|
|
18218
|
+
className: cn("flex flex-col gap-1.5", startsRun && i > 0 && "mt-2.5"),
|
|
18219
|
+
children: [
|
|
18220
|
+
newDay && /* @__PURE__ */ jsxRuntime.jsx(Seam, { variant: "chip", label: dayLabel(msg.created_at) }),
|
|
18221
|
+
msg.id === firstUnreadId && /* @__PURE__ */ jsxRuntime.jsx(
|
|
18222
|
+
Seam,
|
|
18223
|
+
{
|
|
18224
|
+
variant: "unread",
|
|
18225
|
+
label: `${unreadOnOpen} new message${unreadOnOpen === 1 ? "" : "s"}`
|
|
18226
|
+
}
|
|
17674
18227
|
),
|
|
17675
|
-
|
|
17676
|
-
|
|
17677
|
-
/* @__PURE__ */ jsxRuntime.
|
|
17678
|
-
|
|
18228
|
+
msg.id === firstAgentMessageId && /* @__PURE__ */ jsxRuntime.jsx(Seam, { label: "A person joined" }),
|
|
18229
|
+
msg.sender_type === "system" ? /* @__PURE__ */ jsxRuntime.jsx(Seam, { label: "Passing you to the team" }) : /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "group relative", children: [
|
|
18230
|
+
msg.sender_type !== "customer" && !isOptimistic(msg) && /* @__PURE__ */ jsxRuntime.jsx(HoverRail, { message: msg, onReact, onReply }),
|
|
18231
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
18232
|
+
MessageBubble,
|
|
17679
18233
|
{
|
|
17680
|
-
|
|
17681
|
-
|
|
17682
|
-
|
|
17683
|
-
|
|
17684
|
-
|
|
17685
|
-
|
|
17686
|
-
|
|
17687
|
-
|
|
17688
|
-
|
|
17689
|
-
|
|
17690
|
-
|
|
17691
|
-
className: cn(
|
|
17692
|
-
"mb-1.5 flex gap-1.5 rounded-lg px-2 py-1 text-xs",
|
|
17693
|
-
isCustomer ? "bg-background/15" : "bg-muted"
|
|
17694
|
-
),
|
|
17695
|
-
children: [
|
|
17696
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
17697
|
-
"span",
|
|
17698
|
-
{
|
|
17699
|
-
className: cn(
|
|
17700
|
-
"w-[3px] shrink-0 self-stretch rounded-full",
|
|
17701
|
-
isCustomer ? "bg-background/40" : "bg-muted-foreground/40"
|
|
17702
|
-
)
|
|
17703
|
-
}
|
|
17704
|
-
),
|
|
17705
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 truncate opacity-80", children: msg.reply_to.preview })
|
|
17706
|
-
]
|
|
17707
|
-
}
|
|
17708
|
-
),
|
|
17709
|
-
msg.attachments.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cn("flex flex-wrap gap-1.5", msg.content && "mb-1.5"), children: msg.attachments.map((attachment, index) => {
|
|
17710
|
-
const url = safeAttachmentUrl(attachment.url);
|
|
17711
|
-
if (!url) return null;
|
|
17712
|
-
return attachment.mime_type?.startsWith("image/") ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: url, target: "_blank", rel: "noreferrer", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
17713
|
-
"img",
|
|
17714
|
-
{
|
|
17715
|
-
src: url,
|
|
17716
|
-
alt: attachment.filename ?? "Photo",
|
|
17717
|
-
loading: "lazy",
|
|
17718
|
-
className: "max-h-48 max-w-full rounded-lg object-cover"
|
|
17719
|
-
}
|
|
17720
|
-
) }, index) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
17721
|
-
"a",
|
|
17722
|
-
{
|
|
17723
|
-
href: url,
|
|
17724
|
-
target: "_blank",
|
|
17725
|
-
rel: "noreferrer",
|
|
17726
|
-
className: "truncate text-xs underline",
|
|
17727
|
-
children: attachment.filename ?? "Attachment"
|
|
17728
|
-
},
|
|
17729
|
-
index
|
|
17730
|
-
);
|
|
17731
|
-
}) }),
|
|
17732
|
-
isCustomer ? msg.content && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "whitespace-pre-wrap", children: msg.content }) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
17733
|
-
ChatMarkdown,
|
|
17734
|
-
{
|
|
17735
|
-
text: proseOf(msg.content),
|
|
17736
|
-
className: "[&_p]:my-0 [&_p+p]:mt-1.5 [&_ul]:my-1 [&_ul]:list-disc [&_ul]:pl-4 [&_ol]:my-1 [&_ol]:list-decimal [&_ol]:pl-4 [&_li]:my-0.5 [&_h1]:text-sm [&_h1]:font-bold [&_h2]:text-sm [&_h2]:font-bold [&_h3]:text-sm [&_h3]:font-semibold [&_hr]:my-2 [&_table]:my-1 [&_table]:w-full [&_th]:pb-1 [&_th]:text-left [&_th]:text-[10px] [&_th]:font-semibold [&_th]:uppercase [&_td]:py-1 [&_td:last-child]:text-right [&_td:last-child]:font-semibold [&_td:last-child]:tabular-nums [&_a]:underline"
|
|
17737
|
-
}
|
|
17738
|
-
)
|
|
17739
|
-
]
|
|
18234
|
+
message: msg,
|
|
18235
|
+
reactions: reactionsByTarget.get(msg.id),
|
|
18236
|
+
businessName,
|
|
18237
|
+
group,
|
|
18238
|
+
delivery,
|
|
18239
|
+
onReply,
|
|
18240
|
+
avatar: /* @__PURE__ */ jsxRuntime.jsx(LetterAvatar, { name: businessName }),
|
|
18241
|
+
onQuoteMiss: async () => {
|
|
18242
|
+
onLoadOlder();
|
|
18243
|
+
return true;
|
|
18244
|
+
}
|
|
17740
18245
|
}
|
|
17741
18246
|
)
|
|
17742
|
-
]
|
|
17743
|
-
|
|
17744
|
-
|
|
17745
|
-
|
|
17746
|
-
|
|
17747
|
-
{
|
|
17748
|
-
className: "rounded-full border border-border bg-background px-1.5 py-0.5 text-xs shadow-sm",
|
|
17749
|
-
children: reaction.content
|
|
17750
|
-
},
|
|
17751
|
-
reaction.id
|
|
17752
|
-
)) }),
|
|
17753
|
-
msg.id === seenMessageId && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-0.5 text-right text-[10px] font-medium text-muted-foreground", children: "Seen" })
|
|
17754
|
-
] }, msg.id);
|
|
18247
|
+
] })
|
|
18248
|
+
]
|
|
18249
|
+
},
|
|
18250
|
+
msg.id
|
|
18251
|
+
);
|
|
17755
18252
|
}),
|
|
17756
18253
|
isSending && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mr-auto mt-1", children: /* @__PURE__ */ jsxRuntime.jsx(TypingDots, {}) }),
|
|
17757
18254
|
offerHuman && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mt-2", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -17776,24 +18273,6 @@ function MessageList({
|
|
|
17776
18273
|
}
|
|
17777
18274
|
);
|
|
17778
18275
|
}
|
|
17779
|
-
function sameDay(a, b) {
|
|
17780
|
-
return new Date(a).toDateString() === new Date(b).toDateString();
|
|
17781
|
-
}
|
|
17782
|
-
function SenderChip({
|
|
17783
|
-
sender,
|
|
17784
|
-
businessName
|
|
17785
|
-
}) {
|
|
17786
|
-
if (sender === "bot") {
|
|
17787
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "mb-1 inline-flex items-center gap-1 rounded bg-primary/10 px-1.5 py-0.5 text-[10px] font-semibold text-primary", children: [
|
|
17788
|
-
/* @__PURE__ */ jsxRuntime.jsx(SparkleIcon, { className: "h-[11px] w-[11px]" }),
|
|
17789
|
-
"AI"
|
|
17790
|
-
] });
|
|
17791
|
-
}
|
|
17792
|
-
if (sender === "agent") {
|
|
17793
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mb-1 inline-flex items-center rounded bg-muted px-1.5 py-0.5 text-[10px] font-semibold text-muted-foreground", children: businessName });
|
|
17794
|
-
}
|
|
17795
|
-
return null;
|
|
17796
|
-
}
|
|
17797
18276
|
function HoverRail({
|
|
17798
18277
|
message,
|
|
17799
18278
|
onReact,
|
|
@@ -18186,19 +18665,6 @@ function ReplyIcon({ className }) {
|
|
|
18186
18665
|
}
|
|
18187
18666
|
);
|
|
18188
18667
|
}
|
|
18189
|
-
function SparkleIcon({ className }) {
|
|
18190
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
18191
|
-
"svg",
|
|
18192
|
-
{
|
|
18193
|
-
className,
|
|
18194
|
-
viewBox: "0 0 24 24",
|
|
18195
|
-
fill: "none",
|
|
18196
|
-
stroke: "currentColor",
|
|
18197
|
-
strokeWidth: 2.5,
|
|
18198
|
-
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 2v4m0 12v4M4.93 4.93l2.83 2.83m8.48 8.48l2.83 2.83M2 12h4m12 0h4M4.93 19.07l2.83-2.83m8.48-8.48l2.83-2.83" })
|
|
18199
|
-
}
|
|
18200
|
-
);
|
|
18201
|
-
}
|
|
18202
18668
|
|
|
18203
18669
|
// src/react/genui/catalog.ts
|
|
18204
18670
|
function genUICatalog(registry) {
|
|
@@ -20023,7 +20489,7 @@ async function genUIFingerprint(manifest) {
|
|
|
20023
20489
|
|
|
20024
20490
|
Object.defineProperty(exports, "getVariantDisplayName", {
|
|
20025
20491
|
enumerable: true,
|
|
20026
|
-
get: function () { return
|
|
20492
|
+
get: function () { return chunkQPRI2NII_js.getVariantDisplayName; }
|
|
20027
20493
|
});
|
|
20028
20494
|
Object.defineProperty(exports, "messagePreview", {
|
|
20029
20495
|
enumerable: true,
|
|
@@ -20064,6 +20530,7 @@ exports.BookingPage = BookingPage;
|
|
|
20064
20530
|
exports.BookingSummary = BookingSummary;
|
|
20065
20531
|
exports.BookingsPage = BookingsPage;
|
|
20066
20532
|
exports.BoxIcon24 = BoxIcon24;
|
|
20533
|
+
exports.BubbleTail = BubbleTail;
|
|
20067
20534
|
exports.BundleProductCard = BundleProductCard;
|
|
20068
20535
|
exports.BundleProductLayout = BundleProductLayout;
|
|
20069
20536
|
exports.BundleSelector = BundleSelector;
|
|
@@ -20138,6 +20605,7 @@ exports.LeaseServiceCard = LeaseServiceCard;
|
|
|
20138
20605
|
exports.LineItemDetails = LineItemDetails;
|
|
20139
20606
|
exports.LocationPicker = LocationPicker;
|
|
20140
20607
|
exports.MediaGallery = MediaGallery;
|
|
20608
|
+
exports.MessageBubble = MessageBubble;
|
|
20141
20609
|
exports.MetadataStringList = MetadataStringList;
|
|
20142
20610
|
exports.MobileAccountShell = MobileAccountShell;
|
|
20143
20611
|
exports.MobileBackButton = MobileBackButton;
|
|
@@ -20172,6 +20640,7 @@ exports.ProductTemplate = ProductTemplate;
|
|
|
20172
20640
|
exports.PropertiesTable = PropertiesTable;
|
|
20173
20641
|
exports.QuantitySelector = QuantitySelector;
|
|
20174
20642
|
exports.QuickAddButton = QuickAddButton;
|
|
20643
|
+
exports.QuoteBlock = QuoteBlock;
|
|
20175
20644
|
exports.RecentlyViewed = RecentlyViewed;
|
|
20176
20645
|
exports.RecommendationCarousel = RecommendationCarousel;
|
|
20177
20646
|
exports.RelatedProductsSection = RelatedProductsSection;
|
|
@@ -20179,10 +20648,12 @@ exports.RentalServiceCard = RentalServiceCard;
|
|
|
20179
20648
|
exports.ResourcePicker = ResourcePicker;
|
|
20180
20649
|
exports.RetailProductCard = RetailProductCard;
|
|
20181
20650
|
exports.RichText = RichText;
|
|
20651
|
+
exports.SWIPE_COMMIT_PX = SWIPE_COMMIT_PX;
|
|
20182
20652
|
exports.SaleBadge = SaleBadge;
|
|
20183
20653
|
exports.SalePrice = SalePrice;
|
|
20184
20654
|
exports.SaleTeaser = SaleTeaser;
|
|
20185
20655
|
exports.ScheduleServiceCard = ScheduleServiceCard;
|
|
20656
|
+
exports.Seam = Seam;
|
|
20186
20657
|
exports.SearchInput = SearchInput;
|
|
20187
20658
|
exports.SearchPage = SearchPage;
|
|
20188
20659
|
exports.SearchTemplate = SearchTemplate;
|
|
@@ -20214,26 +20685,39 @@ exports.WelcomeCard = WelcomeCard;
|
|
|
20214
20685
|
exports.WholesaleProductCard = WholesaleProductCard;
|
|
20215
20686
|
exports.WholesaleProductLayout = WholesaleProductLayout;
|
|
20216
20687
|
exports.WishlistButton = WishlistButton;
|
|
20688
|
+
exports.chatTimeline = chatTimeline;
|
|
20217
20689
|
exports.clearOrdersCache = clearOrdersCache;
|
|
20218
20690
|
exports.cn = cn;
|
|
20219
20691
|
exports.createPlacesSessionToken = createPlacesSessionToken;
|
|
20692
|
+
exports.dayLabel = dayLabel;
|
|
20220
20693
|
exports.defaultBoundaryKind = defaultBoundaryKind;
|
|
20694
|
+
exports.deliveryState = deliveryState;
|
|
20221
20695
|
exports.genUICatalog = genUICatalog;
|
|
20222
20696
|
exports.genUIFingerprint = genUIFingerprint;
|
|
20223
20697
|
exports.genUIManifest = genUIManifest;
|
|
20224
20698
|
exports.genUIManifestJson = genUIManifestJson;
|
|
20225
20699
|
exports.getBoundaryLabels = getBoundaryLabels;
|
|
20700
|
+
exports.groupPosition = groupPosition;
|
|
20226
20701
|
exports.isImageAttachment = isImageAttachment;
|
|
20702
|
+
exports.isOptimistic = isOptimistic;
|
|
20227
20703
|
exports.isTerminalOrderStatus = isTerminalOrderStatus;
|
|
20704
|
+
exports.optimisticId = optimisticId;
|
|
20228
20705
|
exports.parseGenUIProgram = parse;
|
|
20229
20706
|
exports.partitionMessages = partitionMessages;
|
|
20707
|
+
exports.prefersReducedMotion = prefersReducedMotion;
|
|
20230
20708
|
exports.prefetchProduct = prefetchProduct;
|
|
20231
20709
|
exports.prefetchProducts = prefetchProducts;
|
|
20710
|
+
exports.proseOf = proseOf;
|
|
20232
20711
|
exports.resolveBoundaryKind = resolveBoundaryKind;
|
|
20233
20712
|
exports.roomToResource = roomToResource;
|
|
20234
20713
|
exports.safeAttachmentUrl = safeAttachmentUrl;
|
|
20714
|
+
exports.sameDay = sameDay;
|
|
20235
20715
|
exports.sanitizeRichTextHtml = sanitizeRichTextHtml;
|
|
20716
|
+
exports.scrollBehavior = scrollBehavior;
|
|
20236
20717
|
exports.stripHtmlToText = stripHtmlToText;
|
|
20718
|
+
exports.swipeCommitted = swipeCommitted;
|
|
20719
|
+
exports.swipeProgress = swipeProgress;
|
|
20720
|
+
exports.swipeTravel = swipeTravel;
|
|
20237
20721
|
exports.toAccountLineItem = toAccountLineItem;
|
|
20238
20722
|
exports.toAccountLineItems = toAccountLineItems;
|
|
20239
20723
|
exports.toAccountOrderView = toAccountOrderView;
|
|
@@ -20282,6 +20766,7 @@ exports.useServices = useServices;
|
|
|
20282
20766
|
exports.useStoreCredit = useStoreCredit;
|
|
20283
20767
|
exports.useSubscription = useSubscription;
|
|
20284
20768
|
exports.useSubscriptions = useSubscriptions;
|
|
20769
|
+
exports.useSwipeReply = useSwipeReply;
|
|
20285
20770
|
exports.useTaxonomies = useTaxonomies;
|
|
20286
20771
|
exports.useTaxonomy = useTaxonomy;
|
|
20287
20772
|
exports.useTaxonomyPath = useTaxonomyPath;
|