@planetaexo/design-system 0.2.13 → 0.2.15
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 +3934 -321
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +470 -25
- package/dist/index.d.ts +470 -25
- package/dist/index.js +3916 -322
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as React18 from 'react';
|
|
2
|
+
import { useState, useRef, useCallback, useEffect } from 'react';
|
|
2
3
|
import { format } from 'date-fns';
|
|
3
|
-
import { MapIcon, MessageCircleIcon, UsersIcon, CreditCardIcon, AlertCircleIcon,
|
|
4
|
+
import { ChevronDownIcon, SearchIcon, MapIcon, MessageCircleIcon, UsersIcon, CreditCardIcon, AlertCircleIcon, MinusIcon, PlusIcon, CalendarIcon, ChevronLeftIcon, ChevronRightIcon, ClockIcon, ChevronUpIcon, UserIcon, MenuIcon, XIcon, SunIcon, MoonIcon, MapPinIcon, PackageIcon, InfoIcon, Loader2Icon, SendIcon, CheckCircleIcon, CheckIcon, CheckCircle2Icon, ArrowLeftIcon, MailIcon, PhoneIcon, CompassIcon, UserPlusIcon, ExternalLinkIcon, CopyIcon, PencilIcon, Trash2Icon, UserMinusIcon, AlertTriangleIcon, CarIcon, ZoomInIcon, StarIcon, LayoutGridIcon } from 'lucide-react';
|
|
4
5
|
import { clsx } from 'clsx';
|
|
5
6
|
import { twMerge } from 'tailwind-merge';
|
|
6
7
|
import { Separator as Separator$1 } from '@base-ui/react/separator';
|
|
@@ -9,6 +10,12 @@ import { Dialog as Dialog$1 } from '@base-ui/react/dialog';
|
|
|
9
10
|
import { Button as Button$1 } from '@base-ui/react/button';
|
|
10
11
|
import { cva } from 'class-variance-authority';
|
|
11
12
|
import { getDefaultClassNames, DayPicker } from 'react-day-picker';
|
|
13
|
+
import { Popover as Popover$1 } from '@base-ui/react/popover';
|
|
14
|
+
import { Checkbox as Checkbox$1 } from '@base-ui/react/checkbox';
|
|
15
|
+
import { Accordion as Accordion$1 } from '@base-ui/react/accordion';
|
|
16
|
+
import { mergeProps } from '@base-ui/react/merge-props';
|
|
17
|
+
import { useRender } from '@base-ui/react/use-render';
|
|
18
|
+
import { Input as Input$1 } from '@base-ui/react/input';
|
|
12
19
|
|
|
13
20
|
var __defProp = Object.defineProperty;
|
|
14
21
|
var __defProps = Object.defineProperties;
|
|
@@ -209,6 +216,23 @@ function DialogTitle(_a) {
|
|
|
209
216
|
}, props)
|
|
210
217
|
);
|
|
211
218
|
}
|
|
219
|
+
function DialogDescription(_a) {
|
|
220
|
+
var _b = _a, {
|
|
221
|
+
className
|
|
222
|
+
} = _b, props = __objRest(_b, [
|
|
223
|
+
"className"
|
|
224
|
+
]);
|
|
225
|
+
return /* @__PURE__ */ jsx(
|
|
226
|
+
Dialog$1.Description,
|
|
227
|
+
__spreadValues({
|
|
228
|
+
"data-slot": "dialog-description",
|
|
229
|
+
className: cn(
|
|
230
|
+
"text-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground",
|
|
231
|
+
className
|
|
232
|
+
)
|
|
233
|
+
}, props)
|
|
234
|
+
);
|
|
235
|
+
}
|
|
212
236
|
function Calendar(_a) {
|
|
213
237
|
var _b = _a, {
|
|
214
238
|
className,
|
|
@@ -377,8 +401,8 @@ function CalendarDayButton(_a) {
|
|
|
377
401
|
"locale"
|
|
378
402
|
]);
|
|
379
403
|
const defaultClassNames = getDefaultClassNames();
|
|
380
|
-
const ref =
|
|
381
|
-
|
|
404
|
+
const ref = React18.useRef(null);
|
|
405
|
+
React18.useEffect(() => {
|
|
382
406
|
var _a2;
|
|
383
407
|
if (modifiers.focused) (_a2 = ref.current) == null ? void 0 : _a2.focus();
|
|
384
408
|
}, [modifiers.focused]);
|
|
@@ -400,10 +424,10 @@ function CalendarDayButton(_a) {
|
|
|
400
424
|
}, props)
|
|
401
425
|
);
|
|
402
426
|
}
|
|
403
|
-
var FloatingInput =
|
|
427
|
+
var FloatingInput = React18.forwardRef(
|
|
404
428
|
(_a, ref) => {
|
|
405
429
|
var _b = _a, { label, error, id, className, required } = _b, props = __objRest(_b, ["label", "error", "id", "className", "required"]);
|
|
406
|
-
const inputId = id != null ? id :
|
|
430
|
+
const inputId = id != null ? id : React18.useId();
|
|
407
431
|
return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
|
|
408
432
|
/* @__PURE__ */ jsx(
|
|
409
433
|
"input",
|
|
@@ -443,10 +467,10 @@ var FloatingInput = React4.forwardRef(
|
|
|
443
467
|
}
|
|
444
468
|
);
|
|
445
469
|
FloatingInput.displayName = "FloatingInput";
|
|
446
|
-
var FloatingSelect =
|
|
470
|
+
var FloatingSelect = React18.forwardRef(
|
|
447
471
|
(_a, ref) => {
|
|
448
472
|
var _b = _a, { label, error, id, className, required, children } = _b, props = __objRest(_b, ["label", "error", "id", "className", "required", "children"]);
|
|
449
|
-
const inputId = id != null ? id :
|
|
473
|
+
const inputId = id != null ? id : React18.useId();
|
|
450
474
|
return /* @__PURE__ */ jsxs("div", { className: cn("relative", className), children: [
|
|
451
475
|
/* @__PURE__ */ jsx(
|
|
452
476
|
"select",
|
|
@@ -707,11 +731,11 @@ function PhoneCountrySelect({
|
|
|
707
731
|
className
|
|
708
732
|
}) {
|
|
709
733
|
var _a;
|
|
710
|
-
const [open, setOpen] =
|
|
711
|
-
const containerRef =
|
|
712
|
-
const listRef =
|
|
734
|
+
const [open, setOpen] = React18.useState(false);
|
|
735
|
+
const containerRef = React18.useRef(null);
|
|
736
|
+
const listRef = React18.useRef(null);
|
|
713
737
|
const selected = (_a = PHONE_COUNTRIES.find((c) => c.code === value)) != null ? _a : PHONE_COUNTRIES[0];
|
|
714
|
-
|
|
738
|
+
React18.useEffect(() => {
|
|
715
739
|
if (!open) return;
|
|
716
740
|
const handler = (e) => {
|
|
717
741
|
var _a2;
|
|
@@ -722,7 +746,7 @@ function PhoneCountrySelect({
|
|
|
722
746
|
document.addEventListener("mousedown", handler);
|
|
723
747
|
return () => document.removeEventListener("mousedown", handler);
|
|
724
748
|
}, [open]);
|
|
725
|
-
|
|
749
|
+
React18.useEffect(() => {
|
|
726
750
|
if (!open || !listRef.current) return;
|
|
727
751
|
const activeEl = listRef.current.querySelector("[data-selected=true]");
|
|
728
752
|
activeEl == null ? void 0 : activeEl.scrollIntoView({ block: "nearest" });
|
|
@@ -818,9 +842,214 @@ function PhoneCountrySelect({
|
|
|
818
842
|
)
|
|
819
843
|
] });
|
|
820
844
|
}
|
|
845
|
+
var COUNTRIES = [
|
|
846
|
+
{ code: "AF", name: "Afghanistan" },
|
|
847
|
+
{ code: "AL", name: "Albania" },
|
|
848
|
+
{ code: "DZ", name: "Algeria" },
|
|
849
|
+
{ code: "AO", name: "Angola" },
|
|
850
|
+
{ code: "AR", name: "Argentina" },
|
|
851
|
+
{ code: "AM", name: "Armenia" },
|
|
852
|
+
{ code: "AU", name: "Australia" },
|
|
853
|
+
{ code: "AT", name: "Austria" },
|
|
854
|
+
{ code: "AZ", name: "Azerbaijan" },
|
|
855
|
+
{ code: "BE", name: "Belgium" },
|
|
856
|
+
{ code: "BO", name: "Bolivia" },
|
|
857
|
+
{ code: "BA", name: "Bosnia" },
|
|
858
|
+
{ code: "BR", name: "Brazil" },
|
|
859
|
+
{ code: "BG", name: "Bulgaria" },
|
|
860
|
+
{ code: "KH", name: "Cambodia" },
|
|
861
|
+
{ code: "CA", name: "Canada" },
|
|
862
|
+
{ code: "CL", name: "Chile" },
|
|
863
|
+
{ code: "CN", name: "China" },
|
|
864
|
+
{ code: "CO", name: "Colombia" },
|
|
865
|
+
{ code: "CR", name: "Costa Rica" },
|
|
866
|
+
{ code: "HR", name: "Croatia" },
|
|
867
|
+
{ code: "CU", name: "Cuba" },
|
|
868
|
+
{ code: "CZ", name: "Czech Republic" },
|
|
869
|
+
{ code: "DK", name: "Denmark" },
|
|
870
|
+
{ code: "DO", name: "Dominican Republic" },
|
|
871
|
+
{ code: "EC", name: "Ecuador" },
|
|
872
|
+
{ code: "EG", name: "Egypt" },
|
|
873
|
+
{ code: "SV", name: "El Salvador" },
|
|
874
|
+
{ code: "ET", name: "Ethiopia" },
|
|
875
|
+
{ code: "FI", name: "Finland" },
|
|
876
|
+
{ code: "FR", name: "France" },
|
|
877
|
+
{ code: "GE", name: "Georgia" },
|
|
878
|
+
{ code: "DE", name: "Germany" },
|
|
879
|
+
{ code: "GH", name: "Ghana" },
|
|
880
|
+
{ code: "GR", name: "Greece" },
|
|
881
|
+
{ code: "GT", name: "Guatemala" },
|
|
882
|
+
{ code: "HN", name: "Honduras" },
|
|
883
|
+
{ code: "HK", name: "Hong Kong" },
|
|
884
|
+
{ code: "HU", name: "Hungary" },
|
|
885
|
+
{ code: "IS", name: "Iceland" },
|
|
886
|
+
{ code: "IN", name: "India" },
|
|
887
|
+
{ code: "ID", name: "Indonesia" },
|
|
888
|
+
{ code: "IR", name: "Iran" },
|
|
889
|
+
{ code: "IQ", name: "Iraq" },
|
|
890
|
+
{ code: "IE", name: "Ireland" },
|
|
891
|
+
{ code: "IL", name: "Israel" },
|
|
892
|
+
{ code: "IT", name: "Italy" },
|
|
893
|
+
{ code: "JM", name: "Jamaica" },
|
|
894
|
+
{ code: "JP", name: "Japan" },
|
|
895
|
+
{ code: "JO", name: "Jordan" },
|
|
896
|
+
{ code: "KZ", name: "Kazakhstan" },
|
|
897
|
+
{ code: "KE", name: "Kenya" },
|
|
898
|
+
{ code: "KW", name: "Kuwait" },
|
|
899
|
+
{ code: "LB", name: "Lebanon" },
|
|
900
|
+
{ code: "LY", name: "Libya" },
|
|
901
|
+
{ code: "MY", name: "Malaysia" },
|
|
902
|
+
{ code: "MX", name: "Mexico" },
|
|
903
|
+
{ code: "MA", name: "Morocco" },
|
|
904
|
+
{ code: "MZ", name: "Mozambique" },
|
|
905
|
+
{ code: "NP", name: "Nepal" },
|
|
906
|
+
{ code: "NL", name: "Netherlands" },
|
|
907
|
+
{ code: "NZ", name: "New Zealand" },
|
|
908
|
+
{ code: "NI", name: "Nicaragua" },
|
|
909
|
+
{ code: "NG", name: "Nigeria" },
|
|
910
|
+
{ code: "NO", name: "Norway" },
|
|
911
|
+
{ code: "PK", name: "Pakistan" },
|
|
912
|
+
{ code: "PA", name: "Panama" },
|
|
913
|
+
{ code: "PY", name: "Paraguay" },
|
|
914
|
+
{ code: "PE", name: "Peru" },
|
|
915
|
+
{ code: "PH", name: "Philippines" },
|
|
916
|
+
{ code: "PL", name: "Poland" },
|
|
917
|
+
{ code: "PT", name: "Portugal" },
|
|
918
|
+
{ code: "QA", name: "Qatar" },
|
|
919
|
+
{ code: "RO", name: "Romania" },
|
|
920
|
+
{ code: "RU", name: "Russia" },
|
|
921
|
+
{ code: "SA", name: "Saudi Arabia" },
|
|
922
|
+
{ code: "SN", name: "Senegal" },
|
|
923
|
+
{ code: "RS", name: "Serbia" },
|
|
924
|
+
{ code: "SG", name: "Singapore" },
|
|
925
|
+
{ code: "ZA", name: "South Africa" },
|
|
926
|
+
{ code: "KR", name: "South Korea" },
|
|
927
|
+
{ code: "ES", name: "Spain" },
|
|
928
|
+
{ code: "LK", name: "Sri Lanka" },
|
|
929
|
+
{ code: "SE", name: "Sweden" },
|
|
930
|
+
{ code: "CH", name: "Switzerland" },
|
|
931
|
+
{ code: "TW", name: "Taiwan" },
|
|
932
|
+
{ code: "TZ", name: "Tanzania" },
|
|
933
|
+
{ code: "TH", name: "Thailand" },
|
|
934
|
+
{ code: "TN", name: "Tunisia" },
|
|
935
|
+
{ code: "TR", name: "Turkey" },
|
|
936
|
+
{ code: "UA", name: "Ukraine" },
|
|
937
|
+
{ code: "AE", name: "United Arab Emirates" },
|
|
938
|
+
{ code: "GB", name: "United Kingdom" },
|
|
939
|
+
{ code: "US", name: "United States" },
|
|
940
|
+
{ code: "UY", name: "Uruguay" },
|
|
941
|
+
{ code: "UZ", name: "Uzbekistan" },
|
|
942
|
+
{ code: "VE", name: "Venezuela" },
|
|
943
|
+
{ code: "VN", name: "Vietnam" },
|
|
944
|
+
{ code: "YE", name: "Yemen" },
|
|
945
|
+
{ code: "ZW", name: "Zimbabwe" }
|
|
946
|
+
];
|
|
947
|
+
function CountrySearchField({
|
|
948
|
+
value,
|
|
949
|
+
onChange,
|
|
950
|
+
required,
|
|
951
|
+
label = "Country",
|
|
952
|
+
countries,
|
|
953
|
+
placeholder = "Search country\u2026",
|
|
954
|
+
className
|
|
955
|
+
}) {
|
|
956
|
+
var _a;
|
|
957
|
+
const list = countries != null ? countries : COUNTRIES;
|
|
958
|
+
const [query, setQuery] = React18.useState("");
|
|
959
|
+
const [open, setOpen] = React18.useState(false);
|
|
960
|
+
const containerRef = React18.useRef(null);
|
|
961
|
+
const searchRef = React18.useRef(null);
|
|
962
|
+
const selected = list.find((c) => c.code === value);
|
|
963
|
+
const isFloated = open || !!selected;
|
|
964
|
+
const filtered = query.trim() ? list.filter((c) => c.name.toLowerCase().includes(query.toLowerCase())) : list;
|
|
965
|
+
React18.useEffect(() => {
|
|
966
|
+
if (!open) return;
|
|
967
|
+
const handler = (e) => {
|
|
968
|
+
var _a2;
|
|
969
|
+
if (!((_a2 = containerRef.current) == null ? void 0 : _a2.contains(e.target))) {
|
|
970
|
+
setOpen(false);
|
|
971
|
+
setQuery("");
|
|
972
|
+
}
|
|
973
|
+
};
|
|
974
|
+
document.addEventListener("mousedown", handler);
|
|
975
|
+
return () => document.removeEventListener("mousedown", handler);
|
|
976
|
+
}, [open]);
|
|
977
|
+
const handleOpen = () => {
|
|
978
|
+
setOpen(true);
|
|
979
|
+
setQuery("");
|
|
980
|
+
setTimeout(() => {
|
|
981
|
+
var _a2;
|
|
982
|
+
return (_a2 = searchRef.current) == null ? void 0 : _a2.focus();
|
|
983
|
+
}, 0);
|
|
984
|
+
};
|
|
985
|
+
const handleSelect = (code) => {
|
|
986
|
+
onChange(code);
|
|
987
|
+
setOpen(false);
|
|
988
|
+
setQuery("");
|
|
989
|
+
};
|
|
990
|
+
return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: cn("relative w-full", className), children: [
|
|
991
|
+
/* @__PURE__ */ jsxs(
|
|
992
|
+
"button",
|
|
993
|
+
{
|
|
994
|
+
type: "button",
|
|
995
|
+
onClick: handleOpen,
|
|
996
|
+
className: cn(
|
|
997
|
+
"relative flex w-full items-center rounded-lg border border-border bg-background h-14 px-3 text-left transition-colors",
|
|
998
|
+
open && "border-primary ring-1 ring-primary"
|
|
999
|
+
),
|
|
1000
|
+
children: [
|
|
1001
|
+
/* @__PURE__ */ jsxs(
|
|
1002
|
+
"span",
|
|
1003
|
+
{
|
|
1004
|
+
className: cn(
|
|
1005
|
+
"pointer-events-none absolute left-3 transition-all duration-150 font-ui",
|
|
1006
|
+
isFloated ? "top-2 text-xs text-primary" : "top-1/2 -translate-y-1/2 text-base text-muted-foreground"
|
|
1007
|
+
),
|
|
1008
|
+
children: [
|
|
1009
|
+
label,
|
|
1010
|
+
required && /* @__PURE__ */ jsx("span", { className: "text-primary ml-0.5", children: "*" })
|
|
1011
|
+
]
|
|
1012
|
+
}
|
|
1013
|
+
),
|
|
1014
|
+
/* @__PURE__ */ jsx("span", { className: cn("flex-1 pt-3 text-base font-ui truncate", selected ? "text-foreground" : "invisible"), children: (_a = selected == null ? void 0 : selected.name) != null ? _a : "\u2014" }),
|
|
1015
|
+
/* @__PURE__ */ jsx(ChevronDownIcon, { className: cn("h-4 w-4 shrink-0 text-muted-foreground transition-transform", open && "rotate-180") })
|
|
1016
|
+
]
|
|
1017
|
+
}
|
|
1018
|
+
),
|
|
1019
|
+
open && /* @__PURE__ */ jsxs("div", { className: "absolute top-[calc(100%+4px)] left-0 right-0 z-50 rounded-xl border border-border bg-background shadow-lg overflow-hidden", children: [
|
|
1020
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-3 py-2 border-b border-border", children: [
|
|
1021
|
+
/* @__PURE__ */ jsx(SearchIcon, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
1022
|
+
/* @__PURE__ */ jsx(
|
|
1023
|
+
"input",
|
|
1024
|
+
{
|
|
1025
|
+
ref: searchRef,
|
|
1026
|
+
type: "text",
|
|
1027
|
+
value: query,
|
|
1028
|
+
onChange: (e) => setQuery(e.target.value),
|
|
1029
|
+
placeholder,
|
|
1030
|
+
className: "flex-1 bg-transparent text-sm font-ui text-foreground placeholder:text-muted-foreground focus:outline-none"
|
|
1031
|
+
}
|
|
1032
|
+
)
|
|
1033
|
+
] }),
|
|
1034
|
+
/* @__PURE__ */ jsx("div", { className: "max-h-52 overflow-y-auto py-1", children: filtered.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-3 py-2 text-sm font-ui text-muted-foreground", children: "No countries found" }) : filtered.map((c) => /* @__PURE__ */ jsx(
|
|
1035
|
+
"button",
|
|
1036
|
+
{
|
|
1037
|
+
type: "button",
|
|
1038
|
+
onClick: () => handleSelect(c.code),
|
|
1039
|
+
className: cn(
|
|
1040
|
+
"flex w-full items-center px-3 py-2 text-sm font-ui text-left transition-colors hover:bg-muted",
|
|
1041
|
+
c.code === value && "bg-primary/10 text-primary font-semibold"
|
|
1042
|
+
),
|
|
1043
|
+
children: c.name
|
|
1044
|
+
},
|
|
1045
|
+
c.code
|
|
1046
|
+
)) })
|
|
1047
|
+
] })
|
|
1048
|
+
] });
|
|
1049
|
+
}
|
|
821
1050
|
function AdventureCard({ adventure }) {
|
|
822
1051
|
var _a, _b, _c;
|
|
823
|
-
const [checked, setChecked] =
|
|
1052
|
+
const [checked, setChecked] = React18.useState(
|
|
824
1053
|
new Set((_b = (_a = adventure.optionals) == null ? void 0 : _a.filter((o) => o.defaultChecked).map((o) => o.id)) != null ? _b : [])
|
|
825
1054
|
);
|
|
826
1055
|
const toggleOptional = (id) => setChecked((prev) => {
|
|
@@ -1110,220 +1339,20 @@ function OfferSummarySection({
|
|
|
1110
1339
|
)
|
|
1111
1340
|
] });
|
|
1112
1341
|
}
|
|
1113
|
-
var COUNTRIES = [
|
|
1114
|
-
{ code: "AF", name: "Afghanistan" },
|
|
1115
|
-
{ code: "AL", name: "Albania" },
|
|
1116
|
-
{ code: "DZ", name: "Algeria" },
|
|
1117
|
-
{ code: "AO", name: "Angola" },
|
|
1118
|
-
{ code: "AR", name: "Argentina" },
|
|
1119
|
-
{ code: "AM", name: "Armenia" },
|
|
1120
|
-
{ code: "AU", name: "Australia" },
|
|
1121
|
-
{ code: "AT", name: "Austria" },
|
|
1122
|
-
{ code: "AZ", name: "Azerbaijan" },
|
|
1123
|
-
{ code: "BE", name: "Belgium" },
|
|
1124
|
-
{ code: "BO", name: "Bolivia" },
|
|
1125
|
-
{ code: "BA", name: "Bosnia" },
|
|
1126
|
-
{ code: "BR", name: "Brazil" },
|
|
1127
|
-
{ code: "BG", name: "Bulgaria" },
|
|
1128
|
-
{ code: "KH", name: "Cambodia" },
|
|
1129
|
-
{ code: "CA", name: "Canada" },
|
|
1130
|
-
{ code: "CL", name: "Chile" },
|
|
1131
|
-
{ code: "CN", name: "China" },
|
|
1132
|
-
{ code: "CO", name: "Colombia" },
|
|
1133
|
-
{ code: "CR", name: "Costa Rica" },
|
|
1134
|
-
{ code: "HR", name: "Croatia" },
|
|
1135
|
-
{ code: "CU", name: "Cuba" },
|
|
1136
|
-
{ code: "CZ", name: "Czech Republic" },
|
|
1137
|
-
{ code: "DK", name: "Denmark" },
|
|
1138
|
-
{ code: "DO", name: "Dominican Republic" },
|
|
1139
|
-
{ code: "EC", name: "Ecuador" },
|
|
1140
|
-
{ code: "EG", name: "Egypt" },
|
|
1141
|
-
{ code: "SV", name: "El Salvador" },
|
|
1142
|
-
{ code: "ET", name: "Ethiopia" },
|
|
1143
|
-
{ code: "FI", name: "Finland" },
|
|
1144
|
-
{ code: "FR", name: "France" },
|
|
1145
|
-
{ code: "GE", name: "Georgia" },
|
|
1146
|
-
{ code: "DE", name: "Germany" },
|
|
1147
|
-
{ code: "GH", name: "Ghana" },
|
|
1148
|
-
{ code: "GR", name: "Greece" },
|
|
1149
|
-
{ code: "GT", name: "Guatemala" },
|
|
1150
|
-
{ code: "HN", name: "Honduras" },
|
|
1151
|
-
{ code: "HK", name: "Hong Kong" },
|
|
1152
|
-
{ code: "HU", name: "Hungary" },
|
|
1153
|
-
{ code: "IS", name: "Iceland" },
|
|
1154
|
-
{ code: "IN", name: "India" },
|
|
1155
|
-
{ code: "ID", name: "Indonesia" },
|
|
1156
|
-
{ code: "IR", name: "Iran" },
|
|
1157
|
-
{ code: "IQ", name: "Iraq" },
|
|
1158
|
-
{ code: "IE", name: "Ireland" },
|
|
1159
|
-
{ code: "IL", name: "Israel" },
|
|
1160
|
-
{ code: "IT", name: "Italy" },
|
|
1161
|
-
{ code: "JM", name: "Jamaica" },
|
|
1162
|
-
{ code: "JP", name: "Japan" },
|
|
1163
|
-
{ code: "JO", name: "Jordan" },
|
|
1164
|
-
{ code: "KZ", name: "Kazakhstan" },
|
|
1165
|
-
{ code: "KE", name: "Kenya" },
|
|
1166
|
-
{ code: "KW", name: "Kuwait" },
|
|
1167
|
-
{ code: "LB", name: "Lebanon" },
|
|
1168
|
-
{ code: "LY", name: "Libya" },
|
|
1169
|
-
{ code: "MY", name: "Malaysia" },
|
|
1170
|
-
{ code: "MX", name: "Mexico" },
|
|
1171
|
-
{ code: "MA", name: "Morocco" },
|
|
1172
|
-
{ code: "MZ", name: "Mozambique" },
|
|
1173
|
-
{ code: "NP", name: "Nepal" },
|
|
1174
|
-
{ code: "NL", name: "Netherlands" },
|
|
1175
|
-
{ code: "NZ", name: "New Zealand" },
|
|
1176
|
-
{ code: "NI", name: "Nicaragua" },
|
|
1177
|
-
{ code: "NG", name: "Nigeria" },
|
|
1178
|
-
{ code: "NO", name: "Norway" },
|
|
1179
|
-
{ code: "PK", name: "Pakistan" },
|
|
1180
|
-
{ code: "PA", name: "Panama" },
|
|
1181
|
-
{ code: "PY", name: "Paraguay" },
|
|
1182
|
-
{ code: "PE", name: "Peru" },
|
|
1183
|
-
{ code: "PH", name: "Philippines" },
|
|
1184
|
-
{ code: "PL", name: "Poland" },
|
|
1185
|
-
{ code: "PT", name: "Portugal" },
|
|
1186
|
-
{ code: "QA", name: "Qatar" },
|
|
1187
|
-
{ code: "RO", name: "Romania" },
|
|
1188
|
-
{ code: "RU", name: "Russia" },
|
|
1189
|
-
{ code: "SA", name: "Saudi Arabia" },
|
|
1190
|
-
{ code: "SN", name: "Senegal" },
|
|
1191
|
-
{ code: "RS", name: "Serbia" },
|
|
1192
|
-
{ code: "SG", name: "Singapore" },
|
|
1193
|
-
{ code: "ZA", name: "South Africa" },
|
|
1194
|
-
{ code: "KR", name: "South Korea" },
|
|
1195
|
-
{ code: "ES", name: "Spain" },
|
|
1196
|
-
{ code: "LK", name: "Sri Lanka" },
|
|
1197
|
-
{ code: "SE", name: "Sweden" },
|
|
1198
|
-
{ code: "CH", name: "Switzerland" },
|
|
1199
|
-
{ code: "TW", name: "Taiwan" },
|
|
1200
|
-
{ code: "TZ", name: "Tanzania" },
|
|
1201
|
-
{ code: "TH", name: "Thailand" },
|
|
1202
|
-
{ code: "TN", name: "Tunisia" },
|
|
1203
|
-
{ code: "TR", name: "Turkey" },
|
|
1204
|
-
{ code: "UA", name: "Ukraine" },
|
|
1205
|
-
{ code: "AE", name: "United Arab Emirates" },
|
|
1206
|
-
{ code: "GB", name: "United Kingdom" },
|
|
1207
|
-
{ code: "US", name: "United States" },
|
|
1208
|
-
{ code: "UY", name: "Uruguay" },
|
|
1209
|
-
{ code: "UZ", name: "Uzbekistan" },
|
|
1210
|
-
{ code: "VE", name: "Venezuela" },
|
|
1211
|
-
{ code: "VN", name: "Vietnam" },
|
|
1212
|
-
{ code: "YE", name: "Yemen" },
|
|
1213
|
-
{ code: "ZW", name: "Zimbabwe" }
|
|
1214
|
-
];
|
|
1215
|
-
function CountrySearchField({
|
|
1216
|
-
value,
|
|
1217
|
-
onChange,
|
|
1218
|
-
required
|
|
1219
|
-
}) {
|
|
1220
|
-
var _a;
|
|
1221
|
-
const [query, setQuery] = React4.useState("");
|
|
1222
|
-
const [open, setOpen] = React4.useState(false);
|
|
1223
|
-
const containerRef = React4.useRef(null);
|
|
1224
|
-
const searchRef = React4.useRef(null);
|
|
1225
|
-
const selected = COUNTRIES.find((c) => c.code === value);
|
|
1226
|
-
const isFloated = open || !!selected;
|
|
1227
|
-
const filtered = query.trim() ? COUNTRIES.filter((c) => c.name.toLowerCase().includes(query.toLowerCase())) : COUNTRIES;
|
|
1228
|
-
React4.useEffect(() => {
|
|
1229
|
-
if (!open) return;
|
|
1230
|
-
const handler = (e) => {
|
|
1231
|
-
var _a2;
|
|
1232
|
-
if (!((_a2 = containerRef.current) == null ? void 0 : _a2.contains(e.target))) {
|
|
1233
|
-
setOpen(false);
|
|
1234
|
-
setQuery("");
|
|
1235
|
-
}
|
|
1236
|
-
};
|
|
1237
|
-
document.addEventListener("mousedown", handler);
|
|
1238
|
-
return () => document.removeEventListener("mousedown", handler);
|
|
1239
|
-
}, [open]);
|
|
1240
|
-
const handleOpen = () => {
|
|
1241
|
-
setOpen(true);
|
|
1242
|
-
setQuery("");
|
|
1243
|
-
setTimeout(() => {
|
|
1244
|
-
var _a2;
|
|
1245
|
-
return (_a2 = searchRef.current) == null ? void 0 : _a2.focus();
|
|
1246
|
-
}, 0);
|
|
1247
|
-
};
|
|
1248
|
-
const handleSelect = (code) => {
|
|
1249
|
-
onChange(code);
|
|
1250
|
-
setOpen(false);
|
|
1251
|
-
setQuery("");
|
|
1252
|
-
};
|
|
1253
|
-
return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "relative w-full", children: [
|
|
1254
|
-
/* @__PURE__ */ jsxs(
|
|
1255
|
-
"button",
|
|
1256
|
-
{
|
|
1257
|
-
type: "button",
|
|
1258
|
-
onClick: handleOpen,
|
|
1259
|
-
className: cn(
|
|
1260
|
-
"relative flex w-full items-center rounded-lg border border-border bg-background h-14 px-3 text-left transition-colors",
|
|
1261
|
-
open && "border-primary ring-1 ring-primary"
|
|
1262
|
-
),
|
|
1263
|
-
children: [
|
|
1264
|
-
/* @__PURE__ */ jsxs(
|
|
1265
|
-
"span",
|
|
1266
|
-
{
|
|
1267
|
-
className: cn(
|
|
1268
|
-
"pointer-events-none absolute left-3 transition-all duration-150 font-ui",
|
|
1269
|
-
isFloated ? "top-2 text-xs text-primary" : "top-1/2 -translate-y-1/2 text-base text-muted-foreground"
|
|
1270
|
-
),
|
|
1271
|
-
children: [
|
|
1272
|
-
"Country",
|
|
1273
|
-
required && /* @__PURE__ */ jsx("span", { className: "text-primary ml-0.5", children: "*" })
|
|
1274
|
-
]
|
|
1275
|
-
}
|
|
1276
|
-
),
|
|
1277
|
-
/* @__PURE__ */ jsx("span", { className: cn("flex-1 pt-3 text-base font-ui truncate", selected ? "text-foreground" : "invisible"), children: (_a = selected == null ? void 0 : selected.name) != null ? _a : "\u2014" }),
|
|
1278
|
-
/* @__PURE__ */ jsx(ChevronDownIcon, { className: cn("h-4 w-4 shrink-0 text-muted-foreground transition-transform", open && "rotate-180") })
|
|
1279
|
-
]
|
|
1280
|
-
}
|
|
1281
|
-
),
|
|
1282
|
-
open && /* @__PURE__ */ jsxs("div", { className: "absolute top-[calc(100%+4px)] left-0 right-0 z-50 rounded-xl border border-border bg-background shadow-lg overflow-hidden", children: [
|
|
1283
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 px-3 py-2 border-b border-border", children: [
|
|
1284
|
-
/* @__PURE__ */ jsx(SearchIcon, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
|
|
1285
|
-
/* @__PURE__ */ jsx(
|
|
1286
|
-
"input",
|
|
1287
|
-
{
|
|
1288
|
-
ref: searchRef,
|
|
1289
|
-
type: "text",
|
|
1290
|
-
value: query,
|
|
1291
|
-
onChange: (e) => setQuery(e.target.value),
|
|
1292
|
-
placeholder: "Search country\u2026",
|
|
1293
|
-
className: "flex-1 bg-transparent text-sm font-ui text-foreground placeholder:text-muted-foreground focus:outline-none"
|
|
1294
|
-
}
|
|
1295
|
-
)
|
|
1296
|
-
] }),
|
|
1297
|
-
/* @__PURE__ */ jsx("div", { className: "max-h-52 overflow-y-auto py-1", children: filtered.length === 0 ? /* @__PURE__ */ jsx("p", { className: "px-3 py-2 text-sm font-ui text-muted-foreground", children: "No countries found" }) : filtered.map((c) => /* @__PURE__ */ jsx(
|
|
1298
|
-
"button",
|
|
1299
|
-
{
|
|
1300
|
-
type: "button",
|
|
1301
|
-
onClick: () => handleSelect(c.code),
|
|
1302
|
-
className: cn(
|
|
1303
|
-
"flex w-full items-center px-3 py-2 text-sm font-ui text-left transition-colors hover:bg-muted",
|
|
1304
|
-
c.code === value && "bg-primary/10 text-primary font-semibold"
|
|
1305
|
-
),
|
|
1306
|
-
children: c.name
|
|
1307
|
-
},
|
|
1308
|
-
c.code
|
|
1309
|
-
)) })
|
|
1310
|
-
] })
|
|
1311
|
-
] });
|
|
1312
|
-
}
|
|
1313
1342
|
function BirthDateField({
|
|
1314
1343
|
label,
|
|
1315
1344
|
required,
|
|
1316
1345
|
value,
|
|
1317
1346
|
onChange
|
|
1318
1347
|
}) {
|
|
1319
|
-
const [open, setOpen] =
|
|
1320
|
-
const [text, setText] =
|
|
1321
|
-
const containerRef =
|
|
1322
|
-
const inputId =
|
|
1323
|
-
|
|
1348
|
+
const [open, setOpen] = React18.useState(false);
|
|
1349
|
+
const [text, setText] = React18.useState(value ? format(value, "dd/MM/yyyy") : "");
|
|
1350
|
+
const containerRef = React18.useRef(null);
|
|
1351
|
+
const inputId = React18.useId();
|
|
1352
|
+
React18.useEffect(() => {
|
|
1324
1353
|
setText(value ? format(value, "dd/MM/yyyy") : "");
|
|
1325
1354
|
}, [value]);
|
|
1326
|
-
|
|
1355
|
+
React18.useEffect(() => {
|
|
1327
1356
|
if (!open) return;
|
|
1328
1357
|
const handler = (e) => {
|
|
1329
1358
|
var _a;
|
|
@@ -1424,9 +1453,9 @@ function BookingWizard({
|
|
|
1424
1453
|
depositInfo,
|
|
1425
1454
|
onCancel
|
|
1426
1455
|
}) {
|
|
1427
|
-
const [step, setStep] =
|
|
1428
|
-
const [error, setError] =
|
|
1429
|
-
const [responsible, setResponsible] =
|
|
1456
|
+
const [step, setStep] = React18.useState("responsible");
|
|
1457
|
+
const [error, setError] = React18.useState(null);
|
|
1458
|
+
const [responsible, setResponsible] = React18.useState({
|
|
1430
1459
|
firstName: "",
|
|
1431
1460
|
lastName: "",
|
|
1432
1461
|
email: "",
|
|
@@ -1445,7 +1474,7 @@ function BookingWizard({
|
|
|
1445
1474
|
return s + ((_b = (_a = a.slots) == null ? void 0 : _a.children) != null ? _b : 0);
|
|
1446
1475
|
}, 0);
|
|
1447
1476
|
const totalPax = totalAdults + totalChildren;
|
|
1448
|
-
const [travellers, setTravellers] =
|
|
1477
|
+
const [travellers, setTravellers] = React18.useState(
|
|
1449
1478
|
Array.from({ length: Math.max(totalPax, 1) }, () => ({
|
|
1450
1479
|
firstName: "",
|
|
1451
1480
|
lastName: "",
|
|
@@ -1453,10 +1482,10 @@ function BookingWizard({
|
|
|
1453
1482
|
email: ""
|
|
1454
1483
|
}))
|
|
1455
1484
|
);
|
|
1456
|
-
const [payAmount, setPayAmount] =
|
|
1457
|
-
const [payMethod, setPayMethod] =
|
|
1458
|
-
const [termsAccepted, setTermsAccepted] =
|
|
1459
|
-
const [termsModalOpen, setTermsModalOpen] =
|
|
1485
|
+
const [payAmount, setPayAmount] = React18.useState("full");
|
|
1486
|
+
const [payMethod, setPayMethod] = React18.useState("stripe");
|
|
1487
|
+
const [termsAccepted, setTermsAccepted] = React18.useState(false);
|
|
1488
|
+
const [termsModalOpen, setTermsModalOpen] = React18.useState(false);
|
|
1460
1489
|
const setR = (k, v) => setResponsible((p) => __spreadProps(__spreadValues({}, p), { [k]: v }));
|
|
1461
1490
|
const setT = (i, k, v) => setTravellers((prev) => prev.map((t, idx) => idx === i ? __spreadProps(__spreadValues({}, t), { [k]: v }) : t));
|
|
1462
1491
|
const setTDob = (i, v) => setTravellers((prev) => prev.map((t, idx) => idx === i ? __spreadProps(__spreadValues({}, t), { dateOfBirth: v }) : t));
|
|
@@ -1528,7 +1557,7 @@ function BookingWizard({
|
|
|
1528
1557
|
return /* @__PURE__ */ jsxs("div", { className: "rounded-2xl border border-border bg-card overflow-hidden", children: [
|
|
1529
1558
|
/* @__PURE__ */ jsxs("div", { className: "border-b border-border px-5 py-4 bg-muted/20", children: [
|
|
1530
1559
|
/* @__PURE__ */ jsx("h3", { className: "text-base font-bold text-foreground font-heading mb-2", children: "Booking details" }),
|
|
1531
|
-
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: WIZARD_STEPS.map((s, i) => /* @__PURE__ */ jsxs(
|
|
1560
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: WIZARD_STEPS.map((s, i) => /* @__PURE__ */ jsxs(React18.Fragment, { children: [
|
|
1532
1561
|
/* @__PURE__ */ jsx(
|
|
1533
1562
|
"span",
|
|
1534
1563
|
{
|
|
@@ -1806,7 +1835,7 @@ function Offer({
|
|
|
1806
1835
|
continueDisabled,
|
|
1807
1836
|
className
|
|
1808
1837
|
}) {
|
|
1809
|
-
const [showBooking, setShowBooking] =
|
|
1838
|
+
const [showBooking, setShowBooking] = React18.useState(false);
|
|
1810
1839
|
const handleBook = () => {
|
|
1811
1840
|
if (!externalBookingFlow) setShowBooking(true);
|
|
1812
1841
|
onContinue == null ? void 0 : onContinue();
|
|
@@ -1927,9 +1956,9 @@ function AdventureSection({
|
|
|
1927
1956
|
onAddSuggestedTraveller
|
|
1928
1957
|
}) {
|
|
1929
1958
|
var _a, _b, _c;
|
|
1930
|
-
const [detailsOpen, setDetailsOpen] =
|
|
1931
|
-
const [addModalOpen, setAddModalOpen] =
|
|
1932
|
-
const [newTraveller, setNewTraveller] =
|
|
1959
|
+
const [detailsOpen, setDetailsOpen] = React18.useState(false);
|
|
1960
|
+
const [addModalOpen, setAddModalOpen] = React18.useState(false);
|
|
1961
|
+
const [newTraveller, setNewTraveller] = React18.useState({
|
|
1933
1962
|
firstName: "",
|
|
1934
1963
|
lastName: "",
|
|
1935
1964
|
passport: "",
|
|
@@ -2606,96 +2635,9 @@ function BookingDetails({
|
|
|
2606
2635
|
);
|
|
2607
2636
|
}
|
|
2608
2637
|
var DEFAULT_LOGO = "/logo-planetaexo.png";
|
|
2609
|
-
function BookingConfirmationEmail({
|
|
2610
|
-
recipientName,
|
|
2611
|
-
addTravellersUrl,
|
|
2612
|
-
logoUrl = DEFAULT_LOGO,
|
|
2613
|
-
bookingNumber,
|
|
2614
|
-
activity,
|
|
2615
|
-
adventure,
|
|
2616
|
-
startingDate,
|
|
2617
|
-
numberOfPeople,
|
|
2618
|
-
host,
|
|
2619
|
-
className
|
|
2620
|
-
}) {
|
|
2621
|
-
const AddTravellersCta = addTravellersUrl ? /* @__PURE__ */ jsx(
|
|
2622
|
-
"a",
|
|
2623
|
-
{
|
|
2624
|
-
href: addTravellersUrl,
|
|
2625
|
-
className: "inline-flex items-center justify-center rounded-lg bg-primary px-6 py-3 text-sm font-bold text-primary-foreground font-heading hover:bg-primary-800 transition-colors no-underline",
|
|
2626
|
-
children: "Add travellers to your booking"
|
|
2627
|
-
}
|
|
2628
|
-
) : /* @__PURE__ */ jsx(
|
|
2629
|
-
"span",
|
|
2630
|
-
{
|
|
2631
|
-
className: "inline-flex items-center justify-center rounded-lg bg-primary px-6 py-3 text-sm font-bold text-primary-foreground font-heading",
|
|
2632
|
-
role: "presentation",
|
|
2633
|
-
children: "Add travellers to your booking"
|
|
2634
|
-
}
|
|
2635
|
-
);
|
|
2636
|
-
return /* @__PURE__ */ jsxs(
|
|
2637
|
-
"div",
|
|
2638
|
-
{
|
|
2639
|
-
className: cn(
|
|
2640
|
-
"max-w-xl mx-auto bg-white text-foreground font-sans text-base leading-relaxed",
|
|
2641
|
-
className
|
|
2642
|
-
),
|
|
2643
|
-
children: [
|
|
2644
|
-
/* @__PURE__ */ jsx("div", { className: "mt-8 mb-8 flex justify-center", children: /* @__PURE__ */ jsx(
|
|
2645
|
-
"img",
|
|
2646
|
-
{
|
|
2647
|
-
src: logoUrl,
|
|
2648
|
-
alt: "PlanetaEXO",
|
|
2649
|
-
className: "h-[70px] w-auto object-contain"
|
|
2650
|
-
}
|
|
2651
|
-
) }),
|
|
2652
|
-
/* @__PURE__ */ jsxs("p", { className: "mb-4", children: [
|
|
2653
|
-
"Hi ",
|
|
2654
|
-
recipientName,
|
|
2655
|
-
","
|
|
2656
|
-
] }),
|
|
2657
|
-
/* @__PURE__ */ jsx("p", { className: "mb-4", children: "Thank you for booking your adventure with PlanetaEXO \u2014 we're really looking forward to your adventure." }),
|
|
2658
|
-
/* @__PURE__ */ jsx("p", { className: "mb-4", children: "To move forward, the first step is to add all travellers included in your booking. Once you do this, each person \u2014 including you \u2014 will receive an email with a link to complete their individual registration." }),
|
|
2659
|
-
/* @__PURE__ */ jsx("div", { className: "mb-8", children: AddTravellersCta }),
|
|
2660
|
-
/* @__PURE__ */ jsx("hr", { className: "border-t border-border mb-8" }),
|
|
2661
|
-
/* @__PURE__ */ jsx("p", { className: "mb-4 font-heading font-bold text-foreground", children: "\u{1F4DD} Here's a quick summary of your booking:" }),
|
|
2662
|
-
/* @__PURE__ */ jsx("table", { className: "w-full text-sm mb-8", children: /* @__PURE__ */ jsxs("tbody", { className: "divide-y divide-border", children: [
|
|
2663
|
-
/* @__PURE__ */ jsxs("tr", { children: [
|
|
2664
|
-
/* @__PURE__ */ jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Booking Number:" }),
|
|
2665
|
-
/* @__PURE__ */ jsx("td", { className: "py-1 font-medium text-foreground", children: bookingNumber })
|
|
2666
|
-
] }),
|
|
2667
|
-
/* @__PURE__ */ jsxs("tr", { children: [
|
|
2668
|
-
/* @__PURE__ */ jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Activity:" }),
|
|
2669
|
-
/* @__PURE__ */ jsx("td", { className: "py-1 font-medium text-foreground", children: activity })
|
|
2670
|
-
] }),
|
|
2671
|
-
/* @__PURE__ */ jsxs("tr", { children: [
|
|
2672
|
-
/* @__PURE__ */ jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Adventure:" }),
|
|
2673
|
-
/* @__PURE__ */ jsx("td", { className: "py-1 font-medium text-foreground", children: adventure })
|
|
2674
|
-
] }),
|
|
2675
|
-
/* @__PURE__ */ jsxs("tr", { children: [
|
|
2676
|
-
/* @__PURE__ */ jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Starting Date:" }),
|
|
2677
|
-
/* @__PURE__ */ jsx("td", { className: "py-1 font-medium text-foreground", children: startingDate })
|
|
2678
|
-
] }),
|
|
2679
|
-
/* @__PURE__ */ jsxs("tr", { children: [
|
|
2680
|
-
/* @__PURE__ */ jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Number of People:" }),
|
|
2681
|
-
/* @__PURE__ */ jsx("td", { className: "py-1 font-medium text-foreground", children: numberOfPeople })
|
|
2682
|
-
] }),
|
|
2683
|
-
/* @__PURE__ */ jsxs("tr", { children: [
|
|
2684
|
-
/* @__PURE__ */ jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Host:" }),
|
|
2685
|
-
/* @__PURE__ */ jsx("td", { className: "py-1 font-medium text-foreground", children: host })
|
|
2686
|
-
] })
|
|
2687
|
-
] }) }),
|
|
2688
|
-
/* @__PURE__ */ jsx("hr", { className: "border-t border-border mb-8" }),
|
|
2689
|
-
/* @__PURE__ */ jsx("p", { className: "mb-4", children: "After adding everyone, you will also receive your own registration email, just like the other travellers. Please make sure everyone completes this step so we can organise everything properly." }),
|
|
2690
|
-
/* @__PURE__ */ jsx("p", { children: "If you have any questions, just reply to this email \u2014 happy to help." })
|
|
2691
|
-
]
|
|
2692
|
-
}
|
|
2693
|
-
);
|
|
2694
|
-
}
|
|
2695
|
-
var DEFAULT_LOGO2 = "/logo-planetaexo.png";
|
|
2696
2638
|
function BookingConfirmation({
|
|
2697
2639
|
recipientName,
|
|
2698
|
-
logoUrl =
|
|
2640
|
+
logoUrl = DEFAULT_LOGO,
|
|
2699
2641
|
bookingReference,
|
|
2700
2642
|
adventures,
|
|
2701
2643
|
summaryLineItems,
|
|
@@ -3022,7 +2964,3659 @@ function BookingConfirmation({
|
|
|
3022
2964
|
}
|
|
3023
2965
|
);
|
|
3024
2966
|
}
|
|
2967
|
+
var DEFAULT_LOGO2 = "/logo-planetaexo.png";
|
|
2968
|
+
function BookingConfirmationEmail({
|
|
2969
|
+
recipientName,
|
|
2970
|
+
addTravellersUrl,
|
|
2971
|
+
logoUrl = DEFAULT_LOGO2,
|
|
2972
|
+
bookingNumber,
|
|
2973
|
+
activity,
|
|
2974
|
+
adventure,
|
|
2975
|
+
startingDate,
|
|
2976
|
+
numberOfPeople,
|
|
2977
|
+
host,
|
|
2978
|
+
className
|
|
2979
|
+
}) {
|
|
2980
|
+
const AddTravellersCta = addTravellersUrl ? /* @__PURE__ */ jsx(
|
|
2981
|
+
"a",
|
|
2982
|
+
{
|
|
2983
|
+
href: addTravellersUrl,
|
|
2984
|
+
className: "inline-flex items-center justify-center rounded-lg bg-primary px-6 py-3 text-sm font-bold text-primary-foreground font-heading hover:bg-primary-800 transition-colors no-underline",
|
|
2985
|
+
children: "Add travellers to your booking"
|
|
2986
|
+
}
|
|
2987
|
+
) : /* @__PURE__ */ jsx(
|
|
2988
|
+
"span",
|
|
2989
|
+
{
|
|
2990
|
+
className: "inline-flex items-center justify-center rounded-lg bg-primary px-6 py-3 text-sm font-bold text-primary-foreground font-heading",
|
|
2991
|
+
role: "presentation",
|
|
2992
|
+
children: "Add travellers to your booking"
|
|
2993
|
+
}
|
|
2994
|
+
);
|
|
2995
|
+
return /* @__PURE__ */ jsxs(
|
|
2996
|
+
"div",
|
|
2997
|
+
{
|
|
2998
|
+
className: cn(
|
|
2999
|
+
"max-w-xl mx-auto bg-white text-foreground font-sans text-base leading-relaxed",
|
|
3000
|
+
className
|
|
3001
|
+
),
|
|
3002
|
+
children: [
|
|
3003
|
+
/* @__PURE__ */ jsx("div", { className: "mt-8 mb-8 flex justify-center", children: /* @__PURE__ */ jsx(
|
|
3004
|
+
"img",
|
|
3005
|
+
{
|
|
3006
|
+
src: logoUrl,
|
|
3007
|
+
alt: "PlanetaEXO",
|
|
3008
|
+
className: "h-[70px] w-auto object-contain"
|
|
3009
|
+
}
|
|
3010
|
+
) }),
|
|
3011
|
+
/* @__PURE__ */ jsxs("p", { className: "mb-4", children: [
|
|
3012
|
+
"Hi ",
|
|
3013
|
+
recipientName,
|
|
3014
|
+
","
|
|
3015
|
+
] }),
|
|
3016
|
+
/* @__PURE__ */ jsx("p", { className: "mb-4", children: "Thank you for booking your adventure with PlanetaEXO \u2014 we're really looking forward to your adventure." }),
|
|
3017
|
+
/* @__PURE__ */ jsx("p", { className: "mb-4", children: "To move forward, the first step is to add all travellers included in your booking. Once you do this, each person \u2014 including you \u2014 will receive an email with a link to complete their individual registration." }),
|
|
3018
|
+
/* @__PURE__ */ jsx("div", { className: "mb-8", children: AddTravellersCta }),
|
|
3019
|
+
/* @__PURE__ */ jsx("hr", { className: "border-t border-border mb-8" }),
|
|
3020
|
+
/* @__PURE__ */ jsx("p", { className: "mb-4 font-heading font-bold text-foreground", children: "\u{1F4DD} Here's a quick summary of your booking:" }),
|
|
3021
|
+
/* @__PURE__ */ jsx("table", { className: "w-full text-sm mb-8", children: /* @__PURE__ */ jsxs("tbody", { className: "divide-y divide-border", children: [
|
|
3022
|
+
/* @__PURE__ */ jsxs("tr", { children: [
|
|
3023
|
+
/* @__PURE__ */ jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Booking Number:" }),
|
|
3024
|
+
/* @__PURE__ */ jsx("td", { className: "py-1 font-medium text-foreground", children: bookingNumber })
|
|
3025
|
+
] }),
|
|
3026
|
+
/* @__PURE__ */ jsxs("tr", { children: [
|
|
3027
|
+
/* @__PURE__ */ jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Activity:" }),
|
|
3028
|
+
/* @__PURE__ */ jsx("td", { className: "py-1 font-medium text-foreground", children: activity })
|
|
3029
|
+
] }),
|
|
3030
|
+
/* @__PURE__ */ jsxs("tr", { children: [
|
|
3031
|
+
/* @__PURE__ */ jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Adventure:" }),
|
|
3032
|
+
/* @__PURE__ */ jsx("td", { className: "py-1 font-medium text-foreground", children: adventure })
|
|
3033
|
+
] }),
|
|
3034
|
+
/* @__PURE__ */ jsxs("tr", { children: [
|
|
3035
|
+
/* @__PURE__ */ jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Starting Date:" }),
|
|
3036
|
+
/* @__PURE__ */ jsx("td", { className: "py-1 font-medium text-foreground", children: startingDate })
|
|
3037
|
+
] }),
|
|
3038
|
+
/* @__PURE__ */ jsxs("tr", { children: [
|
|
3039
|
+
/* @__PURE__ */ jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Number of People:" }),
|
|
3040
|
+
/* @__PURE__ */ jsx("td", { className: "py-1 font-medium text-foreground", children: numberOfPeople })
|
|
3041
|
+
] }),
|
|
3042
|
+
/* @__PURE__ */ jsxs("tr", { children: [
|
|
3043
|
+
/* @__PURE__ */ jsx("td", { className: "py-1 pr-4 text-muted-foreground font-ui", children: "Host:" }),
|
|
3044
|
+
/* @__PURE__ */ jsx("td", { className: "py-1 font-medium text-foreground", children: host })
|
|
3045
|
+
] })
|
|
3046
|
+
] }) }),
|
|
3047
|
+
/* @__PURE__ */ jsx("hr", { className: "border-t border-border mb-8" }),
|
|
3048
|
+
/* @__PURE__ */ jsx("p", { className: "mb-4", children: "After adding everyone, you will also receive your own registration email, just like the other travellers. Please make sure everyone completes this step so we can organise everything properly." }),
|
|
3049
|
+
/* @__PURE__ */ jsx("p", { children: "If you have any questions, just reply to this email \u2014 happy to help." })
|
|
3050
|
+
]
|
|
3051
|
+
}
|
|
3052
|
+
);
|
|
3053
|
+
}
|
|
3054
|
+
function CounterField({
|
|
3055
|
+
label,
|
|
3056
|
+
sublabel,
|
|
3057
|
+
required,
|
|
3058
|
+
value,
|
|
3059
|
+
min = 0,
|
|
3060
|
+
max = 99,
|
|
3061
|
+
onChange,
|
|
3062
|
+
className
|
|
3063
|
+
}) {
|
|
3064
|
+
const decrement = () => {
|
|
3065
|
+
if (value > min) onChange(value - 1);
|
|
3066
|
+
};
|
|
3067
|
+
const increment = () => {
|
|
3068
|
+
if (value < max) onChange(value + 1);
|
|
3069
|
+
};
|
|
3070
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-2", className), children: [
|
|
3071
|
+
/* @__PURE__ */ jsxs("label", { className: "text-sm font-ui text-foreground", children: [
|
|
3072
|
+
label,
|
|
3073
|
+
sublabel && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground font-normal ml-1", children: sublabel }),
|
|
3074
|
+
required && /* @__PURE__ */ jsx("span", { className: "text-primary ml-0.5", children: "*" })
|
|
3075
|
+
] }),
|
|
3076
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between rounded-lg border border-border bg-background px-4 py-3 h-14", children: [
|
|
3077
|
+
/* @__PURE__ */ jsx("span", { className: "text-xl font-semibold text-foreground tabular-nums w-8 font-ui", children: value }),
|
|
3078
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
3079
|
+
/* @__PURE__ */ jsx(
|
|
3080
|
+
"button",
|
|
3081
|
+
{
|
|
3082
|
+
type: "button",
|
|
3083
|
+
onClick: decrement,
|
|
3084
|
+
disabled: value <= min,
|
|
3085
|
+
"aria-label": `Diminuir ${label}`,
|
|
3086
|
+
className: cn(
|
|
3087
|
+
"inline-flex h-8 w-8 items-center justify-center rounded-full border border-border",
|
|
3088
|
+
"text-foreground transition-colors",
|
|
3089
|
+
"hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
3090
|
+
"disabled:pointer-events-none disabled:opacity-30"
|
|
3091
|
+
),
|
|
3092
|
+
children: /* @__PURE__ */ jsx(MinusIcon, { className: "h-3.5 w-3.5" })
|
|
3093
|
+
}
|
|
3094
|
+
),
|
|
3095
|
+
/* @__PURE__ */ jsx(
|
|
3096
|
+
"button",
|
|
3097
|
+
{
|
|
3098
|
+
type: "button",
|
|
3099
|
+
onClick: increment,
|
|
3100
|
+
disabled: value >= max,
|
|
3101
|
+
"aria-label": `Aumentar ${label}`,
|
|
3102
|
+
className: cn(
|
|
3103
|
+
"inline-flex h-8 w-8 items-center justify-center rounded-full border border-border",
|
|
3104
|
+
"text-foreground transition-colors",
|
|
3105
|
+
"hover:bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
3106
|
+
"disabled:pointer-events-none disabled:opacity-30"
|
|
3107
|
+
),
|
|
3108
|
+
children: /* @__PURE__ */ jsx(PlusIcon, { className: "h-3.5 w-3.5" })
|
|
3109
|
+
}
|
|
3110
|
+
)
|
|
3111
|
+
] })
|
|
3112
|
+
] })
|
|
3113
|
+
] });
|
|
3114
|
+
}
|
|
3115
|
+
function Popover(_a) {
|
|
3116
|
+
var props = __objRest(_a, []);
|
|
3117
|
+
return /* @__PURE__ */ jsx(Popover$1.Root, __spreadValues({ "data-slot": "popover" }, props));
|
|
3118
|
+
}
|
|
3119
|
+
function PopoverTrigger(_a) {
|
|
3120
|
+
var props = __objRest(_a, []);
|
|
3121
|
+
return /* @__PURE__ */ jsx(Popover$1.Trigger, __spreadValues({ "data-slot": "popover-trigger" }, props));
|
|
3122
|
+
}
|
|
3123
|
+
function PopoverContent(_a) {
|
|
3124
|
+
var _b = _a, {
|
|
3125
|
+
className,
|
|
3126
|
+
align = "center",
|
|
3127
|
+
alignOffset = 0,
|
|
3128
|
+
side = "bottom",
|
|
3129
|
+
sideOffset = 4
|
|
3130
|
+
} = _b, props = __objRest(_b, [
|
|
3131
|
+
"className",
|
|
3132
|
+
"align",
|
|
3133
|
+
"alignOffset",
|
|
3134
|
+
"side",
|
|
3135
|
+
"sideOffset"
|
|
3136
|
+
]);
|
|
3137
|
+
return /* @__PURE__ */ jsx(Popover$1.Portal, { children: /* @__PURE__ */ jsx(
|
|
3138
|
+
Popover$1.Positioner,
|
|
3139
|
+
{
|
|
3140
|
+
align,
|
|
3141
|
+
alignOffset,
|
|
3142
|
+
side,
|
|
3143
|
+
sideOffset,
|
|
3144
|
+
className: "isolate z-50",
|
|
3145
|
+
children: /* @__PURE__ */ jsx(
|
|
3146
|
+
Popover$1.Popup,
|
|
3147
|
+
__spreadValues({
|
|
3148
|
+
"data-slot": "popover-content",
|
|
3149
|
+
className: cn(
|
|
3150
|
+
"z-50 flex w-72 origin-(--transform-origin) flex-col gap-2.5 rounded-lg bg-popover p-2.5 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95",
|
|
3151
|
+
className
|
|
3152
|
+
)
|
|
3153
|
+
}, props)
|
|
3154
|
+
)
|
|
3155
|
+
}
|
|
3156
|
+
) });
|
|
3157
|
+
}
|
|
3158
|
+
function DatePickerField({
|
|
3159
|
+
label,
|
|
3160
|
+
required,
|
|
3161
|
+
value,
|
|
3162
|
+
onChange,
|
|
3163
|
+
placeholder = "Select a date",
|
|
3164
|
+
disabled,
|
|
3165
|
+
fromDate,
|
|
3166
|
+
className
|
|
3167
|
+
}) {
|
|
3168
|
+
const [open, setOpen] = React18.useState(false);
|
|
3169
|
+
const containerRef = React18.useRef(null);
|
|
3170
|
+
const [calendarWidth, setCalendarWidth] = React18.useState();
|
|
3171
|
+
const hasValue = !!value;
|
|
3172
|
+
React18.useEffect(() => {
|
|
3173
|
+
if (!containerRef.current) return;
|
|
3174
|
+
const observer = new ResizeObserver(([entry]) => {
|
|
3175
|
+
setCalendarWidth(entry.contentRect.width);
|
|
3176
|
+
});
|
|
3177
|
+
observer.observe(containerRef.current);
|
|
3178
|
+
return () => observer.disconnect();
|
|
3179
|
+
}, []);
|
|
3180
|
+
return /* @__PURE__ */ jsx("div", { ref: containerRef, className: cn("w-full", className), children: /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
|
|
3181
|
+
/* @__PURE__ */ jsxs(
|
|
3182
|
+
PopoverTrigger,
|
|
3183
|
+
{
|
|
3184
|
+
disabled,
|
|
3185
|
+
className: cn(
|
|
3186
|
+
"relative flex w-full items-center rounded-lg border border-border bg-background",
|
|
3187
|
+
"px-3 text-left text-base font-ui transition-colors h-14",
|
|
3188
|
+
"focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary",
|
|
3189
|
+
"disabled:pointer-events-none disabled:opacity-50",
|
|
3190
|
+
open && "border-primary ring-1 ring-primary"
|
|
3191
|
+
),
|
|
3192
|
+
children: [
|
|
3193
|
+
/* @__PURE__ */ jsxs(
|
|
3194
|
+
"span",
|
|
3195
|
+
{
|
|
3196
|
+
className: cn(
|
|
3197
|
+
"pointer-events-none absolute left-3 transition-all duration-150 font-ui",
|
|
3198
|
+
hasValue || open ? "top-2 text-xs text-primary" : "top-1/2 -translate-y-1/2 text-base text-muted-foreground"
|
|
3199
|
+
),
|
|
3200
|
+
children: [
|
|
3201
|
+
label,
|
|
3202
|
+
required && /* @__PURE__ */ jsx("span", { className: "text-primary ml-0.5", children: "*" })
|
|
3203
|
+
]
|
|
3204
|
+
}
|
|
3205
|
+
),
|
|
3206
|
+
/* @__PURE__ */ jsx(
|
|
3207
|
+
"span",
|
|
3208
|
+
{
|
|
3209
|
+
className: cn(
|
|
3210
|
+
"flex-1 truncate mt-3",
|
|
3211
|
+
hasValue ? "text-foreground" : "invisible"
|
|
3212
|
+
),
|
|
3213
|
+
children: hasValue ? format(value, "dd MMM yyyy") : placeholder
|
|
3214
|
+
}
|
|
3215
|
+
),
|
|
3216
|
+
/* @__PURE__ */ jsx(CalendarIcon, { className: "ml-2 h-4 w-4 shrink-0 text-muted-foreground" })
|
|
3217
|
+
]
|
|
3218
|
+
}
|
|
3219
|
+
),
|
|
3220
|
+
/* @__PURE__ */ jsx(
|
|
3221
|
+
PopoverContent,
|
|
3222
|
+
{
|
|
3223
|
+
className: "p-0",
|
|
3224
|
+
align: "start",
|
|
3225
|
+
style: calendarWidth ? { width: calendarWidth } : void 0,
|
|
3226
|
+
children: /* @__PURE__ */ jsx(
|
|
3227
|
+
Calendar,
|
|
3228
|
+
{
|
|
3229
|
+
mode: "single",
|
|
3230
|
+
selected: value,
|
|
3231
|
+
onSelect: (date) => {
|
|
3232
|
+
onChange == null ? void 0 : onChange(date);
|
|
3233
|
+
setOpen(false);
|
|
3234
|
+
},
|
|
3235
|
+
fromDate: fromDate != null ? fromDate : /* @__PURE__ */ new Date(),
|
|
3236
|
+
className: "font-ui w-full",
|
|
3237
|
+
autoFocus: true
|
|
3238
|
+
}
|
|
3239
|
+
)
|
|
3240
|
+
}
|
|
3241
|
+
)
|
|
3242
|
+
] }) });
|
|
3243
|
+
}
|
|
3244
|
+
function FormSection({
|
|
3245
|
+
title,
|
|
3246
|
+
children,
|
|
3247
|
+
className
|
|
3248
|
+
}) {
|
|
3249
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-5", className), children: [
|
|
3250
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-4", children: [
|
|
3251
|
+
/* @__PURE__ */ jsx("h3", { className: "text-base font-bold text-foreground whitespace-nowrap font-heading", children: title }),
|
|
3252
|
+
/* @__PURE__ */ jsx("div", { className: "h-px flex-1 bg-border" })
|
|
3253
|
+
] }),
|
|
3254
|
+
children
|
|
3255
|
+
] });
|
|
3256
|
+
}
|
|
3257
|
+
var defaultInitial = {
|
|
3258
|
+
adults: 2,
|
|
3259
|
+
children: 0,
|
|
3260
|
+
travelDate: void 0,
|
|
3261
|
+
budget: "",
|
|
3262
|
+
project: "",
|
|
3263
|
+
civility: "",
|
|
3264
|
+
phoneCountry: "BR",
|
|
3265
|
+
lastName: "",
|
|
3266
|
+
firstName: "",
|
|
3267
|
+
country: "France",
|
|
3268
|
+
phone: "",
|
|
3269
|
+
email: ""
|
|
3270
|
+
};
|
|
3271
|
+
function BookingForm({
|
|
3272
|
+
defaultValues,
|
|
3273
|
+
onSubmit,
|
|
3274
|
+
submitLabel = "Send my request",
|
|
3275
|
+
loading = false,
|
|
3276
|
+
showHeader = true,
|
|
3277
|
+
title = "Check availability for your trip",
|
|
3278
|
+
subtitle = "Free enquiry \u2013 no commitment",
|
|
3279
|
+
className
|
|
3280
|
+
}) {
|
|
3281
|
+
const [values, setValues] = React18.useState(__spreadValues(__spreadValues({}, defaultInitial), defaultValues));
|
|
3282
|
+
const set = (key, value) => setValues((prev) => __spreadProps(__spreadValues({}, prev), { [key]: value }));
|
|
3283
|
+
const handleSubmit = (e) => {
|
|
3284
|
+
e.preventDefault();
|
|
3285
|
+
onSubmit == null ? void 0 : onSubmit(values);
|
|
3286
|
+
};
|
|
3287
|
+
return /* @__PURE__ */ jsxs(
|
|
3288
|
+
"form",
|
|
3289
|
+
{
|
|
3290
|
+
onSubmit: handleSubmit,
|
|
3291
|
+
className: cn("flex flex-col gap-10", className),
|
|
3292
|
+
noValidate: true,
|
|
3293
|
+
children: [
|
|
3294
|
+
showHeader && /* @__PURE__ */ jsxs("div", { children: [
|
|
3295
|
+
/* @__PURE__ */ jsx("h2", { className: "text-2xl font-black uppercase tracking-wide text-foreground font-heading leading-tight", children: title }),
|
|
3296
|
+
/* @__PURE__ */ jsx("p", { className: "mt-1.5 text-sm text-muted-foreground font-ui", children: subtitle })
|
|
3297
|
+
] }),
|
|
3298
|
+
/* @__PURE__ */ jsx(FormSection, { title: "Who's joining the adventure?", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
|
|
3299
|
+
/* @__PURE__ */ jsx(
|
|
3300
|
+
CounterField,
|
|
3301
|
+
{
|
|
3302
|
+
label: "Adults",
|
|
3303
|
+
required: true,
|
|
3304
|
+
value: values.adults,
|
|
3305
|
+
min: 1,
|
|
3306
|
+
onChange: (v) => set("adults", v)
|
|
3307
|
+
}
|
|
3308
|
+
),
|
|
3309
|
+
/* @__PURE__ */ jsx(
|
|
3310
|
+
CounterField,
|
|
3311
|
+
{
|
|
3312
|
+
label: "Children",
|
|
3313
|
+
sublabel: "(under 12)",
|
|
3314
|
+
value: values.children,
|
|
3315
|
+
min: 0,
|
|
3316
|
+
onChange: (v) => set("children", v)
|
|
3317
|
+
}
|
|
3318
|
+
)
|
|
3319
|
+
] }) }),
|
|
3320
|
+
/* @__PURE__ */ jsx(FormSection, { title: "Your next trip", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
|
|
3321
|
+
/* @__PURE__ */ jsx(
|
|
3322
|
+
DatePickerField,
|
|
3323
|
+
{
|
|
3324
|
+
label: "Travel date",
|
|
3325
|
+
required: true,
|
|
3326
|
+
value: values.travelDate,
|
|
3327
|
+
onChange: (d) => set("travelDate", d),
|
|
3328
|
+
placeholder: "Pick a date"
|
|
3329
|
+
}
|
|
3330
|
+
),
|
|
3331
|
+
/* @__PURE__ */ jsx(
|
|
3332
|
+
FloatingInput,
|
|
3333
|
+
{
|
|
3334
|
+
label: "Budget (per person)",
|
|
3335
|
+
required: true,
|
|
3336
|
+
type: "number",
|
|
3337
|
+
min: 0,
|
|
3338
|
+
value: values.budget,
|
|
3339
|
+
onChange: (e) => set("budget", e.target.value)
|
|
3340
|
+
}
|
|
3341
|
+
)
|
|
3342
|
+
] }) }),
|
|
3343
|
+
/* @__PURE__ */ jsx(FormSection, { title: "Tell us about your trip", children: /* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
3344
|
+
/* @__PURE__ */ jsx(
|
|
3345
|
+
"textarea",
|
|
3346
|
+
{
|
|
3347
|
+
id: "project",
|
|
3348
|
+
placeholder: " ",
|
|
3349
|
+
rows: 5,
|
|
3350
|
+
value: values.project,
|
|
3351
|
+
onChange: (e) => set("project", e.target.value),
|
|
3352
|
+
className: cn(
|
|
3353
|
+
"peer block w-full resize-none rounded-lg border border-border bg-background",
|
|
3354
|
+
"px-3 pt-6 pb-3 text-base text-foreground font-ui",
|
|
3355
|
+
"transition-colors placeholder-transparent",
|
|
3356
|
+
"focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary"
|
|
3357
|
+
)
|
|
3358
|
+
}
|
|
3359
|
+
),
|
|
3360
|
+
/* @__PURE__ */ jsxs(
|
|
3361
|
+
"label",
|
|
3362
|
+
{
|
|
3363
|
+
htmlFor: "project",
|
|
3364
|
+
className: cn(
|
|
3365
|
+
"pointer-events-none absolute left-3 top-4",
|
|
3366
|
+
"text-base text-muted-foreground font-ui transition-all duration-150",
|
|
3367
|
+
"peer-focus:top-2 peer-focus:text-xs peer-focus:text-primary",
|
|
3368
|
+
"peer-not-placeholder-shown:top-2 peer-not-placeholder-shown:text-xs peer-not-placeholder-shown:text-muted-foreground"
|
|
3369
|
+
),
|
|
3370
|
+
children: [
|
|
3371
|
+
"Your trip in a few words",
|
|
3372
|
+
" ",
|
|
3373
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground font-normal", children: "(optional)" })
|
|
3374
|
+
]
|
|
3375
|
+
}
|
|
3376
|
+
)
|
|
3377
|
+
] }) }),
|
|
3378
|
+
/* @__PURE__ */ jsxs(FormSection, { title: "Contact details", children: [
|
|
3379
|
+
/* @__PURE__ */ jsx(
|
|
3380
|
+
"div",
|
|
3381
|
+
{
|
|
3382
|
+
role: "radiogroup",
|
|
3383
|
+
"aria-label": "Title",
|
|
3384
|
+
className: "flex flex-wrap items-center gap-x-6 gap-y-3",
|
|
3385
|
+
children: ["ms", "mr"].map((c) => /* @__PURE__ */ jsxs(
|
|
3386
|
+
"label",
|
|
3387
|
+
{
|
|
3388
|
+
className: "flex min-h-9 cursor-pointer items-center gap-2.5 font-ui text-sm text-foreground",
|
|
3389
|
+
children: [
|
|
3390
|
+
/* @__PURE__ */ jsx(
|
|
3391
|
+
"input",
|
|
3392
|
+
{
|
|
3393
|
+
type: "radio",
|
|
3394
|
+
name: "civility",
|
|
3395
|
+
value: c,
|
|
3396
|
+
checked: values.civility === c,
|
|
3397
|
+
onChange: () => set("civility", c),
|
|
3398
|
+
className: "h-4 w-4 shrink-0 accent-primary cursor-pointer"
|
|
3399
|
+
}
|
|
3400
|
+
),
|
|
3401
|
+
c === "ms" ? "Ms." : "Mr."
|
|
3402
|
+
]
|
|
3403
|
+
},
|
|
3404
|
+
c
|
|
3405
|
+
))
|
|
3406
|
+
}
|
|
3407
|
+
),
|
|
3408
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 min-w-0", children: [
|
|
3409
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-0", children: /* @__PURE__ */ jsx(
|
|
3410
|
+
FloatingInput,
|
|
3411
|
+
{
|
|
3412
|
+
label: "Last name",
|
|
3413
|
+
required: true,
|
|
3414
|
+
value: values.lastName,
|
|
3415
|
+
onChange: (e) => set("lastName", e.target.value)
|
|
3416
|
+
}
|
|
3417
|
+
) }),
|
|
3418
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-0", children: /* @__PURE__ */ jsx(
|
|
3419
|
+
FloatingInput,
|
|
3420
|
+
{
|
|
3421
|
+
label: "First name",
|
|
3422
|
+
required: true,
|
|
3423
|
+
value: values.firstName,
|
|
3424
|
+
onChange: (e) => set("firstName", e.target.value)
|
|
3425
|
+
}
|
|
3426
|
+
) }),
|
|
3427
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-0 sm:col-span-2 lg:col-span-1", children: /* @__PURE__ */ jsxs(
|
|
3428
|
+
FloatingSelect,
|
|
3429
|
+
{
|
|
3430
|
+
label: "Country of residence",
|
|
3431
|
+
required: true,
|
|
3432
|
+
value: values.country,
|
|
3433
|
+
onChange: (e) => set("country", e.target.value),
|
|
3434
|
+
children: [
|
|
3435
|
+
/* @__PURE__ */ jsx("option", { value: "", disabled: true, hidden: true }),
|
|
3436
|
+
/* @__PURE__ */ jsx("option", { value: "France", children: "France" }),
|
|
3437
|
+
/* @__PURE__ */ jsx("option", { value: "Belgium", children: "Belgium" }),
|
|
3438
|
+
/* @__PURE__ */ jsx("option", { value: "Switzerland", children: "Switzerland" }),
|
|
3439
|
+
/* @__PURE__ */ jsx("option", { value: "Canada", children: "Canada" }),
|
|
3440
|
+
/* @__PURE__ */ jsx("option", { value: "Luxembourg", children: "Luxembourg" }),
|
|
3441
|
+
/* @__PURE__ */ jsx("option", { value: "United Kingdom", children: "United Kingdom" }),
|
|
3442
|
+
/* @__PURE__ */ jsx("option", { value: "United States", children: "United States" }),
|
|
3443
|
+
/* @__PURE__ */ jsx("option", { value: "Other", children: "Other" })
|
|
3444
|
+
]
|
|
3445
|
+
}
|
|
3446
|
+
) })
|
|
3447
|
+
] }),
|
|
3448
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 lg:grid-cols-2", children: [
|
|
3449
|
+
/* @__PURE__ */ jsxs("div", { className: "flex w-full min-w-0", children: [
|
|
3450
|
+
/* @__PURE__ */ jsx(
|
|
3451
|
+
PhoneCountrySelect,
|
|
3452
|
+
{
|
|
3453
|
+
value: values.phoneCountry,
|
|
3454
|
+
onChange: (code) => set("phoneCountry", code),
|
|
3455
|
+
className: "shrink-0"
|
|
3456
|
+
}
|
|
3457
|
+
),
|
|
3458
|
+
/* @__PURE__ */ jsxs("div", { className: "relative min-w-0 flex-1", children: [
|
|
3459
|
+
/* @__PURE__ */ jsx(
|
|
3460
|
+
"input",
|
|
3461
|
+
{
|
|
3462
|
+
id: "phone",
|
|
3463
|
+
type: "tel",
|
|
3464
|
+
placeholder: " ",
|
|
3465
|
+
value: values.phone,
|
|
3466
|
+
onChange: (e) => set("phone", e.target.value),
|
|
3467
|
+
className: cn(
|
|
3468
|
+
"peer block h-14 w-full rounded-r-lg border border-border bg-background",
|
|
3469
|
+
"px-3 pt-5 pb-2 text-base text-foreground font-ui",
|
|
3470
|
+
"transition-colors placeholder-transparent",
|
|
3471
|
+
"focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary"
|
|
3472
|
+
)
|
|
3473
|
+
}
|
|
3474
|
+
),
|
|
3475
|
+
/* @__PURE__ */ jsxs(
|
|
3476
|
+
"label",
|
|
3477
|
+
{
|
|
3478
|
+
htmlFor: "phone",
|
|
3479
|
+
className: cn(
|
|
3480
|
+
"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2",
|
|
3481
|
+
"text-base text-muted-foreground font-ui transition-all duration-150",
|
|
3482
|
+
"peer-focus:top-3 peer-focus:translate-y-0 peer-focus:text-xs peer-focus:text-primary",
|
|
3483
|
+
"peer-not-placeholder-shown:top-3 peer-not-placeholder-shown:translate-y-0 peer-not-placeholder-shown:text-xs peer-not-placeholder-shown:text-muted-foreground"
|
|
3484
|
+
),
|
|
3485
|
+
children: [
|
|
3486
|
+
"Phone ",
|
|
3487
|
+
/* @__PURE__ */ jsx("span", { className: "text-primary", children: "*" })
|
|
3488
|
+
]
|
|
3489
|
+
}
|
|
3490
|
+
)
|
|
3491
|
+
] })
|
|
3492
|
+
] }),
|
|
3493
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-0", children: /* @__PURE__ */ jsx(
|
|
3494
|
+
FloatingInput,
|
|
3495
|
+
{
|
|
3496
|
+
label: "Email",
|
|
3497
|
+
required: true,
|
|
3498
|
+
type: "email",
|
|
3499
|
+
value: values.email,
|
|
3500
|
+
onChange: (e) => set("email", e.target.value)
|
|
3501
|
+
}
|
|
3502
|
+
) })
|
|
3503
|
+
] })
|
|
3504
|
+
] }),
|
|
3505
|
+
/* @__PURE__ */ jsx("div", { className: "flex justify-center pt-2", children: /* @__PURE__ */ jsx(
|
|
3506
|
+
"button",
|
|
3507
|
+
{
|
|
3508
|
+
type: "submit",
|
|
3509
|
+
disabled: loading,
|
|
3510
|
+
className: cn(
|
|
3511
|
+
"inline-flex items-center justify-center gap-2 rounded-full px-10 py-3.5",
|
|
3512
|
+
"bg-primary text-primary-foreground font-ui font-semibold text-sm",
|
|
3513
|
+
"transition-colors hover:bg-primary/90 focus-visible:outline-none",
|
|
3514
|
+
"focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
|
3515
|
+
"disabled:pointer-events-none disabled:opacity-60"
|
|
3516
|
+
),
|
|
3517
|
+
children: loading ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3518
|
+
/* @__PURE__ */ jsxs("svg", { className: "h-4 w-4 animate-spin", viewBox: "0 0 24 24", fill: "none", children: [
|
|
3519
|
+
/* @__PURE__ */ jsx(
|
|
3520
|
+
"circle",
|
|
3521
|
+
{
|
|
3522
|
+
className: "opacity-25",
|
|
3523
|
+
cx: "12",
|
|
3524
|
+
cy: "12",
|
|
3525
|
+
r: "10",
|
|
3526
|
+
stroke: "currentColor",
|
|
3527
|
+
strokeWidth: "4"
|
|
3528
|
+
}
|
|
3529
|
+
),
|
|
3530
|
+
/* @__PURE__ */ jsx(
|
|
3531
|
+
"path",
|
|
3532
|
+
{
|
|
3533
|
+
className: "opacity-75",
|
|
3534
|
+
fill: "currentColor",
|
|
3535
|
+
d: "M4 12a8 8 0 018-8v4l3-3-3-3v4a8 8 0 00-8 8h4z"
|
|
3536
|
+
}
|
|
3537
|
+
)
|
|
3538
|
+
] }),
|
|
3539
|
+
"Sending\u2026"
|
|
3540
|
+
] }) : submitLabel
|
|
3541
|
+
}
|
|
3542
|
+
) })
|
|
3543
|
+
]
|
|
3544
|
+
}
|
|
3545
|
+
);
|
|
3546
|
+
}
|
|
3547
|
+
function Checkbox(_a) {
|
|
3548
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
3549
|
+
return /* @__PURE__ */ jsx(
|
|
3550
|
+
Checkbox$1.Root,
|
|
3551
|
+
__spreadProps(__spreadValues({
|
|
3552
|
+
"data-slot": "checkbox",
|
|
3553
|
+
className: cn(
|
|
3554
|
+
"peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input transition-colors outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary",
|
|
3555
|
+
className
|
|
3556
|
+
)
|
|
3557
|
+
}, props), {
|
|
3558
|
+
children: /* @__PURE__ */ jsx(
|
|
3559
|
+
Checkbox$1.Indicator,
|
|
3560
|
+
{
|
|
3561
|
+
"data-slot": "checkbox-indicator",
|
|
3562
|
+
className: "grid place-content-center text-current transition-none [&>svg]:size-3.5",
|
|
3563
|
+
children: /* @__PURE__ */ jsx(
|
|
3564
|
+
CheckIcon,
|
|
3565
|
+
{}
|
|
3566
|
+
)
|
|
3567
|
+
}
|
|
3568
|
+
)
|
|
3569
|
+
})
|
|
3570
|
+
);
|
|
3571
|
+
}
|
|
3572
|
+
var AccordionVariantContext = React18.createContext("default");
|
|
3573
|
+
function Accordion(_a) {
|
|
3574
|
+
var _b = _a, { className, variant = "default" } = _b, props = __objRest(_b, ["className", "variant"]);
|
|
3575
|
+
return /* @__PURE__ */ jsx(AccordionVariantContext.Provider, { value: variant, children: /* @__PURE__ */ jsx(
|
|
3576
|
+
Accordion$1.Root,
|
|
3577
|
+
__spreadValues({
|
|
3578
|
+
"data-slot": "accordion",
|
|
3579
|
+
"data-variant": variant,
|
|
3580
|
+
className: cn(
|
|
3581
|
+
"flex w-full flex-col",
|
|
3582
|
+
variant === "faq" && "gap-3",
|
|
3583
|
+
className
|
|
3584
|
+
)
|
|
3585
|
+
}, props)
|
|
3586
|
+
) });
|
|
3587
|
+
}
|
|
3588
|
+
function AccordionItem(_a) {
|
|
3589
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
3590
|
+
const variant = React18.useContext(AccordionVariantContext);
|
|
3591
|
+
return /* @__PURE__ */ jsx(
|
|
3592
|
+
Accordion$1.Item,
|
|
3593
|
+
__spreadValues({
|
|
3594
|
+
"data-slot": "accordion-item",
|
|
3595
|
+
className: cn(
|
|
3596
|
+
variant === "default" && "not-last:border-b",
|
|
3597
|
+
variant === "faq" && "rounded-lg border border-border bg-card",
|
|
3598
|
+
className
|
|
3599
|
+
)
|
|
3600
|
+
}, props)
|
|
3601
|
+
);
|
|
3602
|
+
}
|
|
3603
|
+
function AccordionTrigger(_a) {
|
|
3604
|
+
var _b = _a, {
|
|
3605
|
+
className,
|
|
3606
|
+
children
|
|
3607
|
+
} = _b, props = __objRest(_b, [
|
|
3608
|
+
"className",
|
|
3609
|
+
"children"
|
|
3610
|
+
]);
|
|
3611
|
+
const variant = React18.useContext(AccordionVariantContext);
|
|
3612
|
+
return /* @__PURE__ */ jsx(Accordion$1.Header, { className: "flex", children: /* @__PURE__ */ jsxs(
|
|
3613
|
+
Accordion$1.Trigger,
|
|
3614
|
+
__spreadProps(__spreadValues({
|
|
3615
|
+
"data-slot": "accordion-trigger",
|
|
3616
|
+
className: cn(
|
|
3617
|
+
"group/accordion-trigger relative flex flex-1 items-center justify-between text-left transition-all outline-none",
|
|
3618
|
+
"focus-visible:ring-3 focus-visible:ring-ring/50 aria-disabled:pointer-events-none aria-disabled:opacity-50",
|
|
3619
|
+
variant === "default" && [
|
|
3620
|
+
"rounded-lg border border-transparent py-2.5 text-sm font-medium",
|
|
3621
|
+
"hover:underline focus-visible:border-ring",
|
|
3622
|
+
"**:data-[slot=accordion-trigger-icon]:ml-auto **:data-[slot=accordion-trigger-icon]:size-4 **:data-[slot=accordion-trigger-icon]:text-muted-foreground"
|
|
3623
|
+
],
|
|
3624
|
+
variant === "faq" && [
|
|
3625
|
+
"px-5 py-4 text-base font-bold",
|
|
3626
|
+
"hover:bg-muted/30 rounded-lg"
|
|
3627
|
+
],
|
|
3628
|
+
className
|
|
3629
|
+
)
|
|
3630
|
+
}, props), {
|
|
3631
|
+
children: [
|
|
3632
|
+
children,
|
|
3633
|
+
variant === "default" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3634
|
+
/* @__PURE__ */ jsx(
|
|
3635
|
+
ChevronDownIcon,
|
|
3636
|
+
{
|
|
3637
|
+
"data-slot": "accordion-trigger-icon",
|
|
3638
|
+
className: "pointer-events-none shrink-0 group-aria-expanded/accordion-trigger:hidden"
|
|
3639
|
+
}
|
|
3640
|
+
),
|
|
3641
|
+
/* @__PURE__ */ jsx(
|
|
3642
|
+
ChevronUpIcon,
|
|
3643
|
+
{
|
|
3644
|
+
"data-slot": "accordion-trigger-icon",
|
|
3645
|
+
className: "pointer-events-none hidden shrink-0 group-aria-expanded/accordion-trigger:inline"
|
|
3646
|
+
}
|
|
3647
|
+
)
|
|
3648
|
+
] }),
|
|
3649
|
+
variant === "faq" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3650
|
+
/* @__PURE__ */ jsx(PlusIcon, { className: "pointer-events-none shrink-0 size-5 text-foreground group-aria-expanded/accordion-trigger:hidden" }),
|
|
3651
|
+
/* @__PURE__ */ jsx(MinusIcon, { className: "pointer-events-none hidden shrink-0 size-5 text-foreground group-aria-expanded/accordion-trigger:inline" })
|
|
3652
|
+
] })
|
|
3653
|
+
]
|
|
3654
|
+
})
|
|
3655
|
+
) });
|
|
3656
|
+
}
|
|
3657
|
+
function AccordionContent(_a) {
|
|
3658
|
+
var _b = _a, {
|
|
3659
|
+
className,
|
|
3660
|
+
children
|
|
3661
|
+
} = _b, props = __objRest(_b, [
|
|
3662
|
+
"className",
|
|
3663
|
+
"children"
|
|
3664
|
+
]);
|
|
3665
|
+
const variant = React18.useContext(AccordionVariantContext);
|
|
3666
|
+
return /* @__PURE__ */ jsx(
|
|
3667
|
+
Accordion$1.Panel,
|
|
3668
|
+
__spreadProps(__spreadValues({
|
|
3669
|
+
"data-slot": "accordion-content",
|
|
3670
|
+
className: "overflow-hidden text-sm data-open:animate-accordion-down data-closed:animate-accordion-up"
|
|
3671
|
+
}, props), {
|
|
3672
|
+
children: /* @__PURE__ */ jsx(
|
|
3673
|
+
"div",
|
|
3674
|
+
{
|
|
3675
|
+
className: cn(
|
|
3676
|
+
"h-(--accordion-panel-height) pt-0 data-ending-style:h-0 data-starting-style:h-0",
|
|
3677
|
+
"[&_a]:underline [&_a]:underline-offset-3 [&_a]:hover:text-foreground [&_p:not(:last-child)]:mb-4",
|
|
3678
|
+
variant === "default" && "pb-2.5",
|
|
3679
|
+
variant === "faq" && "px-5 pb-5 text-base text-muted-foreground leading-relaxed",
|
|
3680
|
+
className
|
|
3681
|
+
),
|
|
3682
|
+
children
|
|
3683
|
+
}
|
|
3684
|
+
)
|
|
3685
|
+
})
|
|
3686
|
+
);
|
|
3687
|
+
}
|
|
3688
|
+
function FilterPanel({
|
|
3689
|
+
groups,
|
|
3690
|
+
value,
|
|
3691
|
+
onChange,
|
|
3692
|
+
onClearAll,
|
|
3693
|
+
alwaysShowClear = false,
|
|
3694
|
+
title = "Filters",
|
|
3695
|
+
className
|
|
3696
|
+
}) {
|
|
3697
|
+
const [internalValue, setInternalValue] = React18.useState(
|
|
3698
|
+
() => Object.fromEntries(groups.map((g) => [g.id, []]))
|
|
3699
|
+
);
|
|
3700
|
+
const selected = value != null ? value : internalValue;
|
|
3701
|
+
const handleToggle = (groupId, itemId) => {
|
|
3702
|
+
var _a;
|
|
3703
|
+
const current = (_a = selected[groupId]) != null ? _a : [];
|
|
3704
|
+
const next = current.includes(itemId) ? current.filter((id) => id !== itemId) : [...current, itemId];
|
|
3705
|
+
const nextValue = __spreadProps(__spreadValues({}, selected), { [groupId]: next });
|
|
3706
|
+
if (onChange) {
|
|
3707
|
+
onChange(nextValue);
|
|
3708
|
+
} else {
|
|
3709
|
+
setInternalValue(nextValue);
|
|
3710
|
+
}
|
|
3711
|
+
};
|
|
3712
|
+
const handleClearAll = () => {
|
|
3713
|
+
const cleared = Object.fromEntries(groups.map((g) => [g.id, []]));
|
|
3714
|
+
if (onChange) {
|
|
3715
|
+
onChange(cleared);
|
|
3716
|
+
} else {
|
|
3717
|
+
setInternalValue(cleared);
|
|
3718
|
+
}
|
|
3719
|
+
onClearAll == null ? void 0 : onClearAll();
|
|
3720
|
+
};
|
|
3721
|
+
const totalSelected = Object.values(selected).flat().length;
|
|
3722
|
+
const showClear = alwaysShowClear || totalSelected > 0;
|
|
3723
|
+
const defaultOpenValues = groups.filter((g) => g.defaultOpen).map((g) => g.id);
|
|
3724
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-4", className), children: [
|
|
3725
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
3726
|
+
/* @__PURE__ */ jsx("h3", { className: "text-base font-bold text-foreground font-ui", children: title }),
|
|
3727
|
+
totalSelected > 0 && /* @__PURE__ */ jsx("span", { className: "inline-flex h-5 w-5 items-center justify-center rounded-full bg-primary text-[10px] font-bold text-primary-foreground", children: totalSelected })
|
|
3728
|
+
] }),
|
|
3729
|
+
/* @__PURE__ */ jsx(
|
|
3730
|
+
Accordion,
|
|
3731
|
+
{
|
|
3732
|
+
defaultValue: defaultOpenValues,
|
|
3733
|
+
className: "flex flex-col gap-2",
|
|
3734
|
+
children: groups.map((group) => {
|
|
3735
|
+
var _a;
|
|
3736
|
+
const groupSelected = (_a = selected[group.id]) != null ? _a : [];
|
|
3737
|
+
return /* @__PURE__ */ jsxs(
|
|
3738
|
+
AccordionItem,
|
|
3739
|
+
{
|
|
3740
|
+
value: group.id,
|
|
3741
|
+
className: "border-0 border-b border-border last:border-b-0",
|
|
3742
|
+
children: [
|
|
3743
|
+
/* @__PURE__ */ jsx(AccordionTrigger, { className: "px-0 py-3.5 hover:no-underline transition-colors", children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2.5", children: [
|
|
3744
|
+
group.icon && /* @__PURE__ */ jsx("span", { className: "text-primary shrink-0", children: group.icon }),
|
|
3745
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-bold text-foreground font-ui", children: group.label }),
|
|
3746
|
+
groupSelected.length > 0 && /* @__PURE__ */ jsx("span", { className: "ml-1 inline-flex h-4 w-4 items-center justify-center rounded-full bg-primary text-[9px] font-bold text-primary-foreground", children: groupSelected.length })
|
|
3747
|
+
] }) }),
|
|
3748
|
+
/* @__PURE__ */ jsx(AccordionContent, { className: "px-4 pb-3 pt-1", children: /* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-0.5", children: group.items.map((item) => {
|
|
3749
|
+
const checked = groupSelected.includes(item.id);
|
|
3750
|
+
const checkboxId = `filter-${group.id}-${item.id}`;
|
|
3751
|
+
return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
|
|
3752
|
+
"label",
|
|
3753
|
+
{
|
|
3754
|
+
htmlFor: checkboxId,
|
|
3755
|
+
className: "flex cursor-pointer items-center gap-3 rounded-md px-1 py-2 transition-colors hover:bg-muted/50",
|
|
3756
|
+
children: [
|
|
3757
|
+
/* @__PURE__ */ jsx(
|
|
3758
|
+
Checkbox,
|
|
3759
|
+
{
|
|
3760
|
+
id: checkboxId,
|
|
3761
|
+
checked,
|
|
3762
|
+
onCheckedChange: () => handleToggle(group.id, item.id),
|
|
3763
|
+
className: "shrink-0"
|
|
3764
|
+
}
|
|
3765
|
+
),
|
|
3766
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 text-sm text-foreground font-ui", children: item.label }),
|
|
3767
|
+
item.count !== void 0 && /* @__PURE__ */ jsxs("span", { className: "text-xs font-medium text-primary font-ui", children: [
|
|
3768
|
+
"(",
|
|
3769
|
+
item.count,
|
|
3770
|
+
")"
|
|
3771
|
+
] })
|
|
3772
|
+
]
|
|
3773
|
+
}
|
|
3774
|
+
) }, item.id);
|
|
3775
|
+
}) }) })
|
|
3776
|
+
]
|
|
3777
|
+
},
|
|
3778
|
+
group.id
|
|
3779
|
+
);
|
|
3780
|
+
})
|
|
3781
|
+
}
|
|
3782
|
+
),
|
|
3783
|
+
showClear && /* @__PURE__ */ jsx(
|
|
3784
|
+
"button",
|
|
3785
|
+
{
|
|
3786
|
+
onClick: handleClearAll,
|
|
3787
|
+
className: "self-start text-sm text-muted-foreground underline underline-offset-2 transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring font-ui",
|
|
3788
|
+
children: "Remove all filters"
|
|
3789
|
+
}
|
|
3790
|
+
)
|
|
3791
|
+
] });
|
|
3792
|
+
}
|
|
3793
|
+
function ItineraryDayCard({
|
|
3794
|
+
stop,
|
|
3795
|
+
onOpen
|
|
3796
|
+
}) {
|
|
3797
|
+
const hasDescription = !!stop.description;
|
|
3798
|
+
return /* @__PURE__ */ jsxs(
|
|
3799
|
+
"div",
|
|
3800
|
+
{
|
|
3801
|
+
onClick: onOpen,
|
|
3802
|
+
className: "group relative flex-none w-56 sm:w-64 h-80 rounded-2xl overflow-hidden cursor-pointer shadow-sm hover:shadow-lg transition-shadow duration-300",
|
|
3803
|
+
children: [
|
|
3804
|
+
/* @__PURE__ */ jsx(
|
|
3805
|
+
"img",
|
|
3806
|
+
{
|
|
3807
|
+
src: stop.coverImage,
|
|
3808
|
+
alt: stop.title,
|
|
3809
|
+
className: "absolute inset-0 h-full w-full object-cover transition-transform duration-500 group-hover:scale-105"
|
|
3810
|
+
}
|
|
3811
|
+
),
|
|
3812
|
+
/* @__PURE__ */ jsx("div", { className: "absolute top-3 right-3 z-10 rounded-md bg-primary px-2 py-1", children: /* @__PURE__ */ jsxs("span", { className: "text-xs font-semibold text-primary-foreground font-ui", children: [
|
|
3813
|
+
"Day ",
|
|
3814
|
+
stop.dayNumber
|
|
3815
|
+
] }) }),
|
|
3816
|
+
/* @__PURE__ */ jsxs(
|
|
3817
|
+
"div",
|
|
3818
|
+
{
|
|
3819
|
+
className: cn(
|
|
3820
|
+
"absolute inset-x-0 bottom-0 z-10 bg-gradient-to-t from-black/70 via-black/20 to-transparent p-4 transition-opacity duration-300",
|
|
3821
|
+
hasDescription && "group-hover:opacity-0"
|
|
3822
|
+
),
|
|
3823
|
+
children: [
|
|
3824
|
+
/* @__PURE__ */ jsx("h3", { className: "text-base font-bold text-white leading-tight font-heading", children: stop.title }),
|
|
3825
|
+
stop.location && /* @__PURE__ */ jsxs("p", { className: "mt-0.5 flex items-center gap-1 text-xs text-white/80 font-ui", children: [
|
|
3826
|
+
/* @__PURE__ */ jsx(MapPinIcon, { className: "h-3 w-3 shrink-0" }),
|
|
3827
|
+
stop.location
|
|
3828
|
+
] }),
|
|
3829
|
+
stop.route && /* @__PURE__ */ jsxs("p", { className: "mt-1 flex items-center gap-1.5 text-xs text-white/80 font-ui", children: [
|
|
3830
|
+
/* @__PURE__ */ jsx(CarIcon, { className: "h-3 w-3 shrink-0" }),
|
|
3831
|
+
stop.route.distance,
|
|
3832
|
+
" \xB7 ",
|
|
3833
|
+
stop.route.duration
|
|
3834
|
+
] })
|
|
3835
|
+
]
|
|
3836
|
+
}
|
|
3837
|
+
),
|
|
3838
|
+
hasDescription && /* @__PURE__ */ jsxs("div", { className: "absolute inset-x-0 bottom-0 z-20 bg-background translate-y-full group-hover:translate-y-0 transition-transform duration-300 ease-out p-4", children: [
|
|
3839
|
+
/* @__PURE__ */ jsx("h3", { className: "text-sm font-bold text-foreground font-heading leading-tight", children: stop.title }),
|
|
3840
|
+
stop.location && /* @__PURE__ */ jsxs("p", { className: "mt-0.5 flex items-center gap-1 text-xs text-muted-foreground font-ui", children: [
|
|
3841
|
+
/* @__PURE__ */ jsx(MapPinIcon, { className: "h-3 w-3 shrink-0 text-primary" }),
|
|
3842
|
+
stop.location
|
|
3843
|
+
] }),
|
|
3844
|
+
/* @__PURE__ */ jsx("div", { className: "mt-2 line-clamp-3 text-xs text-foreground/80 leading-relaxed [&_p]:inline [&_strong]:font-semibold", children: stop.description }),
|
|
3845
|
+
/* @__PURE__ */ jsx("span", { className: "mt-2 inline-block text-xs font-semibold text-primary font-ui", children: "Read more \u2192" })
|
|
3846
|
+
] })
|
|
3847
|
+
]
|
|
3848
|
+
}
|
|
3849
|
+
);
|
|
3850
|
+
}
|
|
3851
|
+
function ItineraryModal({
|
|
3852
|
+
stop,
|
|
3853
|
+
allStops,
|
|
3854
|
+
onClose,
|
|
3855
|
+
onPrev,
|
|
3856
|
+
onNext
|
|
3857
|
+
}) {
|
|
3858
|
+
var _a, _b, _c;
|
|
3859
|
+
const [imgIndex, setImgIndex] = React18.useState(0);
|
|
3860
|
+
const images = stop ? [stop.coverImage, ...(_a = stop.images) != null ? _a : []] : [];
|
|
3861
|
+
const isFirst = (stop == null ? void 0 : stop.dayNumber) === ((_b = allStops[0]) == null ? void 0 : _b.dayNumber);
|
|
3862
|
+
const isLast = (stop == null ? void 0 : stop.dayNumber) === ((_c = allStops[allStops.length - 1]) == null ? void 0 : _c.dayNumber);
|
|
3863
|
+
React18.useEffect(() => {
|
|
3864
|
+
setImgIndex(0);
|
|
3865
|
+
}, [stop == null ? void 0 : stop.dayNumber]);
|
|
3866
|
+
if (!stop) return null;
|
|
3867
|
+
return /* @__PURE__ */ jsx(Dialog, { open: !!stop, onOpenChange: (open) => !open && onClose(), children: /* @__PURE__ */ jsxs(
|
|
3868
|
+
DialogContent,
|
|
3869
|
+
{
|
|
3870
|
+
className: cn(
|
|
3871
|
+
/* Override shadcn defaults: remove padding, gap, grid, max-w-sm */
|
|
3872
|
+
"p-0 gap-0 sm:max-w-2xl max-w-[calc(100%-2rem)] overflow-hidden rounded-2xl",
|
|
3873
|
+
/* Outer flex column: [header+body] / [footer] */
|
|
3874
|
+
"flex flex-col"
|
|
3875
|
+
),
|
|
3876
|
+
children: [
|
|
3877
|
+
/* @__PURE__ */ jsxs(DialogTitle, { className: "sr-only", children: [
|
|
3878
|
+
stop.title,
|
|
3879
|
+
" \u2014 Day ",
|
|
3880
|
+
stop.dayNumber
|
|
3881
|
+
] }),
|
|
3882
|
+
/* @__PURE__ */ jsxs(DialogDescription, { className: "sr-only", children: [
|
|
3883
|
+
"Itinerary details for Day ",
|
|
3884
|
+
stop.dayNumber
|
|
3885
|
+
] }),
|
|
3886
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col sm:flex-row flex-1 min-h-0", children: [
|
|
3887
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col flex-1 p-6 sm:p-8 overflow-y-auto max-h-[50vh] sm:max-h-[70vh]", children: [
|
|
3888
|
+
/* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-foreground font-heading leading-tight", children: stop.title }),
|
|
3889
|
+
stop.location && /* @__PURE__ */ jsxs("p", { className: "mt-1.5 flex items-center gap-1.5 text-sm text-muted-foreground font-ui", children: [
|
|
3890
|
+
/* @__PURE__ */ jsx(MapPinIcon, { className: "h-4 w-4 shrink-0 text-primary" }),
|
|
3891
|
+
stop.location
|
|
3892
|
+
] }),
|
|
3893
|
+
/* @__PURE__ */ jsxs("p", { className: "mt-4 text-sm font-bold text-foreground font-heading", children: [
|
|
3894
|
+
"Day ",
|
|
3895
|
+
stop.dayNumber
|
|
3896
|
+
] }),
|
|
3897
|
+
stop.description && /* @__PURE__ */ jsx("div", { className: "mt-2 text-sm text-foreground/80 leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline [&_a]:underline-offset-2", children: stop.description }),
|
|
3898
|
+
stop.route && /* @__PURE__ */ jsxs("div", { className: "mt-4 flex items-center gap-2 text-sm text-muted-foreground font-ui", children: [
|
|
3899
|
+
/* @__PURE__ */ jsx(CarIcon, { className: "h-4 w-4 shrink-0 text-primary" }),
|
|
3900
|
+
/* @__PURE__ */ jsxs("span", { children: [
|
|
3901
|
+
stop.route.distance,
|
|
3902
|
+
" \xB7 ",
|
|
3903
|
+
stop.route.duration
|
|
3904
|
+
] })
|
|
3905
|
+
] })
|
|
3906
|
+
] }),
|
|
3907
|
+
images.length > 0 && /* @__PURE__ */ jsxs("div", { className: "relative sm:w-72 sm:shrink-0 h-52 sm:h-auto bg-muted overflow-hidden", children: [
|
|
3908
|
+
/* @__PURE__ */ jsx(
|
|
3909
|
+
"img",
|
|
3910
|
+
{
|
|
3911
|
+
src: images[imgIndex],
|
|
3912
|
+
alt: `${stop.title} ${imgIndex + 1}`,
|
|
3913
|
+
className: "h-full w-full object-cover"
|
|
3914
|
+
},
|
|
3915
|
+
imgIndex
|
|
3916
|
+
),
|
|
3917
|
+
images.length > 1 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3918
|
+
/* @__PURE__ */ jsx(
|
|
3919
|
+
"button",
|
|
3920
|
+
{
|
|
3921
|
+
type: "button",
|
|
3922
|
+
onClick: () => setImgIndex((i) => (i - 1 + images.length) % images.length),
|
|
3923
|
+
className: "absolute left-2 top-1/2 -translate-y-1/2 flex h-8 w-8 items-center justify-center rounded-full bg-background/80 shadow hover:bg-background transition-colors",
|
|
3924
|
+
children: /* @__PURE__ */ jsx(ChevronLeftIcon, { className: "h-4 w-4" })
|
|
3925
|
+
}
|
|
3926
|
+
),
|
|
3927
|
+
/* @__PURE__ */ jsx(
|
|
3928
|
+
"button",
|
|
3929
|
+
{
|
|
3930
|
+
type: "button",
|
|
3931
|
+
onClick: () => setImgIndex((i) => (i + 1) % images.length),
|
|
3932
|
+
className: "absolute right-2 top-1/2 -translate-y-1/2 flex h-8 w-8 items-center justify-center rounded-full bg-background/80 shadow hover:bg-background transition-colors",
|
|
3933
|
+
children: /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-4 w-4" })
|
|
3934
|
+
}
|
|
3935
|
+
),
|
|
3936
|
+
/* @__PURE__ */ jsx("div", { className: "absolute bottom-3 inset-x-0 flex justify-center gap-1.5", children: images.map((_, i) => /* @__PURE__ */ jsx(
|
|
3937
|
+
"button",
|
|
3938
|
+
{
|
|
3939
|
+
type: "button",
|
|
3940
|
+
onClick: () => setImgIndex(i),
|
|
3941
|
+
className: cn(
|
|
3942
|
+
"h-1.5 rounded-full transition-all",
|
|
3943
|
+
i === imgIndex ? "w-4 bg-white" : "w-1.5 bg-white/50"
|
|
3944
|
+
)
|
|
3945
|
+
},
|
|
3946
|
+
i
|
|
3947
|
+
)) })
|
|
3948
|
+
] })
|
|
3949
|
+
] })
|
|
3950
|
+
] }),
|
|
3951
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between border-t border-border px-6 py-3 bg-background shrink-0", children: [
|
|
3952
|
+
/* @__PURE__ */ jsxs(
|
|
3953
|
+
"button",
|
|
3954
|
+
{
|
|
3955
|
+
type: "button",
|
|
3956
|
+
onClick: onPrev,
|
|
3957
|
+
disabled: isFirst,
|
|
3958
|
+
className: cn(
|
|
3959
|
+
"flex items-center gap-1.5 text-sm font-ui transition-colors",
|
|
3960
|
+
isFirst ? "text-muted-foreground/40 pointer-events-none" : "text-foreground hover:text-primary"
|
|
3961
|
+
),
|
|
3962
|
+
children: [
|
|
3963
|
+
/* @__PURE__ */ jsx("span", { className: "flex h-6 w-6 items-center justify-center rounded-full border border-current", children: /* @__PURE__ */ jsx(ChevronLeftIcon, { className: "h-3.5 w-3.5" }) }),
|
|
3964
|
+
"Last day"
|
|
3965
|
+
]
|
|
3966
|
+
}
|
|
3967
|
+
),
|
|
3968
|
+
/* @__PURE__ */ jsxs(
|
|
3969
|
+
"button",
|
|
3970
|
+
{
|
|
3971
|
+
type: "button",
|
|
3972
|
+
onClick: onNext,
|
|
3973
|
+
disabled: isLast,
|
|
3974
|
+
className: cn(
|
|
3975
|
+
"flex items-center gap-1.5 text-sm font-ui transition-colors",
|
|
3976
|
+
isLast ? "text-muted-foreground/40 pointer-events-none" : "text-foreground hover:text-primary"
|
|
3977
|
+
),
|
|
3978
|
+
children: [
|
|
3979
|
+
"Next day",
|
|
3980
|
+
/* @__PURE__ */ jsx("span", { className: "flex h-6 w-6 items-center justify-center rounded-full border border-current", children: /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-3.5 w-3.5" }) })
|
|
3981
|
+
]
|
|
3982
|
+
}
|
|
3983
|
+
)
|
|
3984
|
+
] })
|
|
3985
|
+
]
|
|
3986
|
+
}
|
|
3987
|
+
) });
|
|
3988
|
+
}
|
|
3989
|
+
function Itinerary({ title, subtitle, stops, className }) {
|
|
3990
|
+
const [activeIndex, setActiveIndex] = React18.useState(null);
|
|
3991
|
+
const scrollRef = React18.useRef(null);
|
|
3992
|
+
const activeStop = activeIndex !== null ? stops[activeIndex] : null;
|
|
3993
|
+
const scrollBy = (dir) => {
|
|
3994
|
+
if (!scrollRef.current) return;
|
|
3995
|
+
const amount = 280;
|
|
3996
|
+
scrollRef.current.scrollBy({
|
|
3997
|
+
left: dir === "right" ? amount : -amount,
|
|
3998
|
+
behavior: "smooth"
|
|
3999
|
+
});
|
|
4000
|
+
};
|
|
4001
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("w-full", className), children: [
|
|
4002
|
+
(title || subtitle) && /* @__PURE__ */ jsxs("div", { className: "mb-6 text-center px-4", children: [
|
|
4003
|
+
title && /* @__PURE__ */ jsx("h2", { className: "text-2xl sm:text-3xl font-bold text-foreground font-heading", children: title }),
|
|
4004
|
+
subtitle && /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-muted-foreground max-w-md mx-auto leading-relaxed", children: subtitle })
|
|
4005
|
+
] }),
|
|
4006
|
+
/* @__PURE__ */ jsxs("div", { className: "relative group/strip", children: [
|
|
4007
|
+
/* @__PURE__ */ jsx(
|
|
4008
|
+
"button",
|
|
4009
|
+
{
|
|
4010
|
+
type: "button",
|
|
4011
|
+
onClick: () => scrollBy("left"),
|
|
4012
|
+
"aria-label": "Scroll left",
|
|
4013
|
+
className: cn(
|
|
4014
|
+
"absolute left-0 top-1/2 -translate-y-1/2 z-20",
|
|
4015
|
+
"-translate-x-1/2 sm:-translate-x-5",
|
|
4016
|
+
"flex h-9 w-9 items-center justify-center rounded-full",
|
|
4017
|
+
"bg-background border border-border shadow-md",
|
|
4018
|
+
"transition-opacity hover:bg-muted",
|
|
4019
|
+
"opacity-0 group-hover/strip:opacity-100"
|
|
4020
|
+
),
|
|
4021
|
+
children: /* @__PURE__ */ jsx(ChevronLeftIcon, { className: "h-4 w-4 text-foreground" })
|
|
4022
|
+
}
|
|
4023
|
+
),
|
|
4024
|
+
/* @__PURE__ */ jsx(
|
|
4025
|
+
"button",
|
|
4026
|
+
{
|
|
4027
|
+
type: "button",
|
|
4028
|
+
onClick: () => scrollBy("right"),
|
|
4029
|
+
"aria-label": "Scroll right",
|
|
4030
|
+
className: cn(
|
|
4031
|
+
"absolute right-0 top-1/2 -translate-y-1/2 z-20",
|
|
4032
|
+
"translate-x-1/2 sm:translate-x-5",
|
|
4033
|
+
"flex h-9 w-9 items-center justify-center rounded-full",
|
|
4034
|
+
"bg-background border border-border shadow-md",
|
|
4035
|
+
"transition-opacity hover:bg-muted",
|
|
4036
|
+
"opacity-0 group-hover/strip:opacity-100"
|
|
4037
|
+
),
|
|
4038
|
+
children: /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-4 w-4 text-foreground" })
|
|
4039
|
+
}
|
|
4040
|
+
),
|
|
4041
|
+
/* @__PURE__ */ jsx(
|
|
4042
|
+
"div",
|
|
4043
|
+
{
|
|
4044
|
+
ref: scrollRef,
|
|
4045
|
+
className: cn(
|
|
4046
|
+
"flex gap-3 sm:gap-4 overflow-x-auto pb-4",
|
|
4047
|
+
"snap-x snap-mandatory scroll-smooth",
|
|
4048
|
+
"[&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]",
|
|
4049
|
+
"px-4 sm:px-2"
|
|
4050
|
+
),
|
|
4051
|
+
children: stops.map((stop, i) => /* @__PURE__ */ jsx("div", { className: "snap-start shrink-0", children: /* @__PURE__ */ jsx(ItineraryDayCard, { stop, onOpen: () => setActiveIndex(i) }) }, stop.dayNumber))
|
|
4052
|
+
}
|
|
4053
|
+
)
|
|
4054
|
+
] }),
|
|
4055
|
+
/* @__PURE__ */ jsx(
|
|
4056
|
+
ItineraryModal,
|
|
4057
|
+
{
|
|
4058
|
+
stop: activeStop,
|
|
4059
|
+
allStops: stops,
|
|
4060
|
+
onClose: () => setActiveIndex(null),
|
|
4061
|
+
onPrev: () => setActiveIndex((i) => i !== null ? Math.max(0, i - 1) : 0),
|
|
4062
|
+
onNext: () => setActiveIndex(
|
|
4063
|
+
(i) => i !== null ? Math.min(stops.length - 1, i + 1) : 0
|
|
4064
|
+
)
|
|
4065
|
+
}
|
|
4066
|
+
)
|
|
4067
|
+
] });
|
|
4068
|
+
}
|
|
4069
|
+
function MenuTrip({
|
|
4070
|
+
sections,
|
|
4071
|
+
activeSection,
|
|
4072
|
+
onSelect,
|
|
4073
|
+
variant = "pill",
|
|
4074
|
+
bold = true,
|
|
4075
|
+
className
|
|
4076
|
+
}) {
|
|
4077
|
+
const scrollRef = React18.useRef(null);
|
|
4078
|
+
React18.useEffect(() => {
|
|
4079
|
+
if (!scrollRef.current || !activeSection) return;
|
|
4080
|
+
const container = scrollRef.current;
|
|
4081
|
+
const btn = container.querySelector(
|
|
4082
|
+
`[data-section="${activeSection}"]`
|
|
4083
|
+
);
|
|
4084
|
+
if (!btn) return;
|
|
4085
|
+
const btnLeft = btn.offsetLeft;
|
|
4086
|
+
const btnRight = btnLeft + btn.offsetWidth;
|
|
4087
|
+
const cLeft = container.scrollLeft;
|
|
4088
|
+
const cRight = cLeft + container.offsetWidth;
|
|
4089
|
+
if (btnLeft < cLeft) {
|
|
4090
|
+
container.scrollTo({ left: btnLeft - 16, behavior: "smooth" });
|
|
4091
|
+
} else if (btnRight > cRight) {
|
|
4092
|
+
container.scrollTo({ left: btnRight - container.offsetWidth + 16, behavior: "smooth" });
|
|
4093
|
+
}
|
|
4094
|
+
}, [activeSection]);
|
|
4095
|
+
if (variant === "underline") {
|
|
4096
|
+
return /* @__PURE__ */ jsx(
|
|
4097
|
+
"div",
|
|
4098
|
+
{
|
|
4099
|
+
ref: scrollRef,
|
|
4100
|
+
className: cn(
|
|
4101
|
+
"overflow-x-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]",
|
|
4102
|
+
"border-b border-border",
|
|
4103
|
+
className
|
|
4104
|
+
),
|
|
4105
|
+
children: /* @__PURE__ */ jsx("div", { className: "inline-flex min-w-max items-end gap-0", children: sections.map((s) => /* @__PURE__ */ jsx(
|
|
4106
|
+
"button",
|
|
4107
|
+
{
|
|
4108
|
+
"data-section": s.id,
|
|
4109
|
+
type: "button",
|
|
4110
|
+
onClick: () => onSelect == null ? void 0 : onSelect(s.id),
|
|
4111
|
+
className: cn(
|
|
4112
|
+
"relative px-4 py-2.5 text-sm font-ui whitespace-nowrap transition-colors duration-150",
|
|
4113
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1",
|
|
4114
|
+
"after:absolute after:inset-x-0 after:bottom-0 after:h-0.5 after:rounded-full after:transition-all",
|
|
4115
|
+
bold ? "font-semibold" : "font-normal",
|
|
4116
|
+
activeSection === s.id ? "text-foreground after:bg-primary" : "text-muted-foreground hover:text-foreground after:bg-transparent"
|
|
4117
|
+
),
|
|
4118
|
+
children: s.label
|
|
4119
|
+
},
|
|
4120
|
+
s.id
|
|
4121
|
+
)) })
|
|
4122
|
+
}
|
|
4123
|
+
);
|
|
4124
|
+
}
|
|
4125
|
+
if (variant === "outlined") {
|
|
4126
|
+
return /* @__PURE__ */ jsx(
|
|
4127
|
+
"div",
|
|
4128
|
+
{
|
|
4129
|
+
ref: scrollRef,
|
|
4130
|
+
className: cn(
|
|
4131
|
+
"overflow-x-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]",
|
|
4132
|
+
className
|
|
4133
|
+
),
|
|
4134
|
+
children: /* @__PURE__ */ jsx("div", { className: "inline-flex min-w-max items-center gap-2", children: sections.map((s) => /* @__PURE__ */ jsx(
|
|
4135
|
+
"button",
|
|
4136
|
+
{
|
|
4137
|
+
"data-section": s.id,
|
|
4138
|
+
type: "button",
|
|
4139
|
+
onClick: () => onSelect == null ? void 0 : onSelect(s.id),
|
|
4140
|
+
className: cn(
|
|
4141
|
+
"rounded-full border px-4 py-1.5 text-sm font-ui whitespace-nowrap transition-all duration-150",
|
|
4142
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
4143
|
+
bold ? "font-semibold" : "font-normal",
|
|
4144
|
+
activeSection === s.id ? "border-foreground bg-foreground text-background" : "border-border bg-background text-muted-foreground hover:border-foreground/50 hover:text-foreground"
|
|
4145
|
+
),
|
|
4146
|
+
children: s.label
|
|
4147
|
+
},
|
|
4148
|
+
s.id
|
|
4149
|
+
)) })
|
|
4150
|
+
}
|
|
4151
|
+
);
|
|
4152
|
+
}
|
|
4153
|
+
if (variant === "floating") {
|
|
4154
|
+
return /* @__PURE__ */ jsx(
|
|
4155
|
+
"div",
|
|
4156
|
+
{
|
|
4157
|
+
ref: scrollRef,
|
|
4158
|
+
className: cn(
|
|
4159
|
+
"overflow-x-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]",
|
|
4160
|
+
"py-1 px-0.5",
|
|
4161
|
+
/* padding so shadow isn't clipped by overflow */
|
|
4162
|
+
className
|
|
4163
|
+
),
|
|
4164
|
+
children: /* @__PURE__ */ jsx("div", { className: "inline-flex min-w-max items-center gap-0.5 rounded-full border border-border/40 bg-background/90 backdrop-blur-md shadow-sm px-1.5 py-1.5", children: sections.map((s) => /* @__PURE__ */ jsx(
|
|
4165
|
+
"button",
|
|
4166
|
+
{
|
|
4167
|
+
"data-section": s.id,
|
|
4168
|
+
type: "button",
|
|
4169
|
+
onClick: () => onSelect == null ? void 0 : onSelect(s.id),
|
|
4170
|
+
className: cn(
|
|
4171
|
+
"rounded-full px-4 py-1.5 text-sm font-ui whitespace-nowrap transition-all duration-150",
|
|
4172
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
4173
|
+
bold ? "font-semibold" : "font-normal",
|
|
4174
|
+
activeSection === s.id ? "bg-foreground text-background shadow-sm" : "text-foreground/60 hover:text-foreground hover:bg-muted/60"
|
|
4175
|
+
),
|
|
4176
|
+
children: s.label
|
|
4177
|
+
},
|
|
4178
|
+
s.id
|
|
4179
|
+
)) })
|
|
4180
|
+
}
|
|
4181
|
+
);
|
|
4182
|
+
}
|
|
4183
|
+
return /* @__PURE__ */ jsx(
|
|
4184
|
+
"div",
|
|
4185
|
+
{
|
|
4186
|
+
ref: scrollRef,
|
|
4187
|
+
className: cn(
|
|
4188
|
+
"overflow-x-auto [&::-webkit-scrollbar]:hidden [-ms-overflow-style:none] [scrollbar-width:none]",
|
|
4189
|
+
className
|
|
4190
|
+
),
|
|
4191
|
+
children: /* @__PURE__ */ jsx("div", { className: "inline-flex min-w-max items-center gap-1 p-1", children: sections.map((s) => /* @__PURE__ */ jsx(
|
|
4192
|
+
"button",
|
|
4193
|
+
{
|
|
4194
|
+
"data-section": s.id,
|
|
4195
|
+
type: "button",
|
|
4196
|
+
onClick: () => onSelect == null ? void 0 : onSelect(s.id),
|
|
4197
|
+
className: cn(
|
|
4198
|
+
"rounded-full px-4 py-1.5 text-sm font-ui whitespace-nowrap transition-all duration-150",
|
|
4199
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
4200
|
+
bold ? "font-semibold" : "font-normal",
|
|
4201
|
+
activeSection === s.id ? "bg-foreground text-background shadow-sm" : "bg-white text-foreground/70 hover:text-foreground shadow-sm"
|
|
4202
|
+
),
|
|
4203
|
+
children: s.label
|
|
4204
|
+
},
|
|
4205
|
+
s.id
|
|
4206
|
+
)) })
|
|
4207
|
+
}
|
|
4208
|
+
);
|
|
4209
|
+
}
|
|
4210
|
+
function normalise(p) {
|
|
4211
|
+
return typeof p === "string" ? { src: p } : p;
|
|
4212
|
+
}
|
|
4213
|
+
function gridCols(total) {
|
|
4214
|
+
if (total === 1) return "grid-cols-1";
|
|
4215
|
+
if (total === 2) return "grid-cols-2";
|
|
4216
|
+
return "grid-cols-3";
|
|
4217
|
+
}
|
|
4218
|
+
function Lightbox({
|
|
4219
|
+
photos,
|
|
4220
|
+
initialIndex,
|
|
4221
|
+
onClose
|
|
4222
|
+
}) {
|
|
4223
|
+
var _a;
|
|
4224
|
+
const [index, setIndex] = React18.useState(initialIndex);
|
|
4225
|
+
const total = photos.length;
|
|
4226
|
+
const photo = photos[index];
|
|
4227
|
+
const prev = React18.useCallback(
|
|
4228
|
+
() => setIndex((i) => (i - 1 + total) % total),
|
|
4229
|
+
[total]
|
|
4230
|
+
);
|
|
4231
|
+
const next = React18.useCallback(
|
|
4232
|
+
() => setIndex((i) => (i + 1) % total),
|
|
4233
|
+
[total]
|
|
4234
|
+
);
|
|
4235
|
+
React18.useEffect(() => {
|
|
4236
|
+
const onKey = (e) => {
|
|
4237
|
+
if (e.key === "Escape") onClose();
|
|
4238
|
+
if (e.key === "ArrowLeft") prev();
|
|
4239
|
+
if (e.key === "ArrowRight") next();
|
|
4240
|
+
};
|
|
4241
|
+
document.addEventListener("keydown", onKey);
|
|
4242
|
+
return () => document.removeEventListener("keydown", onKey);
|
|
4243
|
+
}, [onClose, prev, next]);
|
|
4244
|
+
return /* @__PURE__ */ jsxs(
|
|
4245
|
+
"div",
|
|
4246
|
+
{
|
|
4247
|
+
className: "fixed inset-0 z-50 bg-black/92 flex flex-col items-center justify-center",
|
|
4248
|
+
onClick: onClose,
|
|
4249
|
+
children: [
|
|
4250
|
+
/* @__PURE__ */ jsx(
|
|
4251
|
+
"button",
|
|
4252
|
+
{
|
|
4253
|
+
type: "button",
|
|
4254
|
+
onClick: onClose,
|
|
4255
|
+
className: "absolute top-5 right-5 flex h-10 w-10 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/20 transition-colors z-10",
|
|
4256
|
+
"aria-label": "Close lightbox",
|
|
4257
|
+
children: /* @__PURE__ */ jsx(XIcon, { className: "h-5 w-5" })
|
|
4258
|
+
}
|
|
4259
|
+
),
|
|
4260
|
+
total > 1 && /* @__PURE__ */ jsx(
|
|
4261
|
+
"button",
|
|
4262
|
+
{
|
|
4263
|
+
type: "button",
|
|
4264
|
+
onClick: (e) => {
|
|
4265
|
+
e.stopPropagation();
|
|
4266
|
+
prev();
|
|
4267
|
+
},
|
|
4268
|
+
className: "absolute left-4 top-1/2 -translate-y-1/2 flex h-11 w-11 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/25 transition-colors z-10",
|
|
4269
|
+
"aria-label": "Previous photo",
|
|
4270
|
+
children: /* @__PURE__ */ jsx(ChevronLeftIcon, { className: "h-5 w-5" })
|
|
4271
|
+
}
|
|
4272
|
+
),
|
|
4273
|
+
total > 1 && /* @__PURE__ */ jsx(
|
|
4274
|
+
"button",
|
|
4275
|
+
{
|
|
4276
|
+
type: "button",
|
|
4277
|
+
onClick: (e) => {
|
|
4278
|
+
e.stopPropagation();
|
|
4279
|
+
next();
|
|
4280
|
+
},
|
|
4281
|
+
className: "absolute right-4 top-1/2 -translate-y-1/2 flex h-11 w-11 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/25 transition-colors z-10",
|
|
4282
|
+
"aria-label": "Next photo",
|
|
4283
|
+
children: /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-5 w-5" })
|
|
4284
|
+
}
|
|
4285
|
+
),
|
|
4286
|
+
/* @__PURE__ */ jsx(
|
|
4287
|
+
"img",
|
|
4288
|
+
{
|
|
4289
|
+
src: photo.src,
|
|
4290
|
+
alt: (_a = photo.alt) != null ? _a : `Photo ${index + 1}`,
|
|
4291
|
+
className: "max-w-[calc(100%-6rem)] max-h-[calc(100vh-11rem)] object-contain rounded-lg shadow-2xl",
|
|
4292
|
+
onClick: (e) => e.stopPropagation()
|
|
4293
|
+
}
|
|
4294
|
+
),
|
|
4295
|
+
(photo.caption || photo.credit) && /* @__PURE__ */ jsxs(
|
|
4296
|
+
"div",
|
|
4297
|
+
{
|
|
4298
|
+
className: "mt-4 flex flex-col items-center gap-0.5 px-16 text-center",
|
|
4299
|
+
onClick: (e) => e.stopPropagation(),
|
|
4300
|
+
children: [
|
|
4301
|
+
photo.caption && /* @__PURE__ */ jsx("p", { className: "text-sm text-white/90 font-ui leading-snug max-w-xl", children: photo.caption }),
|
|
4302
|
+
photo.credit && /* @__PURE__ */ jsxs("p", { className: "text-xs text-white/45 font-ui", children: [
|
|
4303
|
+
"\xA9 ",
|
|
4304
|
+
photo.credit
|
|
4305
|
+
] })
|
|
4306
|
+
]
|
|
4307
|
+
}
|
|
4308
|
+
),
|
|
4309
|
+
total > 1 && /* @__PURE__ */ jsxs(
|
|
4310
|
+
"div",
|
|
4311
|
+
{
|
|
4312
|
+
className: "absolute bottom-5 inset-x-0 flex items-center justify-center gap-3 px-5",
|
|
4313
|
+
onClick: (e) => e.stopPropagation(),
|
|
4314
|
+
children: [
|
|
4315
|
+
/* @__PURE__ */ jsx(
|
|
4316
|
+
"button",
|
|
4317
|
+
{
|
|
4318
|
+
type: "button",
|
|
4319
|
+
onClick: (e) => {
|
|
4320
|
+
e.stopPropagation();
|
|
4321
|
+
prev();
|
|
4322
|
+
},
|
|
4323
|
+
className: "flex h-9 w-9 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/20 transition-colors",
|
|
4324
|
+
"aria-label": "Previous photo",
|
|
4325
|
+
children: /* @__PURE__ */ jsx(ChevronLeftIcon, { className: "h-4 w-4" })
|
|
4326
|
+
}
|
|
4327
|
+
),
|
|
4328
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5", children: photos.map((_, i) => /* @__PURE__ */ jsx(
|
|
4329
|
+
"button",
|
|
4330
|
+
{
|
|
4331
|
+
type: "button",
|
|
4332
|
+
onClick: (e) => {
|
|
4333
|
+
e.stopPropagation();
|
|
4334
|
+
setIndex(i);
|
|
4335
|
+
},
|
|
4336
|
+
"aria-label": `Go to photo ${i + 1}`,
|
|
4337
|
+
className: cn(
|
|
4338
|
+
"h-1.5 rounded-full transition-all duration-300 focus-visible:outline-none",
|
|
4339
|
+
i === index ? "w-6 bg-primary" : "w-1.5 bg-white/40 hover:bg-white/70"
|
|
4340
|
+
)
|
|
4341
|
+
},
|
|
4342
|
+
i
|
|
4343
|
+
)) }),
|
|
4344
|
+
/* @__PURE__ */ jsx(
|
|
4345
|
+
"button",
|
|
4346
|
+
{
|
|
4347
|
+
type: "button",
|
|
4348
|
+
onClick: (e) => {
|
|
4349
|
+
e.stopPropagation();
|
|
4350
|
+
next();
|
|
4351
|
+
},
|
|
4352
|
+
className: "flex h-9 w-9 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/20 transition-colors",
|
|
4353
|
+
"aria-label": "Next photo",
|
|
4354
|
+
children: /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-4 w-4" })
|
|
4355
|
+
}
|
|
4356
|
+
)
|
|
4357
|
+
]
|
|
4358
|
+
}
|
|
4359
|
+
)
|
|
4360
|
+
]
|
|
4361
|
+
}
|
|
4362
|
+
);
|
|
4363
|
+
}
|
|
4364
|
+
function PhotoTile({
|
|
4365
|
+
photo,
|
|
4366
|
+
index,
|
|
4367
|
+
className,
|
|
4368
|
+
onClick
|
|
4369
|
+
}) {
|
|
4370
|
+
var _a, _b;
|
|
4371
|
+
return /* @__PURE__ */ jsxs(
|
|
4372
|
+
"button",
|
|
4373
|
+
{
|
|
4374
|
+
type: "button",
|
|
4375
|
+
onClick,
|
|
4376
|
+
className: cn(
|
|
4377
|
+
"relative overflow-hidden group block w-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
4378
|
+
className
|
|
4379
|
+
),
|
|
4380
|
+
"aria-label": (_a = photo.alt) != null ? _a : `Photo ${index + 1}`,
|
|
4381
|
+
children: [
|
|
4382
|
+
/* @__PURE__ */ jsx(
|
|
4383
|
+
"img",
|
|
4384
|
+
{
|
|
4385
|
+
src: photo.src,
|
|
4386
|
+
alt: (_b = photo.alt) != null ? _b : `Photo ${index + 1}`,
|
|
4387
|
+
className: "w-full h-full object-cover transition-transform duration-700 group-hover:scale-105",
|
|
4388
|
+
loading: "lazy"
|
|
4389
|
+
}
|
|
4390
|
+
),
|
|
4391
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors duration-300 flex items-center justify-center", children: /* @__PURE__ */ jsx(ZoomInIcon, { className: "h-8 w-8 text-white opacity-0 group-hover:opacity-100 transition-opacity duration-300 drop-shadow-lg" }) })
|
|
4392
|
+
]
|
|
4393
|
+
}
|
|
4394
|
+
);
|
|
4395
|
+
}
|
|
4396
|
+
function ShowMoreButton({
|
|
4397
|
+
count,
|
|
4398
|
+
expanded,
|
|
4399
|
+
onClick
|
|
4400
|
+
}) {
|
|
4401
|
+
return /* @__PURE__ */ jsx("div", { className: "flex justify-center py-4", children: /* @__PURE__ */ jsx(
|
|
4402
|
+
"button",
|
|
4403
|
+
{
|
|
4404
|
+
type: "button",
|
|
4405
|
+
onClick,
|
|
4406
|
+
className: cn(
|
|
4407
|
+
"inline-flex items-center gap-2 rounded-full border border-border bg-background px-5 py-2.5",
|
|
4408
|
+
"text-sm font-semibold text-foreground shadow-sm",
|
|
4409
|
+
"hover:bg-muted transition-colors duration-150",
|
|
4410
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
4411
|
+
),
|
|
4412
|
+
children: expanded ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4413
|
+
/* @__PURE__ */ jsx(ChevronUpIcon, { className: "h-4 w-4 text-muted-foreground" }),
|
|
4414
|
+
"Show less"
|
|
4415
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4416
|
+
/* @__PURE__ */ jsx(LayoutGridIcon, { className: "h-4 w-4 text-muted-foreground" }),
|
|
4417
|
+
"See more (",
|
|
4418
|
+
count,
|
|
4419
|
+
")"
|
|
4420
|
+
] })
|
|
4421
|
+
}
|
|
4422
|
+
) });
|
|
4423
|
+
}
|
|
4424
|
+
function GridGallery({
|
|
4425
|
+
photos,
|
|
4426
|
+
initialVisible,
|
|
4427
|
+
onOpen
|
|
4428
|
+
}) {
|
|
4429
|
+
const [expanded, setExpanded] = React18.useState(false);
|
|
4430
|
+
const cols = gridCols(photos.length);
|
|
4431
|
+
const hasMore = photos.length > initialVisible;
|
|
4432
|
+
const visible = expanded || !hasMore ? photos : photos.slice(0, initialVisible);
|
|
4433
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4434
|
+
/* @__PURE__ */ jsx("div", { className: cn("grid", cols), children: visible.map((p, i) => /* @__PURE__ */ jsx(
|
|
4435
|
+
PhotoTile,
|
|
4436
|
+
{
|
|
4437
|
+
photo: p,
|
|
4438
|
+
index: i,
|
|
4439
|
+
className: "aspect-[4/3]",
|
|
4440
|
+
onClick: () => onOpen(i)
|
|
4441
|
+
},
|
|
4442
|
+
i
|
|
4443
|
+
)) }),
|
|
4444
|
+
hasMore && /* @__PURE__ */ jsx(
|
|
4445
|
+
ShowMoreButton,
|
|
4446
|
+
{
|
|
4447
|
+
count: photos.length - initialVisible,
|
|
4448
|
+
expanded,
|
|
4449
|
+
onClick: () => setExpanded((v) => !v)
|
|
4450
|
+
}
|
|
4451
|
+
)
|
|
4452
|
+
] });
|
|
4453
|
+
}
|
|
4454
|
+
function MasonryGallery({
|
|
4455
|
+
photos,
|
|
4456
|
+
initialVisible,
|
|
4457
|
+
onOpen
|
|
4458
|
+
}) {
|
|
4459
|
+
const [expanded, setExpanded] = React18.useState(false);
|
|
4460
|
+
const hasMore = photos.length > initialVisible;
|
|
4461
|
+
const visible = expanded || !hasMore ? photos : photos.slice(0, initialVisible);
|
|
4462
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4463
|
+
/* @__PURE__ */ jsx("div", { className: "columns-2 sm:columns-3 gap-1 [&>*]:break-inside-avoid [&>*]:mb-1", children: visible.map((p, i) => {
|
|
4464
|
+
var _a, _b;
|
|
4465
|
+
return /* @__PURE__ */ jsxs(
|
|
4466
|
+
"button",
|
|
4467
|
+
{
|
|
4468
|
+
type: "button",
|
|
4469
|
+
onClick: () => onOpen(i),
|
|
4470
|
+
className: "relative overflow-hidden group block w-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
4471
|
+
"aria-label": (_a = p.alt) != null ? _a : `Photo ${i + 1}`,
|
|
4472
|
+
children: [
|
|
4473
|
+
/* @__PURE__ */ jsx(
|
|
4474
|
+
"img",
|
|
4475
|
+
{
|
|
4476
|
+
src: p.src,
|
|
4477
|
+
alt: (_b = p.alt) != null ? _b : `Photo ${i + 1}`,
|
|
4478
|
+
className: "w-full h-auto object-cover transition-transform duration-700 group-hover:scale-105",
|
|
4479
|
+
loading: "lazy"
|
|
4480
|
+
}
|
|
4481
|
+
),
|
|
4482
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors duration-300 flex items-center justify-center", children: /* @__PURE__ */ jsx(ZoomInIcon, { className: "h-7 w-7 text-white opacity-0 group-hover:opacity-100 transition-opacity duration-300 drop-shadow-lg" }) })
|
|
4483
|
+
]
|
|
4484
|
+
},
|
|
4485
|
+
i
|
|
4486
|
+
);
|
|
4487
|
+
}) }),
|
|
4488
|
+
hasMore && /* @__PURE__ */ jsx(
|
|
4489
|
+
ShowMoreButton,
|
|
4490
|
+
{
|
|
4491
|
+
count: photos.length - initialVisible,
|
|
4492
|
+
expanded,
|
|
4493
|
+
onClick: () => setExpanded((v) => !v)
|
|
4494
|
+
}
|
|
4495
|
+
)
|
|
4496
|
+
] });
|
|
4497
|
+
}
|
|
4498
|
+
function FilmstripGallery({
|
|
4499
|
+
photos,
|
|
4500
|
+
onOpen
|
|
4501
|
+
}) {
|
|
4502
|
+
return /* @__PURE__ */ jsx("div", { className: "overflow-x-auto flex gap-1 snap-x snap-mandatory pb-1 scrollbar-none", children: photos.map((p, i) => {
|
|
4503
|
+
var _a, _b;
|
|
4504
|
+
return /* @__PURE__ */ jsxs(
|
|
4505
|
+
"button",
|
|
4506
|
+
{
|
|
4507
|
+
type: "button",
|
|
4508
|
+
onClick: () => onOpen(i),
|
|
4509
|
+
className: "relative shrink-0 overflow-hidden group h-56 w-auto aspect-[4/3] snap-start focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
4510
|
+
"aria-label": (_a = p.alt) != null ? _a : `Photo ${i + 1}`,
|
|
4511
|
+
children: [
|
|
4512
|
+
/* @__PURE__ */ jsx(
|
|
4513
|
+
"img",
|
|
4514
|
+
{
|
|
4515
|
+
src: p.src,
|
|
4516
|
+
alt: (_b = p.alt) != null ? _b : `Photo ${i + 1}`,
|
|
4517
|
+
className: "h-full w-full object-cover transition-transform duration-700 group-hover:scale-105",
|
|
4518
|
+
loading: "lazy"
|
|
4519
|
+
}
|
|
4520
|
+
),
|
|
4521
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors duration-300 flex items-center justify-center", children: /* @__PURE__ */ jsx(ZoomInIcon, { className: "h-7 w-7 text-white opacity-0 group-hover:opacity-100 transition-opacity duration-300 drop-shadow-lg" }) })
|
|
4522
|
+
]
|
|
4523
|
+
},
|
|
4524
|
+
i
|
|
4525
|
+
);
|
|
4526
|
+
}) });
|
|
4527
|
+
}
|
|
4528
|
+
function FeaturedGallery({
|
|
4529
|
+
photos,
|
|
4530
|
+
onOpen
|
|
4531
|
+
}) {
|
|
4532
|
+
const [expanded, setExpanded] = React18.useState(false);
|
|
4533
|
+
const featured = photos.slice(0, 3);
|
|
4534
|
+
const extra = photos.slice(3);
|
|
4535
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4536
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-3 gap-1.5 h-72 sm:h-80 lg:h-96 rounded-xl overflow-hidden", children: [
|
|
4537
|
+
featured[0] && /* @__PURE__ */ jsx(
|
|
4538
|
+
PhotoTile,
|
|
4539
|
+
{
|
|
4540
|
+
photo: featured[0],
|
|
4541
|
+
index: 0,
|
|
4542
|
+
className: "col-span-2 h-full",
|
|
4543
|
+
onClick: () => onOpen(0)
|
|
4544
|
+
}
|
|
4545
|
+
),
|
|
4546
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5 h-full", children: [
|
|
4547
|
+
featured[1] && /* @__PURE__ */ jsx(
|
|
4548
|
+
PhotoTile,
|
|
4549
|
+
{
|
|
4550
|
+
photo: featured[1],
|
|
4551
|
+
index: 1,
|
|
4552
|
+
className: "flex-1 min-h-0",
|
|
4553
|
+
onClick: () => onOpen(1)
|
|
4554
|
+
}
|
|
4555
|
+
),
|
|
4556
|
+
featured[2] && /* @__PURE__ */ jsx(
|
|
4557
|
+
PhotoTile,
|
|
4558
|
+
{
|
|
4559
|
+
photo: featured[2],
|
|
4560
|
+
index: 2,
|
|
4561
|
+
className: "flex-1 min-h-0",
|
|
4562
|
+
onClick: () => onOpen(2)
|
|
4563
|
+
}
|
|
4564
|
+
)
|
|
4565
|
+
] })
|
|
4566
|
+
] }),
|
|
4567
|
+
expanded && extra.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-1.5 overflow-x-auto flex gap-1.5 snap-x snap-mandatory scrollbar-none rounded-xl overflow-hidden pb-0", children: extra.map((p, i) => {
|
|
4568
|
+
var _a, _b;
|
|
4569
|
+
return /* @__PURE__ */ jsxs(
|
|
4570
|
+
"button",
|
|
4571
|
+
{
|
|
4572
|
+
type: "button",
|
|
4573
|
+
onClick: () => onOpen(i + 3),
|
|
4574
|
+
className: "relative shrink-0 overflow-hidden group h-40 sm:h-48 aspect-[4/3] snap-start rounded-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
4575
|
+
"aria-label": (_a = p.alt) != null ? _a : `Photo ${i + 4}`,
|
|
4576
|
+
children: [
|
|
4577
|
+
/* @__PURE__ */ jsx(
|
|
4578
|
+
"img",
|
|
4579
|
+
{
|
|
4580
|
+
src: p.src,
|
|
4581
|
+
alt: (_b = p.alt) != null ? _b : `Photo ${i + 4}`,
|
|
4582
|
+
className: "h-full w-full object-cover transition-transform duration-700 group-hover:scale-105",
|
|
4583
|
+
loading: "lazy"
|
|
4584
|
+
}
|
|
4585
|
+
),
|
|
4586
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-black/0 group-hover:bg-black/20 transition-colors duration-300 flex items-center justify-center", children: /* @__PURE__ */ jsx(ZoomInIcon, { className: "h-7 w-7 text-white opacity-0 group-hover:opacity-100 transition-opacity duration-300 drop-shadow-lg" }) })
|
|
4587
|
+
]
|
|
4588
|
+
},
|
|
4589
|
+
i + 3
|
|
4590
|
+
);
|
|
4591
|
+
}) }),
|
|
4592
|
+
extra.length > 0 && /* @__PURE__ */ jsx(
|
|
4593
|
+
ShowMoreButton,
|
|
4594
|
+
{
|
|
4595
|
+
count: extra.length,
|
|
4596
|
+
expanded,
|
|
4597
|
+
onClick: () => setExpanded((v) => !v)
|
|
4598
|
+
}
|
|
4599
|
+
)
|
|
4600
|
+
] });
|
|
4601
|
+
}
|
|
4602
|
+
function PhotoGallery({
|
|
4603
|
+
photos,
|
|
4604
|
+
variant = "grid",
|
|
4605
|
+
initialVisible = 6,
|
|
4606
|
+
onPhotoClick,
|
|
4607
|
+
className
|
|
4608
|
+
}) {
|
|
4609
|
+
const [lightboxIndex, setLightboxIndex] = React18.useState(null);
|
|
4610
|
+
const normalised = React18.useMemo(() => photos.map(normalise), [photos]);
|
|
4611
|
+
const handleOpen = (index) => {
|
|
4612
|
+
setLightboxIndex(index);
|
|
4613
|
+
onPhotoClick == null ? void 0 : onPhotoClick(normalised[index].src, index);
|
|
4614
|
+
};
|
|
4615
|
+
if (normalised.length === 0) return null;
|
|
4616
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("w-full", className), children: [
|
|
4617
|
+
variant === "grid" && /* @__PURE__ */ jsx(
|
|
4618
|
+
GridGallery,
|
|
4619
|
+
{
|
|
4620
|
+
photos: normalised,
|
|
4621
|
+
initialVisible,
|
|
4622
|
+
onOpen: handleOpen
|
|
4623
|
+
}
|
|
4624
|
+
),
|
|
4625
|
+
variant === "masonry" && /* @__PURE__ */ jsx(
|
|
4626
|
+
MasonryGallery,
|
|
4627
|
+
{
|
|
4628
|
+
photos: normalised,
|
|
4629
|
+
initialVisible,
|
|
4630
|
+
onOpen: handleOpen
|
|
4631
|
+
}
|
|
4632
|
+
),
|
|
4633
|
+
variant === "filmstrip" && /* @__PURE__ */ jsx(FilmstripGallery, { photos: normalised, onOpen: handleOpen }),
|
|
4634
|
+
variant === "featured" && /* @__PURE__ */ jsx(FeaturedGallery, { photos: normalised, onOpen: handleOpen }),
|
|
4635
|
+
lightboxIndex !== null && /* @__PURE__ */ jsx(
|
|
4636
|
+
Lightbox,
|
|
4637
|
+
{
|
|
4638
|
+
photos: normalised,
|
|
4639
|
+
initialIndex: lightboxIndex,
|
|
4640
|
+
onClose: () => setLightboxIndex(null)
|
|
4641
|
+
}
|
|
4642
|
+
)
|
|
4643
|
+
] });
|
|
4644
|
+
}
|
|
4645
|
+
var badgeVariants = cva(
|
|
4646
|
+
"group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!",
|
|
4647
|
+
{
|
|
4648
|
+
variants: {
|
|
4649
|
+
variant: {
|
|
4650
|
+
default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
|
|
4651
|
+
secondary: "bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",
|
|
4652
|
+
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",
|
|
4653
|
+
outline: "border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground",
|
|
4654
|
+
ghost: "hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",
|
|
4655
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
4656
|
+
}
|
|
4657
|
+
},
|
|
4658
|
+
defaultVariants: {
|
|
4659
|
+
variant: "default"
|
|
4660
|
+
}
|
|
4661
|
+
}
|
|
4662
|
+
);
|
|
4663
|
+
function Badge(_a) {
|
|
4664
|
+
var _b = _a, {
|
|
4665
|
+
className,
|
|
4666
|
+
variant = "default",
|
|
4667
|
+
render
|
|
4668
|
+
} = _b, props = __objRest(_b, [
|
|
4669
|
+
"className",
|
|
4670
|
+
"variant",
|
|
4671
|
+
"render"
|
|
4672
|
+
]);
|
|
4673
|
+
return useRender({
|
|
4674
|
+
defaultTagName: "span",
|
|
4675
|
+
props: mergeProps(
|
|
4676
|
+
{
|
|
4677
|
+
className: cn(badgeVariants({ variant }), className)
|
|
4678
|
+
},
|
|
4679
|
+
props
|
|
4680
|
+
),
|
|
4681
|
+
render,
|
|
4682
|
+
state: {
|
|
4683
|
+
slot: "badge",
|
|
4684
|
+
variant
|
|
4685
|
+
}
|
|
4686
|
+
});
|
|
4687
|
+
}
|
|
4688
|
+
function PricingTrip({
|
|
4689
|
+
priceFrom,
|
|
4690
|
+
currency = "CHF",
|
|
4691
|
+
season,
|
|
4692
|
+
departureTimes,
|
|
4693
|
+
pricingOptions,
|
|
4694
|
+
onBook,
|
|
4695
|
+
bookLabel = "Check availability",
|
|
4696
|
+
variant = "card",
|
|
4697
|
+
className
|
|
4698
|
+
}) {
|
|
4699
|
+
const [showPricing, setShowPricing] = React18.useState(false);
|
|
4700
|
+
if (variant === "compact") {
|
|
4701
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex items-center gap-3", className), children: [
|
|
4702
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
4703
|
+
/* @__PURE__ */ jsx("p", { className: "text-[10px] uppercase tracking-wide text-muted-foreground font-ui leading-none mb-0.5", children: "from" }),
|
|
4704
|
+
/* @__PURE__ */ jsxs("p", { className: "text-lg font-bold text-foreground font-heading leading-none", children: [
|
|
4705
|
+
currency,
|
|
4706
|
+
" ",
|
|
4707
|
+
/* @__PURE__ */ jsx("span", { className: "text-primary", children: priceFrom })
|
|
4708
|
+
] })
|
|
4709
|
+
] }),
|
|
4710
|
+
/* @__PURE__ */ jsx(
|
|
4711
|
+
"button",
|
|
4712
|
+
{
|
|
4713
|
+
type: "button",
|
|
4714
|
+
onClick: onBook,
|
|
4715
|
+
className: cn(
|
|
4716
|
+
"flex-1 rounded-full bg-primary px-4 py-2 text-sm font-semibold",
|
|
4717
|
+
"text-primary-foreground font-ui transition-colors hover:bg-primary/90",
|
|
4718
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
4719
|
+
),
|
|
4720
|
+
children: bookLabel
|
|
4721
|
+
}
|
|
4722
|
+
)
|
|
4723
|
+
] });
|
|
4724
|
+
}
|
|
4725
|
+
if (variant === "bar") {
|
|
4726
|
+
return /* @__PURE__ */ jsxs(
|
|
4727
|
+
"div",
|
|
4728
|
+
{
|
|
4729
|
+
className: cn(
|
|
4730
|
+
"flex items-center gap-4 rounded-2xl border border-border bg-card px-5 py-3 shadow-sm",
|
|
4731
|
+
className
|
|
4732
|
+
),
|
|
4733
|
+
children: [
|
|
4734
|
+
season && /* @__PURE__ */ jsxs("div", { className: "hidden sm:flex items-center gap-1.5 text-sm text-muted-foreground font-ui shrink-0", children: [
|
|
4735
|
+
/* @__PURE__ */ jsx(CalendarIcon, { className: "h-3.5 w-3.5 text-primary shrink-0" }),
|
|
4736
|
+
/* @__PURE__ */ jsx("span", { className: "truncate max-w-[180px]", children: season })
|
|
4737
|
+
] }),
|
|
4738
|
+
departureTimes && departureTimes.length > 0 && /* @__PURE__ */ jsxs("div", { className: "hidden md:flex items-center gap-1.5 shrink-0", children: [
|
|
4739
|
+
/* @__PURE__ */ jsx(ClockIcon, { className: "h-3.5 w-3.5 text-primary shrink-0" }),
|
|
4740
|
+
/* @__PURE__ */ jsx("div", { className: "flex gap-1", children: departureTimes.map((t) => /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "font-ui text-xs px-1.5 py-0.5", children: t }, t)) })
|
|
4741
|
+
] }),
|
|
4742
|
+
/* @__PURE__ */ jsx("div", { className: "flex-1" }),
|
|
4743
|
+
/* @__PURE__ */ jsxs("div", { className: "shrink-0 text-right", children: [
|
|
4744
|
+
/* @__PURE__ */ jsx("span", { className: "block text-[10px] uppercase tracking-wide text-muted-foreground font-ui leading-none mb-0.5", children: "from" }),
|
|
4745
|
+
/* @__PURE__ */ jsxs("span", { className: "text-xl font-bold text-foreground font-heading leading-none", children: [
|
|
4746
|
+
currency,
|
|
4747
|
+
" ",
|
|
4748
|
+
/* @__PURE__ */ jsx("span", { className: "text-primary", children: priceFrom })
|
|
4749
|
+
] })
|
|
4750
|
+
] }),
|
|
4751
|
+
/* @__PURE__ */ jsxs(
|
|
4752
|
+
"button",
|
|
4753
|
+
{
|
|
4754
|
+
type: "button",
|
|
4755
|
+
onClick: onBook,
|
|
4756
|
+
className: cn(
|
|
4757
|
+
"shrink-0 flex items-center gap-2 rounded-full bg-primary px-5 py-2.5",
|
|
4758
|
+
"text-sm font-semibold text-primary-foreground font-ui",
|
|
4759
|
+
"transition-colors hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
4760
|
+
),
|
|
4761
|
+
children: [
|
|
4762
|
+
/* @__PURE__ */ jsx(CalendarIcon, { className: "h-4 w-4 shrink-0" }),
|
|
4763
|
+
bookLabel
|
|
4764
|
+
]
|
|
4765
|
+
}
|
|
4766
|
+
)
|
|
4767
|
+
]
|
|
4768
|
+
}
|
|
4769
|
+
);
|
|
4770
|
+
}
|
|
4771
|
+
return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-4", className), children: [
|
|
4772
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
4773
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground font-ui uppercase tracking-wide", children: "From" }),
|
|
4774
|
+
/* @__PURE__ */ jsxs("p", { className: "text-3xl font-bold text-foreground font-heading", children: [
|
|
4775
|
+
currency,
|
|
4776
|
+
" ",
|
|
4777
|
+
/* @__PURE__ */ jsx("span", { className: "text-primary", children: priceFrom }),
|
|
4778
|
+
/* @__PURE__ */ jsx("span", { className: "text-base font-normal text-muted-foreground font-ui", children: " / guest" })
|
|
4779
|
+
] })
|
|
4780
|
+
] }),
|
|
4781
|
+
season && /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2 text-sm text-muted-foreground font-ui", children: [
|
|
4782
|
+
/* @__PURE__ */ jsx(CalendarIcon, { className: "h-4 w-4 shrink-0 text-primary mt-0.5" }),
|
|
4783
|
+
/* @__PURE__ */ jsx("span", { children: season })
|
|
4784
|
+
] }),
|
|
4785
|
+
departureTimes && departureTimes.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
|
|
4786
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs font-semibold text-foreground font-ui uppercase tracking-wide", children: "Departure times" }),
|
|
4787
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1.5", children: departureTimes.map((t) => /* @__PURE__ */ jsx(Badge, { variant: "outline", className: "font-ui text-xs", children: t }, t)) })
|
|
4788
|
+
] }),
|
|
4789
|
+
pricingOptions && pricingOptions.length > 0 && /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
4790
|
+
/* @__PURE__ */ jsx(
|
|
4791
|
+
"button",
|
|
4792
|
+
{
|
|
4793
|
+
type: "button",
|
|
4794
|
+
onClick: () => setShowPricing((v) => !v),
|
|
4795
|
+
className: "flex items-center gap-1 text-xs text-primary font-ui text-left hover:underline underline-offset-2",
|
|
4796
|
+
children: showPricing ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4797
|
+
"Show pricing options ",
|
|
4798
|
+
/* @__PURE__ */ jsx(ChevronUpIcon, { className: "h-3 w-3" })
|
|
4799
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4800
|
+
"Show pricing options ",
|
|
4801
|
+
/* @__PURE__ */ jsx(ChevronDownIcon, { className: "h-3 w-3" })
|
|
4802
|
+
] })
|
|
4803
|
+
}
|
|
4804
|
+
),
|
|
4805
|
+
showPricing && /* @__PURE__ */ jsx("div", { className: "rounded-lg border border-border overflow-hidden", children: pricingOptions.map((opt, i) => /* @__PURE__ */ jsxs(
|
|
4806
|
+
"div",
|
|
4807
|
+
{
|
|
4808
|
+
className: cn(
|
|
4809
|
+
"flex items-center justify-between px-3 py-2.5 text-sm",
|
|
4810
|
+
i < pricingOptions.length - 1 && "border-b border-border"
|
|
4811
|
+
),
|
|
4812
|
+
children: [
|
|
4813
|
+
/* @__PURE__ */ jsx("span", { className: "text-foreground font-ui", children: opt.label }),
|
|
4814
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-right", children: [
|
|
4815
|
+
opt.originalPrice && /* @__PURE__ */ jsxs("span", { className: "text-xs text-muted-foreground line-through font-ui", children: [
|
|
4816
|
+
currency,
|
|
4817
|
+
" ",
|
|
4818
|
+
opt.originalPrice
|
|
4819
|
+
] }),
|
|
4820
|
+
/* @__PURE__ */ jsxs("span", { className: "font-bold text-foreground font-ui", children: [
|
|
4821
|
+
currency,
|
|
4822
|
+
" ",
|
|
4823
|
+
opt.price,
|
|
4824
|
+
opt.unit && /* @__PURE__ */ jsxs("span", { className: "text-xs font-normal text-muted-foreground", children: [
|
|
4825
|
+
" ",
|
|
4826
|
+
"/ ",
|
|
4827
|
+
opt.unit
|
|
4828
|
+
] })
|
|
4829
|
+
] })
|
|
4830
|
+
] })
|
|
4831
|
+
]
|
|
4832
|
+
},
|
|
4833
|
+
i
|
|
4834
|
+
)) })
|
|
4835
|
+
] }),
|
|
4836
|
+
/* @__PURE__ */ jsx(
|
|
4837
|
+
"button",
|
|
4838
|
+
{
|
|
4839
|
+
type: "button",
|
|
4840
|
+
onClick: onBook,
|
|
4841
|
+
className: cn(
|
|
4842
|
+
"w-full rounded-full bg-primary py-3 text-center text-sm font-semibold",
|
|
4843
|
+
"text-primary-foreground font-ui transition-colors hover:bg-primary/90",
|
|
4844
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
4845
|
+
),
|
|
4846
|
+
children: bookLabel
|
|
4847
|
+
}
|
|
4848
|
+
)
|
|
4849
|
+
] });
|
|
4850
|
+
}
|
|
4851
|
+
var VARIANT = {
|
|
4852
|
+
transparent: {
|
|
4853
|
+
header: "",
|
|
4854
|
+
navItem: "text-white hover:text-white/80",
|
|
4855
|
+
navItemOpen: "text-white bg-white/10",
|
|
4856
|
+
chevron: "text-white/50",
|
|
4857
|
+
lang: "text-white/70 hover:text-white",
|
|
4858
|
+
langOpen: "text-white bg-white/10",
|
|
4859
|
+
langChevron: "text-white/40",
|
|
4860
|
+
icon: "text-white/60 hover:text-white hover:bg-white/10",
|
|
4861
|
+
mobileTrigger: "text-white/70 hover:text-primary-400 hover:bg-white/8",
|
|
4862
|
+
mobileDrawer: "bg-primary-900 border-t border-white/10",
|
|
4863
|
+
mobileLink: "text-white hover:text-primary-400 border-b border-white/10",
|
|
4864
|
+
mobileSub: "text-white/70 font-bold hover:text-primary-400 border-b border-white/8",
|
|
4865
|
+
mobileLangActive: "text-primary-400 font-semibold",
|
|
4866
|
+
mobileLangIdle: "text-white/40 hover:text-primary-400",
|
|
4867
|
+
logoBlend: "mix-blend-screen"
|
|
4868
|
+
},
|
|
4869
|
+
white: {
|
|
4870
|
+
header: "bg-white border-b border-border shadow-sm",
|
|
4871
|
+
navItem: "text-foreground/70 hover:text-foreground",
|
|
4872
|
+
navItemOpen: "text-foreground bg-muted",
|
|
4873
|
+
chevron: "text-foreground/35",
|
|
4874
|
+
lang: "text-foreground/60 hover:text-foreground",
|
|
4875
|
+
langOpen: "text-foreground bg-muted",
|
|
4876
|
+
langChevron: "text-foreground/30",
|
|
4877
|
+
icon: "text-foreground/50 hover:text-foreground hover:bg-muted",
|
|
4878
|
+
mobileTrigger: "text-foreground/50 hover:text-foreground hover:bg-muted",
|
|
4879
|
+
mobileDrawer: "bg-white border-t border-border",
|
|
4880
|
+
mobileLink: "text-foreground/80 hover:text-foreground border-b border-border",
|
|
4881
|
+
mobileSub: "text-foreground/50 font-bold hover:text-foreground border-b border-border/40",
|
|
4882
|
+
mobileLangActive: "text-primary font-semibold",
|
|
4883
|
+
mobileLangIdle: "text-muted-foreground hover:text-foreground",
|
|
4884
|
+
logoBlend: "invert mix-blend-multiply"
|
|
4885
|
+
},
|
|
4886
|
+
dark: {
|
|
4887
|
+
header: "bg-neutral-950 border-b border-white/10",
|
|
4888
|
+
navItem: "text-white/70 hover:text-white",
|
|
4889
|
+
navItemOpen: "text-white bg-white/10",
|
|
4890
|
+
chevron: "text-white/40",
|
|
4891
|
+
lang: "text-white/60 hover:text-white",
|
|
4892
|
+
langOpen: "text-white bg-white/10",
|
|
4893
|
+
langChevron: "text-white/30",
|
|
4894
|
+
icon: "text-white/50 hover:text-white hover:bg-white/10",
|
|
4895
|
+
mobileTrigger: "text-white/50 hover:text-white hover:bg-white/10",
|
|
4896
|
+
mobileDrawer: "bg-neutral-950 border-t border-white/10",
|
|
4897
|
+
mobileLink: "text-white/80 hover:text-white border-b border-white/8",
|
|
4898
|
+
mobileSub: "text-white/45 font-bold hover:text-white border-b border-white/5",
|
|
4899
|
+
mobileLangActive: "text-white font-semibold",
|
|
4900
|
+
mobileLangIdle: "text-white/35 hover:text-white/60",
|
|
4901
|
+
logoBlend: "mix-blend-screen"
|
|
4902
|
+
}
|
|
4903
|
+
};
|
|
4904
|
+
var DEFAULT_HEADER_LINKS = [
|
|
4905
|
+
{ label: "All trips", href: "#" },
|
|
4906
|
+
{
|
|
4907
|
+
label: "Destinations",
|
|
4908
|
+
items: [
|
|
4909
|
+
{ label: "Europe", href: "#" },
|
|
4910
|
+
{ label: "South America", href: "#" },
|
|
4911
|
+
{ label: "Africa", href: "#" },
|
|
4912
|
+
{ label: "Asia", href: "#" },
|
|
4913
|
+
{ label: "North America", href: "#" },
|
|
4914
|
+
{ label: "Oceania", href: "#" }
|
|
4915
|
+
]
|
|
4916
|
+
},
|
|
4917
|
+
{
|
|
4918
|
+
label: "Travel themes",
|
|
4919
|
+
items: [
|
|
4920
|
+
{ label: "Adventure", href: "#" },
|
|
4921
|
+
{ label: "Cultural", href: "#" },
|
|
4922
|
+
{ label: "Wildlife", href: "#" },
|
|
4923
|
+
{ label: "Beach & Coast", href: "#" },
|
|
4924
|
+
{ label: "Trekking", href: "#" }
|
|
4925
|
+
]
|
|
4926
|
+
},
|
|
4927
|
+
{
|
|
4928
|
+
label: "About",
|
|
4929
|
+
items: [
|
|
4930
|
+
{ label: "About us", href: "#" },
|
|
4931
|
+
{ label: "Sustainability", href: "#" },
|
|
4932
|
+
{ label: "Jobs", href: "#" },
|
|
4933
|
+
{ label: "FAQ", href: "#" },
|
|
4934
|
+
{ label: "Contact", href: "#" },
|
|
4935
|
+
{ label: "Gift Card", href: "#" }
|
|
4936
|
+
]
|
|
4937
|
+
},
|
|
4938
|
+
{ label: "Blog", href: "#" }
|
|
4939
|
+
];
|
|
4940
|
+
var DEFAULT_LANGUAGES = [
|
|
4941
|
+
{ code: "EN", label: "English" },
|
|
4942
|
+
{ code: "PT", label: "Portugu\xEAs" },
|
|
4943
|
+
{ code: "NL", label: "Nederlands" },
|
|
4944
|
+
{ code: "DE", label: "Deutsch" },
|
|
4945
|
+
{ code: "FR", label: "Fran\xE7ais" },
|
|
4946
|
+
{ code: "ES", label: "Espa\xF1ol" }
|
|
4947
|
+
];
|
|
4948
|
+
function NavDropdown({
|
|
4949
|
+
items,
|
|
4950
|
+
onClose,
|
|
4951
|
+
onMouseEnter,
|
|
4952
|
+
onMouseLeave
|
|
4953
|
+
}) {
|
|
4954
|
+
return /* @__PURE__ */ jsx(
|
|
4955
|
+
"div",
|
|
4956
|
+
{
|
|
4957
|
+
className: "absolute top-[calc(100%+8px)] left-0 min-w-[200px] rounded-xl bg-white shadow-2xl border border-black/8 py-1.5 z-50",
|
|
4958
|
+
onMouseEnter,
|
|
4959
|
+
onMouseLeave,
|
|
4960
|
+
children: items.map((item) => {
|
|
4961
|
+
var _a;
|
|
4962
|
+
return /* @__PURE__ */ jsx(
|
|
4963
|
+
"a",
|
|
4964
|
+
{
|
|
4965
|
+
href: (_a = item.href) != null ? _a : "#",
|
|
4966
|
+
onClick: onClose,
|
|
4967
|
+
className: "block px-5 py-2.5 text-sm text-foreground/75 font-ui font-bold hover:text-foreground hover:bg-muted transition-colors whitespace-nowrap",
|
|
4968
|
+
children: item.label
|
|
4969
|
+
},
|
|
4970
|
+
item.label
|
|
4971
|
+
);
|
|
4972
|
+
})
|
|
4973
|
+
}
|
|
4974
|
+
);
|
|
4975
|
+
}
|
|
4976
|
+
function LangDropdown({
|
|
4977
|
+
languages,
|
|
4978
|
+
activeLang,
|
|
4979
|
+
onSelect,
|
|
4980
|
+
onMouseEnter,
|
|
4981
|
+
onMouseLeave
|
|
4982
|
+
}) {
|
|
4983
|
+
return /* @__PURE__ */ jsx(
|
|
4984
|
+
"div",
|
|
4985
|
+
{
|
|
4986
|
+
className: "absolute top-[calc(100%+8px)] right-0 min-w-[160px] rounded-xl bg-white shadow-2xl border border-black/8 py-1.5 z-50",
|
|
4987
|
+
onMouseEnter,
|
|
4988
|
+
onMouseLeave,
|
|
4989
|
+
children: languages.map((lang) => /* @__PURE__ */ jsxs(
|
|
4990
|
+
"button",
|
|
4991
|
+
{
|
|
4992
|
+
type: "button",
|
|
4993
|
+
onClick: () => onSelect(lang.code),
|
|
4994
|
+
className: cn(
|
|
4995
|
+
"flex items-center gap-3 w-full px-5 py-2.5 text-sm font-ui text-left transition-colors hover:bg-muted",
|
|
4996
|
+
lang.code === activeLang ? "text-primary font-semibold" : "text-foreground"
|
|
4997
|
+
),
|
|
4998
|
+
children: [
|
|
4999
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold w-8 shrink-0", children: lang.code }),
|
|
5000
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: lang.label })
|
|
5001
|
+
]
|
|
5002
|
+
},
|
|
5003
|
+
lang.code
|
|
5004
|
+
))
|
|
5005
|
+
}
|
|
5006
|
+
);
|
|
5007
|
+
}
|
|
5008
|
+
function SiteHeader({
|
|
5009
|
+
variant = "transparent",
|
|
5010
|
+
links = DEFAULT_HEADER_LINKS,
|
|
5011
|
+
logoSrc = "/logo-planetaexo.png",
|
|
5012
|
+
logoAlt = "Planeta Exo",
|
|
5013
|
+
languages = DEFAULT_LANGUAGES,
|
|
5014
|
+
currentLanguage = "EN",
|
|
5015
|
+
onLanguageChange,
|
|
5016
|
+
onSearch,
|
|
5017
|
+
onAccount,
|
|
5018
|
+
position = variant === "transparent" ? "overlay" : "fixed",
|
|
5019
|
+
className
|
|
5020
|
+
}) {
|
|
5021
|
+
const t = VARIANT[variant];
|
|
5022
|
+
const [openMenu, setOpenMenu] = React18.useState(null);
|
|
5023
|
+
const [langOpen, setLangOpen] = React18.useState(false);
|
|
5024
|
+
const [mobileOpen, setMobileOpen] = React18.useState(false);
|
|
5025
|
+
const [openMobileSection, setOpenMobileSection] = React18.useState(null);
|
|
5026
|
+
const [activeLang, setActiveLang] = React18.useState(currentLanguage);
|
|
5027
|
+
const toggleMobileSection = (label) => setOpenMobileSection((prev) => prev === label ? null : label);
|
|
5028
|
+
const menuCloseTimer = React18.useRef(void 0);
|
|
5029
|
+
const langCloseTimer = React18.useRef(void 0);
|
|
5030
|
+
const handleMenuEnter = (label) => {
|
|
5031
|
+
clearTimeout(menuCloseTimer.current);
|
|
5032
|
+
setOpenMenu(label);
|
|
5033
|
+
};
|
|
5034
|
+
const handleMenuLeave = () => {
|
|
5035
|
+
menuCloseTimer.current = setTimeout(() => setOpenMenu(null), 120);
|
|
5036
|
+
};
|
|
5037
|
+
const handleLangEnter = () => {
|
|
5038
|
+
clearTimeout(langCloseTimer.current);
|
|
5039
|
+
setLangOpen(true);
|
|
5040
|
+
};
|
|
5041
|
+
const handleLangLeave = () => {
|
|
5042
|
+
langCloseTimer.current = setTimeout(() => setLangOpen(false), 120);
|
|
5043
|
+
};
|
|
5044
|
+
const closeAll = () => {
|
|
5045
|
+
clearTimeout(menuCloseTimer.current);
|
|
5046
|
+
clearTimeout(langCloseTimer.current);
|
|
5047
|
+
setOpenMenu(null);
|
|
5048
|
+
setLangOpen(false);
|
|
5049
|
+
};
|
|
5050
|
+
React18.useEffect(() => () => {
|
|
5051
|
+
clearTimeout(menuCloseTimer.current);
|
|
5052
|
+
clearTimeout(langCloseTimer.current);
|
|
5053
|
+
}, []);
|
|
5054
|
+
const handleLangSelect = (code) => {
|
|
5055
|
+
setActiveLang(code);
|
|
5056
|
+
onLanguageChange == null ? void 0 : onLanguageChange(code);
|
|
5057
|
+
setLangOpen(false);
|
|
5058
|
+
};
|
|
5059
|
+
const positionClass = position === "overlay" ? "absolute" : position === "fixed" ? "fixed" : "relative";
|
|
5060
|
+
return /* @__PURE__ */ jsxs(
|
|
5061
|
+
"header",
|
|
5062
|
+
{
|
|
5063
|
+
className: cn(
|
|
5064
|
+
positionClass,
|
|
5065
|
+
"top-0 left-0 right-0 z-40",
|
|
5066
|
+
t.header,
|
|
5067
|
+
className
|
|
5068
|
+
),
|
|
5069
|
+
children: [
|
|
5070
|
+
variant === "transparent" && /* @__PURE__ */ jsx("div", { className: "absolute inset-x-0 top-0 h-52 bg-gradient-to-b from-black/55 via-black/20 to-transparent pointer-events-none" }),
|
|
5071
|
+
/* @__PURE__ */ jsxs("div", { className: "relative flex items-center gap-2 px-6 sm:px-10 h-[72px]", children: [
|
|
5072
|
+
/* @__PURE__ */ jsx("a", { href: "#", className: "shrink-0 flex items-center mr-4", children: /* @__PURE__ */ jsx(
|
|
5073
|
+
"img",
|
|
5074
|
+
{
|
|
5075
|
+
src: logoSrc,
|
|
5076
|
+
alt: logoAlt,
|
|
5077
|
+
className: cn("h-11 w-auto select-none", t.logoBlend),
|
|
5078
|
+
draggable: false
|
|
5079
|
+
}
|
|
5080
|
+
) }),
|
|
5081
|
+
/* @__PURE__ */ jsx("nav", { className: "hidden lg:flex items-center gap-0.5 mx-auto", children: links.map((link) => {
|
|
5082
|
+
var _a, _b;
|
|
5083
|
+
const hasDropdown = !!((_a = link.items) == null ? void 0 : _a.length);
|
|
5084
|
+
const isOpen = openMenu === link.label;
|
|
5085
|
+
return /* @__PURE__ */ jsxs(
|
|
5086
|
+
"div",
|
|
5087
|
+
{
|
|
5088
|
+
className: "relative",
|
|
5089
|
+
onMouseEnter: () => hasDropdown && handleMenuEnter(link.label),
|
|
5090
|
+
onMouseLeave: handleMenuLeave,
|
|
5091
|
+
children: [
|
|
5092
|
+
/* @__PURE__ */ jsxs(
|
|
5093
|
+
"a",
|
|
5094
|
+
{
|
|
5095
|
+
href: (_b = link.href) != null ? _b : "#",
|
|
5096
|
+
onClick: hasDropdown ? (e) => e.preventDefault() : void 0,
|
|
5097
|
+
className: cn(
|
|
5098
|
+
"flex items-center gap-1 px-3.5 py-1.5 rounded-full",
|
|
5099
|
+
"text-base font-ui font-black transition-colors whitespace-nowrap",
|
|
5100
|
+
t.navItem,
|
|
5101
|
+
isOpen && t.navItemOpen
|
|
5102
|
+
),
|
|
5103
|
+
children: [
|
|
5104
|
+
link.label,
|
|
5105
|
+
hasDropdown && /* @__PURE__ */ jsx(
|
|
5106
|
+
ChevronDownIcon,
|
|
5107
|
+
{
|
|
5108
|
+
className: cn(
|
|
5109
|
+
"h-3.5 w-3.5 transition-transform duration-150 shrink-0",
|
|
5110
|
+
t.chevron,
|
|
5111
|
+
isOpen && "rotate-180"
|
|
5112
|
+
)
|
|
5113
|
+
}
|
|
5114
|
+
)
|
|
5115
|
+
]
|
|
5116
|
+
}
|
|
5117
|
+
),
|
|
5118
|
+
isOpen && link.items && /* @__PURE__ */ jsx(
|
|
5119
|
+
NavDropdown,
|
|
5120
|
+
{
|
|
5121
|
+
items: link.items,
|
|
5122
|
+
onClose: closeAll,
|
|
5123
|
+
onMouseEnter: () => handleMenuEnter(link.label),
|
|
5124
|
+
onMouseLeave: handleMenuLeave
|
|
5125
|
+
}
|
|
5126
|
+
)
|
|
5127
|
+
]
|
|
5128
|
+
},
|
|
5129
|
+
link.label
|
|
5130
|
+
);
|
|
5131
|
+
}) }),
|
|
5132
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1 ml-auto lg:ml-0 shrink-0", children: [
|
|
5133
|
+
languages.length > 0 && /* @__PURE__ */ jsxs(
|
|
5134
|
+
"div",
|
|
5135
|
+
{
|
|
5136
|
+
className: "relative hidden lg:block",
|
|
5137
|
+
onMouseEnter: handleLangEnter,
|
|
5138
|
+
onMouseLeave: handleLangLeave,
|
|
5139
|
+
children: [
|
|
5140
|
+
/* @__PURE__ */ jsxs(
|
|
5141
|
+
"button",
|
|
5142
|
+
{
|
|
5143
|
+
type: "button",
|
|
5144
|
+
"aria-label": "Language",
|
|
5145
|
+
className: cn(
|
|
5146
|
+
"flex items-center gap-0.5 px-2.5 py-1.5 rounded-full",
|
|
5147
|
+
"text-sm font-ui transition-colors",
|
|
5148
|
+
t.lang,
|
|
5149
|
+
langOpen && t.langOpen
|
|
5150
|
+
),
|
|
5151
|
+
children: [
|
|
5152
|
+
activeLang,
|
|
5153
|
+
/* @__PURE__ */ jsx(
|
|
5154
|
+
ChevronDownIcon,
|
|
5155
|
+
{
|
|
5156
|
+
className: cn(
|
|
5157
|
+
"h-3 w-3 transition-transform duration-150",
|
|
5158
|
+
t.langChevron,
|
|
5159
|
+
langOpen && "rotate-180"
|
|
5160
|
+
)
|
|
5161
|
+
}
|
|
5162
|
+
)
|
|
5163
|
+
]
|
|
5164
|
+
}
|
|
5165
|
+
),
|
|
5166
|
+
langOpen && /* @__PURE__ */ jsx(
|
|
5167
|
+
LangDropdown,
|
|
5168
|
+
{
|
|
5169
|
+
languages,
|
|
5170
|
+
activeLang,
|
|
5171
|
+
onSelect: handleLangSelect,
|
|
5172
|
+
onMouseEnter: handleLangEnter,
|
|
5173
|
+
onMouseLeave: handleLangLeave
|
|
5174
|
+
}
|
|
5175
|
+
)
|
|
5176
|
+
]
|
|
5177
|
+
}
|
|
5178
|
+
),
|
|
5179
|
+
/* @__PURE__ */ jsx(
|
|
5180
|
+
"button",
|
|
5181
|
+
{
|
|
5182
|
+
type: "button",
|
|
5183
|
+
onClick: onSearch,
|
|
5184
|
+
"aria-label": "Search",
|
|
5185
|
+
className: cn(
|
|
5186
|
+
"flex h-9 w-9 items-center justify-center rounded-full transition-colors",
|
|
5187
|
+
t.icon
|
|
5188
|
+
),
|
|
5189
|
+
children: /* @__PURE__ */ jsx(SearchIcon, { className: "h-[18px] w-[18px]" })
|
|
5190
|
+
}
|
|
5191
|
+
),
|
|
5192
|
+
/* @__PURE__ */ jsx(
|
|
5193
|
+
"button",
|
|
5194
|
+
{
|
|
5195
|
+
type: "button",
|
|
5196
|
+
onClick: onAccount,
|
|
5197
|
+
"aria-label": "Account",
|
|
5198
|
+
className: cn(
|
|
5199
|
+
"flex h-9 w-9 items-center justify-center rounded-full transition-colors",
|
|
5200
|
+
t.icon
|
|
5201
|
+
),
|
|
5202
|
+
children: /* @__PURE__ */ jsx(UserIcon, { className: "h-[18px] w-[18px]" })
|
|
5203
|
+
}
|
|
5204
|
+
),
|
|
5205
|
+
/* @__PURE__ */ jsx(
|
|
5206
|
+
"button",
|
|
5207
|
+
{
|
|
5208
|
+
type: "button",
|
|
5209
|
+
onClick: () => setMobileOpen(true),
|
|
5210
|
+
"aria-label": "Open menu",
|
|
5211
|
+
className: cn(
|
|
5212
|
+
"flex lg:hidden h-9 w-9 items-center justify-center rounded-full transition-colors ml-0.5",
|
|
5213
|
+
t.mobileTrigger
|
|
5214
|
+
),
|
|
5215
|
+
children: /* @__PURE__ */ jsx(MenuIcon, { className: "h-[18px] w-[18px]" })
|
|
5216
|
+
}
|
|
5217
|
+
)
|
|
5218
|
+
] })
|
|
5219
|
+
] }),
|
|
5220
|
+
mobileOpen && /* @__PURE__ */ jsxs(
|
|
5221
|
+
"div",
|
|
5222
|
+
{
|
|
5223
|
+
className: cn(
|
|
5224
|
+
"fixed inset-0 z-50 lg:hidden flex flex-col",
|
|
5225
|
+
variant === "white" ? "bg-white" : "bg-primary-900"
|
|
5226
|
+
),
|
|
5227
|
+
children: [
|
|
5228
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between px-6 h-[72px] shrink-0 border-b border-white/8", children: [
|
|
5229
|
+
/* @__PURE__ */ jsx("a", { href: "#", className: "shrink-0 flex items-center", onClick: () => setMobileOpen(false), children: /* @__PURE__ */ jsx(
|
|
5230
|
+
"img",
|
|
5231
|
+
{
|
|
5232
|
+
src: logoSrc,
|
|
5233
|
+
alt: logoAlt,
|
|
5234
|
+
className: cn("h-11 w-auto select-none", t.logoBlend),
|
|
5235
|
+
draggable: false
|
|
5236
|
+
}
|
|
5237
|
+
) }),
|
|
5238
|
+
/* @__PURE__ */ jsx(
|
|
5239
|
+
"button",
|
|
5240
|
+
{
|
|
5241
|
+
type: "button",
|
|
5242
|
+
onClick: () => setMobileOpen(false),
|
|
5243
|
+
"aria-label": "Close menu",
|
|
5244
|
+
className: cn(
|
|
5245
|
+
"flex h-9 w-9 items-center justify-center rounded-full transition-colors",
|
|
5246
|
+
t.mobileTrigger
|
|
5247
|
+
),
|
|
5248
|
+
children: /* @__PURE__ */ jsx(XIcon, { className: "h-5 w-5" })
|
|
5249
|
+
}
|
|
5250
|
+
)
|
|
5251
|
+
] }),
|
|
5252
|
+
/* @__PURE__ */ jsx("nav", { className: "flex-1 overflow-y-auto px-6 py-6 flex flex-col gap-1", children: links.map((link) => {
|
|
5253
|
+
var _a, _b;
|
|
5254
|
+
const hasDropdown = !!((_a = link.items) == null ? void 0 : _a.length);
|
|
5255
|
+
const isExpanded = openMobileSection === link.label;
|
|
5256
|
+
return /* @__PURE__ */ jsxs("div", { children: [
|
|
5257
|
+
hasDropdown ? /* @__PURE__ */ jsxs(
|
|
5258
|
+
"button",
|
|
5259
|
+
{
|
|
5260
|
+
type: "button",
|
|
5261
|
+
onClick: () => toggleMobileSection(link.label),
|
|
5262
|
+
className: cn(
|
|
5263
|
+
"flex items-center justify-between w-full py-4 text-xl font-ui font-black transition-colors border-b border-white/8",
|
|
5264
|
+
t.mobileLink
|
|
5265
|
+
),
|
|
5266
|
+
children: [
|
|
5267
|
+
link.label,
|
|
5268
|
+
/* @__PURE__ */ jsx(
|
|
5269
|
+
ChevronDownIcon,
|
|
5270
|
+
{
|
|
5271
|
+
className: cn(
|
|
5272
|
+
"h-5 w-5 transition-transform duration-200 opacity-40",
|
|
5273
|
+
isExpanded && "rotate-180"
|
|
5274
|
+
)
|
|
5275
|
+
}
|
|
5276
|
+
)
|
|
5277
|
+
]
|
|
5278
|
+
}
|
|
5279
|
+
) : /* @__PURE__ */ jsx(
|
|
5280
|
+
"a",
|
|
5281
|
+
{
|
|
5282
|
+
href: (_b = link.href) != null ? _b : "#",
|
|
5283
|
+
onClick: () => setMobileOpen(false),
|
|
5284
|
+
className: cn(
|
|
5285
|
+
"flex items-center py-4 text-xl font-ui font-black transition-colors border-b border-white/8",
|
|
5286
|
+
t.mobileLink
|
|
5287
|
+
),
|
|
5288
|
+
children: link.label
|
|
5289
|
+
}
|
|
5290
|
+
),
|
|
5291
|
+
hasDropdown && isExpanded && /* @__PURE__ */ jsx("div", { className: "flex flex-col gap-0 pl-4 pb-2", children: link.items.map((item) => {
|
|
5292
|
+
var _a2;
|
|
5293
|
+
return /* @__PURE__ */ jsx(
|
|
5294
|
+
"a",
|
|
5295
|
+
{
|
|
5296
|
+
href: (_a2 = item.href) != null ? _a2 : "#",
|
|
5297
|
+
onClick: () => setMobileOpen(false),
|
|
5298
|
+
className: cn(
|
|
5299
|
+
"py-3 text-base font-ui font-bold transition-colors border-b",
|
|
5300
|
+
t.mobileSub
|
|
5301
|
+
),
|
|
5302
|
+
children: item.label
|
|
5303
|
+
},
|
|
5304
|
+
item.label
|
|
5305
|
+
);
|
|
5306
|
+
}) })
|
|
5307
|
+
] }, link.label);
|
|
5308
|
+
}) }),
|
|
5309
|
+
/* @__PURE__ */ jsxs("div", { className: cn(
|
|
5310
|
+
"shrink-0 px-6 py-5 flex items-center justify-between border-t",
|
|
5311
|
+
variant === "white" ? "border-border" : "border-white/10"
|
|
5312
|
+
), children: [
|
|
5313
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: languages.map((lang, i) => {
|
|
5314
|
+
const isActive = lang.code === activeLang;
|
|
5315
|
+
return /* @__PURE__ */ jsxs(React18.Fragment, { children: [
|
|
5316
|
+
i > 0 && /* @__PURE__ */ jsx("span", { className: cn(
|
|
5317
|
+
"text-xs select-none",
|
|
5318
|
+
variant === "white" ? "text-border" : "text-white/15"
|
|
5319
|
+
), children: "\xB7" }),
|
|
5320
|
+
/* @__PURE__ */ jsx(
|
|
5321
|
+
"button",
|
|
5322
|
+
{
|
|
5323
|
+
type: "button",
|
|
5324
|
+
onClick: () => handleLangSelect(lang.code),
|
|
5325
|
+
className: cn(
|
|
5326
|
+
"font-ui font-black transition-all duration-150 rounded-full",
|
|
5327
|
+
isActive ? cn(
|
|
5328
|
+
"text-sm px-3 py-1 border",
|
|
5329
|
+
variant === "white" ? "text-primary border-primary bg-primary/8" : "text-primary-400 border-primary-400/50 bg-primary-400/10"
|
|
5330
|
+
) : cn(
|
|
5331
|
+
"text-xs px-2 py-1",
|
|
5332
|
+
variant === "white" ? "text-muted-foreground hover:text-foreground" : "text-white/35 hover:text-white/70"
|
|
5333
|
+
)
|
|
5334
|
+
),
|
|
5335
|
+
children: lang.code
|
|
5336
|
+
}
|
|
5337
|
+
)
|
|
5338
|
+
] }, lang.code);
|
|
5339
|
+
}) }),
|
|
5340
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
5341
|
+
/* @__PURE__ */ jsx(
|
|
5342
|
+
"button",
|
|
5343
|
+
{
|
|
5344
|
+
type: "button",
|
|
5345
|
+
onClick: () => {
|
|
5346
|
+
onSearch == null ? void 0 : onSearch();
|
|
5347
|
+
setMobileOpen(false);
|
|
5348
|
+
},
|
|
5349
|
+
"aria-label": "Search",
|
|
5350
|
+
className: cn("flex h-9 w-9 items-center justify-center rounded-full transition-colors", t.icon),
|
|
5351
|
+
children: /* @__PURE__ */ jsx(SearchIcon, { className: "h-[18px] w-[18px]" })
|
|
5352
|
+
}
|
|
5353
|
+
),
|
|
5354
|
+
/* @__PURE__ */ jsx(
|
|
5355
|
+
"button",
|
|
5356
|
+
{
|
|
5357
|
+
type: "button",
|
|
5358
|
+
onClick: () => {
|
|
5359
|
+
onAccount == null ? void 0 : onAccount();
|
|
5360
|
+
setMobileOpen(false);
|
|
5361
|
+
},
|
|
5362
|
+
"aria-label": "Account",
|
|
5363
|
+
className: cn("flex h-9 w-9 items-center justify-center rounded-full transition-colors", t.icon),
|
|
5364
|
+
children: /* @__PURE__ */ jsx(UserIcon, { className: "h-[18px] w-[18px]" })
|
|
5365
|
+
}
|
|
5366
|
+
)
|
|
5367
|
+
] })
|
|
5368
|
+
] })
|
|
5369
|
+
]
|
|
5370
|
+
}
|
|
5371
|
+
)
|
|
5372
|
+
]
|
|
5373
|
+
}
|
|
5374
|
+
);
|
|
5375
|
+
}
|
|
5376
|
+
function ThemeToggle({ className }) {
|
|
5377
|
+
const [dark, setDark] = React18.useState(false);
|
|
5378
|
+
React18.useEffect(() => {
|
|
5379
|
+
const saved = localStorage.getItem("theme");
|
|
5380
|
+
const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
|
|
5381
|
+
const isDark = saved === "dark" || !saved && prefersDark;
|
|
5382
|
+
setDark(isDark);
|
|
5383
|
+
document.documentElement.classList.toggle("dark", isDark);
|
|
5384
|
+
}, []);
|
|
5385
|
+
const toggle = () => {
|
|
5386
|
+
const next = !dark;
|
|
5387
|
+
setDark(next);
|
|
5388
|
+
document.documentElement.classList.toggle("dark", next);
|
|
5389
|
+
localStorage.setItem("theme", next ? "dark" : "light");
|
|
5390
|
+
};
|
|
5391
|
+
return /* @__PURE__ */ jsx(
|
|
5392
|
+
"button",
|
|
5393
|
+
{
|
|
5394
|
+
type: "button",
|
|
5395
|
+
onClick: toggle,
|
|
5396
|
+
"aria-label": dark ? "Switch to light mode" : "Switch to dark mode",
|
|
5397
|
+
className: cn(
|
|
5398
|
+
"flex h-8 w-8 items-center justify-center rounded-md",
|
|
5399
|
+
"bg-card border border-border text-muted-foreground shadow-sm",
|
|
5400
|
+
"hover:text-foreground hover:bg-muted transition-colors",
|
|
5401
|
+
className
|
|
5402
|
+
),
|
|
5403
|
+
children: dark ? /* @__PURE__ */ jsx(SunIcon, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(MoonIcon, { className: "h-4 w-4" })
|
|
5404
|
+
}
|
|
5405
|
+
);
|
|
5406
|
+
}
|
|
5407
|
+
function CalendarIcon5() {
|
|
5408
|
+
return /* @__PURE__ */ jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
5409
|
+
/* @__PURE__ */ jsx("rect", { x: "3", y: "4", width: "18", height: "18", rx: "2" }),
|
|
5410
|
+
/* @__PURE__ */ jsx("line", { x1: "16", y1: "2", x2: "16", y2: "6" }),
|
|
5411
|
+
/* @__PURE__ */ jsx("line", { x1: "8", y1: "2", x2: "8", y2: "6" }),
|
|
5412
|
+
/* @__PURE__ */ jsx("line", { x1: "3", y1: "10", x2: "21", y2: "10" })
|
|
5413
|
+
] });
|
|
5414
|
+
}
|
|
5415
|
+
function TrendingIcon() {
|
|
5416
|
+
return /* @__PURE__ */ jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
5417
|
+
/* @__PURE__ */ jsx("polyline", { points: "23 6 13.5 15.5 8.5 10.5 1 18" }),
|
|
5418
|
+
/* @__PURE__ */ jsx("polyline", { points: "17 6 23 6 23 12" })
|
|
5419
|
+
] });
|
|
5420
|
+
}
|
|
5421
|
+
function ArrowIcon() {
|
|
5422
|
+
return /* @__PURE__ */ jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
5423
|
+
/* @__PURE__ */ jsx("line", { x1: "5", y1: "12", x2: "19", y2: "12" }),
|
|
5424
|
+
/* @__PURE__ */ jsx("polyline", { points: "12 5 19 12 12 19" })
|
|
5425
|
+
] });
|
|
5426
|
+
}
|
|
5427
|
+
var sizeConfig = {
|
|
5428
|
+
sm: {
|
|
5429
|
+
card: "h-72 w-56",
|
|
5430
|
+
title: "text-lg font-bold",
|
|
5431
|
+
meta: "text-xs",
|
|
5432
|
+
description: "text-xs"
|
|
5433
|
+
},
|
|
5434
|
+
md: {
|
|
5435
|
+
card: "h-96 w-72",
|
|
5436
|
+
title: "text-xl font-bold",
|
|
5437
|
+
meta: "text-xs",
|
|
5438
|
+
description: "text-sm"
|
|
5439
|
+
},
|
|
5440
|
+
lg: {
|
|
5441
|
+
card: "h-[28rem] w-96",
|
|
5442
|
+
title: "text-2xl font-bold",
|
|
5443
|
+
meta: "text-sm",
|
|
5444
|
+
description: "text-sm"
|
|
5445
|
+
}
|
|
5446
|
+
};
|
|
5447
|
+
var statusConfig = {
|
|
5448
|
+
"sold-out": {
|
|
5449
|
+
label: "All seats taken",
|
|
5450
|
+
icon: /* @__PURE__ */ jsx(CalendarIcon5, {})
|
|
5451
|
+
},
|
|
5452
|
+
trending: {
|
|
5453
|
+
label: "Trending",
|
|
5454
|
+
icon: /* @__PURE__ */ jsx(TrendingIcon, {})
|
|
5455
|
+
}
|
|
5456
|
+
};
|
|
5457
|
+
function TripCard({
|
|
5458
|
+
image,
|
|
5459
|
+
imageAlt = "",
|
|
5460
|
+
status,
|
|
5461
|
+
nights,
|
|
5462
|
+
period,
|
|
5463
|
+
title,
|
|
5464
|
+
description,
|
|
5465
|
+
cta,
|
|
5466
|
+
price,
|
|
5467
|
+
size = "md",
|
|
5468
|
+
className
|
|
5469
|
+
}) {
|
|
5470
|
+
const s = sizeConfig[size];
|
|
5471
|
+
const statusInfo = status ? statusConfig[status] : null;
|
|
5472
|
+
const meta = [
|
|
5473
|
+
nights ? `${nights} nights` : null,
|
|
5474
|
+
period != null ? period : null
|
|
5475
|
+
].filter(Boolean).join(" | ");
|
|
5476
|
+
return /* @__PURE__ */ jsxs(
|
|
5477
|
+
"div",
|
|
5478
|
+
{
|
|
5479
|
+
className: cn(
|
|
5480
|
+
"group relative flex flex-col justify-between overflow-hidden rounded-2xl",
|
|
5481
|
+
"shadow-md transition-shadow duration-300 hover:shadow-xl",
|
|
5482
|
+
s.card,
|
|
5483
|
+
className
|
|
5484
|
+
),
|
|
5485
|
+
children: [
|
|
5486
|
+
/* @__PURE__ */ jsx(
|
|
5487
|
+
"img",
|
|
5488
|
+
{
|
|
5489
|
+
src: image,
|
|
5490
|
+
alt: imageAlt,
|
|
5491
|
+
className: "absolute inset-0 h-full w-full object-cover transition-transform duration-500 group-hover:scale-105"
|
|
5492
|
+
}
|
|
5493
|
+
),
|
|
5494
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/80 via-black/30 to-transparent" }),
|
|
5495
|
+
statusInfo && /* @__PURE__ */ jsx("div", { className: "relative z-10 p-3", children: /* @__PURE__ */ jsxs("div", { className: "inline-flex items-center gap-1.5 rounded-xl bg-card/90 px-3 py-1.5 backdrop-blur-sm shadow-sm", children: [
|
|
5496
|
+
/* @__PURE__ */ jsx("span", { className: "text-primary", children: statusInfo.icon }),
|
|
5497
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-semibold text-foreground font-ui", children: statusInfo.label })
|
|
5498
|
+
] }) }),
|
|
5499
|
+
!statusInfo && /* @__PURE__ */ jsx("div", { className: "relative z-10" }),
|
|
5500
|
+
/* @__PURE__ */ jsxs("div", { className: "relative z-10 flex flex-col gap-1.5 p-5", children: [
|
|
5501
|
+
meta && /* @__PURE__ */ jsx("p", { className: cn("text-white/70 font-medium font-ui", s.meta), children: meta }),
|
|
5502
|
+
/* @__PURE__ */ jsx("h3", { className: cn("text-white leading-snug", s.title), children: title }),
|
|
5503
|
+
description && /* @__PURE__ */ jsx("p", { className: cn("text-white/80 leading-relaxed mt-0.5", s.description), children: description }),
|
|
5504
|
+
(cta || price) && /* @__PURE__ */ jsxs("div", { className: "mt-3 flex items-center justify-between gap-4", children: [
|
|
5505
|
+
cta && /* @__PURE__ */ jsxs(
|
|
5506
|
+
"button",
|
|
5507
|
+
{
|
|
5508
|
+
onClick: cta.onClick,
|
|
5509
|
+
className: cn(
|
|
5510
|
+
"group/cta inline-flex items-center gap-1.5 border-b border-white/70 pb-0.5",
|
|
5511
|
+
"text-sm font-semibold text-white transition-colors hover:border-white hover:text-white",
|
|
5512
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/50",
|
|
5513
|
+
"font-ui"
|
|
5514
|
+
),
|
|
5515
|
+
children: [
|
|
5516
|
+
cta.label,
|
|
5517
|
+
/* @__PURE__ */ jsx("span", { className: "transition-transform duration-150 group-hover/cta:translate-x-0.5", children: /* @__PURE__ */ jsx(ArrowIcon, {}) })
|
|
5518
|
+
]
|
|
5519
|
+
}
|
|
5520
|
+
),
|
|
5521
|
+
price && /* @__PURE__ */ jsx("p", { className: "text-sm font-semibold text-white/90 whitespace-nowrap font-ui", children: price })
|
|
5522
|
+
] })
|
|
5523
|
+
] })
|
|
5524
|
+
]
|
|
5525
|
+
}
|
|
5526
|
+
);
|
|
5527
|
+
}
|
|
5528
|
+
function useHlsVideo(videoRef, src) {
|
|
5529
|
+
React18.useEffect(() => {
|
|
5530
|
+
if (!src || !videoRef.current) return;
|
|
5531
|
+
const video = videoRef.current;
|
|
5532
|
+
if (!src.includes(".m3u8")) return;
|
|
5533
|
+
let hlsInstance = null;
|
|
5534
|
+
import('hls.js').then(({ default: Hls }) => {
|
|
5535
|
+
if (!Hls.isSupported()) {
|
|
5536
|
+
video.src = src;
|
|
5537
|
+
return;
|
|
5538
|
+
}
|
|
5539
|
+
hlsInstance = new Hls({
|
|
5540
|
+
/* Start with low-quality level to show first frame ASAP */
|
|
5541
|
+
startLevel: 0,
|
|
5542
|
+
/* Limit initial buffer to 10s — faster start */
|
|
5543
|
+
maxBufferLength: 10,
|
|
5544
|
+
maxMaxBufferLength: 30
|
|
5545
|
+
});
|
|
5546
|
+
hlsInstance.loadSource(src);
|
|
5547
|
+
hlsInstance.attachMedia(video);
|
|
5548
|
+
hlsInstance.on(Hls.Events.MANIFEST_PARSED, () => {
|
|
5549
|
+
video.play().catch(() => {
|
|
5550
|
+
});
|
|
5551
|
+
});
|
|
5552
|
+
});
|
|
5553
|
+
return () => {
|
|
5554
|
+
hlsInstance == null ? void 0 : hlsInstance.destroy();
|
|
5555
|
+
};
|
|
5556
|
+
}, [src, videoRef]);
|
|
5557
|
+
}
|
|
5558
|
+
function TripHeader({
|
|
5559
|
+
images,
|
|
5560
|
+
videoUrl,
|
|
5561
|
+
title,
|
|
5562
|
+
breadcrumb,
|
|
5563
|
+
destination,
|
|
5564
|
+
duration,
|
|
5565
|
+
tagline,
|
|
5566
|
+
siteHeader,
|
|
5567
|
+
uiVariant = "v1",
|
|
5568
|
+
className
|
|
5569
|
+
}) {
|
|
5570
|
+
var _a;
|
|
5571
|
+
const [heroIndex, setHeroIndex] = React18.useState(0);
|
|
5572
|
+
const [videoReady, setVideoReady] = React18.useState(false);
|
|
5573
|
+
const videoRef = React18.useRef(null);
|
|
5574
|
+
const isHls = !!(videoUrl == null ? void 0 : videoUrl.includes(".m3u8"));
|
|
5575
|
+
const validImages = React18.useMemo(
|
|
5576
|
+
() => images.map((u) => u == null ? void 0 : u.trim()).filter(Boolean),
|
|
5577
|
+
[images]
|
|
5578
|
+
);
|
|
5579
|
+
const hasHeroImage = validImages.length > 0;
|
|
5580
|
+
const heroSrc = (i) => {
|
|
5581
|
+
var _a2;
|
|
5582
|
+
return (_a2 = validImages[i]) != null ? _a2 : "";
|
|
5583
|
+
};
|
|
5584
|
+
const safeIndex = Math.min(heroIndex, Math.max(0, validImages.length - 1));
|
|
5585
|
+
const currentSrc = heroSrc(safeIndex);
|
|
5586
|
+
const showCarousel = !videoUrl && validImages.length > 1;
|
|
5587
|
+
const nights = duration ? (_a = duration.nights) != null ? _a : Math.max(duration.days - 1, 1) : null;
|
|
5588
|
+
const hasMeta = !!(destination || duration);
|
|
5589
|
+
useHlsVideo(videoRef, isHls ? videoUrl : void 0);
|
|
5590
|
+
React18.useEffect(() => {
|
|
5591
|
+
if (!videoUrl) return;
|
|
5592
|
+
const el = videoRef.current;
|
|
5593
|
+
if (!el) return;
|
|
5594
|
+
const observer = new IntersectionObserver(
|
|
5595
|
+
([entry]) => {
|
|
5596
|
+
if (entry.isIntersecting) {
|
|
5597
|
+
el.play().catch(() => {
|
|
5598
|
+
});
|
|
5599
|
+
} else {
|
|
5600
|
+
el.pause();
|
|
5601
|
+
}
|
|
5602
|
+
},
|
|
5603
|
+
{ threshold: 0.1 }
|
|
5604
|
+
);
|
|
5605
|
+
observer.observe(el);
|
|
5606
|
+
return () => observer.disconnect();
|
|
5607
|
+
}, [videoUrl]);
|
|
5608
|
+
return /* @__PURE__ */ jsxs(
|
|
5609
|
+
"div",
|
|
5610
|
+
{
|
|
5611
|
+
className: cn("w-full", className),
|
|
5612
|
+
"data-trip-header-variant": uiVariant,
|
|
5613
|
+
children: [
|
|
5614
|
+
/* @__PURE__ */ jsxs(
|
|
5615
|
+
"div",
|
|
5616
|
+
{
|
|
5617
|
+
className: cn(
|
|
5618
|
+
"relative w-full overflow-hidden",
|
|
5619
|
+
hasHeroImage ? "bg-muted" : "bg-zinc-900",
|
|
5620
|
+
siteHeader ? "h-[80vh] min-h-[520px]" : "h-[70vh] min-h-[420px]"
|
|
5621
|
+
),
|
|
5622
|
+
children: [
|
|
5623
|
+
!videoUrl && !hasHeroImage && /* @__PURE__ */ jsx(
|
|
5624
|
+
"div",
|
|
5625
|
+
{
|
|
5626
|
+
className: "absolute inset-0 bg-gradient-to-br from-zinc-900 via-zinc-800 to-zinc-950",
|
|
5627
|
+
"aria-hidden": true
|
|
5628
|
+
}
|
|
5629
|
+
),
|
|
5630
|
+
videoUrl ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5631
|
+
hasHeroImage ? /* @__PURE__ */ jsx(
|
|
5632
|
+
"img",
|
|
5633
|
+
{
|
|
5634
|
+
src: validImages[0],
|
|
5635
|
+
alt: "",
|
|
5636
|
+
"aria-hidden": true,
|
|
5637
|
+
fetchPriority: "high",
|
|
5638
|
+
className: cn(
|
|
5639
|
+
"absolute inset-0 h-full w-full object-cover transition-opacity duration-700",
|
|
5640
|
+
videoReady ? "opacity-0 pointer-events-none" : "opacity-100"
|
|
5641
|
+
)
|
|
5642
|
+
}
|
|
5643
|
+
) : /* @__PURE__ */ jsx(
|
|
5644
|
+
"div",
|
|
5645
|
+
{
|
|
5646
|
+
className: "absolute inset-0 bg-gradient-to-br from-zinc-900 via-zinc-800 to-zinc-950 transition-opacity duration-700",
|
|
5647
|
+
"aria-hidden": true
|
|
5648
|
+
}
|
|
5649
|
+
),
|
|
5650
|
+
/* @__PURE__ */ jsx(
|
|
5651
|
+
"video",
|
|
5652
|
+
{
|
|
5653
|
+
ref: videoRef,
|
|
5654
|
+
src: isHls ? void 0 : videoUrl,
|
|
5655
|
+
autoPlay: true,
|
|
5656
|
+
muted: true,
|
|
5657
|
+
loop: true,
|
|
5658
|
+
playsInline: true,
|
|
5659
|
+
preload: "auto",
|
|
5660
|
+
poster: hasHeroImage ? validImages[0] : void 0,
|
|
5661
|
+
onCanPlay: () => setVideoReady(true),
|
|
5662
|
+
className: cn(
|
|
5663
|
+
"absolute inset-0 h-full w-full object-cover transition-opacity duration-700",
|
|
5664
|
+
videoReady ? "opacity-100" : "opacity-0"
|
|
5665
|
+
)
|
|
5666
|
+
}
|
|
5667
|
+
)
|
|
5668
|
+
] }) : hasHeroImage ? /* @__PURE__ */ jsx(
|
|
5669
|
+
"img",
|
|
5670
|
+
{
|
|
5671
|
+
src: currentSrc,
|
|
5672
|
+
alt: title,
|
|
5673
|
+
fetchPriority: safeIndex === 0 ? "high" : "auto",
|
|
5674
|
+
className: "absolute inset-0 h-full w-full object-cover transition-opacity duration-700"
|
|
5675
|
+
}
|
|
5676
|
+
) : null,
|
|
5677
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/85 via-black/20 to-transparent" }),
|
|
5678
|
+
siteHeader && /* @__PURE__ */ jsx(
|
|
5679
|
+
SiteHeader,
|
|
5680
|
+
{
|
|
5681
|
+
links: Array.isArray(siteHeader) ? siteHeader : void 0,
|
|
5682
|
+
position: "overlay"
|
|
5683
|
+
}
|
|
5684
|
+
),
|
|
5685
|
+
!videoUrl && showCarousel && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5686
|
+
/* @__PURE__ */ jsx(
|
|
5687
|
+
"button",
|
|
5688
|
+
{
|
|
5689
|
+
type: "button",
|
|
5690
|
+
onClick: () => setHeroIndex(
|
|
5691
|
+
(i) => (i - 1 + validImages.length) % validImages.length
|
|
5692
|
+
),
|
|
5693
|
+
className: "absolute left-4 top-1/2 -translate-y-1/2 flex h-10 w-10 items-center justify-center rounded-full bg-black/30 text-white backdrop-blur-sm hover:bg-black/50 transition-colors",
|
|
5694
|
+
"aria-label": "Imagem anterior",
|
|
5695
|
+
children: /* @__PURE__ */ jsx(ChevronLeftIcon, { className: "h-5 w-5" })
|
|
5696
|
+
}
|
|
5697
|
+
),
|
|
5698
|
+
/* @__PURE__ */ jsx(
|
|
5699
|
+
"button",
|
|
5700
|
+
{
|
|
5701
|
+
type: "button",
|
|
5702
|
+
onClick: () => setHeroIndex((i) => (i + 1) % validImages.length),
|
|
5703
|
+
className: "absolute right-4 top-1/2 -translate-y-1/2 flex h-10 w-10 items-center justify-center rounded-full bg-black/30 text-white backdrop-blur-sm hover:bg-black/50 transition-colors",
|
|
5704
|
+
"aria-label": "Pr\xF3xima imagem",
|
|
5705
|
+
children: /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-5 w-5" })
|
|
5706
|
+
}
|
|
5707
|
+
),
|
|
5708
|
+
/* @__PURE__ */ jsx("div", { className: "absolute bottom-5 right-5 flex gap-1.5", children: validImages.map((_, i) => /* @__PURE__ */ jsx(
|
|
5709
|
+
"button",
|
|
5710
|
+
{
|
|
5711
|
+
type: "button",
|
|
5712
|
+
onClick: () => setHeroIndex(i),
|
|
5713
|
+
className: cn(
|
|
5714
|
+
"h-1.5 rounded-full transition-all",
|
|
5715
|
+
i === safeIndex ? "w-5 bg-white" : "w-1.5 bg-white/50"
|
|
5716
|
+
)
|
|
5717
|
+
},
|
|
5718
|
+
i
|
|
5719
|
+
)) })
|
|
5720
|
+
] })
|
|
5721
|
+
]
|
|
5722
|
+
}
|
|
5723
|
+
),
|
|
5724
|
+
/* @__PURE__ */ jsx("div", { className: "mx-auto w-full max-w-5xl px-4 sm:px-6", children: /* @__PURE__ */ jsxs(
|
|
5725
|
+
"div",
|
|
5726
|
+
{
|
|
5727
|
+
className: cn(
|
|
5728
|
+
"relative z-10 pb-10",
|
|
5729
|
+
siteHeader ? "-mt-44" : "-mt-36"
|
|
5730
|
+
),
|
|
5731
|
+
children: [
|
|
5732
|
+
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(React18.Fragment, { children: [
|
|
5733
|
+
i > 0 && /* @__PURE__ */ jsx(ChevronRightIcon, { className: "h-3 w-3 text-white/50 shrink-0" }),
|
|
5734
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-white/70 font-ui hover:text-white/90 cursor-default", children: crumb.label })
|
|
5735
|
+
] }, i)) }),
|
|
5736
|
+
/* @__PURE__ */ jsx("h1", { className: "text-3xl sm:text-5xl font-bold text-white font-heading leading-tight", children: title }),
|
|
5737
|
+
hasMeta ? /* @__PURE__ */ jsxs("div", { className: "mt-3 flex items-center gap-5 flex-wrap", children: [
|
|
5738
|
+
destination && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-white/85", children: [
|
|
5739
|
+
/* @__PURE__ */ jsx(MapPinIcon, { className: "h-4 w-4 shrink-0 text-primary-400" }),
|
|
5740
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-ui font-semibold", children: destination })
|
|
5741
|
+
] }),
|
|
5742
|
+
duration && nights !== null && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1.5 text-white/85", children: [
|
|
5743
|
+
/* @__PURE__ */ jsx(MoonIcon, { className: "h-4 w-4 shrink-0 text-primary-400" }),
|
|
5744
|
+
/* @__PURE__ */ jsxs("span", { className: "text-sm font-ui font-semibold", children: [
|
|
5745
|
+
nights,
|
|
5746
|
+
" ",
|
|
5747
|
+
nights === 1 ? "noite" : "noites"
|
|
5748
|
+
] }),
|
|
5749
|
+
/* @__PURE__ */ jsx("span", { className: "text-white/40", children: "\xB7" }),
|
|
5750
|
+
/* @__PURE__ */ jsx(SunIcon, { className: "h-4 w-4 shrink-0 text-primary-400" }),
|
|
5751
|
+
/* @__PURE__ */ jsxs("span", { className: "text-sm font-ui font-semibold", children: [
|
|
5752
|
+
duration.days,
|
|
5753
|
+
" ",
|
|
5754
|
+
duration.days === 1 ? "dia" : "dias"
|
|
5755
|
+
] })
|
|
5756
|
+
] })
|
|
5757
|
+
] }) : tagline ? /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm sm:text-base text-white/80 font-ui", children: tagline }) : null
|
|
5758
|
+
]
|
|
5759
|
+
}
|
|
5760
|
+
) })
|
|
5761
|
+
]
|
|
5762
|
+
}
|
|
5763
|
+
);
|
|
5764
|
+
}
|
|
5765
|
+
function Stars({ count = 5 }) {
|
|
5766
|
+
return /* @__PURE__ */ jsx("span", { className: "flex gap-0.5", children: Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ jsx(
|
|
5767
|
+
StarIcon,
|
|
5768
|
+
{
|
|
5769
|
+
className: cn(
|
|
5770
|
+
"h-3.5 w-3.5",
|
|
5771
|
+
i < count ? "fill-primary text-primary" : "fill-muted text-muted"
|
|
5772
|
+
)
|
|
5773
|
+
},
|
|
5774
|
+
i
|
|
5775
|
+
)) });
|
|
5776
|
+
}
|
|
5777
|
+
function ItineraryTimeline({ steps }) {
|
|
5778
|
+
return /* @__PURE__ */ jsx("ol", { className: "relative flex flex-col gap-0", children: steps.map((step, i) => /* @__PURE__ */ jsxs("li", { className: "relative flex gap-4 pb-8 last:pb-0", children: [
|
|
5779
|
+
i < steps.length - 1 && /* @__PURE__ */ jsx("div", { className: "absolute left-3.5 top-7 bottom-0 w-px bg-border" }),
|
|
5780
|
+
/* @__PURE__ */ jsx("div", { className: "relative z-10 mt-1 flex h-7 w-7 shrink-0 items-center justify-center rounded-full border-2 border-primary bg-background", children: /* @__PURE__ */ jsx("span", { className: "text-[10px] font-bold text-primary font-ui", children: i + 1 }) }),
|
|
5781
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 pt-0.5 flex-1", children: [
|
|
5782
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [
|
|
5783
|
+
/* @__PURE__ */ jsx("h4", { className: "text-sm font-bold text-foreground font-heading", children: step.label }),
|
|
5784
|
+
step.duration && /* @__PURE__ */ jsxs(Badge, { variant: "outline", className: "text-xs font-ui h-5 px-2", children: [
|
|
5785
|
+
/* @__PURE__ */ jsx(ClockIcon, { className: "h-3 w-3 mr-1" }),
|
|
5786
|
+
step.duration
|
|
5787
|
+
] }),
|
|
5788
|
+
step.isTransfer && /* @__PURE__ */ jsx(Badge, { variant: "secondary", className: "text-xs font-ui h-5 px-2", children: "Transfer" })
|
|
5789
|
+
] }),
|
|
5790
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground leading-relaxed [&_p:not(:last-child)]:mb-2 [&_strong]:text-foreground [&_strong]:font-semibold", children: step.description })
|
|
5791
|
+
] })
|
|
5792
|
+
] }, i)) });
|
|
5793
|
+
}
|
|
5794
|
+
function Checklist({ items, icon }) {
|
|
5795
|
+
return /* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-2", children: items.map((item, i) => /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-2.5 text-sm text-foreground", children: [
|
|
5796
|
+
/* @__PURE__ */ jsx("span", { className: "mt-0.5 shrink-0 text-primary", children: icon != null ? icon : /* @__PURE__ */ jsx(CheckIcon, { className: "h-4 w-4" }) }),
|
|
5797
|
+
item
|
|
5798
|
+
] }, i)) });
|
|
5799
|
+
}
|
|
5800
|
+
function TripPage({
|
|
5801
|
+
title,
|
|
5802
|
+
tagline,
|
|
5803
|
+
destination,
|
|
5804
|
+
duration,
|
|
5805
|
+
images,
|
|
5806
|
+
videoUrl,
|
|
5807
|
+
breadcrumb,
|
|
5808
|
+
highlights,
|
|
5809
|
+
infoGroups,
|
|
5810
|
+
recommendedFor,
|
|
5811
|
+
overview,
|
|
5812
|
+
itinerary,
|
|
5813
|
+
gallery,
|
|
5814
|
+
included,
|
|
5815
|
+
whatToBring,
|
|
5816
|
+
weather,
|
|
5817
|
+
meetingPoints,
|
|
5818
|
+
faqs,
|
|
5819
|
+
reviews,
|
|
5820
|
+
priceFrom,
|
|
5821
|
+
currency = "CHF",
|
|
5822
|
+
season,
|
|
5823
|
+
departureTimes,
|
|
5824
|
+
pricingOptions,
|
|
5825
|
+
onBook,
|
|
5826
|
+
bookLabel,
|
|
5827
|
+
siteHeader,
|
|
5828
|
+
uiVariant = "v1",
|
|
5829
|
+
features,
|
|
5830
|
+
className
|
|
5831
|
+
}) {
|
|
5832
|
+
const [activeSection, setActiveSection] = React18.useState("");
|
|
5833
|
+
const [navFloating, setNavFloating] = React18.useState(false);
|
|
5834
|
+
const [navHidden, setNavHidden] = React18.useState(false);
|
|
5835
|
+
const [isFloating, setIsFloating] = React18.useState(false);
|
|
5836
|
+
const [sidebarPos, setSidebarPos] = React18.useState(null);
|
|
5837
|
+
const [pricingBarVisible, setPricingBarVisible] = React18.useState(false);
|
|
5838
|
+
const navRef = React18.useRef(null);
|
|
5839
|
+
const navSentinelRef = React18.useRef(null);
|
|
5840
|
+
const sentinelRef = React18.useRef(null);
|
|
5841
|
+
const sidebarPlaceholderRef = React18.useRef(null);
|
|
5842
|
+
const pricingBarRef = React18.useRef(null);
|
|
5843
|
+
const galleryRef = React18.useRef(null);
|
|
5844
|
+
const sections = React18.useMemo(
|
|
5845
|
+
() => [
|
|
5846
|
+
{ id: "key-info", label: "Key info", show: !!(infoGroups == null ? void 0 : infoGroups.length) },
|
|
5847
|
+
{ id: "overview", label: "Overview", show: !!overview },
|
|
5848
|
+
{ id: "itinerary", label: "Itinerary", show: !!(itinerary == null ? void 0 : itinerary.length) },
|
|
5849
|
+
{ id: "included", label: "Included", show: !!((included == null ? void 0 : included.length) || (whatToBring == null ? void 0 : whatToBring.length)) },
|
|
5850
|
+
{ id: "what-to-bring", label: "What to bring", show: !!(whatToBring == null ? void 0 : whatToBring.length) },
|
|
5851
|
+
{ id: "weather", label: "Weather", show: !!weather },
|
|
5852
|
+
{ id: "meeting", label: "Meeting point", show: !!(meetingPoints == null ? void 0 : meetingPoints.length) },
|
|
5853
|
+
{ id: "faq", label: "FAQ", show: !!(faqs == null ? void 0 : faqs.length) },
|
|
5854
|
+
{ id: "gallery", label: "Photos", show: !!(gallery == null ? void 0 : gallery.length) }
|
|
5855
|
+
].filter((s) => s.show),
|
|
5856
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
5857
|
+
[]
|
|
5858
|
+
);
|
|
5859
|
+
React18.useEffect(() => {
|
|
5860
|
+
const sentinel = navSentinelRef.current;
|
|
5861
|
+
if (!sentinel) return;
|
|
5862
|
+
const update = () => setNavFloating(sentinel.getBoundingClientRect().top < 1);
|
|
5863
|
+
document.addEventListener("scroll", update, { passive: true, capture: true });
|
|
5864
|
+
update();
|
|
5865
|
+
return () => document.removeEventListener("scroll", update, { capture: true });
|
|
5866
|
+
}, []);
|
|
5867
|
+
React18.useEffect(() => {
|
|
5868
|
+
const sentinel = sentinelRef.current;
|
|
5869
|
+
if (!sentinel) return;
|
|
5870
|
+
const update = () => setIsFloating(sentinel.getBoundingClientRect().top < 1);
|
|
5871
|
+
document.addEventListener("scroll", update, { passive: true, capture: true });
|
|
5872
|
+
update();
|
|
5873
|
+
return () => document.removeEventListener("scroll", update, { capture: true });
|
|
5874
|
+
}, []);
|
|
5875
|
+
React18.useEffect(() => {
|
|
5876
|
+
const measure = () => {
|
|
5877
|
+
if (!sidebarPlaceholderRef.current) return;
|
|
5878
|
+
const rect = sidebarPlaceholderRef.current.getBoundingClientRect();
|
|
5879
|
+
setSidebarPos({ left: rect.left, width: rect.width });
|
|
5880
|
+
};
|
|
5881
|
+
measure();
|
|
5882
|
+
window.addEventListener("resize", measure);
|
|
5883
|
+
return () => window.removeEventListener("resize", measure);
|
|
5884
|
+
}, [isFloating]);
|
|
5885
|
+
React18.useEffect(() => {
|
|
5886
|
+
const check = () => {
|
|
5887
|
+
var _a;
|
|
5888
|
+
const target = (_a = galleryRef.current) != null ? _a : pricingBarRef.current;
|
|
5889
|
+
if (!target) return;
|
|
5890
|
+
setPricingBarVisible(target.getBoundingClientRect().top < window.innerHeight * 0.75);
|
|
5891
|
+
};
|
|
5892
|
+
document.addEventListener("scroll", check, { passive: true, capture: true });
|
|
5893
|
+
check();
|
|
5894
|
+
return () => document.removeEventListener("scroll", check, { capture: true });
|
|
5895
|
+
}, []);
|
|
5896
|
+
React18.useEffect(() => {
|
|
5897
|
+
const check = () => {
|
|
5898
|
+
if (!pricingBarRef.current) return;
|
|
5899
|
+
setNavHidden(pricingBarRef.current.getBoundingClientRect().top < window.innerHeight * 0.92);
|
|
5900
|
+
};
|
|
5901
|
+
document.addEventListener("scroll", check, { passive: true, capture: true });
|
|
5902
|
+
check();
|
|
5903
|
+
return () => document.removeEventListener("scroll", check, { capture: true });
|
|
5904
|
+
}, []);
|
|
5905
|
+
React18.useEffect(() => {
|
|
5906
|
+
if (sections.length === 0) return;
|
|
5907
|
+
setActiveSection(sections[0].id);
|
|
5908
|
+
const update = () => {
|
|
5909
|
+
var _a, _b;
|
|
5910
|
+
const navH = ((_b = (_a = navRef.current) == null ? void 0 : _a.offsetHeight) != null ? _b : 56) + 20;
|
|
5911
|
+
for (const { id } of [...sections].reverse()) {
|
|
5912
|
+
const el = document.getElementById(`trip-section-${id}`);
|
|
5913
|
+
if (el && el.getBoundingClientRect().top <= navH) {
|
|
5914
|
+
setActiveSection(id);
|
|
5915
|
+
return;
|
|
5916
|
+
}
|
|
5917
|
+
}
|
|
5918
|
+
setActiveSection(sections[0].id);
|
|
5919
|
+
};
|
|
5920
|
+
document.addEventListener("scroll", update, { passive: true, capture: true });
|
|
5921
|
+
return () => document.removeEventListener("scroll", update, { capture: true });
|
|
5922
|
+
}, [sections]);
|
|
5923
|
+
const scrollToBookingForm = () => {
|
|
5924
|
+
var _a, _b, _c;
|
|
5925
|
+
const el = document.getElementById("trip-booking-form");
|
|
5926
|
+
if (!el) return;
|
|
5927
|
+
const navHeight = ((_b = (_a = navRef.current) == null ? void 0 : _a.offsetHeight) != null ? _b : 56) + 16;
|
|
5928
|
+
const scrollEl = (_c = navRef.current) == null ? void 0 : _c.closest("main");
|
|
5929
|
+
const elTop = el.getBoundingClientRect().top;
|
|
5930
|
+
const containerTop = scrollEl ? scrollEl.getBoundingClientRect().top : 0;
|
|
5931
|
+
const currentScroll = scrollEl ? scrollEl.scrollTop : window.scrollY;
|
|
5932
|
+
const target = currentScroll + (elTop - containerTop) - navHeight;
|
|
5933
|
+
if (scrollEl) {
|
|
5934
|
+
scrollEl.scrollTo({ top: target, behavior: "smooth" });
|
|
5935
|
+
} else {
|
|
5936
|
+
window.scrollTo({ top: target, behavior: "smooth" });
|
|
5937
|
+
}
|
|
5938
|
+
};
|
|
5939
|
+
const scrollToSection = (id) => {
|
|
5940
|
+
var _a, _b, _c;
|
|
5941
|
+
const el = document.getElementById(`trip-section-${id}`);
|
|
5942
|
+
if (!el) return;
|
|
5943
|
+
const navHeight = (_b = (_a = navRef.current) == null ? void 0 : _a.offsetHeight) != null ? _b : 56;
|
|
5944
|
+
const scrollEl = (_c = navRef.current) == null ? void 0 : _c.closest("main");
|
|
5945
|
+
const currentScroll = scrollEl ? scrollEl.scrollTop : window.scrollY;
|
|
5946
|
+
const elTop = el.getBoundingClientRect().top;
|
|
5947
|
+
const containerTop = scrollEl ? scrollEl.getBoundingClientRect().top : 0;
|
|
5948
|
+
const target = currentScroll + (elTop - containerTop) - navHeight - 12;
|
|
5949
|
+
if (scrollEl) {
|
|
5950
|
+
scrollEl.scrollTo({ top: target, behavior: "smooth" });
|
|
5951
|
+
} else {
|
|
5952
|
+
window.scrollTo({ top: target, behavior: "smooth" });
|
|
5953
|
+
}
|
|
5954
|
+
};
|
|
5955
|
+
return /* @__PURE__ */ jsxs(
|
|
5956
|
+
"div",
|
|
5957
|
+
{
|
|
5958
|
+
className: cn("w-full overflow-x-hidden", className),
|
|
5959
|
+
"data-ui-variant": uiVariant,
|
|
5960
|
+
"data-features": features ? JSON.stringify(features) : void 0,
|
|
5961
|
+
children: [
|
|
5962
|
+
/* @__PURE__ */ jsx(
|
|
5963
|
+
TripHeader,
|
|
5964
|
+
{
|
|
5965
|
+
images,
|
|
5966
|
+
videoUrl,
|
|
5967
|
+
title,
|
|
5968
|
+
breadcrumb,
|
|
5969
|
+
destination,
|
|
5970
|
+
duration,
|
|
5971
|
+
tagline,
|
|
5972
|
+
siteHeader,
|
|
5973
|
+
uiVariant
|
|
5974
|
+
}
|
|
5975
|
+
),
|
|
5976
|
+
/* @__PURE__ */ jsxs("div", { className: "mx-auto w-full max-w-5xl px-4 sm:px-6", children: [
|
|
5977
|
+
highlights && highlights.length > 0 && /* @__PURE__ */ jsx("div", { className: "mt-6 flex flex-wrap justify-center gap-6 py-2", children: highlights.map((h, i) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col items-center gap-2 text-center", children: [
|
|
5978
|
+
h.icon && /* @__PURE__ */ jsx("div", { className: "flex h-12 w-12 items-center justify-center rounded-full border-2 border-border text-foreground", children: h.icon }),
|
|
5979
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold text-foreground font-ui", children: h.label })
|
|
5980
|
+
] }, i)) }),
|
|
5981
|
+
/* @__PURE__ */ jsx("div", { ref: navSentinelRef, className: "h-px", "aria-hidden": true }),
|
|
5982
|
+
sections.length > 0 ? /* @__PURE__ */ jsx(
|
|
5983
|
+
"div",
|
|
5984
|
+
{
|
|
5985
|
+
className: cn(
|
|
5986
|
+
"py-2 flex justify-center transition-opacity duration-150",
|
|
5987
|
+
navFloating ? "opacity-0 pointer-events-none" : "opacity-100"
|
|
5988
|
+
),
|
|
5989
|
+
children: /* @__PURE__ */ jsx(
|
|
5990
|
+
MenuTrip,
|
|
5991
|
+
{
|
|
5992
|
+
sections,
|
|
5993
|
+
activeSection,
|
|
5994
|
+
onSelect: scrollToSection,
|
|
5995
|
+
variant: "floating"
|
|
5996
|
+
}
|
|
5997
|
+
)
|
|
5998
|
+
}
|
|
5999
|
+
) : /* @__PURE__ */ jsx(Separator, { className: "my-6" }),
|
|
6000
|
+
/* @__PURE__ */ jsx("div", { ref: sentinelRef, className: "h-px -mt-px", "aria-hidden": true }),
|
|
6001
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col lg:flex-row gap-8 mt-4", children: [
|
|
6002
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0 space-y-12 pb-12", children: [
|
|
6003
|
+
infoGroups && infoGroups.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-key-info", className: "scroll-mt-20", children: [
|
|
6004
|
+
/* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-6", children: "Key info" }),
|
|
6005
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-6", children: infoGroups.map((group, i) => /* @__PURE__ */ jsxs("div", { children: [
|
|
6006
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 mb-3", children: [
|
|
6007
|
+
group.icon && /* @__PURE__ */ jsx("span", { className: "text-primary", children: group.icon }),
|
|
6008
|
+
/* @__PURE__ */ jsx("h3", { className: "text-base font-bold text-foreground font-heading", children: group.title })
|
|
6009
|
+
] }),
|
|
6010
|
+
/* @__PURE__ */ jsx(Checklist, { items: group.items }),
|
|
6011
|
+
i < infoGroups.length - 1 && /* @__PURE__ */ jsx(Separator, { className: "mt-6" })
|
|
6012
|
+
] }, i)) })
|
|
6013
|
+
] }),
|
|
6014
|
+
overview && /* @__PURE__ */ jsxs("section", { id: "trip-section-overview", className: "scroll-mt-20", children: [
|
|
6015
|
+
/* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-4", children: "Overview" }),
|
|
6016
|
+
recommendedFor && /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-2.5 rounded-xl bg-primary/8 border border-primary/20 p-4 mb-4", children: [
|
|
6017
|
+
/* @__PURE__ */ jsx(UsersIcon, { className: "h-4 w-4 text-primary mt-0.5 shrink-0" }),
|
|
6018
|
+
/* @__PURE__ */ jsxs("p", { className: "text-sm text-foreground font-ui", children: [
|
|
6019
|
+
/* @__PURE__ */ jsx("span", { className: "font-semibold", children: "Recommended for: " }),
|
|
6020
|
+
recommendedFor
|
|
6021
|
+
] })
|
|
6022
|
+
] }),
|
|
6023
|
+
/* @__PURE__ */ jsx("div", { className: "text-sm text-foreground leading-relaxed space-y-3 [&_strong]:font-semibold [&_a]:text-primary [&_a]:underline", children: overview })
|
|
6024
|
+
] }),
|
|
6025
|
+
itinerary && itinerary.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-itinerary", className: "scroll-mt-20", children: [
|
|
6026
|
+
/* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-6", children: "Itinerary" }),
|
|
6027
|
+
/* @__PURE__ */ jsx(ItineraryTimeline, { steps: itinerary })
|
|
6028
|
+
] }),
|
|
6029
|
+
included && included.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-included", className: "scroll-mt-20", children: [
|
|
6030
|
+
/* @__PURE__ */ jsxs("h2", { className: "text-xl font-bold text-foreground font-heading mb-4 flex items-center gap-2", children: [
|
|
6031
|
+
/* @__PURE__ */ jsx(PackageIcon, { className: "h-5 w-5 text-primary" }),
|
|
6032
|
+
"Included"
|
|
6033
|
+
] }),
|
|
6034
|
+
/* @__PURE__ */ jsx(Checklist, { items: included })
|
|
6035
|
+
] }),
|
|
6036
|
+
whatToBring && whatToBring.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-what-to-bring", className: "scroll-mt-20", children: [
|
|
6037
|
+
/* @__PURE__ */ jsxs("h2", { className: "text-xl font-bold text-foreground font-heading mb-4 flex items-center gap-2", children: [
|
|
6038
|
+
/* @__PURE__ */ jsx(PackageIcon, { className: "h-5 w-5 text-primary" }),
|
|
6039
|
+
"What to bring"
|
|
6040
|
+
] }),
|
|
6041
|
+
/* @__PURE__ */ jsx(Checklist, { items: whatToBring, icon: /* @__PURE__ */ jsx(InfoIcon, { className: "h-4 w-4" }) })
|
|
6042
|
+
] }),
|
|
6043
|
+
weather && /* @__PURE__ */ jsxs("section", { id: "trip-section-weather", className: "scroll-mt-20", children: [
|
|
6044
|
+
/* @__PURE__ */ jsxs("h2", { className: "text-xl font-bold text-foreground font-heading mb-4 flex items-center gap-2", children: [
|
|
6045
|
+
/* @__PURE__ */ jsx(SunIcon, { className: "h-5 w-5 text-primary" }),
|
|
6046
|
+
"Weather"
|
|
6047
|
+
] }),
|
|
6048
|
+
/* @__PURE__ */ jsx("div", { className: "flex items-start gap-3 rounded-xl bg-muted/60 border border-border p-5", children: /* @__PURE__ */ jsx("div", { className: "text-sm text-foreground leading-relaxed space-y-2 [&_strong]:font-semibold", children: weather }) })
|
|
6049
|
+
] }),
|
|
6050
|
+
meetingPoints && meetingPoints.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-meeting", className: "scroll-mt-20", children: [
|
|
6051
|
+
/* @__PURE__ */ jsxs("h2", { className: "text-xl font-bold text-foreground font-heading mb-4 flex items-center gap-2", children: [
|
|
6052
|
+
/* @__PURE__ */ jsx(MapPinIcon, { className: "h-5 w-5 text-primary" }),
|
|
6053
|
+
"Meeting point"
|
|
6054
|
+
] }),
|
|
6055
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-3", children: meetingPoints.map((mp, i) => /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3 rounded-xl border border-border p-4", children: [
|
|
6056
|
+
/* @__PURE__ */ jsx("div", { className: "mt-0.5 flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-primary/10", children: /* @__PURE__ */ jsx(MapPinIcon, { className: "h-4 w-4 text-primary" }) }),
|
|
6057
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
6058
|
+
mp.type && /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground font-ui uppercase tracking-wide mb-0.5", children: mp.type === "activity" ? "Activity location" : mp.type === "alternative" ? "Alternative meeting point" : "Meeting point" }),
|
|
6059
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm font-bold text-foreground font-heading", children: mp.name }),
|
|
6060
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground font-ui mt-0.5", children: mp.address })
|
|
6061
|
+
] })
|
|
6062
|
+
] }, i)) })
|
|
6063
|
+
] }),
|
|
6064
|
+
faqs && faqs.length > 0 && /* @__PURE__ */ jsxs("section", { id: "trip-section-faq", className: "scroll-mt-20", children: [
|
|
6065
|
+
/* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-6", children: "FAQ" }),
|
|
6066
|
+
/* @__PURE__ */ jsx(Accordion, { variant: "faq", children: faqs.map((faq, i) => /* @__PURE__ */ jsxs(AccordionItem, { value: `faq-${i}`, children: [
|
|
6067
|
+
/* @__PURE__ */ jsx(AccordionTrigger, { children: faq.question }),
|
|
6068
|
+
/* @__PURE__ */ jsx(AccordionContent, { children: faq.answer })
|
|
6069
|
+
] }, i)) })
|
|
6070
|
+
] }),
|
|
6071
|
+
reviews && reviews.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
6072
|
+
/* @__PURE__ */ jsx(Separator, { className: "mb-10" }),
|
|
6073
|
+
/* @__PURE__ */ jsx("h2", { className: "text-xl font-bold text-foreground font-heading mb-5", children: "What our guests think" }),
|
|
6074
|
+
/* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-4", children: reviews.map((r, i) => {
|
|
6075
|
+
var _a;
|
|
6076
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 rounded-xl border border-border p-5", children: [
|
|
6077
|
+
/* @__PURE__ */ jsx(Stars, { count: (_a = r.rating) != null ? _a : 5 }),
|
|
6078
|
+
/* @__PURE__ */ jsxs("p", { className: "text-sm text-foreground leading-relaxed line-clamp-4", children: [
|
|
6079
|
+
"\u201C",
|
|
6080
|
+
r.text,
|
|
6081
|
+
"\u201D"
|
|
6082
|
+
] }),
|
|
6083
|
+
/* @__PURE__ */ jsxs("p", { className: "text-xs font-semibold text-muted-foreground font-ui mt-auto", children: [
|
|
6084
|
+
"\u2014 ",
|
|
6085
|
+
r.author
|
|
6086
|
+
] })
|
|
6087
|
+
] }, i);
|
|
6088
|
+
}) })
|
|
6089
|
+
] })
|
|
6090
|
+
] }),
|
|
6091
|
+
/* @__PURE__ */ jsx("div", { ref: sidebarPlaceholderRef, className: "hidden lg:block lg:w-72 xl:w-80 shrink-0", children: !isFloating && /* @__PURE__ */ jsx("div", { className: "sticky top-20 rounded-2xl border border-border bg-card p-6 shadow-sm", children: /* @__PURE__ */ jsx(
|
|
6092
|
+
PricingTrip,
|
|
6093
|
+
{
|
|
6094
|
+
priceFrom,
|
|
6095
|
+
currency,
|
|
6096
|
+
season,
|
|
6097
|
+
departureTimes,
|
|
6098
|
+
pricingOptions,
|
|
6099
|
+
onBook: (gallery == null ? void 0 : gallery.length) ? scrollToBookingForm : onBook,
|
|
6100
|
+
bookLabel: bookLabel != null ? bookLabel : "Check availability",
|
|
6101
|
+
variant: "card"
|
|
6102
|
+
}
|
|
6103
|
+
) }) })
|
|
6104
|
+
] })
|
|
6105
|
+
] }),
|
|
6106
|
+
sections.length > 0 && /* @__PURE__ */ jsx(
|
|
6107
|
+
"div",
|
|
6108
|
+
{
|
|
6109
|
+
ref: navRef,
|
|
6110
|
+
className: cn(
|
|
6111
|
+
"fixed top-0 left-0 right-0 z-20 py-3 transition-all duration-200",
|
|
6112
|
+
navFloating && !navHidden ? "translate-y-0 opacity-100" : "-translate-y-full opacity-0 pointer-events-none"
|
|
6113
|
+
),
|
|
6114
|
+
children: /* @__PURE__ */ jsx("div", { className: "mx-auto w-full max-w-5xl px-4 sm:px-6 flex justify-center", children: /* @__PURE__ */ jsx(
|
|
6115
|
+
MenuTrip,
|
|
6116
|
+
{
|
|
6117
|
+
sections,
|
|
6118
|
+
activeSection,
|
|
6119
|
+
onSelect: scrollToSection,
|
|
6120
|
+
variant: "floating"
|
|
6121
|
+
}
|
|
6122
|
+
) })
|
|
6123
|
+
}
|
|
6124
|
+
),
|
|
6125
|
+
isFloating && !pricingBarVisible && sidebarPos && /* @__PURE__ */ jsx(
|
|
6126
|
+
"div",
|
|
6127
|
+
{
|
|
6128
|
+
className: "hidden lg:block fixed z-20",
|
|
6129
|
+
style: { top: "5rem", left: sidebarPos.left, width: sidebarPos.width },
|
|
6130
|
+
children: /* @__PURE__ */ jsx("div", { className: "rounded-2xl border border-border bg-card p-6 shadow-sm", children: /* @__PURE__ */ jsx(
|
|
6131
|
+
PricingTrip,
|
|
6132
|
+
{
|
|
6133
|
+
priceFrom,
|
|
6134
|
+
currency,
|
|
6135
|
+
season,
|
|
6136
|
+
departureTimes,
|
|
6137
|
+
pricingOptions,
|
|
6138
|
+
onBook: (gallery == null ? void 0 : gallery.length) ? scrollToBookingForm : onBook,
|
|
6139
|
+
bookLabel: bookLabel != null ? bookLabel : "Check availability",
|
|
6140
|
+
variant: "card"
|
|
6141
|
+
}
|
|
6142
|
+
) })
|
|
6143
|
+
}
|
|
6144
|
+
),
|
|
6145
|
+
gallery && gallery.length > 0 && /* @__PURE__ */ jsx("section", { ref: galleryRef, id: "trip-section-gallery", className: "scroll-mt-20", children: /* @__PURE__ */ jsx(
|
|
6146
|
+
PhotoGallery,
|
|
6147
|
+
{
|
|
6148
|
+
photos: gallery,
|
|
6149
|
+
variant: "grid",
|
|
6150
|
+
initialVisible: 6
|
|
6151
|
+
}
|
|
6152
|
+
) }),
|
|
6153
|
+
gallery && gallery.length > 0 && /* @__PURE__ */ jsx("div", { ref: pricingBarRef, className: "mx-auto w-full max-w-5xl px-4 sm:px-6 py-12", children: /* @__PURE__ */ jsx("div", { id: "trip-booking-form", className: "rounded-2xl border border-border bg-card p-8 shadow-sm", children: /* @__PURE__ */ jsx(BookingForm, { onSubmit: onBook ? (values) => onBook() : void 0 }) }) }),
|
|
6154
|
+
/* @__PURE__ */ jsx("div", { className: "fixed bottom-0 inset-x-0 z-30 lg:hidden border-t border-border bg-background/95 backdrop-blur-sm px-4 py-3", children: /* @__PURE__ */ jsx(
|
|
6155
|
+
PricingTrip,
|
|
6156
|
+
{
|
|
6157
|
+
priceFrom,
|
|
6158
|
+
currency,
|
|
6159
|
+
onBook: (gallery == null ? void 0 : gallery.length) ? scrollToBookingForm : onBook,
|
|
6160
|
+
bookLabel: bookLabel != null ? bookLabel : "Book now",
|
|
6161
|
+
variant: "compact"
|
|
6162
|
+
}
|
|
6163
|
+
) }),
|
|
6164
|
+
/* @__PURE__ */ jsx("div", { className: "h-20 lg:hidden" })
|
|
6165
|
+
]
|
|
6166
|
+
}
|
|
6167
|
+
);
|
|
6168
|
+
}
|
|
6169
|
+
var sizeConfig2 = {
|
|
6170
|
+
sm: {
|
|
6171
|
+
card: "w-56",
|
|
6172
|
+
image: "h-36",
|
|
6173
|
+
title: "text-sm font-bold",
|
|
6174
|
+
description: "text-xs",
|
|
6175
|
+
price: "text-xs py-2"
|
|
6176
|
+
},
|
|
6177
|
+
md: {
|
|
6178
|
+
card: "w-72",
|
|
6179
|
+
image: "h-52",
|
|
6180
|
+
title: "text-base font-bold",
|
|
6181
|
+
description: "text-sm",
|
|
6182
|
+
price: "text-sm py-2.5"
|
|
6183
|
+
},
|
|
6184
|
+
lg: {
|
|
6185
|
+
card: "w-96",
|
|
6186
|
+
image: "h-64",
|
|
6187
|
+
title: "text-lg font-bold",
|
|
6188
|
+
description: "text-sm",
|
|
6189
|
+
price: "text-sm py-3"
|
|
6190
|
+
}
|
|
6191
|
+
};
|
|
6192
|
+
function ActivityCard({
|
|
6193
|
+
image,
|
|
6194
|
+
imageAlt = "",
|
|
6195
|
+
badge,
|
|
6196
|
+
icon,
|
|
6197
|
+
title,
|
|
6198
|
+
description,
|
|
6199
|
+
price,
|
|
6200
|
+
onClick,
|
|
6201
|
+
size = "md",
|
|
6202
|
+
className
|
|
6203
|
+
}) {
|
|
6204
|
+
const s = sizeConfig2[size];
|
|
6205
|
+
return /* @__PURE__ */ jsxs(
|
|
6206
|
+
"div",
|
|
6207
|
+
{
|
|
6208
|
+
role: onClick ? "button" : void 0,
|
|
6209
|
+
tabIndex: onClick ? 0 : void 0,
|
|
6210
|
+
onClick,
|
|
6211
|
+
onKeyDown: onClick ? (e) => (e.key === "Enter" || e.key === " ") && onClick() : void 0,
|
|
6212
|
+
className: cn(
|
|
6213
|
+
"group flex flex-col overflow-hidden rounded-[1.25rem] bg-card",
|
|
6214
|
+
"border border-border shadow-md transition-shadow duration-200",
|
|
6215
|
+
onClick && "cursor-pointer hover:shadow-lg focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
6216
|
+
s.card,
|
|
6217
|
+
className
|
|
6218
|
+
),
|
|
6219
|
+
children: [
|
|
6220
|
+
/* @__PURE__ */ jsxs("div", { className: cn("relative w-full shrink-0 overflow-hidden", s.image), children: [
|
|
6221
|
+
/* @__PURE__ */ jsx(
|
|
6222
|
+
"img",
|
|
6223
|
+
{
|
|
6224
|
+
src: image,
|
|
6225
|
+
alt: imageAlt,
|
|
6226
|
+
className: "h-full w-full object-cover transition-transform duration-300 group-hover:scale-105"
|
|
6227
|
+
}
|
|
6228
|
+
),
|
|
6229
|
+
icon && /* @__PURE__ */ jsx("div", { className: "absolute left-3 top-3 flex h-8 w-8 items-center justify-center rounded-full bg-black/30 text-white backdrop-blur-sm", children: icon }),
|
|
6230
|
+
badge && /* @__PURE__ */ jsx("div", { className: "absolute right-3 top-3", children: /* @__PURE__ */ jsx(
|
|
6231
|
+
Badge,
|
|
6232
|
+
{
|
|
6233
|
+
variant: "secondary",
|
|
6234
|
+
className: "rounded-full bg-card/90 text-foreground backdrop-blur-sm shadow-sm border-0 font-medium font-ui",
|
|
6235
|
+
children: badge
|
|
6236
|
+
}
|
|
6237
|
+
) })
|
|
6238
|
+
] }),
|
|
6239
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-2 p-4", children: [
|
|
6240
|
+
/* @__PURE__ */ jsx("p", { className: cn("text-foreground leading-snug font-ui", s.title), children: title }),
|
|
6241
|
+
description && /* @__PURE__ */ jsx("p", { className: cn("text-muted-foreground leading-relaxed", s.description), children: description }),
|
|
6242
|
+
price && /* @__PURE__ */ jsx("div", { className: "mt-auto pt-2", children: /* @__PURE__ */ jsx(
|
|
6243
|
+
"div",
|
|
6244
|
+
{
|
|
6245
|
+
className: cn(
|
|
6246
|
+
"w-full rounded-full bg-muted text-center font-semibold text-foreground font-ui",
|
|
6247
|
+
s.price
|
|
6248
|
+
),
|
|
6249
|
+
children: price
|
|
6250
|
+
}
|
|
6251
|
+
) })
|
|
6252
|
+
] })
|
|
6253
|
+
]
|
|
6254
|
+
}
|
|
6255
|
+
);
|
|
6256
|
+
}
|
|
6257
|
+
function Input(_a) {
|
|
6258
|
+
var _b = _a, { className, type } = _b, props = __objRest(_b, ["className", "type"]);
|
|
6259
|
+
return /* @__PURE__ */ jsx(
|
|
6260
|
+
Input$1,
|
|
6261
|
+
__spreadValues({
|
|
6262
|
+
type,
|
|
6263
|
+
"data-slot": "input",
|
|
6264
|
+
className: cn(
|
|
6265
|
+
"h-8 w-full min-w-0 rounded-lg border border-input bg-transparent px-2.5 py-1 text-base transition-colors outline-none file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:bg-input/50 disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:disabled:bg-input/80 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40",
|
|
6266
|
+
className
|
|
6267
|
+
)
|
|
6268
|
+
}, props)
|
|
6269
|
+
);
|
|
6270
|
+
}
|
|
6271
|
+
function Label(_a) {
|
|
6272
|
+
var _b = _a, { className } = _b, props = __objRest(_b, ["className"]);
|
|
6273
|
+
return /* @__PURE__ */ jsx(
|
|
6274
|
+
"label",
|
|
6275
|
+
__spreadValues({
|
|
6276
|
+
"data-slot": "label",
|
|
6277
|
+
className: cn(
|
|
6278
|
+
"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50",
|
|
6279
|
+
className
|
|
6280
|
+
)
|
|
6281
|
+
}, props)
|
|
6282
|
+
);
|
|
6283
|
+
}
|
|
6284
|
+
var DEFAULTS = {
|
|
6285
|
+
heading: "Where will your next adventure take you?",
|
|
6286
|
+
subtitle: "Tell us about your dream trip and our travel experts will craft the perfect itinerary for you.",
|
|
6287
|
+
nameLabel: "Your name",
|
|
6288
|
+
namePlaceholder: "e.g. Maria Silva",
|
|
6289
|
+
emailLabel: "Email",
|
|
6290
|
+
emailPlaceholder: "you@example.com",
|
|
6291
|
+
travelDateLabel: "When are you planning to travel?",
|
|
6292
|
+
travelDateOptions: [
|
|
6293
|
+
"In the next 30 days",
|
|
6294
|
+
"1 \u2013 3 months from now",
|
|
6295
|
+
"3 \u2013 6 months from now",
|
|
6296
|
+
"6 \u2013 12 months from now",
|
|
6297
|
+
"I'm just exploring"
|
|
6298
|
+
],
|
|
6299
|
+
submitLabel: "Send my request",
|
|
6300
|
+
successHeading: "Thank you!",
|
|
6301
|
+
successMessage: "One of our travel experts will reach out soon to help plan your perfect trip.",
|
|
6302
|
+
privacyText: 'By submitting you agree to our <a href="/privacy-policy" target="_blank" rel="noopener">Privacy Policy</a>.',
|
|
6303
|
+
trigger: "delay",
|
|
6304
|
+
delaySeconds: 5,
|
|
6305
|
+
scrollPercent: 50,
|
|
6306
|
+
dismissDays: 7,
|
|
6307
|
+
overlayOpacity: 40,
|
|
6308
|
+
position: "center"
|
|
6309
|
+
};
|
|
6310
|
+
var COOKIE_NAME = "pexo_lead_popup_dismissed";
|
|
6311
|
+
function isDismissed() {
|
|
6312
|
+
return document.cookie.includes(`${COOKIE_NAME}=1`);
|
|
6313
|
+
}
|
|
6314
|
+
function setDismissed(days) {
|
|
6315
|
+
const expires = new Date(Date.now() + days * 864e5).toUTCString();
|
|
6316
|
+
document.cookie = `${COOKIE_NAME}=1; expires=${expires}; path=/; SameSite=Lax`;
|
|
6317
|
+
}
|
|
6318
|
+
function LeadCapturePopup({
|
|
6319
|
+
config: _config
|
|
6320
|
+
}) {
|
|
6321
|
+
var _a;
|
|
6322
|
+
const config = __spreadValues(__spreadValues({}, DEFAULTS), _config);
|
|
6323
|
+
const [open, setOpen] = useState(false);
|
|
6324
|
+
const [closing, setClosing] = useState(false);
|
|
6325
|
+
const [submitted, setSubmitted] = useState(false);
|
|
6326
|
+
const [submitting, setSubmitting] = useState(false);
|
|
6327
|
+
const [error, setError] = useState(null);
|
|
6328
|
+
const [name, setName] = useState("");
|
|
6329
|
+
const [email, setEmail] = useState("");
|
|
6330
|
+
const [travelDate, setTravelDate] = useState("");
|
|
6331
|
+
const panelRef = useRef(null);
|
|
6332
|
+
const nameRef = useRef(null);
|
|
6333
|
+
const show = useCallback(() => {
|
|
6334
|
+
if (isDismissed()) return;
|
|
6335
|
+
setOpen(true);
|
|
6336
|
+
}, []);
|
|
6337
|
+
useEffect(() => {
|
|
6338
|
+
var _a2;
|
|
6339
|
+
if (isDismissed()) return;
|
|
6340
|
+
if (config.trigger === "delay") {
|
|
6341
|
+
const t = setTimeout(show, ((_a2 = config.delaySeconds) != null ? _a2 : 5) * 1e3);
|
|
6342
|
+
return () => clearTimeout(t);
|
|
6343
|
+
}
|
|
6344
|
+
if (config.trigger === "exit_intent") {
|
|
6345
|
+
const handler = (e) => {
|
|
6346
|
+
if (e.clientY <= 5) show();
|
|
6347
|
+
};
|
|
6348
|
+
document.addEventListener("mouseout", handler);
|
|
6349
|
+
return () => document.removeEventListener("mouseout", handler);
|
|
6350
|
+
}
|
|
6351
|
+
if (config.trigger === "scroll") {
|
|
6352
|
+
const handler = () => {
|
|
6353
|
+
var _a3;
|
|
6354
|
+
const pct = window.scrollY / (document.documentElement.scrollHeight - window.innerHeight) * 100;
|
|
6355
|
+
if (pct >= ((_a3 = config.scrollPercent) != null ? _a3 : 50)) {
|
|
6356
|
+
show();
|
|
6357
|
+
window.removeEventListener("scroll", handler);
|
|
6358
|
+
}
|
|
6359
|
+
};
|
|
6360
|
+
window.addEventListener("scroll", handler, { passive: true });
|
|
6361
|
+
return () => window.removeEventListener("scroll", handler);
|
|
6362
|
+
}
|
|
6363
|
+
}, [config.trigger, config.delaySeconds, config.scrollPercent, show]);
|
|
6364
|
+
useEffect(() => {
|
|
6365
|
+
if (open && !submitted) {
|
|
6366
|
+
requestAnimationFrame(() => {
|
|
6367
|
+
var _a2;
|
|
6368
|
+
return (_a2 = nameRef.current) == null ? void 0 : _a2.focus();
|
|
6369
|
+
});
|
|
6370
|
+
}
|
|
6371
|
+
}, [open, submitted]);
|
|
6372
|
+
const close = useCallback(() => {
|
|
6373
|
+
setClosing(true);
|
|
6374
|
+
setDismissed(config.dismissDays);
|
|
6375
|
+
setTimeout(() => {
|
|
6376
|
+
setOpen(false);
|
|
6377
|
+
setClosing(false);
|
|
6378
|
+
}, 250);
|
|
6379
|
+
}, [config.dismissDays]);
|
|
6380
|
+
useEffect(() => {
|
|
6381
|
+
if (!open) return;
|
|
6382
|
+
const handler = (e) => {
|
|
6383
|
+
if (e.key === "Escape") close();
|
|
6384
|
+
};
|
|
6385
|
+
document.addEventListener("keydown", handler);
|
|
6386
|
+
return () => document.removeEventListener("keydown", handler);
|
|
6387
|
+
}, [open, close]);
|
|
6388
|
+
const onOverlayClick = useCallback(
|
|
6389
|
+
(e) => {
|
|
6390
|
+
if (panelRef.current && !panelRef.current.contains(e.target)) {
|
|
6391
|
+
close();
|
|
6392
|
+
}
|
|
6393
|
+
},
|
|
6394
|
+
[close]
|
|
6395
|
+
);
|
|
6396
|
+
const handleSubmit = async (e) => {
|
|
6397
|
+
var _a2;
|
|
6398
|
+
e.preventDefault();
|
|
6399
|
+
setError(null);
|
|
6400
|
+
if (!name.trim() || !email.trim() || !travelDate) {
|
|
6401
|
+
setError("Please fill in all fields.");
|
|
6402
|
+
return;
|
|
6403
|
+
}
|
|
6404
|
+
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) {
|
|
6405
|
+
setError("Please enter a valid email address.");
|
|
6406
|
+
return;
|
|
6407
|
+
}
|
|
6408
|
+
setSubmitting(true);
|
|
6409
|
+
try {
|
|
6410
|
+
if (config.ajaxUrl) {
|
|
6411
|
+
const res = await fetch(config.ajaxUrl, {
|
|
6412
|
+
method: "POST",
|
|
6413
|
+
headers: { "Content-Type": "application/json" },
|
|
6414
|
+
body: JSON.stringify({
|
|
6415
|
+
name: name.trim(),
|
|
6416
|
+
email: email.trim(),
|
|
6417
|
+
travel_date: travelDate,
|
|
6418
|
+
nonce: (_a2 = config.nonce) != null ? _a2 : ""
|
|
6419
|
+
})
|
|
6420
|
+
});
|
|
6421
|
+
if (!res.ok) throw new Error("Server error");
|
|
6422
|
+
}
|
|
6423
|
+
setSubmitted(true);
|
|
6424
|
+
setDismissed(config.dismissDays);
|
|
6425
|
+
} catch (e2) {
|
|
6426
|
+
setError("Something went wrong. Please try again.");
|
|
6427
|
+
} finally {
|
|
6428
|
+
setSubmitting(false);
|
|
6429
|
+
}
|
|
6430
|
+
};
|
|
6431
|
+
if (!open) return null;
|
|
6432
|
+
const accentStyle = config.accentColor ? { "--popup-accent": config.accentColor } : void 0;
|
|
6433
|
+
const isCenter = config.position === "center";
|
|
6434
|
+
return /* @__PURE__ */ jsxs(
|
|
6435
|
+
"div",
|
|
6436
|
+
{
|
|
6437
|
+
className: cn(
|
|
6438
|
+
"pexo-lead-popup fixed inset-0 z-[99999] flex",
|
|
6439
|
+
isCenter ? "items-center justify-center" : "items-end justify-end",
|
|
6440
|
+
closing ? "animate-fade-out" : "animate-fade-in"
|
|
6441
|
+
),
|
|
6442
|
+
style: {
|
|
6443
|
+
backgroundColor: `rgba(0,0,0,${((_a = config.overlayOpacity) != null ? _a : 40) / 100})`,
|
|
6444
|
+
backdropFilter: "blur(4px)",
|
|
6445
|
+
WebkitBackdropFilter: "blur(4px)"
|
|
6446
|
+
},
|
|
6447
|
+
onClick: onOverlayClick,
|
|
6448
|
+
role: "dialog",
|
|
6449
|
+
"aria-modal": "true",
|
|
6450
|
+
"aria-label": config.heading,
|
|
6451
|
+
children: [
|
|
6452
|
+
/* @__PURE__ */ jsxs(
|
|
6453
|
+
"div",
|
|
6454
|
+
{
|
|
6455
|
+
ref: panelRef,
|
|
6456
|
+
className: cn(
|
|
6457
|
+
"relative flex flex-col overflow-hidden bg-background text-foreground shadow-2xl ring-1 ring-foreground/5",
|
|
6458
|
+
isCenter ? "m-4 w-full max-w-md rounded-2xl sm:max-w-lg" : "m-4 w-full max-w-sm rounded-2xl sm:m-6",
|
|
6459
|
+
closing ? isCenter ? "animate-zoom-out" : "animate-slide-out-right" : isCenter ? "animate-zoom-in" : "animate-slide-in-right"
|
|
6460
|
+
),
|
|
6461
|
+
style: accentStyle,
|
|
6462
|
+
children: [
|
|
6463
|
+
/* @__PURE__ */ jsx(
|
|
6464
|
+
"button",
|
|
6465
|
+
{
|
|
6466
|
+
onClick: close,
|
|
6467
|
+
className: "absolute top-3 right-3 z-10 flex h-8 w-8 items-center justify-center rounded-full bg-black/30 text-white backdrop-blur-sm transition-colors hover:bg-black/50",
|
|
6468
|
+
"aria-label": "Close",
|
|
6469
|
+
children: /* @__PURE__ */ jsx(XIcon, { className: "h-4 w-4" })
|
|
6470
|
+
}
|
|
6471
|
+
),
|
|
6472
|
+
config.imageUrl && /* @__PURE__ */ jsxs("div", { className: "relative h-44 w-full shrink-0 overflow-hidden sm:h-52", children: [
|
|
6473
|
+
/* @__PURE__ */ jsx(
|
|
6474
|
+
"img",
|
|
6475
|
+
{
|
|
6476
|
+
src: config.imageUrl,
|
|
6477
|
+
alt: "",
|
|
6478
|
+
className: "h-full w-full object-cover",
|
|
6479
|
+
loading: "eager"
|
|
6480
|
+
}
|
|
6481
|
+
),
|
|
6482
|
+
/* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-gradient-to-t from-black/50 to-transparent" })
|
|
6483
|
+
] }),
|
|
6484
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-1 flex-col gap-5 p-5 sm:p-6", children: !submitted ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6485
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
6486
|
+
/* @__PURE__ */ jsx("h2", { className: "font-heading text-lg font-bold leading-tight tracking-tight text-foreground sm:text-xl", children: config.heading }),
|
|
6487
|
+
config.subtitle && /* @__PURE__ */ jsx("p", { className: "text-sm leading-relaxed text-muted-foreground", children: config.subtitle })
|
|
6488
|
+
] }),
|
|
6489
|
+
/* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "flex flex-col gap-4", children: [
|
|
6490
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
6491
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "pexo-lead-name", className: "text-xs uppercase tracking-wider text-muted-foreground", children: config.nameLabel }),
|
|
6492
|
+
/* @__PURE__ */ jsx(
|
|
6493
|
+
Input,
|
|
6494
|
+
{
|
|
6495
|
+
ref: nameRef,
|
|
6496
|
+
id: "pexo-lead-name",
|
|
6497
|
+
type: "text",
|
|
6498
|
+
placeholder: config.namePlaceholder,
|
|
6499
|
+
value: name,
|
|
6500
|
+
onChange: (e) => setName(e.target.value),
|
|
6501
|
+
autoComplete: "name",
|
|
6502
|
+
className: "h-10 rounded-lg border-border/60 bg-muted/30 px-3 text-sm focus-visible:border-primary focus-visible:ring-primary/30"
|
|
6503
|
+
}
|
|
6504
|
+
)
|
|
6505
|
+
] }),
|
|
6506
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
6507
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "pexo-lead-email", className: "text-xs uppercase tracking-wider text-muted-foreground", children: config.emailLabel }),
|
|
6508
|
+
/* @__PURE__ */ jsx(
|
|
6509
|
+
Input,
|
|
6510
|
+
{
|
|
6511
|
+
id: "pexo-lead-email",
|
|
6512
|
+
type: "email",
|
|
6513
|
+
placeholder: config.emailPlaceholder,
|
|
6514
|
+
value: email,
|
|
6515
|
+
onChange: (e) => setEmail(e.target.value),
|
|
6516
|
+
autoComplete: "email",
|
|
6517
|
+
className: "h-10 rounded-lg border-border/60 bg-muted/30 px-3 text-sm focus-visible:border-primary focus-visible:ring-primary/30"
|
|
6518
|
+
}
|
|
6519
|
+
)
|
|
6520
|
+
] }),
|
|
6521
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
6522
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "pexo-lead-travel", className: "text-xs uppercase tracking-wider text-muted-foreground", children: config.travelDateLabel }),
|
|
6523
|
+
/* @__PURE__ */ jsxs(
|
|
6524
|
+
"select",
|
|
6525
|
+
{
|
|
6526
|
+
id: "pexo-lead-travel",
|
|
6527
|
+
value: travelDate,
|
|
6528
|
+
onChange: (e) => setTravelDate(e.target.value),
|
|
6529
|
+
className: cn(
|
|
6530
|
+
"h-10 w-full appearance-none rounded-lg border border-border/60 bg-muted/30 px-3 text-sm text-foreground outline-none transition-colors",
|
|
6531
|
+
"focus-visible:border-primary focus-visible:ring-3 focus-visible:ring-primary/30",
|
|
6532
|
+
!travelDate && "text-muted-foreground"
|
|
6533
|
+
),
|
|
6534
|
+
style: {
|
|
6535
|
+
backgroundImage: `url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%239ca3af' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E")`,
|
|
6536
|
+
backgroundRepeat: "no-repeat",
|
|
6537
|
+
backgroundPosition: "right 0.75rem center",
|
|
6538
|
+
paddingRight: "2.5rem"
|
|
6539
|
+
},
|
|
6540
|
+
children: [
|
|
6541
|
+
/* @__PURE__ */ jsx("option", { value: "", disabled: true, children: "Select a timeframe\u2026" }),
|
|
6542
|
+
config.travelDateOptions.map((opt) => /* @__PURE__ */ jsx("option", { value: opt, children: opt }, opt))
|
|
6543
|
+
]
|
|
6544
|
+
}
|
|
6545
|
+
)
|
|
6546
|
+
] }),
|
|
6547
|
+
error && /* @__PURE__ */ jsx("p", { className: "text-xs font-medium text-destructive", role: "alert", children: error }),
|
|
6548
|
+
/* @__PURE__ */ jsxs(
|
|
6549
|
+
Button,
|
|
6550
|
+
{
|
|
6551
|
+
type: "submit",
|
|
6552
|
+
disabled: submitting,
|
|
6553
|
+
className: cn(
|
|
6554
|
+
"h-11 w-full gap-2 rounded-lg text-sm font-bold tracking-wide",
|
|
6555
|
+
config.accentColor ? "border-transparent text-white" : "bg-primary text-primary-foreground hover:bg-primary/90"
|
|
6556
|
+
),
|
|
6557
|
+
style: config.accentColor ? { backgroundColor: config.accentColor } : void 0,
|
|
6558
|
+
children: [
|
|
6559
|
+
submitting ? /* @__PURE__ */ jsx(Loader2Icon, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx(SendIcon, { className: "h-4 w-4" }),
|
|
6560
|
+
submitting ? "Sending\u2026" : config.submitLabel
|
|
6561
|
+
]
|
|
6562
|
+
}
|
|
6563
|
+
),
|
|
6564
|
+
config.privacyText && /* @__PURE__ */ jsx(
|
|
6565
|
+
"p",
|
|
6566
|
+
{
|
|
6567
|
+
className: "text-center text-[11px] leading-relaxed text-muted-foreground [&_a]:underline [&_a]:underline-offset-2 [&_a]:hover:text-foreground",
|
|
6568
|
+
dangerouslySetInnerHTML: { __html: config.privacyText }
|
|
6569
|
+
}
|
|
6570
|
+
)
|
|
6571
|
+
] })
|
|
6572
|
+
] }) : (
|
|
6573
|
+
/* ---- Success state ---- */
|
|
6574
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col items-center justify-center gap-4 py-8 text-center", children: [
|
|
6575
|
+
/* @__PURE__ */ jsx("div", { className: "flex h-16 w-16 items-center justify-center rounded-full bg-primary/10", children: /* @__PURE__ */ jsx(CheckCircleIcon, { className: "h-8 w-8 text-primary" }) }),
|
|
6576
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
|
|
6577
|
+
/* @__PURE__ */ jsx("h2", { className: "font-heading text-lg font-bold text-foreground", children: config.successHeading }),
|
|
6578
|
+
/* @__PURE__ */ jsx("p", { className: "text-sm leading-relaxed text-muted-foreground", children: config.successMessage })
|
|
6579
|
+
] }),
|
|
6580
|
+
/* @__PURE__ */ jsx(
|
|
6581
|
+
Button,
|
|
6582
|
+
{
|
|
6583
|
+
onClick: close,
|
|
6584
|
+
variant: "outline",
|
|
6585
|
+
className: "mt-2 h-10 px-6 text-sm",
|
|
6586
|
+
children: "Close"
|
|
6587
|
+
}
|
|
6588
|
+
)
|
|
6589
|
+
] })
|
|
6590
|
+
) })
|
|
6591
|
+
]
|
|
6592
|
+
}
|
|
6593
|
+
),
|
|
6594
|
+
/* @__PURE__ */ jsx("style", { children: `
|
|
6595
|
+
@keyframes pexo-fade-in { from { opacity: 0 } to { opacity: 1 } }
|
|
6596
|
+
@keyframes pexo-fade-out { from { opacity: 1 } to { opacity: 0 } }
|
|
6597
|
+
@keyframes pexo-zoom-in { from { opacity: 0; transform: scale(0.92) } to { opacity: 1; transform: scale(1) } }
|
|
6598
|
+
@keyframes pexo-zoom-out { from { opacity: 1; transform: scale(1) } to { opacity: 0; transform: scale(0.92) } }
|
|
6599
|
+
@keyframes pexo-slide-in-right { from { opacity: 0; transform: translateX(100%) } to { opacity: 1; transform: translateX(0) } }
|
|
6600
|
+
@keyframes pexo-slide-out-right { from { opacity: 1; transform: translateX(0) } to { opacity: 0; transform: translateX(100%) } }
|
|
6601
|
+
|
|
6602
|
+
.pexo-lead-popup .animate-fade-in { animation: pexo-fade-in 0.3s ease-out both }
|
|
6603
|
+
.pexo-lead-popup .animate-fade-out { animation: pexo-fade-out 0.25s ease-in both }
|
|
6604
|
+
.pexo-lead-popup .animate-zoom-in { animation: pexo-zoom-in 0.35s cubic-bezier(0.16,1,0.3,1) both }
|
|
6605
|
+
.pexo-lead-popup .animate-zoom-out { animation: pexo-zoom-out 0.25s ease-in both }
|
|
6606
|
+
.pexo-lead-popup .animate-slide-in-right { animation: pexo-slide-in-right 0.4s cubic-bezier(0.16,1,0.3,1) both }
|
|
6607
|
+
.pexo-lead-popup .animate-slide-out-right { animation: pexo-slide-out-right 0.3s ease-in both }
|
|
6608
|
+
|
|
6609
|
+
/* Ensure popup fonts inherit from design system */
|
|
6610
|
+
.pexo-lead-popup { font-family: var(--font-sans, "Literata", Georgia, serif); }
|
|
6611
|
+
.pexo-lead-popup h1, .pexo-lead-popup h2, .pexo-lead-popup h3 { font-family: var(--font-heading, "ArcaMajora3", sans-serif); }
|
|
6612
|
+
.pexo-lead-popup button, .pexo-lead-popup label { font-family: var(--font-ui, "ArcaMajora3", sans-serif); }
|
|
6613
|
+
.pexo-lead-popup select { font-family: var(--font-sans, "Literata", Georgia, serif); }
|
|
6614
|
+
` })
|
|
6615
|
+
]
|
|
6616
|
+
}
|
|
6617
|
+
);
|
|
6618
|
+
}
|
|
3025
6619
|
|
|
3026
|
-
export { BookingConfirmation, BookingConfirmationEmail, BookingDetails, FloatingInput, FloatingSelect, Offer, OfferAdventureCard, cn };
|
|
6620
|
+
export { ActivityCard, BookingConfirmation, BookingConfirmationEmail, BookingDetails, BookingForm, COUNTRIES, CounterField, CountrySearchField, DEFAULT_HEADER_LINKS, DEFAULT_LANGUAGES, DatePickerField, FilterPanel, FloatingInput, FloatingSelect, Itinerary, LeadCapturePopup, MenuTrip, Offer, OfferAdventureCard, PhoneCountrySelect, PhotoGallery, PricingTrip, SiteHeader, ThemeToggle, TripCard, TripHeader, TripPage, cn };
|
|
3027
6621
|
//# sourceMappingURL=index.js.map
|
|
3028
6622
|
//# sourceMappingURL=index.js.map
|