@planetaexo/design-system 0.52.3 → 0.54.1
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/index.cjs +1193 -199
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +261 -10
- package/dist/index.d.ts +261 -10
- package/dist/index.js +1154 -171
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as React29 from 'react';
|
|
2
2
|
import { useState, useRef, useCallback, useEffect, useId } from 'react';
|
|
3
3
|
import { cva } from 'class-variance-authority';
|
|
4
4
|
import { clsx } from 'clsx';
|
|
5
5
|
import { twMerge } from 'tailwind-merge';
|
|
6
6
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
7
|
-
import { XIcon, ChevronDownIcon, CalendarIcon, SearchIcon, ChevronRightIcon, ArrowLeftIcon, CheckCircle2Icon, MapIcon, LogOutIcon, UsersIcon, CreditCardIcon, AlertCircleIcon, MinusIcon, PlusIcon, CircleCheckIcon, SlidersHorizontalIcon, ChevronLeftIcon, HomeIcon, SailboatIcon, CarIcon, WavesIcon, FootprintsIcon, InfoIcon, ClockIcon, CheckIcon, ChevronUpIcon, MenuIcon, UserIcon, SunIcon, MoonIcon, MapPinIcon, PackageIcon, BedDoubleIcon, UtensilsIcon, CompassIcon, BackpackIcon, CherryIcon, ReceiptIcon, Loader2Icon, SendIcon, CheckCircleIcon, Info, MailIcon, PhoneIcon, MessageCircleIcon, UserPlusIcon, ExternalLinkIcon,
|
|
7
|
+
import { XIcon, ChevronDownIcon, CalendarIcon, SearchIcon, ChevronRightIcon, ArrowLeftIcon, CheckCircle2Icon, MapIcon, LogOutIcon, UsersIcon, CreditCardIcon, AlertCircleIcon, MinusIcon, PlusIcon, CircleCheckIcon, SlidersHorizontalIcon, ChevronLeftIcon, HomeIcon, SailboatIcon, CarIcon, WavesIcon, FootprintsIcon, InfoIcon, ClockIcon, CheckIcon, ChevronUpIcon, MenuIcon, UserIcon, SunIcon, MoonIcon, MapPinIcon, PackageIcon, BedDoubleIcon, UtensilsIcon, CompassIcon, BackpackIcon, CherryIcon, ReceiptIcon, ArrowRightIcon, Loader2Icon, SendIcon, CheckCircleIcon, ArrowDownIcon, SparkleIcon, Share2Icon, CopyIcon, Info, MailIcon, PhoneIcon, MessageCircleIcon, UserPlusIcon, ExternalLinkIcon, PencilIcon, Trash2Icon, UserMinusIcon, AlertTriangleIcon, ZoomInIcon, StarIcon, TwitterIcon, YoutubeIcon, LinkedinIcon, InstagramIcon, FacebookIcon, LayoutGridIcon } from 'lucide-react';
|
|
8
8
|
import { Separator as Separator$1 } from '@base-ui/react/separator';
|
|
9
9
|
import { Dialog as Dialog$1 } from '@base-ui/react/dialog';
|
|
10
10
|
import { Button as Button$1 } from '@base-ui/react/button';
|
|
@@ -81,7 +81,7 @@ var buttonVariants = cva(
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
);
|
|
84
|
-
var Button =
|
|
84
|
+
var Button = React29.forwardRef(
|
|
85
85
|
(_a, ref) => {
|
|
86
86
|
var _b = _a, { className, variant, size } = _b, props = __objRest(_b, ["className", "variant", "size"]);
|
|
87
87
|
return /* @__PURE__ */ jsx(
|
|
@@ -310,10 +310,10 @@ function DialogDescription(_a) {
|
|
|
310
310
|
}, props)
|
|
311
311
|
);
|
|
312
312
|
}
|
|
313
|
-
var FloatingInput =
|
|
313
|
+
var FloatingInput = React29.forwardRef(
|
|
314
314
|
(_a, ref) => {
|
|
315
315
|
var _b = _a, { label, error, id, className, required } = _b, props = __objRest(_b, ["label", "error", "id", "className", "required"]);
|
|
316
|
-
const inputId = id != null ? id :
|
|
316
|
+
const inputId = id != null ? id : React29.useId();
|
|
317
317
|
return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
|
|
318
318
|
/* @__PURE__ */ jsx(
|
|
319
319
|
"input",
|
|
@@ -353,10 +353,10 @@ var FloatingInput = React28.forwardRef(
|
|
|
353
353
|
}
|
|
354
354
|
);
|
|
355
355
|
FloatingInput.displayName = "FloatingInput";
|
|
356
|
-
var FloatingSelect =
|
|
356
|
+
var FloatingSelect = React29.forwardRef(
|
|
357
357
|
(_a, ref) => {
|
|
358
358
|
var _b = _a, { label, error, id, className, required, children, value } = _b, props = __objRest(_b, ["label", "error", "id", "className", "required", "children", "value"]);
|
|
359
|
-
const inputId = id != null ? id :
|
|
359
|
+
const inputId = id != null ? id : React29.useId();
|
|
360
360
|
const hasValue = typeof value === "string" ? value !== "" : value !== void 0 && value !== null;
|
|
361
361
|
return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
|
|
362
362
|
/* @__PURE__ */ jsx(
|
|
@@ -620,11 +620,11 @@ function PhoneCountrySelect({
|
|
|
620
620
|
disabled
|
|
621
621
|
}) {
|
|
622
622
|
var _a;
|
|
623
|
-
const [open, setOpen] =
|
|
624
|
-
const containerRef =
|
|
625
|
-
const listRef =
|
|
623
|
+
const [open, setOpen] = React29.useState(false);
|
|
624
|
+
const containerRef = React29.useRef(null);
|
|
625
|
+
const listRef = React29.useRef(null);
|
|
626
626
|
const selected = (_a = PHONE_COUNTRIES.find((c) => c.code === value)) != null ? _a : PHONE_COUNTRIES[0];
|
|
627
|
-
|
|
627
|
+
React29.useEffect(() => {
|
|
628
628
|
if (!open) return;
|
|
629
629
|
const handler = (e) => {
|
|
630
630
|
var _a2;
|
|
@@ -635,7 +635,7 @@ function PhoneCountrySelect({
|
|
|
635
635
|
document.addEventListener("mousedown", handler);
|
|
636
636
|
return () => document.removeEventListener("mousedown", handler);
|
|
637
637
|
}, [open]);
|
|
638
|
-
|
|
638
|
+
React29.useEffect(() => {
|
|
639
639
|
if (!open || !listRef.current) return;
|
|
640
640
|
const activeEl = listRef.current.querySelector("[data-selected=true]");
|
|
641
641
|
activeEl == null ? void 0 : activeEl.scrollIntoView({ block: "nearest" });
|
|
@@ -905,8 +905,8 @@ function CalendarDayButton(_a) {
|
|
|
905
905
|
"locale"
|
|
906
906
|
]);
|
|
907
907
|
const defaultClassNames = getDefaultClassNames();
|
|
908
|
-
const ref =
|
|
909
|
-
|
|
908
|
+
const ref = React29.useRef(null);
|
|
909
|
+
React29.useEffect(() => {
|
|
910
910
|
var _a2;
|
|
911
911
|
if (modifiers.focused) (_a2 = ref.current) == null ? void 0 : _a2.focus();
|
|
912
912
|
}, [modifiers.focused]);
|
|
@@ -937,16 +937,16 @@ function BirthDateField({
|
|
|
937
937
|
className,
|
|
938
938
|
disabled
|
|
939
939
|
}) {
|
|
940
|
-
const [open, setOpen] =
|
|
941
|
-
const [text, setText] =
|
|
940
|
+
const [open, setOpen] = React29.useState(false);
|
|
941
|
+
const [text, setText] = React29.useState(
|
|
942
942
|
value ? format(value, "dd/MM/yyyy") : ""
|
|
943
943
|
);
|
|
944
|
-
const containerRef =
|
|
945
|
-
const inputId =
|
|
946
|
-
|
|
944
|
+
const containerRef = React29.useRef(null);
|
|
945
|
+
const inputId = React29.useId();
|
|
946
|
+
React29.useEffect(() => {
|
|
947
947
|
setText(value ? format(value, "dd/MM/yyyy") : "");
|
|
948
948
|
}, [value]);
|
|
949
|
-
|
|
949
|
+
React29.useEffect(() => {
|
|
950
950
|
if (!open) return;
|
|
951
951
|
const handler = (e) => {
|
|
952
952
|
var _a;
|
|
@@ -1155,14 +1155,14 @@ function CountrySearchField({
|
|
|
1155
1155
|
}) {
|
|
1156
1156
|
var _a;
|
|
1157
1157
|
const list = countries != null ? countries : COUNTRIES;
|
|
1158
|
-
const [query, setQuery] =
|
|
1159
|
-
const [open, setOpen] =
|
|
1160
|
-
const containerRef =
|
|
1161
|
-
const searchRef =
|
|
1158
|
+
const [query, setQuery] = React29.useState("");
|
|
1159
|
+
const [open, setOpen] = React29.useState(false);
|
|
1160
|
+
const containerRef = React29.useRef(null);
|
|
1161
|
+
const searchRef = React29.useRef(null);
|
|
1162
1162
|
const selected = list.find((c) => c.code === value);
|
|
1163
1163
|
const isFloated = open || !!selected;
|
|
1164
1164
|
const filtered = query.trim() ? list.filter((c) => c.name.toLowerCase().includes(query.toLowerCase())) : list;
|
|
1165
|
-
|
|
1165
|
+
React29.useEffect(() => {
|
|
1166
1166
|
if (!open) return;
|
|
1167
1167
|
const handler = (e) => {
|
|
1168
1168
|
var _a2;
|
|
@@ -1256,16 +1256,47 @@ var VARIANT_STYLES = {
|
|
|
1256
1256
|
success: "text-primary border-primary/30 bg-primary/10",
|
|
1257
1257
|
info: "text-muted-foreground border-primary/25 bg-primary/5"
|
|
1258
1258
|
};
|
|
1259
|
-
function Alert({
|
|
1260
|
-
|
|
1259
|
+
function Alert({
|
|
1260
|
+
variant = "info",
|
|
1261
|
+
title,
|
|
1262
|
+
icon,
|
|
1263
|
+
action,
|
|
1264
|
+
role = "status",
|
|
1265
|
+
children,
|
|
1266
|
+
className
|
|
1267
|
+
}) {
|
|
1268
|
+
const isBanner = Boolean(title || icon || action);
|
|
1269
|
+
if (!isBanner) {
|
|
1270
|
+
return /* @__PURE__ */ jsx(
|
|
1271
|
+
"div",
|
|
1272
|
+
{
|
|
1273
|
+
role,
|
|
1274
|
+
className: cn(
|
|
1275
|
+
"rounded-lg border px-3 py-2 text-sm font-sans leading-snug",
|
|
1276
|
+
VARIANT_STYLES[variant],
|
|
1277
|
+
className
|
|
1278
|
+
),
|
|
1279
|
+
children
|
|
1280
|
+
}
|
|
1281
|
+
);
|
|
1282
|
+
}
|
|
1283
|
+
return /* @__PURE__ */ jsxs(
|
|
1261
1284
|
"div",
|
|
1262
1285
|
{
|
|
1286
|
+
role,
|
|
1263
1287
|
className: cn(
|
|
1264
|
-
"rounded-lg border px-
|
|
1288
|
+
"flex items-start gap-3 rounded-lg border px-4 py-3 text-sm font-sans leading-snug",
|
|
1265
1289
|
VARIANT_STYLES[variant],
|
|
1266
1290
|
className
|
|
1267
1291
|
),
|
|
1268
|
-
children
|
|
1292
|
+
children: [
|
|
1293
|
+
icon && /* @__PURE__ */ jsx("span", { className: "mt-0.5 shrink-0 [&>svg]:size-4", "aria-hidden": "true", children: icon }),
|
|
1294
|
+
/* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
|
|
1295
|
+
title && /* @__PURE__ */ jsx("p", { className: "font-ui font-bold text-current leading-snug", children: title }),
|
|
1296
|
+
children && /* @__PURE__ */ jsx("div", { className: cn(title && "mt-0.5", "text-current/90"), children })
|
|
1297
|
+
] }),
|
|
1298
|
+
action && /* @__PURE__ */ jsx("div", { className: "shrink-0 self-center", children: action })
|
|
1299
|
+
]
|
|
1269
1300
|
}
|
|
1270
1301
|
);
|
|
1271
1302
|
}
|
|
@@ -1276,10 +1307,10 @@ function AdventureCard({
|
|
|
1276
1307
|
}) {
|
|
1277
1308
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
|
|
1278
1309
|
const isControlled = (_b = (_a = adventure.optionals) == null ? void 0 : _a.some((o) => o.onCheckedChange !== void 0)) != null ? _b : false;
|
|
1279
|
-
const [checkedInternal, setCheckedInternal] =
|
|
1310
|
+
const [checkedInternal, setCheckedInternal] = React29.useState(
|
|
1280
1311
|
new Set((_d = (_c = adventure.optionals) == null ? void 0 : _c.filter((o) => o.defaultChecked).map((o) => o.id)) != null ? _d : [])
|
|
1281
1312
|
);
|
|
1282
|
-
const [openDescriptionId, setOpenDescriptionId] =
|
|
1313
|
+
const [openDescriptionId, setOpenDescriptionId] = React29.useState(null);
|
|
1283
1314
|
const openDescriptionOptional = openDescriptionId ? (_e = adventure.optionals) == null ? void 0 : _e.find((o) => o.id === openDescriptionId) : void 0;
|
|
1284
1315
|
const isChecked = (opt) => {
|
|
1285
1316
|
var _a2;
|
|
@@ -1709,7 +1740,7 @@ function BookingShell({
|
|
|
1709
1740
|
return /* @__PURE__ */ jsxs("div", { className: "rounded-2xl border border-border bg-card overflow-hidden", children: [
|
|
1710
1741
|
/* @__PURE__ */ jsxs("div", { className: "border-b border-border px-5 py-4 bg-muted/20", children: [
|
|
1711
1742
|
/* @__PURE__ */ jsx("h3", { className: "text-base font-bold text-foreground font-heading mb-2", children: title }),
|
|
1712
|
-
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: steps.map((label, i) => /* @__PURE__ */ jsxs(
|
|
1743
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: steps.map((label, i) => /* @__PURE__ */ jsxs(React29.Fragment, { children: [
|
|
1713
1744
|
/* @__PURE__ */ jsx(
|
|
1714
1745
|
"span",
|
|
1715
1746
|
{
|
|
@@ -1908,7 +1939,7 @@ function TermsSection({
|
|
|
1908
1939
|
termsContent
|
|
1909
1940
|
}) {
|
|
1910
1941
|
var _a;
|
|
1911
|
-
const [modalOpen, setModalOpen] =
|
|
1942
|
+
const [modalOpen, setModalOpen] = React29.useState(false);
|
|
1912
1943
|
const i18n = (_a = TERMS_I18N[locale]) != null ? _a : TERMS_I18N.en;
|
|
1913
1944
|
return /* @__PURE__ */ jsxs("div", { className: "rounded-xl border border-border p-4 flex flex-col gap-3", children: [
|
|
1914
1945
|
/* @__PURE__ */ jsx("p", { className: "text-xs font-bold text-muted-foreground font-heading uppercase tracking-widest", children: title }),
|
|
@@ -2046,9 +2077,9 @@ function BookingWizard({
|
|
|
2046
2077
|
}) {
|
|
2047
2078
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T;
|
|
2048
2079
|
const wizardSteps = WIZARD_STEPS_FN(labels);
|
|
2049
|
-
const [step, setStep] =
|
|
2050
|
-
const [error, setError] =
|
|
2051
|
-
const [responsible, setResponsible] =
|
|
2080
|
+
const [step, setStep] = React29.useState("responsible");
|
|
2081
|
+
const [error, setError] = React29.useState(null);
|
|
2082
|
+
const [responsible, setResponsible] = React29.useState({
|
|
2052
2083
|
firstName: "",
|
|
2053
2084
|
lastName: "",
|
|
2054
2085
|
email: "",
|
|
@@ -2067,7 +2098,7 @@ function BookingWizard({
|
|
|
2067
2098
|
return s + ((_b2 = (_a2 = a.slots) == null ? void 0 : _a2.children) != null ? _b2 : 0);
|
|
2068
2099
|
}, 0);
|
|
2069
2100
|
const totalPax = totalAdults + totalChildren;
|
|
2070
|
-
const [travellers, setTravellers] =
|
|
2101
|
+
const [travellers, setTravellers] = React29.useState(
|
|
2071
2102
|
Array.from({ length: Math.max(totalPax, 1) }, () => ({
|
|
2072
2103
|
firstName: "",
|
|
2073
2104
|
lastName: "",
|
|
@@ -2075,9 +2106,9 @@ function BookingWizard({
|
|
|
2075
2106
|
email: ""
|
|
2076
2107
|
}))
|
|
2077
2108
|
);
|
|
2078
|
-
const [payAmount, setPayAmount] =
|
|
2079
|
-
const [payMethod, setPayMethod] =
|
|
2080
|
-
const [termsAccepted, setTermsAccepted] =
|
|
2109
|
+
const [payAmount, setPayAmount] = React29.useState("full");
|
|
2110
|
+
const [payMethod, setPayMethod] = React29.useState("stripe");
|
|
2111
|
+
const [termsAccepted, setTermsAccepted] = React29.useState(false);
|
|
2081
2112
|
const setR = (k, v) => setResponsible((p) => __spreadProps(__spreadValues({}, p), { [k]: v }));
|
|
2082
2113
|
const setT = (i, k, v) => setTravellers((prev) => prev.map((t, idx) => idx === i ? __spreadProps(__spreadValues({}, t), { [k]: v }) : t));
|
|
2083
2114
|
const setTDob = (i, v) => setTravellers((prev) => prev.map((t, idx) => idx === i ? __spreadProps(__spreadValues({}, t), { dateOfBirth: v }) : t));
|
|
@@ -2305,7 +2336,7 @@ function Offer({
|
|
|
2305
2336
|
className
|
|
2306
2337
|
}) {
|
|
2307
2338
|
var _a, _b, _c;
|
|
2308
|
-
const [showBooking, setShowBooking] =
|
|
2339
|
+
const [showBooking, setShowBooking] = React29.useState(false);
|
|
2309
2340
|
const isShowingCheckout = !confirmedState && (!!checkoutSlot || internalDemoCheckout && showBooking);
|
|
2310
2341
|
const handleBook = () => {
|
|
2311
2342
|
if (!checkoutSlot && !externalBookingFlow && internalDemoCheckout) {
|
|
@@ -2672,7 +2703,7 @@ function AdventureSection({
|
|
|
2672
2703
|
labels
|
|
2673
2704
|
}) {
|
|
2674
2705
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r;
|
|
2675
|
-
const [detailsOpen, setDetailsOpen] =
|
|
2706
|
+
const [detailsOpen, setDetailsOpen] = React29.useState(false);
|
|
2676
2707
|
const handleCopyUrl = (url) => {
|
|
2677
2708
|
if (onCopyFormLink) {
|
|
2678
2709
|
onCopyFormLink(url);
|
|
@@ -3185,8 +3216,8 @@ function AddTravellerDialog({
|
|
|
3185
3216
|
errorMessage
|
|
3186
3217
|
}) {
|
|
3187
3218
|
var _a, _b, _c, _d, _e;
|
|
3188
|
-
const [form, setForm] =
|
|
3189
|
-
|
|
3219
|
+
const [form, setForm] = React29.useState(() => createInitialAddFormData(config));
|
|
3220
|
+
React29.useEffect(() => {
|
|
3190
3221
|
if (open) {
|
|
3191
3222
|
setForm(createInitialAddFormData(config));
|
|
3192
3223
|
}
|
|
@@ -3246,7 +3277,7 @@ function EditTravellerDialog({
|
|
|
3246
3277
|
errorMessage
|
|
3247
3278
|
}) {
|
|
3248
3279
|
var _a, _b, _c, _d, _e;
|
|
3249
|
-
const [form, setForm] =
|
|
3280
|
+
const [form, setForm] = React29.useState(() => ({
|
|
3250
3281
|
firstName: "",
|
|
3251
3282
|
lastName: "",
|
|
3252
3283
|
email: "",
|
|
@@ -3255,7 +3286,7 @@ function EditTravellerDialog({
|
|
|
3255
3286
|
birthDate: "",
|
|
3256
3287
|
personType: "ADULT"
|
|
3257
3288
|
}));
|
|
3258
|
-
|
|
3289
|
+
React29.useEffect(() => {
|
|
3259
3290
|
var _a2, _b2, _c2, _d2, _e2, _f;
|
|
3260
3291
|
if (open && traveller) {
|
|
3261
3292
|
setForm({
|
|
@@ -3591,48 +3622,48 @@ function BookingDetails({
|
|
|
3591
3622
|
const hasSubmitAddTraveller = !!onSubmitAddTraveller;
|
|
3592
3623
|
const hasSubmitEditTraveller = !!onSubmitEditTraveller;
|
|
3593
3624
|
const hasConfirmRemoveTraveller = !!onConfirmRemoveTraveller;
|
|
3594
|
-
const [addModalState, setAddModalState] =
|
|
3625
|
+
const [addModalState, setAddModalState] = React29.useState({
|
|
3595
3626
|
open: false,
|
|
3596
3627
|
adventureId: null
|
|
3597
3628
|
});
|
|
3598
|
-
const [editModalState, setEditModalState] =
|
|
3599
|
-
const [deleteModalState, setDeleteModalState] =
|
|
3600
|
-
const [resendInviteDialogState, setResendInviteDialogState] =
|
|
3601
|
-
const handleRequestOpenAddModal =
|
|
3629
|
+
const [editModalState, setEditModalState] = React29.useState({ open: false, adventureId: null, traveller: null });
|
|
3630
|
+
const [deleteModalState, setDeleteModalState] = React29.useState({ open: false, adventureId: null, traveller: null });
|
|
3631
|
+
const [resendInviteDialogState, setResendInviteDialogState] = React29.useState({ open: false, traveller: null });
|
|
3632
|
+
const handleRequestOpenAddModal = React29.useCallback((adventureId) => {
|
|
3602
3633
|
setAddModalState({ open: true, adventureId });
|
|
3603
3634
|
}, []);
|
|
3604
|
-
const handleRequestOpenEditModal =
|
|
3635
|
+
const handleRequestOpenEditModal = React29.useCallback(
|
|
3605
3636
|
(adventureId, traveller) => {
|
|
3606
3637
|
setEditModalState({ open: true, adventureId, traveller });
|
|
3607
3638
|
},
|
|
3608
3639
|
[]
|
|
3609
3640
|
);
|
|
3610
|
-
const handleRequestOpenDeleteModal =
|
|
3641
|
+
const handleRequestOpenDeleteModal = React29.useCallback(
|
|
3611
3642
|
(adventureId, traveller) => {
|
|
3612
3643
|
setDeleteModalState({ open: true, adventureId, traveller });
|
|
3613
3644
|
},
|
|
3614
3645
|
[]
|
|
3615
3646
|
);
|
|
3616
|
-
const handleRequestOpenResendInviteDialog =
|
|
3647
|
+
const handleRequestOpenResendInviteDialog = React29.useCallback(
|
|
3617
3648
|
(traveller) => {
|
|
3618
3649
|
setResendInviteDialogState({ open: true, traveller });
|
|
3619
3650
|
},
|
|
3620
3651
|
[]
|
|
3621
3652
|
);
|
|
3622
|
-
const closeAddModal =
|
|
3653
|
+
const closeAddModal = React29.useCallback(() => {
|
|
3623
3654
|
setAddModalState({ open: false, adventureId: null });
|
|
3624
3655
|
}, []);
|
|
3625
|
-
const closeEditModal =
|
|
3656
|
+
const closeEditModal = React29.useCallback(() => {
|
|
3626
3657
|
setEditModalState({ open: false, adventureId: null, traveller: null });
|
|
3627
3658
|
}, []);
|
|
3628
|
-
const closeDeleteModal =
|
|
3659
|
+
const closeDeleteModal = React29.useCallback(() => {
|
|
3629
3660
|
setDeleteModalState({ open: false, adventureId: null, traveller: null });
|
|
3630
3661
|
}, []);
|
|
3631
|
-
const closeResendInviteDialog =
|
|
3662
|
+
const closeResendInviteDialog = React29.useCallback(() => {
|
|
3632
3663
|
setResendInviteDialogState({ open: false, traveller: null });
|
|
3633
3664
|
}, []);
|
|
3634
|
-
const submitInFlightRef =
|
|
3635
|
-
const handleAddSubmit =
|
|
3665
|
+
const submitInFlightRef = React29.useRef(false);
|
|
3666
|
+
const handleAddSubmit = React29.useCallback(
|
|
3636
3667
|
async (adventureId, data) => {
|
|
3637
3668
|
if (!onSubmitAddTraveller) return;
|
|
3638
3669
|
if (submitInFlightRef.current) return;
|
|
@@ -3647,7 +3678,7 @@ function BookingDetails({
|
|
|
3647
3678
|
},
|
|
3648
3679
|
[onSubmitAddTraveller, closeAddModal]
|
|
3649
3680
|
);
|
|
3650
|
-
const handleEditSubmit =
|
|
3681
|
+
const handleEditSubmit = React29.useCallback(
|
|
3651
3682
|
async (adventureId, travellerId, data) => {
|
|
3652
3683
|
if (!onSubmitEditTraveller) return;
|
|
3653
3684
|
if (submitInFlightRef.current) return;
|
|
@@ -3662,7 +3693,7 @@ function BookingDetails({
|
|
|
3662
3693
|
},
|
|
3663
3694
|
[onSubmitEditTraveller, closeEditModal]
|
|
3664
3695
|
);
|
|
3665
|
-
const handleDeleteConfirm =
|
|
3696
|
+
const handleDeleteConfirm = React29.useCallback(
|
|
3666
3697
|
async (adventureId, travellerId) => {
|
|
3667
3698
|
if (!onConfirmRemoveTraveller) return;
|
|
3668
3699
|
if (submitInFlightRef.current) return;
|
|
@@ -5238,7 +5269,7 @@ function BookingCreatedEmail({
|
|
|
5238
5269
|
}, children: i + 1 }) }),
|
|
5239
5270
|
/* @__PURE__ */ jsx("td", { style: { verticalAlign: "top" }, children: /* @__PURE__ */ jsx("p", { style: { fontSize: "14px", color: emailTokens.bodyText, lineHeight: "1.6", margin: 0 }, children: step }) })
|
|
5240
5271
|
] }) }) }, i)) }),
|
|
5241
|
-
nextStepsImportant && nextStepsImportant.trim().length > 0 && /* @__PURE__ */ jsx("p", { style: { marginBottom: "32px", fontSize: "14px", color: emailTokens.foreground, lineHeight: "1.6" }, children: nextStepsImportant.split("\n").map((line, idx, arr) => /* @__PURE__ */ jsxs(
|
|
5272
|
+
nextStepsImportant && nextStepsImportant.trim().length > 0 && /* @__PURE__ */ jsx("p", { style: { marginBottom: "32px", fontSize: "14px", color: emailTokens.foreground, lineHeight: "1.6" }, children: nextStepsImportant.split("\n").map((line, idx, arr) => /* @__PURE__ */ jsxs(React29.Fragment, { children: [
|
|
5242
5273
|
idx === 0 ? /* @__PURE__ */ jsx("strong", { children: line }) : line,
|
|
5243
5274
|
idx < arr.length - 1 ? /* @__PURE__ */ jsx("br", {}) : null
|
|
5244
5275
|
] }, idx)) })
|
|
@@ -7258,11 +7289,11 @@ function DatePickerField({
|
|
|
7258
7289
|
fromDate,
|
|
7259
7290
|
className
|
|
7260
7291
|
}) {
|
|
7261
|
-
const [open, setOpen] =
|
|
7262
|
-
const containerRef =
|
|
7263
|
-
const [calendarWidth, setCalendarWidth] =
|
|
7292
|
+
const [open, setOpen] = React29.useState(false);
|
|
7293
|
+
const containerRef = React29.useRef(null);
|
|
7294
|
+
const [calendarWidth, setCalendarWidth] = React29.useState();
|
|
7264
7295
|
const hasValue = !!value;
|
|
7265
|
-
|
|
7296
|
+
React29.useEffect(() => {
|
|
7266
7297
|
if (!containerRef.current) return;
|
|
7267
7298
|
const observer = new ResizeObserver(([entry]) => {
|
|
7268
7299
|
setCalendarWidth(entry.contentRect.width);
|
|
@@ -7371,7 +7402,7 @@ function BookingForm({
|
|
|
7371
7402
|
subtitle = "Free enquiry \u2013 no commitment",
|
|
7372
7403
|
className
|
|
7373
7404
|
}) {
|
|
7374
|
-
const [values, setValues] =
|
|
7405
|
+
const [values, setValues] = React29.useState(__spreadValues(__spreadValues({}, defaultInitial), defaultValues));
|
|
7375
7406
|
const set = (key, value) => setValues((prev) => __spreadProps(__spreadValues({}, prev), { [key]: value }));
|
|
7376
7407
|
const handleSubmit = (e) => {
|
|
7377
7408
|
e.preventDefault();
|
|
@@ -7939,11 +7970,11 @@ function FloatingTextarea({
|
|
|
7939
7970
|
}
|
|
7940
7971
|
function SelectField({ field, value, onChange, error, disabled }) {
|
|
7941
7972
|
var _a, _b, _c;
|
|
7942
|
-
const [open, setOpen] =
|
|
7943
|
-
const containerRef =
|
|
7973
|
+
const [open, setOpen] = React29.useState(false);
|
|
7974
|
+
const containerRef = React29.useRef(null);
|
|
7944
7975
|
const options = (_a = field.options) != null ? _a : [];
|
|
7945
7976
|
const selectedOpt = (_b = options.find((o) => o.value === value)) != null ? _b : null;
|
|
7946
|
-
|
|
7977
|
+
React29.useEffect(() => {
|
|
7947
7978
|
if (!open) return;
|
|
7948
7979
|
const handleOutside = (e) => {
|
|
7949
7980
|
if (containerRef.current && !containerRef.current.contains(e.target)) {
|
|
@@ -8408,11 +8439,11 @@ function RegistrationForm({
|
|
|
8408
8439
|
readOnly = false
|
|
8409
8440
|
}) {
|
|
8410
8441
|
var _a;
|
|
8411
|
-
const L =
|
|
8442
|
+
const L = React29.useMemo(
|
|
8412
8443
|
() => __spreadValues(__spreadValues({}, DEFAULT_LABELS12), labels != null ? labels : {}),
|
|
8413
8444
|
[labels]
|
|
8414
8445
|
);
|
|
8415
|
-
const sortedFields =
|
|
8446
|
+
const sortedFields = React29.useMemo(
|
|
8416
8447
|
() => [...fields].sort((a, b) => {
|
|
8417
8448
|
var _a2, _b;
|
|
8418
8449
|
return ((_a2 = a.order) != null ? _a2 : 0) - ((_b = b.order) != null ? _b : 0);
|
|
@@ -8420,7 +8451,7 @@ function RegistrationForm({
|
|
|
8420
8451
|
[fields]
|
|
8421
8452
|
);
|
|
8422
8453
|
const isControlled = values !== void 0;
|
|
8423
|
-
const [internal, setInternal] =
|
|
8454
|
+
const [internal, setInternal] = React29.useState(
|
|
8424
8455
|
() => initializeValues(
|
|
8425
8456
|
sortedFields,
|
|
8426
8457
|
defaultValues != null ? defaultValues : {},
|
|
@@ -8428,9 +8459,9 @@ function RegistrationForm({
|
|
|
8428
8459
|
includeTerms
|
|
8429
8460
|
)
|
|
8430
8461
|
);
|
|
8431
|
-
const [submitAttempted, setSubmitAttempted] =
|
|
8432
|
-
const [validationErrors, setValidationErrors] =
|
|
8433
|
-
|
|
8462
|
+
const [submitAttempted, setSubmitAttempted] = React29.useState(false);
|
|
8463
|
+
const [validationErrors, setValidationErrors] = React29.useState({});
|
|
8464
|
+
React29.useEffect(() => {
|
|
8434
8465
|
if (isControlled) return;
|
|
8435
8466
|
setInternal((prev) => {
|
|
8436
8467
|
const next = initializeValues(
|
|
@@ -8487,7 +8518,7 @@ function RegistrationForm({
|
|
|
8487
8518
|
const termsError = submitAttempted && termsEnabled && !termsAccepted;
|
|
8488
8519
|
const firstErrorFieldId = Object.keys(fieldErrors)[0];
|
|
8489
8520
|
const scrollTargetId = firstErrorFieldId ? `rf-${firstErrorFieldId}` : termsError ? "rf-terms" : null;
|
|
8490
|
-
|
|
8521
|
+
React29.useEffect(() => {
|
|
8491
8522
|
if (!submitAttempted || !scrollTargetId) return;
|
|
8492
8523
|
const timer = setTimeout(() => {
|
|
8493
8524
|
const elem = document.getElementById(scrollTargetId);
|
|
@@ -8949,10 +8980,10 @@ var OTPCodeInput = ({
|
|
|
8949
8980
|
id,
|
|
8950
8981
|
required
|
|
8951
8982
|
}) => {
|
|
8952
|
-
const baseId = id != null ? id :
|
|
8953
|
-
const inputRef =
|
|
8954
|
-
const [focused, setFocused] =
|
|
8955
|
-
const digits =
|
|
8983
|
+
const baseId = id != null ? id : React29.useId();
|
|
8984
|
+
const inputRef = React29.useRef(null);
|
|
8985
|
+
const [focused, setFocused] = React29.useState(false);
|
|
8986
|
+
const digits = React29.useMemo(() => {
|
|
8956
8987
|
const arr = value.split("").slice(0, length);
|
|
8957
8988
|
while (arr.length < length) arr.push("");
|
|
8958
8989
|
return arr;
|
|
@@ -9065,7 +9096,7 @@ function Checkbox(_a) {
|
|
|
9065
9096
|
})
|
|
9066
9097
|
);
|
|
9067
9098
|
}
|
|
9068
|
-
var AccordionVariantContext =
|
|
9099
|
+
var AccordionVariantContext = React29.createContext("default");
|
|
9069
9100
|
function Accordion(_a) {
|
|
9070
9101
|
var _b = _a, { className, variant = "default" } = _b, props = __objRest(_b, ["className", "variant"]);
|
|
9071
9102
|
return /* @__PURE__ */ jsx(AccordionVariantContext.Provider, { value: variant, children: /* @__PURE__ */ jsx(
|
|
@@ -9083,7 +9114,7 @@ function Accordion(_a) {
|
|
|
9083
9114
|
}
|
|
9084
9115
|
function AccordionItem(_a) {
|
|
9085
9116
|
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
9086
|
-
const variant =
|
|
9117
|
+
const variant = React29.useContext(AccordionVariantContext);
|
|
9087
9118
|
return /* @__PURE__ */ jsx(
|
|
9088
9119
|
Accordion$1.Item,
|
|
9089
9120
|
__spreadValues({
|
|
@@ -9104,7 +9135,7 @@ function AccordionTrigger(_a) {
|
|
|
9104
9135
|
"className",
|
|
9105
9136
|
"children"
|
|
9106
9137
|
]);
|
|
9107
|
-
const variant =
|
|
9138
|
+
const variant = React29.useContext(AccordionVariantContext);
|
|
9108
9139
|
return /* @__PURE__ */ jsx(Accordion$1.Header, { className: "flex", children: /* @__PURE__ */ jsxs(
|
|
9109
9140
|
Accordion$1.Trigger,
|
|
9110
9141
|
__spreadProps(__spreadValues({
|
|
@@ -9158,7 +9189,7 @@ function AccordionContent(_a) {
|
|
|
9158
9189
|
"className",
|
|
9159
9190
|
"children"
|
|
9160
9191
|
]);
|
|
9161
|
-
const variant =
|
|
9192
|
+
const variant = React29.useContext(AccordionVariantContext);
|
|
9162
9193
|
return /* @__PURE__ */ jsx(
|
|
9163
9194
|
Accordion$1.Panel,
|
|
9164
9195
|
__spreadProps(__spreadValues({
|
|
@@ -9376,15 +9407,15 @@ function FilterPanel({
|
|
|
9376
9407
|
onSortChange
|
|
9377
9408
|
}) {
|
|
9378
9409
|
var _a, _b;
|
|
9379
|
-
const resolvedGroups =
|
|
9380
|
-
const [internalValue, setInternalValue] =
|
|
9410
|
+
const resolvedGroups = React29.useMemo(() => resolveGroups(groups), [groups]);
|
|
9411
|
+
const [internalValue, setInternalValue] = React29.useState(
|
|
9381
9412
|
() => Object.fromEntries(groups.map((g) => [g.id, []]))
|
|
9382
9413
|
);
|
|
9383
9414
|
const selected = value != null ? value : internalValue;
|
|
9384
|
-
const [expandedItems, setExpandedItems] =
|
|
9415
|
+
const [expandedItems, setExpandedItems] = React29.useState(
|
|
9385
9416
|
() => new Set(groups.flatMap((g) => getDefaultExpandedIds(g.items)))
|
|
9386
9417
|
);
|
|
9387
|
-
const toggleExpanded =
|
|
9418
|
+
const toggleExpanded = React29.useCallback((id) => {
|
|
9388
9419
|
setExpandedItems((prev) => {
|
|
9389
9420
|
const next = new Set(prev);
|
|
9390
9421
|
if (next.has(id)) next.delete(id);
|
|
@@ -9768,11 +9799,11 @@ function FilterPanel({
|
|
|
9768
9799
|
var TRUSTPILOT_SCRIPT_SRC = "https://widget.trustpilot.com/bootstrap/v5/tp.widget.bootstrap.min.js";
|
|
9769
9800
|
function TrustpilotEmbed({ config }) {
|
|
9770
9801
|
var _a, _b, _c, _d, _e, _f;
|
|
9771
|
-
const ref =
|
|
9772
|
-
const [widgetReady, setWidgetReady] =
|
|
9773
|
-
const [delayPassed, setDelayPassed] =
|
|
9802
|
+
const ref = React29.useRef(null);
|
|
9803
|
+
const [widgetReady, setWidgetReady] = React29.useState(false);
|
|
9804
|
+
const [delayPassed, setDelayPassed] = React29.useState(false);
|
|
9774
9805
|
const showFallback = delayPassed && !widgetReady;
|
|
9775
|
-
|
|
9806
|
+
React29.useEffect(() => {
|
|
9776
9807
|
var _a2;
|
|
9777
9808
|
if (typeof document === "undefined" || !ref.current) return;
|
|
9778
9809
|
const node = ref.current;
|
|
@@ -9959,16 +9990,73 @@ function webpVariantUrl(src) {
|
|
|
9959
9990
|
const withoutQuery = query ? src.slice(0, -query.length) : src;
|
|
9960
9991
|
return `${withoutQuery}.webp${query}`;
|
|
9961
9992
|
}
|
|
9993
|
+
var PLACEHOLDER_SRC = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7";
|
|
9962
9994
|
function Picture(_a) {
|
|
9963
|
-
var _b = _a, {
|
|
9995
|
+
var _b = _a, {
|
|
9996
|
+
src,
|
|
9997
|
+
extraSources,
|
|
9998
|
+
eager = false,
|
|
9999
|
+
rootMargin = "200px",
|
|
10000
|
+
decoding,
|
|
10001
|
+
loading
|
|
10002
|
+
} = _b, imgProps = __objRest(_b, [
|
|
10003
|
+
"src",
|
|
10004
|
+
"extraSources",
|
|
10005
|
+
"eager",
|
|
10006
|
+
"rootMargin",
|
|
10007
|
+
"decoding",
|
|
10008
|
+
"loading"
|
|
10009
|
+
]);
|
|
10010
|
+
const ref = React29.useRef(null);
|
|
10011
|
+
const [visible, setVisible] = React29.useState(eager);
|
|
10012
|
+
React29.useEffect(() => {
|
|
10013
|
+
if (eager || visible) return;
|
|
10014
|
+
const el = ref.current;
|
|
10015
|
+
if (!el || typeof IntersectionObserver === "undefined") {
|
|
10016
|
+
setVisible(true);
|
|
10017
|
+
return;
|
|
10018
|
+
}
|
|
10019
|
+
const io = new IntersectionObserver(
|
|
10020
|
+
(entries) => {
|
|
10021
|
+
if (entries.some((e) => e.isIntersecting)) {
|
|
10022
|
+
setVisible(true);
|
|
10023
|
+
io.disconnect();
|
|
10024
|
+
}
|
|
10025
|
+
},
|
|
10026
|
+
{ rootMargin }
|
|
10027
|
+
);
|
|
10028
|
+
io.observe(el);
|
|
10029
|
+
return () => io.disconnect();
|
|
10030
|
+
}, [eager, visible, rootMargin]);
|
|
9964
10031
|
const webp = webpVariantUrl(src);
|
|
10032
|
+
const realSrc = visible ? src : PLACEHOLDER_SRC;
|
|
10033
|
+
const decodingResolved = decoding != null ? decoding : eager ? void 0 : "async";
|
|
9965
10034
|
if (!webp) {
|
|
9966
|
-
return /* @__PURE__ */ jsx(
|
|
10035
|
+
return /* @__PURE__ */ jsx(
|
|
10036
|
+
"img",
|
|
10037
|
+
__spreadValues({
|
|
10038
|
+
ref,
|
|
10039
|
+
src: realSrc,
|
|
10040
|
+
"data-src": visible ? void 0 : src,
|
|
10041
|
+
decoding: decodingResolved,
|
|
10042
|
+
loading: loading != null ? loading : eager ? void 0 : "lazy"
|
|
10043
|
+
}, imgProps)
|
|
10044
|
+
);
|
|
9967
10045
|
}
|
|
9968
10046
|
return /* @__PURE__ */ jsxs("picture", { style: { display: "contents" }, children: [
|
|
9969
|
-
/* @__PURE__ */ jsx("source", { srcSet: webp, type: "image/webp" }),
|
|
10047
|
+
visible && /* @__PURE__ */ jsx("source", { srcSet: webp, type: "image/webp" }),
|
|
9970
10048
|
extraSources,
|
|
9971
|
-
/* @__PURE__ */ jsx(
|
|
10049
|
+
/* @__PURE__ */ jsx(
|
|
10050
|
+
"img",
|
|
10051
|
+
__spreadValues({
|
|
10052
|
+
ref,
|
|
10053
|
+
src: realSrc,
|
|
10054
|
+
"data-src": visible ? void 0 : src,
|
|
10055
|
+
"data-srcset-webp": visible ? void 0 : webp,
|
|
10056
|
+
decoding: decodingResolved,
|
|
10057
|
+
loading: loading != null ? loading : eager ? void 0 : "lazy"
|
|
10058
|
+
}, imgProps)
|
|
10059
|
+
)
|
|
9972
10060
|
] });
|
|
9973
10061
|
}
|
|
9974
10062
|
function ItineraryDayCard({
|
|
@@ -10037,11 +10125,11 @@ function ItineraryModal({
|
|
|
10037
10125
|
onNext
|
|
10038
10126
|
}) {
|
|
10039
10127
|
var _a, _b, _c;
|
|
10040
|
-
const [imgIndex, setImgIndex] =
|
|
10128
|
+
const [imgIndex, setImgIndex] = React29.useState(0);
|
|
10041
10129
|
const images = stop ? [stop.coverImage, ...(_a = stop.images) != null ? _a : []] : [];
|
|
10042
10130
|
const isFirst = (stop == null ? void 0 : stop.dayNumber) === ((_b = allStops[0]) == null ? void 0 : _b.dayNumber);
|
|
10043
10131
|
const isLast = (stop == null ? void 0 : stop.dayNumber) === ((_c = allStops[allStops.length - 1]) == null ? void 0 : _c.dayNumber);
|
|
10044
|
-
|
|
10132
|
+
React29.useEffect(() => {
|
|
10045
10133
|
setImgIndex(0);
|
|
10046
10134
|
}, [stop == null ? void 0 : stop.dayNumber]);
|
|
10047
10135
|
if (!stop) return null;
|
|
@@ -10168,8 +10256,8 @@ function ItineraryModal({
|
|
|
10168
10256
|
) });
|
|
10169
10257
|
}
|
|
10170
10258
|
function Itinerary({ title, subtitle, stops, className }) {
|
|
10171
|
-
const [activeIndex, setActiveIndex] =
|
|
10172
|
-
const scrollRef =
|
|
10259
|
+
const [activeIndex, setActiveIndex] = React29.useState(null);
|
|
10260
|
+
const scrollRef = React29.useRef(null);
|
|
10173
10261
|
const activeStop = activeIndex !== null ? stops[activeIndex] : null;
|
|
10174
10262
|
const scrollBy = (dir) => {
|
|
10175
10263
|
if (!scrollRef.current) return;
|
|
@@ -10261,18 +10349,18 @@ function Lightbox({
|
|
|
10261
10349
|
onClose
|
|
10262
10350
|
}) {
|
|
10263
10351
|
var _a;
|
|
10264
|
-
const [index, setIndex] =
|
|
10352
|
+
const [index, setIndex] = React29.useState(initialIndex);
|
|
10265
10353
|
const total = photos.length;
|
|
10266
10354
|
const photo = photos[index];
|
|
10267
|
-
const prev =
|
|
10355
|
+
const prev = React29.useCallback(
|
|
10268
10356
|
() => setIndex((i) => (i - 1 + total) % total),
|
|
10269
10357
|
[total]
|
|
10270
10358
|
);
|
|
10271
|
-
const next =
|
|
10359
|
+
const next = React29.useCallback(
|
|
10272
10360
|
() => setIndex((i) => (i + 1) % total),
|
|
10273
10361
|
[total]
|
|
10274
10362
|
);
|
|
10275
|
-
|
|
10363
|
+
React29.useEffect(() => {
|
|
10276
10364
|
const onKey = (e) => {
|
|
10277
10365
|
if (e.key === "Escape") onClose();
|
|
10278
10366
|
if (e.key === "ArrowLeft") prev();
|
|
@@ -10438,7 +10526,7 @@ function GridGallery({
|
|
|
10438
10526
|
initialVisible,
|
|
10439
10527
|
onOpen
|
|
10440
10528
|
}) {
|
|
10441
|
-
const [expanded, setExpanded] =
|
|
10529
|
+
const [expanded, setExpanded] = React29.useState(false);
|
|
10442
10530
|
const cols = gridCols(photos.length);
|
|
10443
10531
|
const hasMore = photos.length > initialVisible;
|
|
10444
10532
|
const visible = expanded || !hasMore ? photos : photos.slice(0, initialVisible);
|
|
@@ -10468,7 +10556,7 @@ function CompactGridGallery({
|
|
|
10468
10556
|
initialVisible,
|
|
10469
10557
|
onOpen
|
|
10470
10558
|
}) {
|
|
10471
|
-
const [expanded, setExpanded] =
|
|
10559
|
+
const [expanded, setExpanded] = React29.useState(false);
|
|
10472
10560
|
const hasMore = photos.length > initialVisible;
|
|
10473
10561
|
const visible = expanded || !hasMore ? photos : photos.slice(0, initialVisible);
|
|
10474
10562
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -10497,7 +10585,7 @@ function MasonryGallery({
|
|
|
10497
10585
|
initialVisible,
|
|
10498
10586
|
onOpen
|
|
10499
10587
|
}) {
|
|
10500
|
-
const [expanded, setExpanded] =
|
|
10588
|
+
const [expanded, setExpanded] = React29.useState(false);
|
|
10501
10589
|
const hasMore = photos.length > initialVisible;
|
|
10502
10590
|
const visible = expanded || !hasMore ? photos : photos.slice(0, initialVisible);
|
|
10503
10591
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -10570,7 +10658,7 @@ function FeaturedGallery({
|
|
|
10570
10658
|
photos,
|
|
10571
10659
|
onOpen
|
|
10572
10660
|
}) {
|
|
10573
|
-
const [expanded, setExpanded] =
|
|
10661
|
+
const [expanded, setExpanded] = React29.useState(false);
|
|
10574
10662
|
const featured = photos.slice(0, 3);
|
|
10575
10663
|
const extra = photos.slice(3);
|
|
10576
10664
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -10737,9 +10825,9 @@ function PhotoGallery({
|
|
|
10737
10825
|
onPhotoClick,
|
|
10738
10826
|
className
|
|
10739
10827
|
}) {
|
|
10740
|
-
const [lightboxIndex, setLightboxIndex] =
|
|
10741
|
-
const [carouselIndex, setCarouselIndex] =
|
|
10742
|
-
const normalised =
|
|
10828
|
+
const [lightboxIndex, setLightboxIndex] = React29.useState(null);
|
|
10829
|
+
const [carouselIndex, setCarouselIndex] = React29.useState(0);
|
|
10830
|
+
const normalised = React29.useMemo(() => photos.map(normalise), [photos]);
|
|
10743
10831
|
const handleOpen = (index) => {
|
|
10744
10832
|
setLightboxIndex(index);
|
|
10745
10833
|
onPhotoClick == null ? void 0 : onPhotoClick(normalised[index].src, index);
|
|
@@ -10823,7 +10911,7 @@ function ItineraryDay({
|
|
|
10823
10911
|
photoLayout = "rounded",
|
|
10824
10912
|
className
|
|
10825
10913
|
}) {
|
|
10826
|
-
const photoList =
|
|
10914
|
+
const photoList = React29.useMemo(() => normalisePhotos(photos), [photos]);
|
|
10827
10915
|
const isFullBleed = photoLayout === "fullBleed" || photoLayout === "fullBleedBottom";
|
|
10828
10916
|
const photoPosition = photoLayout === "fullBleedBottom" ? "bottom" : "top";
|
|
10829
10917
|
const gallery = photoList.length > 0 && /* @__PURE__ */ jsx(
|
|
@@ -10878,8 +10966,8 @@ function MenuTrip({
|
|
|
10878
10966
|
bold = true,
|
|
10879
10967
|
className
|
|
10880
10968
|
}) {
|
|
10881
|
-
const scrollRef =
|
|
10882
|
-
|
|
10969
|
+
const scrollRef = React29.useRef(null);
|
|
10970
|
+
React29.useEffect(() => {
|
|
10883
10971
|
if (!scrollRef.current || !activeSection) return;
|
|
10884
10972
|
const container = scrollRef.current;
|
|
10885
10973
|
const btn = container.querySelector(
|
|
@@ -11021,7 +11109,12 @@ var badgeVariants = cva(
|
|
|
11021
11109
|
destructive: "bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20",
|
|
11022
11110
|
outline: "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
|
|
11023
11111
|
ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
|
|
11024
|
-
link: "text-primary underline-offset-4 hover:underline"
|
|
11112
|
+
link: "text-primary underline-offset-4 hover:underline",
|
|
11113
|
+
// ── Semantic soft tones (added for status surfaces) ────────────────
|
|
11114
|
+
success: "bg-success/10 text-success border-success/20 [a]:hover:bg-success/20",
|
|
11115
|
+
warning: "bg-warning/15 text-warning-foreground border-warning/30 dark:bg-warning/20 dark:text-warning [a]:hover:bg-warning/25",
|
|
11116
|
+
info: "bg-info/10 text-info border-info/20 [a]:hover:bg-info/20",
|
|
11117
|
+
neutral: "bg-muted text-muted-foreground border-border [a]:hover:bg-muted/70"
|
|
11025
11118
|
}
|
|
11026
11119
|
},
|
|
11027
11120
|
defaultVariants: {
|
|
@@ -11070,8 +11163,8 @@ function PricingTrip({
|
|
|
11070
11163
|
className
|
|
11071
11164
|
}) {
|
|
11072
11165
|
const rOuter = sharp ? "rounded-none" : "rounded-2xl";
|
|
11073
|
-
const [showEstimates, setShowEstimates] =
|
|
11074
|
-
const [showPriceInfo, setShowPriceInfo] =
|
|
11166
|
+
const [showEstimates, setShowEstimates] = React29.useState(false);
|
|
11167
|
+
const [showPriceInfo, setShowPriceInfo] = React29.useState(false);
|
|
11075
11168
|
if (variant === "compact") {
|
|
11076
11169
|
const showOverlay = showPriceInfo && (!!priceInfo || !!currencyEstimates && currencyEstimates.length > 0);
|
|
11077
11170
|
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-2", className), children: [
|
|
@@ -11511,14 +11604,14 @@ function SiteHeader({
|
|
|
11511
11604
|
}) {
|
|
11512
11605
|
const t = VARIANT[variant];
|
|
11513
11606
|
const resolvedLogo = logoSrc != null ? logoSrc : variant === "white" ? logoSrcDark : logoSrcLight;
|
|
11514
|
-
const [openMenu, setOpenMenu] =
|
|
11515
|
-
const [langOpen, setLangOpen] =
|
|
11516
|
-
const [mobileOpen, setMobileOpen] =
|
|
11517
|
-
const [openMobileSection, setOpenMobileSection] =
|
|
11518
|
-
const [activeLang, setActiveLang] =
|
|
11607
|
+
const [openMenu, setOpenMenu] = React29.useState(null);
|
|
11608
|
+
const [langOpen, setLangOpen] = React29.useState(false);
|
|
11609
|
+
const [mobileOpen, setMobileOpen] = React29.useState(false);
|
|
11610
|
+
const [openMobileSection, setOpenMobileSection] = React29.useState(null);
|
|
11611
|
+
const [activeLang, setActiveLang] = React29.useState(currentLanguage);
|
|
11519
11612
|
const toggleMobileSection = (label) => setOpenMobileSection((prev) => prev === label ? null : label);
|
|
11520
|
-
const menuCloseTimer =
|
|
11521
|
-
const langCloseTimer =
|
|
11613
|
+
const menuCloseTimer = React29.useRef(void 0);
|
|
11614
|
+
const langCloseTimer = React29.useRef(void 0);
|
|
11522
11615
|
const handleMenuEnter = (label) => {
|
|
11523
11616
|
clearTimeout(menuCloseTimer.current);
|
|
11524
11617
|
setOpenMenu(label);
|
|
@@ -11539,7 +11632,7 @@ function SiteHeader({
|
|
|
11539
11632
|
setOpenMenu(null);
|
|
11540
11633
|
setLangOpen(false);
|
|
11541
11634
|
};
|
|
11542
|
-
|
|
11635
|
+
React29.useEffect(() => () => {
|
|
11543
11636
|
clearTimeout(menuCloseTimer.current);
|
|
11544
11637
|
clearTimeout(langCloseTimer.current);
|
|
11545
11638
|
}, []);
|
|
@@ -11815,7 +11908,7 @@ function SiteHeader({
|
|
|
11815
11908
|
), children: [
|
|
11816
11909
|
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: languages.map((lang, i) => {
|
|
11817
11910
|
const isActive = lang.code === activeLang;
|
|
11818
|
-
return /* @__PURE__ */ jsxs(
|
|
11911
|
+
return /* @__PURE__ */ jsxs(React29.Fragment, { children: [
|
|
11819
11912
|
i > 0 && /* @__PURE__ */ jsx("span", { className: cn(
|
|
11820
11913
|
"text-xs select-none",
|
|
11821
11914
|
variant === "white" ? "text-border" : "text-white/15"
|
|
@@ -11877,8 +11970,8 @@ function SiteHeader({
|
|
|
11877
11970
|
);
|
|
11878
11971
|
}
|
|
11879
11972
|
function ThemeToggle({ className }) {
|
|
11880
|
-
const [dark, setDark] =
|
|
11881
|
-
|
|
11973
|
+
const [dark, setDark] = React29.useState(false);
|
|
11974
|
+
React29.useEffect(() => {
|
|
11882
11975
|
const saved = localStorage.getItem("theme");
|
|
11883
11976
|
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
11884
11977
|
const isDark = saved === "dark" || !saved && prefersDark;
|
|
@@ -11928,7 +12021,7 @@ var chipVariants = cva(
|
|
|
11928
12021
|
}
|
|
11929
12022
|
}
|
|
11930
12023
|
);
|
|
11931
|
-
var Chip =
|
|
12024
|
+
var Chip = React29.forwardRef(function Chip2(_a, ref) {
|
|
11932
12025
|
var _b = _a, { className, variant, size, href, children } = _b, props = __objRest(_b, ["className", "variant", "size", "href", "children"]);
|
|
11933
12026
|
const classes = cn(chipVariants({ variant, size }), className);
|
|
11934
12027
|
if (href) {
|
|
@@ -12028,7 +12121,7 @@ function TripCardEditorial(props) {
|
|
|
12028
12121
|
difficulty,
|
|
12029
12122
|
tag
|
|
12030
12123
|
} = props;
|
|
12031
|
-
const [internalFav, setInternalFav] =
|
|
12124
|
+
const [internalFav, setInternalFav] = React29.useState(false);
|
|
12032
12125
|
const favorited = favoritedProp != null ? favoritedProp : internalFav;
|
|
12033
12126
|
const handleFav = (e) => {
|
|
12034
12127
|
e.preventDefault();
|
|
@@ -12173,7 +12266,7 @@ function TripCard(props) {
|
|
|
12173
12266
|
);
|
|
12174
12267
|
}
|
|
12175
12268
|
function useHlsVideo(videoRef, src) {
|
|
12176
|
-
|
|
12269
|
+
React29.useEffect(() => {
|
|
12177
12270
|
if (!src || !videoRef.current) return;
|
|
12178
12271
|
const video = videoRef.current;
|
|
12179
12272
|
if (!src.includes(".m3u8")) return;
|
|
@@ -12217,11 +12310,11 @@ function TripHeader({
|
|
|
12217
12310
|
className
|
|
12218
12311
|
}) {
|
|
12219
12312
|
var _a;
|
|
12220
|
-
const [heroIndex, setHeroIndex] =
|
|
12221
|
-
const [videoReady, setVideoReady] =
|
|
12222
|
-
const videoRef =
|
|
12313
|
+
const [heroIndex, setHeroIndex] = React29.useState(0);
|
|
12314
|
+
const [videoReady, setVideoReady] = React29.useState(false);
|
|
12315
|
+
const videoRef = React29.useRef(null);
|
|
12223
12316
|
const isHls = !!(videoUrl == null ? void 0 : videoUrl.includes(".m3u8"));
|
|
12224
|
-
const validImages =
|
|
12317
|
+
const validImages = React29.useMemo(
|
|
12225
12318
|
() => images.map((u) => u == null ? void 0 : u.trim()).filter(Boolean),
|
|
12226
12319
|
[images]
|
|
12227
12320
|
);
|
|
@@ -12236,7 +12329,7 @@ function TripHeader({
|
|
|
12236
12329
|
const nights = duration ? (_a = duration.nights) != null ? _a : Math.max(duration.days - 1, 1) : null;
|
|
12237
12330
|
const hasMeta = !!(destination || duration);
|
|
12238
12331
|
useHlsVideo(videoRef, isHls ? videoUrl : void 0);
|
|
12239
|
-
|
|
12332
|
+
React29.useEffect(() => {
|
|
12240
12333
|
if (!videoUrl) return;
|
|
12241
12334
|
const el = videoRef.current;
|
|
12242
12335
|
if (!el) return;
|
|
@@ -12284,6 +12377,7 @@ function TripHeader({
|
|
|
12284
12377
|
alt: "",
|
|
12285
12378
|
"aria-hidden": true,
|
|
12286
12379
|
fetchPriority: "high",
|
|
12380
|
+
eager: true,
|
|
12287
12381
|
className: cn(
|
|
12288
12382
|
"absolute inset-0 h-full w-full object-cover transition-opacity duration-700",
|
|
12289
12383
|
videoReady ? "opacity-0 pointer-events-none" : "opacity-100"
|
|
@@ -12320,6 +12414,7 @@ function TripHeader({
|
|
|
12320
12414
|
src: currentSrc,
|
|
12321
12415
|
alt: title,
|
|
12322
12416
|
fetchPriority: safeIndex === 0 ? "high" : "auto",
|
|
12417
|
+
eager: safeIndex === 0,
|
|
12323
12418
|
className: "absolute inset-0 h-full w-full object-cover transition-opacity duration-700"
|
|
12324
12419
|
}
|
|
12325
12420
|
) : null,
|
|
@@ -12377,7 +12472,7 @@ function TripHeader({
|
|
|
12377
12472
|
chips && chips.length > 0 ? siteHeader ? "-mt-[200px] sm:-mt-[214px]" : "-mt-[168px] sm:-mt-[182px]" : siteHeader ? "-mt-44" : "-mt-36"
|
|
12378
12473
|
),
|
|
12379
12474
|
children: [
|
|
12380
|
-
breadcrumb && breadcrumb.length > 0 && /* @__PURE__ */ jsx("div", { className: "mb-3 flex items-center gap-1.5 flex-wrap", children: breadcrumb.map((crumb, i) => /* @__PURE__ */ jsxs(
|
|
12475
|
+
breadcrumb && breadcrumb.length > 0 && /* @__PURE__ */ jsx("div", { className: "mb-3 flex items-center gap-1.5 flex-wrap", children: breadcrumb.map((crumb, i) => /* @__PURE__ */ jsxs(React29.Fragment, { children: [
|
|
12381
12476
|
i > 0 && /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-3 w-3 text-white/50 shrink-0" }),
|
|
12382
12477
|
/* @__PURE__ */ jsx("span", { className: "text-xs text-white/70 font-ui hover:text-white/90 cursor-default", children: crumb.label })
|
|
12383
12478
|
] }, i)) }),
|
|
@@ -12543,10 +12638,10 @@ function LanguagePicker({
|
|
|
12543
12638
|
}) {
|
|
12544
12639
|
var _a;
|
|
12545
12640
|
const t = VARIANT2[variant];
|
|
12546
|
-
const [open, setOpen] =
|
|
12547
|
-
const ref =
|
|
12641
|
+
const [open, setOpen] = React29.useState(false);
|
|
12642
|
+
const ref = React29.useRef(null);
|
|
12548
12643
|
const active = (_a = languages.find((l) => l.code === currentLanguage)) != null ? _a : languages[0];
|
|
12549
|
-
|
|
12644
|
+
React29.useEffect(() => {
|
|
12550
12645
|
if (!open) return;
|
|
12551
12646
|
const onDocClick = (e) => {
|
|
12552
12647
|
if (ref.current && !ref.current.contains(e.target)) {
|
|
@@ -12747,7 +12842,7 @@ function SiteFooter({
|
|
|
12747
12842
|
children: wrapper
|
|
12748
12843
|
},
|
|
12749
12844
|
b.alt + i
|
|
12750
|
-
) : /* @__PURE__ */ jsx(
|
|
12845
|
+
) : /* @__PURE__ */ jsx(React29.Fragment, { children: wrapper }, b.alt + i);
|
|
12751
12846
|
}) })
|
|
12752
12847
|
] }),
|
|
12753
12848
|
themes.length > 0 && /* @__PURE__ */ jsxs("div", { className: "lg:col-span-3", children: [
|
|
@@ -12922,10 +13017,10 @@ function TripPage({
|
|
|
12922
13017
|
className
|
|
12923
13018
|
}) {
|
|
12924
13019
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
|
|
12925
|
-
const [activeSection, setActiveSection] =
|
|
12926
|
-
const [accordionValue, setAccordionValue] =
|
|
12927
|
-
const [faqsExpanded, setFaqsExpanded] =
|
|
12928
|
-
const accordionSectionIds =
|
|
13020
|
+
const [activeSection, setActiveSection] = React29.useState("");
|
|
13021
|
+
const [accordionValue, setAccordionValue] = React29.useState([]);
|
|
13022
|
+
const [faqsExpanded, setFaqsExpanded] = React29.useState(false);
|
|
13023
|
+
const accordionSectionIds = React29.useMemo(
|
|
12929
13024
|
() => /* @__PURE__ */ new Set([
|
|
12930
13025
|
"when-it-operates",
|
|
12931
13026
|
"how-to-get-there",
|
|
@@ -12939,18 +13034,18 @@ function TripPage({
|
|
|
12939
13034
|
]),
|
|
12940
13035
|
[]
|
|
12941
13036
|
);
|
|
12942
|
-
const [navFloating, setNavFloating] =
|
|
12943
|
-
const [navHidden, setNavHidden] =
|
|
12944
|
-
const [isFloating, setIsFloating] =
|
|
12945
|
-
const [sidebarPos, setSidebarPos] =
|
|
12946
|
-
const [pricingBarVisible, setPricingBarVisible] =
|
|
12947
|
-
const navRef =
|
|
12948
|
-
const navSentinelRef =
|
|
12949
|
-
const sentinelRef =
|
|
12950
|
-
const sidebarPlaceholderRef =
|
|
12951
|
-
const pricingBarRef =
|
|
12952
|
-
const galleryRef =
|
|
12953
|
-
const sections =
|
|
13037
|
+
const [navFloating, setNavFloating] = React29.useState(false);
|
|
13038
|
+
const [navHidden, setNavHidden] = React29.useState(false);
|
|
13039
|
+
const [isFloating, setIsFloating] = React29.useState(false);
|
|
13040
|
+
const [sidebarPos, setSidebarPos] = React29.useState(null);
|
|
13041
|
+
const [pricingBarVisible, setPricingBarVisible] = React29.useState(false);
|
|
13042
|
+
const navRef = React29.useRef(null);
|
|
13043
|
+
const navSentinelRef = React29.useRef(null);
|
|
13044
|
+
const sentinelRef = React29.useRef(null);
|
|
13045
|
+
const sidebarPlaceholderRef = React29.useRef(null);
|
|
13046
|
+
const pricingBarRef = React29.useRef(null);
|
|
13047
|
+
const galleryRef = React29.useRef(null);
|
|
13048
|
+
const sections = React29.useMemo(
|
|
12954
13049
|
() => {
|
|
12955
13050
|
var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2;
|
|
12956
13051
|
return [
|
|
@@ -12972,7 +13067,7 @@ function TripPage({
|
|
|
12972
13067
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
12973
13068
|
[]
|
|
12974
13069
|
);
|
|
12975
|
-
|
|
13070
|
+
React29.useEffect(() => {
|
|
12976
13071
|
const sentinel = navSentinelRef.current;
|
|
12977
13072
|
if (!sentinel) return;
|
|
12978
13073
|
const update = () => setNavFloating(sentinel.getBoundingClientRect().top < 1);
|
|
@@ -12980,7 +13075,7 @@ function TripPage({
|
|
|
12980
13075
|
update();
|
|
12981
13076
|
return () => document.removeEventListener("scroll", update, { capture: true });
|
|
12982
13077
|
}, []);
|
|
12983
|
-
|
|
13078
|
+
React29.useEffect(() => {
|
|
12984
13079
|
const sentinel = sentinelRef.current;
|
|
12985
13080
|
if (!sentinel) return;
|
|
12986
13081
|
const update = () => setIsFloating(sentinel.getBoundingClientRect().top < 1);
|
|
@@ -12988,7 +13083,7 @@ function TripPage({
|
|
|
12988
13083
|
update();
|
|
12989
13084
|
return () => document.removeEventListener("scroll", update, { capture: true });
|
|
12990
13085
|
}, []);
|
|
12991
|
-
|
|
13086
|
+
React29.useEffect(() => {
|
|
12992
13087
|
const measure = () => {
|
|
12993
13088
|
if (!sidebarPlaceholderRef.current) return;
|
|
12994
13089
|
const rect = sidebarPlaceholderRef.current.getBoundingClientRect();
|
|
@@ -12998,7 +13093,7 @@ function TripPage({
|
|
|
12998
13093
|
window.addEventListener("resize", measure);
|
|
12999
13094
|
return () => window.removeEventListener("resize", measure);
|
|
13000
13095
|
}, [isFloating]);
|
|
13001
|
-
|
|
13096
|
+
React29.useEffect(() => {
|
|
13002
13097
|
const check = () => {
|
|
13003
13098
|
var _a2;
|
|
13004
13099
|
const target = (_a2 = galleryRef.current) != null ? _a2 : pricingBarRef.current;
|
|
@@ -13009,7 +13104,7 @@ function TripPage({
|
|
|
13009
13104
|
check();
|
|
13010
13105
|
return () => document.removeEventListener("scroll", check, { capture: true });
|
|
13011
13106
|
}, []);
|
|
13012
|
-
|
|
13107
|
+
React29.useEffect(() => {
|
|
13013
13108
|
const check = () => {
|
|
13014
13109
|
if (!pricingBarRef.current) return;
|
|
13015
13110
|
setNavHidden(pricingBarRef.current.getBoundingClientRect().top < window.innerHeight * 0.92);
|
|
@@ -13018,7 +13113,7 @@ function TripPage({
|
|
|
13018
13113
|
check();
|
|
13019
13114
|
return () => document.removeEventListener("scroll", check, { capture: true });
|
|
13020
13115
|
}, []);
|
|
13021
|
-
|
|
13116
|
+
React29.useEffect(() => {
|
|
13022
13117
|
if (sections.length === 0) return;
|
|
13023
13118
|
setActiveSection(sections[0].id);
|
|
13024
13119
|
const update = () => {
|
|
@@ -13493,7 +13588,385 @@ function TripPage({
|
|
|
13493
13588
|
}
|
|
13494
13589
|
);
|
|
13495
13590
|
}
|
|
13591
|
+
function ArrowIcon2() {
|
|
13592
|
+
return /* @__PURE__ */ jsxs(
|
|
13593
|
+
"svg",
|
|
13594
|
+
{
|
|
13595
|
+
width: "13",
|
|
13596
|
+
height: "13",
|
|
13597
|
+
viewBox: "0 0 24 24",
|
|
13598
|
+
fill: "none",
|
|
13599
|
+
stroke: "currentColor",
|
|
13600
|
+
strokeWidth: "2.2",
|
|
13601
|
+
strokeLinecap: "round",
|
|
13602
|
+
strokeLinejoin: "round",
|
|
13603
|
+
children: [
|
|
13604
|
+
/* @__PURE__ */ jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" }),
|
|
13605
|
+
/* @__PURE__ */ jsx("polyline", { points: "12 5 19 12 12 19" })
|
|
13606
|
+
]
|
|
13607
|
+
}
|
|
13608
|
+
);
|
|
13609
|
+
}
|
|
13496
13610
|
var sizeConfig2 = {
|
|
13611
|
+
sm: {
|
|
13612
|
+
card: "h-72 w-56",
|
|
13613
|
+
title: "text-lg font-bold",
|
|
13614
|
+
meta: "text-xs",
|
|
13615
|
+
excerpt: "text-xs"
|
|
13616
|
+
},
|
|
13617
|
+
md: {
|
|
13618
|
+
card: "h-96 w-72",
|
|
13619
|
+
title: "text-xl font-bold",
|
|
13620
|
+
meta: "text-xs",
|
|
13621
|
+
excerpt: "text-sm"
|
|
13622
|
+
},
|
|
13623
|
+
lg: {
|
|
13624
|
+
card: "h-[28rem] w-96",
|
|
13625
|
+
title: "text-2xl font-bold",
|
|
13626
|
+
meta: "text-sm",
|
|
13627
|
+
excerpt: "text-sm"
|
|
13628
|
+
}
|
|
13629
|
+
};
|
|
13630
|
+
function BlogCard({
|
|
13631
|
+
image,
|
|
13632
|
+
imageAlt = "",
|
|
13633
|
+
category,
|
|
13634
|
+
readingTime,
|
|
13635
|
+
date,
|
|
13636
|
+
title,
|
|
13637
|
+
excerpt,
|
|
13638
|
+
href,
|
|
13639
|
+
cta,
|
|
13640
|
+
size = "md",
|
|
13641
|
+
className
|
|
13642
|
+
}) {
|
|
13643
|
+
var _a;
|
|
13644
|
+
const s = sizeConfig2[size];
|
|
13645
|
+
const meta = [date != null ? date : null, readingTime != null ? readingTime : null].filter(Boolean).join(" | ");
|
|
13646
|
+
const ctaLabel = (_a = cta == null ? void 0 : cta.label) != null ? _a : "Read more";
|
|
13647
|
+
const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
13648
|
+
/* @__PURE__ */ jsx(
|
|
13649
|
+
"img",
|
|
13650
|
+
{
|
|
13651
|
+
src: image,
|
|
13652
|
+
alt: imageAlt,
|
|
13653
|
+
loading: "lazy",
|
|
13654
|
+
className: "absolute inset-0 h-full w-full object-cover transition-transform duration-500 group-hover:scale-105"
|
|
13655
|
+
}
|
|
13656
|
+
),
|
|
13657
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/90 via-black/40 to-black/10" }),
|
|
13658
|
+
category ? /* @__PURE__ */ jsx("div", { className: "relative z-10 p-3", children: /* @__PURE__ */ jsx(Chip, { variant: "glass", children: category }) }) : /* @__PURE__ */ jsx("div", { className: "relative z-10" }),
|
|
13659
|
+
/* @__PURE__ */ jsxs("div", { className: "relative z-10 flex flex-col gap-1.5 p-5", children: [
|
|
13660
|
+
meta && /* @__PURE__ */ jsx("p", { className: cn("text-white/70 font-medium font-ui", s.meta), children: meta }),
|
|
13661
|
+
/* @__PURE__ */ jsx("h3", { className: cn("text-white leading-snug", s.title), children: title }),
|
|
13662
|
+
excerpt && /* @__PURE__ */ jsx(
|
|
13663
|
+
"p",
|
|
13664
|
+
{
|
|
13665
|
+
className: cn(
|
|
13666
|
+
"text-white/80 leading-relaxed -mt-1 line-clamp-2",
|
|
13667
|
+
s.excerpt
|
|
13668
|
+
),
|
|
13669
|
+
children: excerpt
|
|
13670
|
+
}
|
|
13671
|
+
),
|
|
13672
|
+
/* @__PURE__ */ jsx("div", { className: "mt-3 flex items-center justify-between gap-4", children: /* @__PURE__ */ jsxs(
|
|
13673
|
+
"span",
|
|
13674
|
+
{
|
|
13675
|
+
className: cn(
|
|
13676
|
+
"group/cta inline-flex items-center gap-1.5 border-b border-white/70 pb-0.5",
|
|
13677
|
+
"text-sm font-semibold text-white transition-colors hover:border-white hover:text-white",
|
|
13678
|
+
"font-ui"
|
|
13679
|
+
),
|
|
13680
|
+
children: [
|
|
13681
|
+
ctaLabel,
|
|
13682
|
+
/* @__PURE__ */ jsx("span", { className: "transition-transform duration-150 group-hover/cta:translate-x-0.5", children: /* @__PURE__ */ jsx(ArrowIcon2, {}) })
|
|
13683
|
+
]
|
|
13684
|
+
}
|
|
13685
|
+
) })
|
|
13686
|
+
] })
|
|
13687
|
+
] });
|
|
13688
|
+
const baseClasses = cn(
|
|
13689
|
+
"group relative flex flex-col justify-between overflow-hidden rounded-2xl",
|
|
13690
|
+
"shadow-md transition-shadow duration-300 hover:shadow-xl",
|
|
13691
|
+
s.card,
|
|
13692
|
+
className
|
|
13693
|
+
);
|
|
13694
|
+
return href ? /* @__PURE__ */ jsx(
|
|
13695
|
+
"a",
|
|
13696
|
+
{
|
|
13697
|
+
href,
|
|
13698
|
+
onClick: cta == null ? void 0 : cta.onClick,
|
|
13699
|
+
className: baseClasses,
|
|
13700
|
+
"aria-label": title,
|
|
13701
|
+
children: inner
|
|
13702
|
+
}
|
|
13703
|
+
) : /* @__PURE__ */ jsx("div", { className: baseClasses, children: inner });
|
|
13704
|
+
}
|
|
13705
|
+
function SectionHeading({
|
|
13706
|
+
eyebrow,
|
|
13707
|
+
title,
|
|
13708
|
+
rightSlot
|
|
13709
|
+
}) {
|
|
13710
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-end justify-between gap-4 flex-wrap mb-6", children: [
|
|
13711
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
13712
|
+
eyebrow && /* @__PURE__ */ jsx("p", { className: "text-xs font-mono font-semibold text-primary uppercase tracking-widest mb-1", children: eyebrow }),
|
|
13713
|
+
/* @__PURE__ */ jsx("h2", { className: "text-2xl sm:text-3xl font-bold text-foreground font-heading leading-tight", children: title })
|
|
13714
|
+
] }),
|
|
13715
|
+
rightSlot
|
|
13716
|
+
] });
|
|
13717
|
+
}
|
|
13718
|
+
function CategoryPage2({
|
|
13719
|
+
title,
|
|
13720
|
+
intro,
|
|
13721
|
+
heroImage,
|
|
13722
|
+
trustpilotMini,
|
|
13723
|
+
breadcrumb,
|
|
13724
|
+
siteHeader,
|
|
13725
|
+
popularTours,
|
|
13726
|
+
popularToursTitle = "More adventures calling your name",
|
|
13727
|
+
popularToursEyebrow = "Popular tours",
|
|
13728
|
+
trips,
|
|
13729
|
+
tripsTitle,
|
|
13730
|
+
tripsEyebrow,
|
|
13731
|
+
filterGroups,
|
|
13732
|
+
sortOptions,
|
|
13733
|
+
defaultSort,
|
|
13734
|
+
tripsInitialCount = 15,
|
|
13735
|
+
trustpilot,
|
|
13736
|
+
reviewsTitle = "Don't just take our word for it",
|
|
13737
|
+
reviewsSubtitle,
|
|
13738
|
+
blogPosts,
|
|
13739
|
+
aboutTitle,
|
|
13740
|
+
aboutContent,
|
|
13741
|
+
blogIntro,
|
|
13742
|
+
travelGuideHref,
|
|
13743
|
+
travelGuideLabel = "Read our Travel Guide",
|
|
13744
|
+
blogPostsTitle,
|
|
13745
|
+
blogPostsViewAllHref,
|
|
13746
|
+
faqs,
|
|
13747
|
+
faqsTitle = "Frequently asked questions",
|
|
13748
|
+
faqInitialCount = 5,
|
|
13749
|
+
gallery,
|
|
13750
|
+
galleryTitle,
|
|
13751
|
+
className
|
|
13752
|
+
}) {
|
|
13753
|
+
var _a;
|
|
13754
|
+
const [faqsExpanded, setFaqsExpanded] = React29.useState(false);
|
|
13755
|
+
const [tripsExpanded, setTripsExpanded] = React29.useState(false);
|
|
13756
|
+
const [filterValue, setFilterValue] = React29.useState({});
|
|
13757
|
+
const [sort, setSort] = React29.useState(
|
|
13758
|
+
defaultSort != null ? defaultSort : (_a = sortOptions == null ? void 0 : sortOptions[0]) == null ? void 0 : _a.id
|
|
13759
|
+
);
|
|
13760
|
+
const sortedTrips = React29.useMemo(
|
|
13761
|
+
() => [...trips].sort((a, b) => {
|
|
13762
|
+
const af = a.featured ? 1 : 0;
|
|
13763
|
+
const bf = b.featured ? 1 : 0;
|
|
13764
|
+
return bf - af;
|
|
13765
|
+
}),
|
|
13766
|
+
[trips]
|
|
13767
|
+
);
|
|
13768
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("w-full", className), children: [
|
|
13769
|
+
/* @__PURE__ */ jsxs(
|
|
13770
|
+
"section",
|
|
13771
|
+
{
|
|
13772
|
+
className: cn(
|
|
13773
|
+
"relative w-full",
|
|
13774
|
+
siteHeader ? "min-h-[420px] pt-[140px]" : "min-h-[300px] pt-16",
|
|
13775
|
+
"pb-12 text-white",
|
|
13776
|
+
!heroImage && "bg-gradient-to-br from-primary-900 via-primary-800 to-primary-950"
|
|
13777
|
+
),
|
|
13778
|
+
children: [
|
|
13779
|
+
heroImage && /* @__PURE__ */ jsxs("div", { className: "absolute inset-0 overflow-hidden", children: [
|
|
13780
|
+
/* @__PURE__ */ jsx(
|
|
13781
|
+
"img",
|
|
13782
|
+
{
|
|
13783
|
+
src: heroImage,
|
|
13784
|
+
alt: "",
|
|
13785
|
+
"aria-hidden": true,
|
|
13786
|
+
fetchPriority: "high",
|
|
13787
|
+
className: "absolute inset-0 h-full w-full object-cover"
|
|
13788
|
+
}
|
|
13789
|
+
),
|
|
13790
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-b from-black/55 via-black/40 to-black/65" })
|
|
13791
|
+
] }),
|
|
13792
|
+
siteHeader && /* @__PURE__ */ jsx(
|
|
13793
|
+
SiteHeader,
|
|
13794
|
+
{
|
|
13795
|
+
links: Array.isArray(siteHeader) ? siteHeader : void 0,
|
|
13796
|
+
position: "overlay"
|
|
13797
|
+
}
|
|
13798
|
+
),
|
|
13799
|
+
/* @__PURE__ */ jsxs("div", { className: "relative mx-auto w-full max-w-6xl px-6 sm:px-8", children: [
|
|
13800
|
+
breadcrumb && breadcrumb.length > 0 && /* @__PURE__ */ jsx("div", { className: "mb-3 flex items-center gap-1.5 flex-wrap", children: breadcrumb.map((crumb, i) => /* @__PURE__ */ jsxs(React29.Fragment, { children: [
|
|
13801
|
+
i > 0 && /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-3 w-3 text-white/50 shrink-0" }),
|
|
13802
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-white/70 font-ui", children: crumb.label })
|
|
13803
|
+
] }, i)) }),
|
|
13804
|
+
/* @__PURE__ */ jsx("h1", { className: "text-3xl sm:text-5xl font-bold text-white font-heading leading-tight max-w-3xl", children: title }),
|
|
13805
|
+
intro && /* @__PURE__ */ jsx("div", { className: "mt-4 text-base sm:text-lg text-white/90 leading-relaxed max-w-2xl [&_strong]:font-semibold [&_a]:underline", children: intro }),
|
|
13806
|
+
trustpilotMini && /* @__PURE__ */ jsx("div", { className: "mt-5 max-w-sm", children: /* @__PURE__ */ jsx(TrustpilotEmbed, { config: trustpilotMini }) })
|
|
13807
|
+
] })
|
|
13808
|
+
]
|
|
13809
|
+
}
|
|
13810
|
+
),
|
|
13811
|
+
popularTours && popularTours.length > 0 && /* @__PURE__ */ jsxs("section", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 py-12", children: [
|
|
13812
|
+
/* @__PURE__ */ jsx(
|
|
13813
|
+
SectionHeading,
|
|
13814
|
+
{
|
|
13815
|
+
eyebrow: popularToursEyebrow,
|
|
13816
|
+
title: popularToursTitle
|
|
13817
|
+
}
|
|
13818
|
+
),
|
|
13819
|
+
/* @__PURE__ */ jsx("div", { className: "-mx-6 sm:-mx-8 px-6 sm:px-8 overflow-x-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]", children: /* @__PURE__ */ jsx("div", { className: "inline-flex gap-5 min-w-max pb-2", children: popularTours.map((trip, i) => {
|
|
13820
|
+
var _b;
|
|
13821
|
+
const _a2 = trip, { featured: _featured, variant: _variant } = _a2, cardProps = __objRest(_a2, ["featured", "variant"]);
|
|
13822
|
+
return /* @__PURE__ */ jsx(
|
|
13823
|
+
TripCard,
|
|
13824
|
+
__spreadProps(__spreadValues({}, cardProps), {
|
|
13825
|
+
variant: "overlay",
|
|
13826
|
+
size: (_b = cardProps.size) != null ? _b : "md"
|
|
13827
|
+
}),
|
|
13828
|
+
i
|
|
13829
|
+
);
|
|
13830
|
+
}) }) })
|
|
13831
|
+
] }),
|
|
13832
|
+
/* @__PURE__ */ jsxs("section", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 pt-6 sm:pt-8 pb-12", children: [
|
|
13833
|
+
(tripsTitle || tripsEyebrow) && /* @__PURE__ */ jsx(SectionHeading, { eyebrow: tripsEyebrow, title: tripsTitle != null ? tripsTitle : "" }),
|
|
13834
|
+
filterGroups && filterGroups.length > 0 && /* @__PURE__ */ jsx("div", { className: "mb-6", children: /* @__PURE__ */ jsx(
|
|
13835
|
+
FilterPanel,
|
|
13836
|
+
{
|
|
13837
|
+
variant: "horizontal",
|
|
13838
|
+
groups: filterGroups,
|
|
13839
|
+
value: filterValue,
|
|
13840
|
+
onChange: setFilterValue,
|
|
13841
|
+
onClearAll: () => setFilterValue({}),
|
|
13842
|
+
sortOptions,
|
|
13843
|
+
sort,
|
|
13844
|
+
onSortChange: setSort
|
|
13845
|
+
}
|
|
13846
|
+
) }),
|
|
13847
|
+
/* @__PURE__ */ jsxs("p", { className: "text-sm text-muted-foreground font-ui mb-5", children: [
|
|
13848
|
+
trips.length,
|
|
13849
|
+
" ",
|
|
13850
|
+
trips.length === 1 ? "trip" : "trips",
|
|
13851
|
+
" found"
|
|
13852
|
+
] }),
|
|
13853
|
+
(() => {
|
|
13854
|
+
const visibleTrips = tripsExpanded ? sortedTrips : sortedTrips.slice(0, tripsInitialCount);
|
|
13855
|
+
const hiddenCount = sortedTrips.length - visibleTrips.length;
|
|
13856
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
13857
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-x-6 gap-y-8 lg:gap-x-[35px] lg:gap-y-[38px]", children: visibleTrips.map((trip, i) => {
|
|
13858
|
+
const _a2 = trip, { featured: _featured } = _a2, cardProps = __objRest(_a2, ["featured"]);
|
|
13859
|
+
return /* @__PURE__ */ jsx(
|
|
13860
|
+
TripCard,
|
|
13861
|
+
__spreadProps(__spreadValues({}, cardProps), {
|
|
13862
|
+
className: cn("w-full h-auto", cardProps.className)
|
|
13863
|
+
}),
|
|
13864
|
+
i
|
|
13865
|
+
);
|
|
13866
|
+
}) }),
|
|
13867
|
+
sortedTrips.length > tripsInitialCount && /* @__PURE__ */ jsx("div", { className: "mt-8 flex justify-center", children: /* @__PURE__ */ jsx(
|
|
13868
|
+
"button",
|
|
13869
|
+
{
|
|
13870
|
+
type: "button",
|
|
13871
|
+
onClick: () => setTripsExpanded((v) => !v),
|
|
13872
|
+
className: cn(
|
|
13873
|
+
"inline-flex items-center gap-2 rounded-full border border-border bg-background px-5 py-2.5",
|
|
13874
|
+
"text-sm font-semibold text-foreground shadow-sm",
|
|
13875
|
+
"hover:bg-muted transition-colors duration-150",
|
|
13876
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
13877
|
+
),
|
|
13878
|
+
children: tripsExpanded ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
13879
|
+
/* @__PURE__ */ jsx(ChevronUpIcon, { className: "h-4 w-4 text-muted-foreground" }),
|
|
13880
|
+
"Show less"
|
|
13881
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
13882
|
+
/* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-4 w-4 text-muted-foreground" }),
|
|
13883
|
+
"Load more (",
|
|
13884
|
+
hiddenCount,
|
|
13885
|
+
")"
|
|
13886
|
+
] })
|
|
13887
|
+
}
|
|
13888
|
+
) })
|
|
13889
|
+
] });
|
|
13890
|
+
})()
|
|
13891
|
+
] }),
|
|
13892
|
+
trustpilot && /* @__PURE__ */ jsxs("section", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 py-12 border-t border-border", children: [
|
|
13893
|
+
/* @__PURE__ */ jsx("h2", { className: "text-2xl sm:text-3xl font-bold text-foreground font-heading mb-2", children: reviewsTitle }),
|
|
13894
|
+
reviewsSubtitle && /* @__PURE__ */ jsx("p", { className: "text-base text-muted-foreground leading-relaxed max-w-3xl mb-6 [&_a]:text-primary [&_a]:underline", children: reviewsSubtitle }),
|
|
13895
|
+
/* @__PURE__ */ jsx("div", { className: "min-h-[400px]", children: /* @__PURE__ */ jsx(TrustpilotEmbed, { config: trustpilot }) })
|
|
13896
|
+
] }),
|
|
13897
|
+
gallery && gallery.length > 0 && /* @__PURE__ */ jsxs("section", { className: "pt-4", children: [
|
|
13898
|
+
galleryTitle && /* @__PURE__ */ jsx("h2", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 mb-6 text-2xl sm:text-3xl font-bold text-foreground font-heading", children: galleryTitle }),
|
|
13899
|
+
/* @__PURE__ */ jsx(PhotoGallery, { photos: gallery, variant: "gridCompact", initialVisible: 8 })
|
|
13900
|
+
] }),
|
|
13901
|
+
(aboutTitle || aboutContent || blogPostsTitle || blogPosts && blogPosts.length > 0) && /* @__PURE__ */ jsx("section", { className: "w-full bg-gray-100", children: /* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 py-14", children: [
|
|
13902
|
+
(aboutTitle || blogPostsTitle) && /* @__PURE__ */ jsx("h2", { className: "text-2xl sm:text-3xl font-bold text-foreground font-heading mb-5", children: aboutTitle != null ? aboutTitle : blogPostsTitle }),
|
|
13903
|
+
aboutContent && /* @__PURE__ */ jsx("div", { className: "text-base text-foreground/85 leading-relaxed space-y-3 max-w-3xl mb-10 [&_strong]:font-semibold [&_a]:text-primary [&_a]:font-bold [&_a]:underline", children: aboutContent }),
|
|
13904
|
+
blogPosts && blogPosts.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
13905
|
+
blogIntro && /* @__PURE__ */ jsx("p", { className: "mb-6 text-base sm:text-lg font-semibold text-foreground font-heading", children: blogIntro }),
|
|
13906
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-5", children: blogPosts.map((post, i) => /* @__PURE__ */ jsx(
|
|
13907
|
+
BlogCard,
|
|
13908
|
+
{
|
|
13909
|
+
href: post.href,
|
|
13910
|
+
image: post.image,
|
|
13911
|
+
imageAlt: post.imageAlt,
|
|
13912
|
+
title: post.title,
|
|
13913
|
+
excerpt: post.excerpt,
|
|
13914
|
+
category: post.category,
|
|
13915
|
+
readingTime: post.readingTime,
|
|
13916
|
+
className: "w-full"
|
|
13917
|
+
},
|
|
13918
|
+
i
|
|
13919
|
+
)) }),
|
|
13920
|
+
(travelGuideHref || blogPostsViewAllHref) && /* @__PURE__ */ jsx("div", { className: "mt-6 flex justify-end", children: /* @__PURE__ */ jsxs(
|
|
13921
|
+
"a",
|
|
13922
|
+
{
|
|
13923
|
+
href: travelGuideHref != null ? travelGuideHref : blogPostsViewAllHref,
|
|
13924
|
+
className: "inline-flex items-center gap-1.5 text-sm font-semibold text-primary hover:underline",
|
|
13925
|
+
children: [
|
|
13926
|
+
travelGuideHref ? travelGuideLabel : "View all posts",
|
|
13927
|
+
/* @__PURE__ */ jsx(ArrowRightIcon, { className: "h-4 w-4" })
|
|
13928
|
+
]
|
|
13929
|
+
}
|
|
13930
|
+
) })
|
|
13931
|
+
] })
|
|
13932
|
+
] }) }),
|
|
13933
|
+
faqs && faqs.length > 0 && (() => {
|
|
13934
|
+
const visibleFaqs = faqsExpanded ? faqs : faqs.slice(0, faqInitialCount);
|
|
13935
|
+
const hiddenCount = faqs.length - visibleFaqs.length;
|
|
13936
|
+
return /* @__PURE__ */ jsxs("section", { className: "mx-auto w-full max-w-6xl px-6 sm:px-8 py-12", children: [
|
|
13937
|
+
/* @__PURE__ */ jsx("h2", { className: "text-2xl sm:text-3xl font-bold text-foreground font-heading mb-6", children: faqsTitle }),
|
|
13938
|
+
/* @__PURE__ */ jsx(Accordion, { variant: "faq", children: visibleFaqs.map((faq, i) => /* @__PURE__ */ jsxs(AccordionItem, { value: `faq-${i}`, children: [
|
|
13939
|
+
/* @__PURE__ */ jsx(AccordionTrigger, { children: faq.question }),
|
|
13940
|
+
/* @__PURE__ */ jsx(AccordionContent, { children: faq.answer })
|
|
13941
|
+
] }, i)) }),
|
|
13942
|
+
faqs.length > faqInitialCount && /* @__PURE__ */ jsx("div", { className: "mt-5 flex justify-center", children: /* @__PURE__ */ jsx(
|
|
13943
|
+
"button",
|
|
13944
|
+
{
|
|
13945
|
+
type: "button",
|
|
13946
|
+
onClick: () => setFaqsExpanded((v) => !v),
|
|
13947
|
+
className: cn(
|
|
13948
|
+
"inline-flex items-center gap-2 rounded-full border border-border bg-background px-5 py-2.5",
|
|
13949
|
+
"text-sm font-semibold text-foreground shadow-sm",
|
|
13950
|
+
"hover:bg-muted transition-colors duration-150",
|
|
13951
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
13952
|
+
),
|
|
13953
|
+
children: faqsExpanded ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
13954
|
+
/* @__PURE__ */ jsx(ChevronUpIcon, { className: "h-4 w-4 text-muted-foreground" }),
|
|
13955
|
+
"Show less"
|
|
13956
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
13957
|
+
/* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-4 w-4 text-muted-foreground" }),
|
|
13958
|
+
"See more (",
|
|
13959
|
+
hiddenCount,
|
|
13960
|
+
")"
|
|
13961
|
+
] })
|
|
13962
|
+
}
|
|
13963
|
+
) })
|
|
13964
|
+
] });
|
|
13965
|
+
})(),
|
|
13966
|
+
/* @__PURE__ */ jsx(SiteFooter, {})
|
|
13967
|
+
] });
|
|
13968
|
+
}
|
|
13969
|
+
var sizeConfig3 = {
|
|
13497
13970
|
sm: {
|
|
13498
13971
|
card: "w-56",
|
|
13499
13972
|
image: "h-36",
|
|
@@ -13528,7 +14001,7 @@ function ActivityCard({
|
|
|
13528
14001
|
size = "md",
|
|
13529
14002
|
className
|
|
13530
14003
|
}) {
|
|
13531
|
-
const s =
|
|
14004
|
+
const s = sizeConfig3[size];
|
|
13532
14005
|
return /* @__PURE__ */ jsxs(
|
|
13533
14006
|
"div",
|
|
13534
14007
|
{
|
|
@@ -13594,12 +14067,12 @@ function Toast({
|
|
|
13594
14067
|
duration = 6e3,
|
|
13595
14068
|
className
|
|
13596
14069
|
}) {
|
|
13597
|
-
const [mounted, setMounted] =
|
|
13598
|
-
const [visible, setVisible] =
|
|
13599
|
-
|
|
14070
|
+
const [mounted, setMounted] = React29.useState(false);
|
|
14071
|
+
const [visible, setVisible] = React29.useState(true);
|
|
14072
|
+
React29.useEffect(() => {
|
|
13600
14073
|
setMounted(true);
|
|
13601
14074
|
}, []);
|
|
13602
|
-
|
|
14075
|
+
React29.useEffect(() => {
|
|
13603
14076
|
if (duration === 0) return;
|
|
13604
14077
|
const t = setTimeout(() => {
|
|
13605
14078
|
setVisible(false);
|
|
@@ -14741,7 +15214,517 @@ function AskExo({
|
|
|
14741
15214
|
)
|
|
14742
15215
|
] });
|
|
14743
15216
|
}
|
|
15217
|
+
var STATUS_MAP = {
|
|
15218
|
+
"draft": { label: "Draft", variant: "neutral", dot: "bg-muted-foreground" },
|
|
15219
|
+
"pending-approval": { label: "Pending approval", variant: "warning", dot: "bg-warning" },
|
|
15220
|
+
"pending-group": { label: "Pending group", variant: "info", dot: "bg-info" },
|
|
15221
|
+
"confirmed": { label: "Confirmed", variant: "success", dot: "bg-success" },
|
|
15222
|
+
"payment-pending": { label: "Payment pending", variant: "warning", dot: "bg-warning" },
|
|
15223
|
+
"payment-reconciliation": { label: "Reconciliation", variant: "info", dot: "bg-info" },
|
|
15224
|
+
"fully-paid": { label: "Fully paid", variant: "default", dot: "bg-primary-foreground" },
|
|
15225
|
+
"full": { label: "Full", variant: "secondary", dot: "bg-secondary-foreground" },
|
|
15226
|
+
"waiting-list": { label: "Waiting list", variant: "info", dot: "bg-info" },
|
|
15227
|
+
"operating": { label: "Operating", variant: "default", dot: "bg-primary-foreground" },
|
|
15228
|
+
"cancelled": { label: "Cancelled", variant: "destructive", dot: "bg-destructive" }
|
|
15229
|
+
};
|
|
15230
|
+
function StatusBadge2({ status, dot = true, label, className }) {
|
|
15231
|
+
const config = STATUS_MAP[status];
|
|
15232
|
+
return /* @__PURE__ */ jsxs(Badge, { variant: config.variant, className: cn("gap-1.5", className), children: [
|
|
15233
|
+
dot && /* @__PURE__ */ jsx(
|
|
15234
|
+
"span",
|
|
15235
|
+
{
|
|
15236
|
+
"aria-hidden": "true",
|
|
15237
|
+
className: cn("size-1.5 shrink-0 rounded-full", config.dot)
|
|
15238
|
+
}
|
|
15239
|
+
),
|
|
15240
|
+
label != null ? label : config.label
|
|
15241
|
+
] });
|
|
15242
|
+
}
|
|
15243
|
+
function GroupStatusBanner({
|
|
15244
|
+
variant = "info",
|
|
15245
|
+
title,
|
|
15246
|
+
icon,
|
|
15247
|
+
action,
|
|
15248
|
+
urgent = false,
|
|
15249
|
+
children,
|
|
15250
|
+
className
|
|
15251
|
+
}) {
|
|
15252
|
+
return /* @__PURE__ */ jsx(
|
|
15253
|
+
Alert,
|
|
15254
|
+
{
|
|
15255
|
+
variant,
|
|
15256
|
+
title,
|
|
15257
|
+
icon,
|
|
15258
|
+
action,
|
|
15259
|
+
role: urgent ? "alert" : "status",
|
|
15260
|
+
className,
|
|
15261
|
+
children
|
|
15262
|
+
}
|
|
15263
|
+
);
|
|
15264
|
+
}
|
|
15265
|
+
function ParticipantCounter({
|
|
15266
|
+
current,
|
|
15267
|
+
max,
|
|
15268
|
+
label = "Travelers",
|
|
15269
|
+
hideIcon = false,
|
|
15270
|
+
className
|
|
15271
|
+
}) {
|
|
15272
|
+
return /* @__PURE__ */ jsxs(
|
|
15273
|
+
"span",
|
|
15274
|
+
{
|
|
15275
|
+
className: cn(
|
|
15276
|
+
"inline-flex items-center gap-1.5 font-ui text-sm text-foreground",
|
|
15277
|
+
className
|
|
15278
|
+
),
|
|
15279
|
+
children: [
|
|
15280
|
+
!hideIcon && /* @__PURE__ */ jsx(UsersIcon, { className: "size-4 text-primary", "aria-hidden": "true" }),
|
|
15281
|
+
/* @__PURE__ */ jsxs("span", { className: "font-bold tabular-nums", children: [
|
|
15282
|
+
current,
|
|
15283
|
+
" / ",
|
|
15284
|
+
max
|
|
15285
|
+
] }),
|
|
15286
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: label })
|
|
15287
|
+
]
|
|
15288
|
+
}
|
|
15289
|
+
);
|
|
15290
|
+
}
|
|
15291
|
+
function GroupProgressBar({
|
|
15292
|
+
current,
|
|
15293
|
+
min,
|
|
15294
|
+
max,
|
|
15295
|
+
hideLabels = false,
|
|
15296
|
+
className
|
|
15297
|
+
}) {
|
|
15298
|
+
const pct = Math.max(0, Math.min(100, current / max * 100));
|
|
15299
|
+
const minPct = Math.max(0, Math.min(100, min / max * 100));
|
|
15300
|
+
const quorumMet = current >= min;
|
|
15301
|
+
const isFull = current >= max;
|
|
15302
|
+
const fillTone = isFull ? "bg-success" : quorumMet ? "bg-primary" : "bg-warning";
|
|
15303
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-1.5", className), children: [
|
|
15304
|
+
/* @__PURE__ */ jsxs(
|
|
15305
|
+
"div",
|
|
15306
|
+
{
|
|
15307
|
+
className: "relative h-3 w-full overflow-visible rounded-full bg-muted",
|
|
15308
|
+
role: "progressbar",
|
|
15309
|
+
"aria-valuenow": current,
|
|
15310
|
+
"aria-valuemin": 0,
|
|
15311
|
+
"aria-valuemax": max,
|
|
15312
|
+
"aria-label": `${current} of ${max} travelers, minimum ${min}${quorumMet ? " met" : " not yet met"}`,
|
|
15313
|
+
children: [
|
|
15314
|
+
/* @__PURE__ */ jsx(
|
|
15315
|
+
"div",
|
|
15316
|
+
{
|
|
15317
|
+
className: cn(
|
|
15318
|
+
"h-full rounded-full transition-[width,background-color] duration-500",
|
|
15319
|
+
fillTone
|
|
15320
|
+
),
|
|
15321
|
+
style: { width: `${pct}%` }
|
|
15322
|
+
}
|
|
15323
|
+
),
|
|
15324
|
+
/* @__PURE__ */ jsx(
|
|
15325
|
+
"span",
|
|
15326
|
+
{
|
|
15327
|
+
"aria-hidden": "true",
|
|
15328
|
+
className: "absolute top-1/2 z-10 h-5 w-0.5 -translate-x-1/2 -translate-y-1/2 rounded-full bg-foreground/60",
|
|
15329
|
+
style: { left: `${minPct}%` }
|
|
15330
|
+
}
|
|
15331
|
+
)
|
|
15332
|
+
]
|
|
15333
|
+
}
|
|
15334
|
+
),
|
|
15335
|
+
!hideLabels && /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between font-ui text-[11px] text-muted-foreground", children: [
|
|
15336
|
+
/* @__PURE__ */ jsx("span", { className: cn(quorumMet && "text-success font-semibold"), children: quorumMet ? "Quorum reached" : `Min ${min} to confirm` }),
|
|
15337
|
+
/* @__PURE__ */ jsxs("span", { className: "tabular-nums", children: [
|
|
15338
|
+
max,
|
|
15339
|
+
" max"
|
|
15340
|
+
] })
|
|
15341
|
+
] })
|
|
15342
|
+
] });
|
|
15343
|
+
}
|
|
15344
|
+
function Card(_a) {
|
|
15345
|
+
var _b = _a, {
|
|
15346
|
+
className,
|
|
15347
|
+
size = "default"
|
|
15348
|
+
} = _b, props = __objRest(_b, [
|
|
15349
|
+
"className",
|
|
15350
|
+
"size"
|
|
15351
|
+
]);
|
|
15352
|
+
return /* @__PURE__ */ jsx(
|
|
15353
|
+
"div",
|
|
15354
|
+
__spreadValues({
|
|
15355
|
+
"data-slot": "card",
|
|
15356
|
+
"data-size": size,
|
|
15357
|
+
className: cn(
|
|
15358
|
+
"group/card flex flex-col gap-4 overflow-hidden rounded-xl bg-card py-4 text-sm text-card-foreground ring-1 ring-foreground/10 has-data-[slot=card-footer]:pb-0 has-[>img:first-child]:pt-0 data-[size=sm]:gap-3 data-[size=sm]:py-3 data-[size=sm]:has-data-[slot=card-footer]:pb-0 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl",
|
|
15359
|
+
className
|
|
15360
|
+
)
|
|
15361
|
+
}, props)
|
|
15362
|
+
);
|
|
15363
|
+
}
|
|
15364
|
+
function CardHeader(_a) {
|
|
15365
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
15366
|
+
return /* @__PURE__ */ jsx(
|
|
15367
|
+
"div",
|
|
15368
|
+
__spreadValues({
|
|
15369
|
+
"data-slot": "card-header",
|
|
15370
|
+
className: cn(
|
|
15371
|
+
"group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-4 group-data-[size=sm]/card:px-3 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3",
|
|
15372
|
+
className
|
|
15373
|
+
)
|
|
15374
|
+
}, props)
|
|
15375
|
+
);
|
|
15376
|
+
}
|
|
15377
|
+
function CardTitle(_a) {
|
|
15378
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
15379
|
+
return /* @__PURE__ */ jsx(
|
|
15380
|
+
"div",
|
|
15381
|
+
__spreadValues({
|
|
15382
|
+
"data-slot": "card-title",
|
|
15383
|
+
className: cn(
|
|
15384
|
+
"text-base leading-snug font-medium group-data-[size=sm]/card:text-sm",
|
|
15385
|
+
className
|
|
15386
|
+
)
|
|
15387
|
+
}, props)
|
|
15388
|
+
);
|
|
15389
|
+
}
|
|
15390
|
+
function CardContent(_a) {
|
|
15391
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
15392
|
+
return /* @__PURE__ */ jsx(
|
|
15393
|
+
"div",
|
|
15394
|
+
__spreadValues({
|
|
15395
|
+
"data-slot": "card-content",
|
|
15396
|
+
className: cn("px-4 group-data-[size=sm]/card:px-3", className)
|
|
15397
|
+
}, props)
|
|
15398
|
+
);
|
|
15399
|
+
}
|
|
15400
|
+
function PricingMatrixCard({
|
|
15401
|
+
tiers,
|
|
15402
|
+
currentTravelers,
|
|
15403
|
+
title = "Group pricing",
|
|
15404
|
+
locked = false,
|
|
15405
|
+
className
|
|
15406
|
+
}) {
|
|
15407
|
+
const activeIndex = tiers.reduce(
|
|
15408
|
+
(acc, t, i) => currentTravelers >= t.threshold ? i : acc,
|
|
15409
|
+
-1
|
|
15410
|
+
);
|
|
15411
|
+
const bestIndex = tiers.length - 1;
|
|
15412
|
+
return /* @__PURE__ */ jsxs(Card, { className, children: [
|
|
15413
|
+
/* @__PURE__ */ jsx(CardHeader, { children: /* @__PURE__ */ jsx(CardTitle, { className: "font-heading", children: title }) }),
|
|
15414
|
+
/* @__PURE__ */ jsx(CardContent, { className: "px-0", children: /* @__PURE__ */ jsxs("table", { className: "w-full text-sm", children: [
|
|
15415
|
+
/* @__PURE__ */ jsx("caption", { className: "sr-only", children: "Price per person by number of travelers" }),
|
|
15416
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: "border-y border-border text-left font-ui text-[11px] uppercase tracking-wide text-muted-foreground", children: [
|
|
15417
|
+
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2 font-semibold", children: "Travelers" }),
|
|
15418
|
+
/* @__PURE__ */ jsx("th", { scope: "col", className: "px-4 py-2 text-right font-semibold", children: "Price / person" })
|
|
15419
|
+
] }) }),
|
|
15420
|
+
/* @__PURE__ */ jsx("tbody", { children: tiers.map((tier, i) => {
|
|
15421
|
+
const isActive = !locked && i === activeIndex;
|
|
15422
|
+
const isBest = i === bestIndex;
|
|
15423
|
+
return /* @__PURE__ */ jsxs(
|
|
15424
|
+
"tr",
|
|
15425
|
+
{
|
|
15426
|
+
className: cn(
|
|
15427
|
+
"border-b border-border last:border-0 transition-colors",
|
|
15428
|
+
isActive && "bg-accent",
|
|
15429
|
+
locked && "opacity-60"
|
|
15430
|
+
),
|
|
15431
|
+
"aria-current": isActive ? "true" : void 0,
|
|
15432
|
+
children: [
|
|
15433
|
+
/* @__PURE__ */ jsx("td", { className: "px-4 py-2.5", children: /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-2", children: [
|
|
15434
|
+
/* @__PURE__ */ jsx("span", { className: "font-ui font-semibold text-foreground", children: tier.travelers }),
|
|
15435
|
+
isActive && /* @__PURE__ */ jsx(Badge, { variant: "success", className: "h-4 px-1.5 text-[10px]", children: "You are here" }),
|
|
15436
|
+
isBest && !isActive && /* @__PURE__ */ jsx(Badge, { variant: "info", className: "h-4 px-1.5 text-[10px]", children: "Best price" })
|
|
15437
|
+
] }) }),
|
|
15438
|
+
/* @__PURE__ */ jsx(
|
|
15439
|
+
"td",
|
|
15440
|
+
{
|
|
15441
|
+
className: cn(
|
|
15442
|
+
"px-4 py-2.5 text-right font-ui tabular-nums",
|
|
15443
|
+
isActive ? "font-bold text-foreground" : "text-muted-foreground",
|
|
15444
|
+
isBest && "text-primary"
|
|
15445
|
+
),
|
|
15446
|
+
children: tier.price
|
|
15447
|
+
}
|
|
15448
|
+
)
|
|
15449
|
+
]
|
|
15450
|
+
},
|
|
15451
|
+
tier.travelers
|
|
15452
|
+
);
|
|
15453
|
+
}) })
|
|
15454
|
+
] }) })
|
|
15455
|
+
] });
|
|
15456
|
+
}
|
|
15457
|
+
function PriceProgress({
|
|
15458
|
+
currentPrice,
|
|
15459
|
+
lowestPrice,
|
|
15460
|
+
travelersToLowest,
|
|
15461
|
+
pct,
|
|
15462
|
+
className
|
|
15463
|
+
}) {
|
|
15464
|
+
const reached = travelersToLowest <= 0;
|
|
15465
|
+
const safePct = reached ? 100 : Math.max(0, Math.min(100, pct));
|
|
15466
|
+
return /* @__PURE__ */ jsxs(
|
|
15467
|
+
"div",
|
|
15468
|
+
{
|
|
15469
|
+
className: cn(
|
|
15470
|
+
"flex flex-col gap-3 rounded-xl border border-border bg-card p-4",
|
|
15471
|
+
className
|
|
15472
|
+
),
|
|
15473
|
+
"aria-live": "polite",
|
|
15474
|
+
children: [
|
|
15475
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-end justify-between gap-4", children: [
|
|
15476
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
15477
|
+
/* @__PURE__ */ jsx("span", { className: "font-ui text-[11px] uppercase tracking-wide text-muted-foreground", children: "Current" }),
|
|
15478
|
+
/* @__PURE__ */ jsx("span", { className: "font-heading text-xl font-bold text-foreground tabular-nums", children: currentPrice })
|
|
15479
|
+
] }),
|
|
15480
|
+
/* @__PURE__ */ jsx(ArrowDownIcon, { className: "mb-1 size-4 shrink-0 text-success", "aria-hidden": "true" }),
|
|
15481
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col text-right", children: [
|
|
15482
|
+
/* @__PURE__ */ jsx("span", { className: "font-ui text-[11px] uppercase tracking-wide text-muted-foreground", children: "Potential" }),
|
|
15483
|
+
/* @__PURE__ */ jsx("span", { className: "font-heading text-xl font-bold text-primary tabular-nums", children: lowestPrice })
|
|
15484
|
+
] })
|
|
15485
|
+
] }),
|
|
15486
|
+
/* @__PURE__ */ jsx("div", { className: "h-2 w-full overflow-hidden rounded-full bg-muted", children: /* @__PURE__ */ jsx(
|
|
15487
|
+
"div",
|
|
15488
|
+
{
|
|
15489
|
+
className: cn(
|
|
15490
|
+
"h-full rounded-full transition-[width] duration-500",
|
|
15491
|
+
reached ? "bg-success" : "bg-primary"
|
|
15492
|
+
),
|
|
15493
|
+
style: { width: `${safePct}%` }
|
|
15494
|
+
}
|
|
15495
|
+
) }),
|
|
15496
|
+
/* @__PURE__ */ jsx(
|
|
15497
|
+
"p",
|
|
15498
|
+
{
|
|
15499
|
+
className: cn(
|
|
15500
|
+
"flex items-center gap-1.5 font-ui text-sm font-semibold",
|
|
15501
|
+
reached ? "text-success" : "text-foreground"
|
|
15502
|
+
),
|
|
15503
|
+
children: reached ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
15504
|
+
/* @__PURE__ */ jsx(SparkleIcon, { className: "size-4", "aria-hidden": "true" }),
|
|
15505
|
+
"Best possible price unlocked"
|
|
15506
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
15507
|
+
travelersToLowest,
|
|
15508
|
+
" more ",
|
|
15509
|
+
travelersToLowest === 1 ? "traveler" : "travelers",
|
|
15510
|
+
" for the lowest price"
|
|
15511
|
+
] })
|
|
15512
|
+
}
|
|
15513
|
+
)
|
|
15514
|
+
]
|
|
15515
|
+
}
|
|
15516
|
+
);
|
|
15517
|
+
}
|
|
15518
|
+
function ParticipantList({
|
|
15519
|
+
participants,
|
|
15520
|
+
emptySlots = 0,
|
|
15521
|
+
title = "Travelers",
|
|
15522
|
+
leaderLabel = "Leader",
|
|
15523
|
+
emptyMessage = "Be the first to join this adventure.",
|
|
15524
|
+
className
|
|
15525
|
+
}) {
|
|
15526
|
+
if (participants.length === 0 && emptySlots === 0) {
|
|
15527
|
+
return /* @__PURE__ */ jsx("p", { className: cn("font-sans text-sm text-muted-foreground", className), children: emptyMessage });
|
|
15528
|
+
}
|
|
15529
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-3", className), children: [
|
|
15530
|
+
title && /* @__PURE__ */ jsx("h3", { className: "font-heading text-sm font-bold text-foreground", children: title }),
|
|
15531
|
+
/* @__PURE__ */ jsxs("ul", { className: "flex flex-col gap-2", children: [
|
|
15532
|
+
participants.map((p, i) => /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-3", children: [
|
|
15533
|
+
/* @__PURE__ */ jsx(
|
|
15534
|
+
"span",
|
|
15535
|
+
{
|
|
15536
|
+
className: "flex size-9 shrink-0 items-center justify-center overflow-hidden rounded-full bg-primary/10 text-primary",
|
|
15537
|
+
"aria-hidden": "true",
|
|
15538
|
+
children: p.avatarUrl ? (
|
|
15539
|
+
// eslint-disable-next-line @next/next/no-img-element
|
|
15540
|
+
/* @__PURE__ */ jsx("img", { src: p.avatarUrl, alt: "", className: "size-full object-cover" })
|
|
15541
|
+
) : /* @__PURE__ */ jsx(UserIcon, { className: "size-4.5" })
|
|
15542
|
+
}
|
|
15543
|
+
),
|
|
15544
|
+
/* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-2", children: [
|
|
15545
|
+
/* @__PURE__ */ jsx("span", { className: "truncate font-ui text-sm font-medium text-foreground", children: p.firstName }),
|
|
15546
|
+
p.flag && /* @__PURE__ */ jsx("span", { "aria-label": p.country, role: "img", className: "text-base leading-none", children: p.flag }),
|
|
15547
|
+
p.isLeader && /* @__PURE__ */ jsx(Badge, { variant: "info", className: "h-4 px-1.5 text-[10px]", children: leaderLabel })
|
|
15548
|
+
] })
|
|
15549
|
+
] }, `${p.firstName}-${i}`)),
|
|
15550
|
+
Array.from({ length: emptySlots }).map((_, i) => /* @__PURE__ */ jsxs("li", { className: "flex items-center gap-3 opacity-60", children: [
|
|
15551
|
+
/* @__PURE__ */ jsx(
|
|
15552
|
+
"span",
|
|
15553
|
+
{
|
|
15554
|
+
"aria-hidden": "true",
|
|
15555
|
+
className: "flex size-9 shrink-0 items-center justify-center rounded-full border border-dashed border-border text-muted-foreground",
|
|
15556
|
+
children: "+"
|
|
15557
|
+
}
|
|
15558
|
+
),
|
|
15559
|
+
/* @__PURE__ */ jsx("span", { className: "font-sans text-sm text-muted-foreground", children: "Open spot" })
|
|
15560
|
+
] }, `empty-${i}`))
|
|
15561
|
+
] })
|
|
15562
|
+
] });
|
|
15563
|
+
}
|
|
15564
|
+
function BrandIcon({ path }) {
|
|
15565
|
+
return /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", className: "size-4", fill: "currentColor", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: path }) });
|
|
15566
|
+
}
|
|
15567
|
+
var WHATSAPP = "M.057 24l1.687-6.163a11.867 11.867 0 01-1.587-5.945C.16 5.335 5.495 0 12.05 0a11.82 11.82 0 018.413 3.488 11.82 11.82 0 013.48 8.414c-.003 6.557-5.338 11.892-11.893 11.892a11.9 11.9 0 01-5.688-1.448L.057 24zm6.597-3.807c1.676.995 3.276 1.591 5.392 1.592 5.448 0 9.886-4.434 9.889-9.885.002-5.462-4.415-9.89-9.881-9.892-5.452 0-9.887 4.434-9.889 9.884a9.82 9.82 0 001.51 5.26l-.999 3.648 3.978-1.945zm5.473-6.231c-.074-.124-.272-.198-.57-.347-.297-.149-1.758-.868-2.031-.967-.272-.099-.47-.149-.669.149-.198.297-.768.967-.941 1.165-.173.198-.347.223-.644.074-.297-.149-1.255-.462-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.297-.347.446-.521.151-.172.2-.296.3-.495.099-.198.05-.372-.025-.521-.075-.148-.669-1.611-.916-2.206-.242-.579-.487-.501-.669-.51l-.57-.01c-.198 0-.52.074-.792.372s-1.04 1.016-1.04 2.479 1.065 2.876 1.213 3.074c.149.198 2.096 3.2 5.077 4.487.709.306 1.263.489 1.694.626.712.226 1.36.194 1.872.118.571-.085 1.758-.719 2.006-1.413.248-.695.248-1.29.173-1.414z";
|
|
15568
|
+
var FACEBOOK = "M24 12.073c0-6.627-5.373-12-12-12s-12 5.373-12 12c0 5.99 4.388 10.954 10.125 11.854v-8.385H7.078v-3.47h3.047V9.43c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.47h-2.796v8.385C19.612 23.027 24 18.062 24 12.073z";
|
|
15569
|
+
var X = "M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z";
|
|
15570
|
+
function ShareWidget({
|
|
15571
|
+
url,
|
|
15572
|
+
message = "Join my adventure and let's unlock a lower price together!",
|
|
15573
|
+
layout = "row",
|
|
15574
|
+
title = "Invite friends & lower the price",
|
|
15575
|
+
className
|
|
15576
|
+
}) {
|
|
15577
|
+
const [copied, setCopied] = React29.useState(false);
|
|
15578
|
+
const [showToast, setShowToast] = React29.useState(false);
|
|
15579
|
+
const encodedUrl = encodeURIComponent(url);
|
|
15580
|
+
const encodedMsg = encodeURIComponent(`${message} ${url}`);
|
|
15581
|
+
const channels = [
|
|
15582
|
+
{
|
|
15583
|
+
key: "whatsapp",
|
|
15584
|
+
label: "WhatsApp",
|
|
15585
|
+
href: `https://wa.me/?text=${encodedMsg}`,
|
|
15586
|
+
path: WHATSAPP,
|
|
15587
|
+
color: "hover:text-[#25D366] hover:border-[#25D366]"
|
|
15588
|
+
},
|
|
15589
|
+
{
|
|
15590
|
+
key: "facebook",
|
|
15591
|
+
label: "Facebook",
|
|
15592
|
+
href: `https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`,
|
|
15593
|
+
path: FACEBOOK,
|
|
15594
|
+
color: "hover:text-[#1877F2] hover:border-[#1877F2]"
|
|
15595
|
+
},
|
|
15596
|
+
{
|
|
15597
|
+
key: "x",
|
|
15598
|
+
label: "X",
|
|
15599
|
+
href: `https://twitter.com/intent/tweet?text=${encodeURIComponent(message)}&url=${encodedUrl}`,
|
|
15600
|
+
path: X,
|
|
15601
|
+
color: "hover:text-foreground hover:border-foreground"
|
|
15602
|
+
}
|
|
15603
|
+
];
|
|
15604
|
+
const copyLink = async () => {
|
|
15605
|
+
try {
|
|
15606
|
+
await navigator.clipboard.writeText(url);
|
|
15607
|
+
} catch (e) {
|
|
15608
|
+
}
|
|
15609
|
+
setCopied(true);
|
|
15610
|
+
setShowToast(true);
|
|
15611
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
15612
|
+
};
|
|
15613
|
+
const isIcons = layout === "icons";
|
|
15614
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-3", className), children: [
|
|
15615
|
+
title && /* @__PURE__ */ jsxs("h3", { className: "flex items-center gap-1.5 font-heading text-sm font-bold text-foreground", children: [
|
|
15616
|
+
/* @__PURE__ */ jsx(Share2Icon, { className: "size-4 text-primary", "aria-hidden": "true" }),
|
|
15617
|
+
title
|
|
15618
|
+
] }),
|
|
15619
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
|
|
15620
|
+
channels.map((c) => /* @__PURE__ */ jsxs(
|
|
15621
|
+
"a",
|
|
15622
|
+
{
|
|
15623
|
+
href: c.href,
|
|
15624
|
+
target: "_blank",
|
|
15625
|
+
rel: "noopener noreferrer",
|
|
15626
|
+
"aria-label": `Share on ${c.label}`,
|
|
15627
|
+
className: cn(
|
|
15628
|
+
"inline-flex items-center gap-2 rounded-full border border-border px-3 py-2 font-ui text-sm text-foreground transition-colors",
|
|
15629
|
+
c.color
|
|
15630
|
+
),
|
|
15631
|
+
children: [
|
|
15632
|
+
/* @__PURE__ */ jsx(BrandIcon, { path: c.path }),
|
|
15633
|
+
!isIcons && /* @__PURE__ */ jsx("span", { children: c.label })
|
|
15634
|
+
]
|
|
15635
|
+
},
|
|
15636
|
+
c.key
|
|
15637
|
+
)),
|
|
15638
|
+
/* @__PURE__ */ jsxs(
|
|
15639
|
+
"button",
|
|
15640
|
+
{
|
|
15641
|
+
type: "button",
|
|
15642
|
+
onClick: copyLink,
|
|
15643
|
+
"aria-label": "Copy link",
|
|
15644
|
+
className: cn(
|
|
15645
|
+
"inline-flex items-center gap-2 rounded-full border border-border px-3 py-2 font-ui text-sm text-foreground transition-colors hover:border-primary hover:text-primary",
|
|
15646
|
+
copied && "border-success text-success"
|
|
15647
|
+
),
|
|
15648
|
+
children: [
|
|
15649
|
+
copied ? /* @__PURE__ */ jsx(CheckIcon, { className: "size-4" }) : /* @__PURE__ */ jsx(CopyIcon, { className: "size-4" }),
|
|
15650
|
+
!isIcons && /* @__PURE__ */ jsx("span", { children: copied ? "Copied!" : "Copy link" })
|
|
15651
|
+
]
|
|
15652
|
+
}
|
|
15653
|
+
)
|
|
15654
|
+
] }),
|
|
15655
|
+
showToast && /* @__PURE__ */ jsx(
|
|
15656
|
+
Toast,
|
|
15657
|
+
{
|
|
15658
|
+
message: "Link copied to clipboard",
|
|
15659
|
+
variant: "success",
|
|
15660
|
+
onClose: () => setShowToast(false),
|
|
15661
|
+
duration: 2500
|
|
15662
|
+
}
|
|
15663
|
+
)
|
|
15664
|
+
] });
|
|
15665
|
+
}
|
|
15666
|
+
var MODE_COPY = {
|
|
15667
|
+
joinable: { cta: "Join this adventure", disabled: false },
|
|
15668
|
+
full: { cta: "Join waiting list", disabled: false },
|
|
15669
|
+
closed: { cta: "Booking closed", disabled: true },
|
|
15670
|
+
owner: { cta: "Share your departure", disabled: false }
|
|
15671
|
+
};
|
|
15672
|
+
function StickyBookingCard({
|
|
15673
|
+
currentPrice,
|
|
15674
|
+
deposit,
|
|
15675
|
+
spotsRemaining,
|
|
15676
|
+
mode = "joinable",
|
|
15677
|
+
onPrimary,
|
|
15678
|
+
note,
|
|
15679
|
+
className
|
|
15680
|
+
}) {
|
|
15681
|
+
const { cta, disabled } = MODE_COPY[mode];
|
|
15682
|
+
return /* @__PURE__ */ jsxs(
|
|
15683
|
+
"div",
|
|
15684
|
+
{
|
|
15685
|
+
className: cn(
|
|
15686
|
+
"flex flex-col gap-4 rounded-2xl border border-border bg-card p-5 ring-1 ring-foreground/5",
|
|
15687
|
+
className
|
|
15688
|
+
),
|
|
15689
|
+
children: [
|
|
15690
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-baseline justify-between", children: [
|
|
15691
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
15692
|
+
/* @__PURE__ */ jsx("span", { className: "font-ui text-[11px] uppercase tracking-wide text-muted-foreground", children: "Current price" }),
|
|
15693
|
+
/* @__PURE__ */ jsx("span", { className: "font-heading text-2xl font-bold text-foreground tabular-nums", children: currentPrice }),
|
|
15694
|
+
/* @__PURE__ */ jsx("span", { className: "font-sans text-xs text-muted-foreground", children: "per person" })
|
|
15695
|
+
] }),
|
|
15696
|
+
mode !== "owner" && /* @__PURE__ */ jsx(
|
|
15697
|
+
"span",
|
|
15698
|
+
{
|
|
15699
|
+
className: cn(
|
|
15700
|
+
"font-ui text-xs font-semibold",
|
|
15701
|
+
spotsRemaining <= 2 && spotsRemaining > 0 ? "text-warning" : "text-muted-foreground"
|
|
15702
|
+
),
|
|
15703
|
+
children: spotsRemaining > 0 ? `${spotsRemaining} spots left` : "Full"
|
|
15704
|
+
}
|
|
15705
|
+
)
|
|
15706
|
+
] }),
|
|
15707
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between rounded-lg bg-muted/60 px-3 py-2", children: [
|
|
15708
|
+
/* @__PURE__ */ jsx("span", { className: "font-sans text-sm text-muted-foreground", children: "Deposit today" }),
|
|
15709
|
+
/* @__PURE__ */ jsx("span", { className: "font-ui text-sm font-bold text-foreground tabular-nums", children: deposit })
|
|
15710
|
+
] }),
|
|
15711
|
+
/* @__PURE__ */ jsx(
|
|
15712
|
+
Button,
|
|
15713
|
+
{
|
|
15714
|
+
variant: "primary",
|
|
15715
|
+
size: "lg",
|
|
15716
|
+
className: "w-full",
|
|
15717
|
+
disabled,
|
|
15718
|
+
onClick: onPrimary,
|
|
15719
|
+
children: cta
|
|
15720
|
+
}
|
|
15721
|
+
),
|
|
15722
|
+
/* @__PURE__ */ jsx("p", { className: "text-center font-sans text-xs text-muted-foreground", children: note != null ? note : "A hold is placed on your card \u2014 no charge until approved." })
|
|
15723
|
+
]
|
|
15724
|
+
}
|
|
15725
|
+
);
|
|
15726
|
+
}
|
|
14744
15727
|
|
|
14745
|
-
export { ActivityCard, AgentContactCard, Alert, AskExo, BirthDateField, BookingAdventureCard, BookingCancellationEmail, BookingConfirmedCard, BookingCreatedEmail, BookingDetails, BookingForm, BookingOtpEmail, BookingPaymentConfirmationEmail, BookingShell, BookingSummary, Button, COUNTRIES, CounterField, CountrySearchField, DEFAULT_HEADER_LINKS, DEFAULT_LANGUAGES, DatePickerField, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, ExoOrb, FilterPanel, FloatingInput, FloatingSelect, Itinerary, ItineraryDay, LOGO_PLANETAEXO_DATA_URI, LeadCapturePopup, MenuTrip, OTPCodeInput, Offer, OfferAdventureCard, PartnerBookingCreatedEmail, PartnerRegistrationCompleteEmail, PaymentAmountSelector, PaymentDetailsBlock, PaymentMethodSelector, PaymentModalShell, PaymentReceiptEmail, PaymentReminderEmail, PhoneCountrySelect, PhotoGallery, Picture, PricingTrip, RegistrationForm, RegistrationProgressBar, RegistrationReminderEmail, RegistrationReminderIndividualEmail, RegistrationSuccessCard, SiteHeader, TERMS_ACCEPT_KEY, TermsSection, ThemeToggle, Toast, TransferDetailsBlock, TravellerFormInviteEmail, TripCard, TripHeader, TripPage, TrustpilotEmbed, buttonVariants, cn, emailTokens, formatCpf, getStripeAppearance, itineraryDaySpecIcons, stripeAppearance, validateCpf, webpVariantUrl, wrapEmailHtml };
|
|
15728
|
+
export { ActivityCard, AgentContactCard, Alert, AskExo, BirthDateField, BookingAdventureCard, BookingCancellationEmail, BookingConfirmedCard, BookingCreatedEmail, BookingDetails, BookingForm, BookingOtpEmail, BookingPaymentConfirmationEmail, BookingShell, BookingSummary, Button, COUNTRIES, CategoryPage2, CounterField, CountrySearchField, DEFAULT_HEADER_LINKS, DEFAULT_LANGUAGES, STATUS_MAP as DEPARTURE_STATUS_MAP, DatePickerField, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, ExoOrb, FilterPanel, FloatingInput, FloatingSelect, GroupProgressBar, GroupStatusBanner, Itinerary, ItineraryDay, LOGO_PLANETAEXO_DATA_URI, LeadCapturePopup, MenuTrip, OTPCodeInput, Offer, OfferAdventureCard, ParticipantCounter, ParticipantList, PartnerBookingCreatedEmail, PartnerRegistrationCompleteEmail, PaymentAmountSelector, PaymentDetailsBlock, PaymentMethodSelector, PaymentModalShell, PaymentReceiptEmail, PaymentReminderEmail, PhoneCountrySelect, PhotoGallery, Picture, PriceProgress, PricingMatrixCard, PricingTrip, RegistrationForm, RegistrationProgressBar, RegistrationReminderEmail, RegistrationReminderIndividualEmail, RegistrationSuccessCard, ShareWidget, SiteHeader, StatusBadge2 as StatusBadge, StickyBookingCard, TERMS_ACCEPT_KEY, TermsSection, ThemeToggle, Toast, TransferDetailsBlock, TravellerFormInviteEmail, TripCard, TripHeader, TripPage, TrustpilotEmbed, buttonVariants, cn, emailTokens, formatCpf, getStripeAppearance, itineraryDaySpecIcons, stripeAppearance, validateCpf, webpVariantUrl, wrapEmailHtml };
|
|
14746
15729
|
//# sourceMappingURL=index.js.map
|
|
14747
15730
|
//# sourceMappingURL=index.js.map
|