@planetaexo/design-system 0.3.2 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1475,6 +1475,184 @@ function BirthDateField({
1475
1475
  ) })
1476
1476
  ] });
1477
1477
  }
1478
+ function BookingShell({
1479
+ steps,
1480
+ currentStep,
1481
+ title = "Booking details",
1482
+ children,
1483
+ onNext,
1484
+ onBack,
1485
+ onCancel,
1486
+ nextLabel = "Next",
1487
+ backLabel = "Back",
1488
+ cancelLabel = "Cancel",
1489
+ nextDisabled,
1490
+ nextBlockedMessage,
1491
+ error,
1492
+ successMessage
1493
+ }) {
1494
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-2xl border border-border bg-card overflow-hidden", children: [
1495
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b border-border px-5 py-4 bg-muted/20", children: [
1496
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-bold text-foreground font-heading mb-2", children: title }),
1497
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: steps.map((label, i) => /* @__PURE__ */ jsxRuntime.jsxs(React18__namespace.Fragment, { children: [
1498
+ /* @__PURE__ */ jsxRuntime.jsx(
1499
+ "span",
1500
+ {
1501
+ className: cn(
1502
+ "text-xs font-sans",
1503
+ i === currentStep ? "text-primary font-semibold" : i < currentStep ? "text-foreground" : "text-muted-foreground"
1504
+ ),
1505
+ children: label
1506
+ }
1507
+ ),
1508
+ i < steps.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, { className: "w-3 h-3 text-muted-foreground shrink-0" })
1509
+ ] }, i)) })
1510
+ ] }),
1511
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-5 flex flex-col gap-5", children: [
1512
+ /* @__PURE__ */ jsxRuntime.jsx("div", { children }),
1513
+ error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-destructive font-sans", children: error }),
1514
+ successMessage && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-sans rounded-lg px-3 py-2 bg-primary/10 border border-primary/30 text-primary", children: successMessage }),
1515
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
1516
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
1517
+ currentStep > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
1518
+ "button",
1519
+ {
1520
+ type: "button",
1521
+ onClick: onBack,
1522
+ className: "flex items-center gap-1.5 rounded-full border border-border px-5 py-2.5 text-sm text-foreground font-sans hover:bg-muted/50 transition-colors",
1523
+ children: [
1524
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeftIcon, { className: "w-3.5 h-3.5" }),
1525
+ backLabel
1526
+ ]
1527
+ }
1528
+ ),
1529
+ /* @__PURE__ */ jsxRuntime.jsx(
1530
+ "button",
1531
+ {
1532
+ type: "button",
1533
+ onClick: onNext,
1534
+ disabled: nextDisabled,
1535
+ className: cn(
1536
+ "rounded-full bg-primary px-8 py-2.5 text-sm font-bold",
1537
+ "text-primary-foreground font-heading transition-colors hover:bg-primary/90",
1538
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
1539
+ nextDisabled && "opacity-50 pointer-events-none"
1540
+ ),
1541
+ children: nextLabel
1542
+ }
1543
+ )
1544
+ ] }),
1545
+ nextDisabled && nextBlockedMessage && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-amber-400 bg-amber-500/10 border border-amber-500/30 rounded-lg px-3 py-2", children: nextBlockedMessage }),
1546
+ currentStep === 0 && onCancel && /* @__PURE__ */ jsxRuntime.jsx(
1547
+ "button",
1548
+ {
1549
+ type: "button",
1550
+ onClick: onCancel,
1551
+ className: "text-sm text-muted-foreground font-sans hover:text-foreground transition-colors self-start underline underline-offset-2",
1552
+ children: cancelLabel
1553
+ }
1554
+ )
1555
+ ] })
1556
+ ] })
1557
+ ] });
1558
+ }
1559
+ function PaymentAmountSelector({
1560
+ title = "What do you want to pay now?",
1561
+ depositLabel,
1562
+ fullLabel,
1563
+ value,
1564
+ onChange
1565
+ }) {
1566
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
1567
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-bold text-foreground font-heading", children: title }),
1568
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-2", children: ["deposit", "full"].map((opt) => /* @__PURE__ */ jsxRuntime.jsx(
1569
+ "button",
1570
+ {
1571
+ type: "button",
1572
+ onClick: () => onChange(opt),
1573
+ className: cn(
1574
+ "rounded-lg border-2 px-4 py-3 text-sm text-left font-sans transition-colors",
1575
+ value === opt ? "border-primary bg-primary/5 text-foreground font-semibold" : "border-border bg-background text-muted-foreground hover:border-primary/40"
1576
+ ),
1577
+ children: opt === "deposit" ? depositLabel : fullLabel
1578
+ },
1579
+ opt
1580
+ )) })
1581
+ ] });
1582
+ }
1583
+ function PaymentMethodSelector({
1584
+ title = "Payment method",
1585
+ methods,
1586
+ value,
1587
+ onChange
1588
+ }) {
1589
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-border p-4 flex flex-col gap-3", children: [
1590
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-bold text-muted-foreground font-heading uppercase tracking-widest", children: title }),
1591
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: methods.map((m) => /* @__PURE__ */ jsxRuntime.jsxs(
1592
+ "button",
1593
+ {
1594
+ type: "button",
1595
+ disabled: m.disabled,
1596
+ onClick: () => !m.disabled && onChange(m.id),
1597
+ className: cn(
1598
+ "flex items-start gap-3 rounded-lg border-2 px-4 py-3 text-left transition-colors",
1599
+ "disabled:opacity-50 disabled:cursor-not-allowed",
1600
+ value === m.id ? "border-primary bg-primary/5" : "border-border bg-background hover:border-primary/40"
1601
+ ),
1602
+ children: [
1603
+ /* @__PURE__ */ jsxRuntime.jsx(
1604
+ "span",
1605
+ {
1606
+ className: cn(
1607
+ "mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full border-2 transition-colors",
1608
+ value === m.id ? "border-primary" : "border-border"
1609
+ ),
1610
+ children: value === m.id && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-2 w-2 rounded-full bg-primary" })
1611
+ }
1612
+ ),
1613
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-col gap-0.5", children: [
1614
+ /* @__PURE__ */ jsxRuntime.jsx(
1615
+ "span",
1616
+ {
1617
+ className: cn(
1618
+ "text-sm font-semibold font-sans",
1619
+ value === m.id ? "text-primary" : "text-foreground"
1620
+ ),
1621
+ children: m.label
1622
+ }
1623
+ ),
1624
+ m.description && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground font-sans", children: m.description })
1625
+ ] })
1626
+ ]
1627
+ },
1628
+ m.id
1629
+ )) })
1630
+ ] });
1631
+ }
1632
+ function TermsSection({
1633
+ title = "Terms and conditions",
1634
+ checked,
1635
+ onChange,
1636
+ label,
1637
+ warningMessage
1638
+ }) {
1639
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-border p-4 flex flex-col gap-3", children: [
1640
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-bold text-muted-foreground font-heading uppercase tracking-widest", children: title }),
1641
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-start gap-2.5 cursor-pointer", children: [
1642
+ /* @__PURE__ */ jsxRuntime.jsx(
1643
+ "input",
1644
+ {
1645
+ type: "checkbox",
1646
+ checked,
1647
+ onChange: (e) => onChange(e.target.checked),
1648
+ className: "h-4 w-4 shrink-0 mt-0.5 rounded border-border accent-primary cursor-pointer"
1649
+ }
1650
+ ),
1651
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-sans text-foreground/80 leading-snug", children: label })
1652
+ ] }),
1653
+ !checked && warningMessage && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-amber-400 flex items-center gap-1", children: warningMessage })
1654
+ ] });
1655
+ }
1478
1656
  var WIZARD_STEPS = [
1479
1657
  { id: "responsible", label: "Responsible party details" },
1480
1658
  { id: "travellers", label: "Travellers" },
@@ -1587,265 +1765,186 @@ function BookingWizard({
1587
1765
  )
1588
1766
  ] });
1589
1767
  }
1590
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-2xl border border-border bg-card overflow-hidden", children: [
1591
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b border-border px-5 py-4 bg-muted/20", children: [
1592
- /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-base font-bold text-foreground font-heading mb-2", children: "Booking details" }),
1593
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1.5 flex-wrap", children: WIZARD_STEPS.map((s, i) => /* @__PURE__ */ jsxRuntime.jsxs(React18__namespace.Fragment, { children: [
1594
- /* @__PURE__ */ jsxRuntime.jsx(
1595
- "span",
1596
- {
1597
- className: cn(
1598
- "text-xs font-sans",
1599
- s.id === step ? "text-primary font-semibold" : i < stepIndex ? "text-foreground" : "text-muted-foreground"
1600
- ),
1601
- children: s.label
1602
- }
1603
- ),
1604
- i < WIZARD_STEPS.length - 1 && /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ChevronRightIcon, { className: "w-3 h-3 text-muted-foreground shrink-0" })
1605
- ] }, s.id)) })
1606
- ] }),
1607
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-5 flex flex-col gap-5", children: [
1608
- step === "responsible" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
1609
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground font-sans", children: "Enter the responsible person's details. This person will receive booking confirmations and is accountable for all travellers." }),
1610
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
1611
- /* @__PURE__ */ jsxRuntime.jsx(FloatingInput, { label: "First name", required: true, value: responsible.firstName, onChange: (e) => setR("firstName", e.target.value) }),
1612
- /* @__PURE__ */ jsxRuntime.jsx(FloatingInput, { label: "Last name", required: true, value: responsible.lastName, onChange: (e) => setR("lastName", e.target.value) })
1613
- ] }),
1614
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
1615
- /* @__PURE__ */ jsxRuntime.jsx(FloatingInput, { label: "Email", type: "email", required: true, value: responsible.email, onChange: (e) => setR("email", e.target.value) }),
1616
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full min-w-0", children: [
1617
- /* @__PURE__ */ jsxRuntime.jsx(PhoneCountrySelect, { value: responsible.phoneCountry, onChange: (c) => setR("phoneCountry", c), className: "shrink-0" }),
1618
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative min-w-0 flex-1", children: [
1619
- /* @__PURE__ */ jsxRuntime.jsx(
1620
- "input",
1621
- {
1622
- id: "wiz-phone",
1623
- type: "tel",
1624
- placeholder: " ",
1625
- value: responsible.phone,
1626
- onChange: (e) => setR("phone", e.target.value),
1627
- className: "peer block h-14 w-full rounded-r-lg border border-border bg-background px-3 pt-5 pb-2 text-base text-foreground font-ui transition-colors placeholder-transparent focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary"
1628
- }
1629
- ),
1630
- /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "wiz-phone", className: "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-base text-muted-foreground font-ui transition-all duration-150 peer-focus:top-3 peer-focus:translate-y-0 peer-focus:text-xs peer-focus:text-primary peer-not-placeholder-shown:top-3 peer-not-placeholder-shown:translate-y-0 peer-not-placeholder-shown:text-xs", children: "Phone" })
1631
- ] })
1632
- ] })
1633
- ] }),
1634
- /* @__PURE__ */ jsxRuntime.jsx(CountrySearchField, { required: true, value: responsible.country, onChange: (code) => setR("country", code) }),
1635
- /* @__PURE__ */ jsxRuntime.jsx(FloatingInput, { label: "Passport / CPF", required: true, value: responsible.passport, onChange: (e) => setR("passport", e.target.value) }),
1636
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
1637
- /* @__PURE__ */ jsxRuntime.jsx(
1638
- "textarea",
1639
- {
1640
- id: "wiz-notes",
1641
- placeholder: " ",
1642
- rows: 3,
1643
- value: responsible.notes,
1644
- onChange: (e) => setR("notes", e.target.value),
1645
- className: "peer block w-full resize-none rounded-lg border border-border bg-background px-3 pt-6 pb-3 text-base text-foreground font-ui transition-colors placeholder-transparent focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary"
1646
- }
1647
- ),
1648
- /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "wiz-notes", className: "pointer-events-none absolute left-3 top-4 text-base text-muted-foreground font-ui transition-all duration-150 peer-focus:top-2 peer-focus:text-xs peer-focus:text-primary peer-not-placeholder-shown:top-2 peer-not-placeholder-shown:text-xs", children: "Notes (optional)" })
1649
- ] })
1650
- ] }),
1651
- step === "travellers" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-5", children: [
1652
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
1653
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UsersIcon, { className: "w-5 h-5 text-primary shrink-0" }),
1654
- /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-bold text-foreground font-heading text-base", children: "Traveller details" })
1655
- ] }),
1656
- travellers.map((t, i) => {
1657
- const isChild = i >= totalAdults;
1658
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-border p-4 flex flex-col gap-3", children: [
1659
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
1660
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm font-bold text-foreground font-heading", children: [
1661
- "Traveller ",
1662
- i + 1
1663
- ] }),
1664
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
1665
- "text-xs font-semibold font-heading rounded-full px-2.5 py-0.5",
1666
- isChild ? "bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400" : "bg-primary/10 text-primary"
1667
- ), children: isChild ? "Crian\xE7a" : "Adulto" })
1668
- ] }),
1669
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2", children: [
1670
- /* @__PURE__ */ jsxRuntime.jsx(FloatingInput, { label: "First name", required: true, value: t.firstName, onChange: (e) => setT(i, "firstName", e.target.value) }),
1671
- /* @__PURE__ */ jsxRuntime.jsx(FloatingInput, { label: "Last name", required: true, value: t.lastName, onChange: (e) => setT(i, "lastName", e.target.value) })
1672
- ] }),
1673
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2", children: [
1674
- /* @__PURE__ */ jsxRuntime.jsx(
1675
- BirthDateField,
1676
- {
1677
- label: "Date of birth",
1678
- required: isChild,
1679
- value: t.dateOfBirth,
1680
- onChange: (d) => setTDob(i, d)
1681
- }
1682
- ),
1683
- /* @__PURE__ */ jsxRuntime.jsx(
1684
- FloatingInput,
1685
- {
1686
- label: "Email",
1687
- type: "email",
1688
- value: t.email,
1689
- onChange: (e) => setT(i, "email", e.target.value)
1690
- }
1691
- )
1768
+ return /* @__PURE__ */ jsxRuntime.jsx(
1769
+ BookingShell,
1770
+ {
1771
+ steps: WIZARD_STEPS.map((s) => s.label),
1772
+ currentStep: stepIndex,
1773
+ title: "Booking details",
1774
+ onNext: goNext,
1775
+ onBack: goPrev,
1776
+ onCancel,
1777
+ nextLabel: step === "payment" ? "Confirm booking" : "Next",
1778
+ backLabel: "Back",
1779
+ cancelLabel: "Cancel",
1780
+ error,
1781
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-5", children: [
1782
+ step === "responsible" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4", children: [
1783
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground font-sans", children: "Enter the responsible person's details. This person will receive booking confirmations and is accountable for all travellers." }),
1784
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
1785
+ /* @__PURE__ */ jsxRuntime.jsx(FloatingInput, { label: "First name", required: true, value: responsible.firstName, onChange: (e) => setR("firstName", e.target.value) }),
1786
+ /* @__PURE__ */ jsxRuntime.jsx(FloatingInput, { label: "Last name", required: true, value: responsible.lastName, onChange: (e) => setR("lastName", e.target.value) })
1787
+ ] }),
1788
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
1789
+ /* @__PURE__ */ jsxRuntime.jsx(FloatingInput, { label: "Email", type: "email", required: true, value: responsible.email, onChange: (e) => setR("email", e.target.value) }),
1790
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex w-full min-w-0", children: [
1791
+ /* @__PURE__ */ jsxRuntime.jsx(PhoneCountrySelect, { value: responsible.phoneCountry, onChange: (c) => setR("phoneCountry", c), className: "shrink-0" }),
1792
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative min-w-0 flex-1", children: [
1793
+ /* @__PURE__ */ jsxRuntime.jsx(
1794
+ "input",
1795
+ {
1796
+ id: "wiz-phone",
1797
+ type: "tel",
1798
+ placeholder: " ",
1799
+ value: responsible.phone,
1800
+ onChange: (e) => setR("phone", e.target.value),
1801
+ className: "peer block h-14 w-full rounded-r-lg border border-border bg-background px-3 pt-5 pb-2 text-base text-foreground font-ui transition-colors placeholder-transparent focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary"
1802
+ }
1803
+ ),
1804
+ /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "wiz-phone", className: "pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-base text-muted-foreground font-ui transition-all duration-150 peer-focus:top-3 peer-focus:translate-y-0 peer-focus:text-xs peer-focus:text-primary peer-not-placeholder-shown:top-3 peer-not-placeholder-shown:translate-y-0 peer-not-placeholder-shown:text-xs", children: "Phone" })
1805
+ ] })
1692
1806
  ] })
1693
- ] }, i);
1694
- })
1695
- ] }),
1696
- step === "payment" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-5", children: [
1697
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground font-sans", children: "When you confirm, we will open secure online payment (Stripe). Choose deposit vs full amount below when applicable." }),
1698
- depositInfo && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
1699
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm font-bold text-foreground font-heading", children: "What do you want to pay now?" }),
1700
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid grid-cols-1 sm:grid-cols-2 gap-2", children: ["deposit", "full"].map((opt) => /* @__PURE__ */ jsxRuntime.jsx(
1701
- "button",
1702
- {
1703
- type: "button",
1704
- onClick: () => setPayAmount(opt),
1705
- className: cn(
1706
- "rounded-lg border-2 px-4 py-3 text-sm text-left font-sans transition-colors",
1707
- payAmount === opt ? "border-primary bg-primary/5 text-foreground font-semibold" : "border-border bg-background text-muted-foreground hover:border-primary/40"
1708
- ),
1709
- children: opt === "deposit" ? depositLabel : fullLabel
1710
- },
1711
- opt
1712
- )) })
1713
- ] }),
1714
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-border p-4 flex flex-col gap-3", children: [
1715
- /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs font-bold text-muted-foreground font-heading uppercase tracking-widest flex items-center gap-1.5", children: [
1716
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "$" }),
1717
- " Payment method"
1718
1807
  ] }),
1719
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex flex-col gap-2", children: [
1720
- { id: "stripe", label: "Credit / Debit card", sub: "Secure payment via Stripe" },
1721
- { id: "pix", label: "PIX", sub: "Instant transfer \u2014 Brazil only" },
1722
- { id: "bank", label: "Bank transfer", sub: "Wire / TED / DOC" }
1723
- ].map((m) => /* @__PURE__ */ jsxRuntime.jsxs(
1724
- "button",
1725
- {
1726
- type: "button",
1727
- onClick: () => setPayMethod(m.id),
1728
- className: cn(
1729
- "flex items-start gap-3 rounded-lg border-2 px-4 py-3 text-left transition-colors",
1730
- payMethod === m.id ? "border-primary bg-primary/5" : "border-border bg-background hover:border-primary/40"
1731
- ),
1732
- children: [
1733
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
1734
- "mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full border-2 transition-colors",
1735
- payMethod === m.id ? "border-primary" : "border-border"
1736
- ), children: payMethod === m.id && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "h-2 w-2 rounded-full bg-primary" }) }),
1737
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex flex-col gap-0.5", children: [
1738
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
1739
- "text-sm font-semibold font-sans",
1740
- payMethod === m.id ? "text-primary" : "text-foreground"
1741
- ), children: m.label }),
1742
- /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-xs text-muted-foreground font-sans", children: m.sub })
1743
- ] })
1744
- ]
1745
- },
1746
- m.id
1747
- )) })
1748
- ] }),
1749
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-border p-4 flex flex-col gap-3", children: [
1750
- /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs font-bold text-muted-foreground font-heading uppercase tracking-widest", children: "Terms and conditions" }),
1751
- /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "flex items-start gap-2.5 cursor-pointer", children: [
1808
+ /* @__PURE__ */ jsxRuntime.jsx(CountrySearchField, { required: true, value: responsible.country, onChange: (code) => setR("country", code) }),
1809
+ /* @__PURE__ */ jsxRuntime.jsx(FloatingInput, { label: "Passport / CPF", required: true, value: responsible.passport, onChange: (e) => setR("passport", e.target.value) }),
1810
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative", children: [
1752
1811
  /* @__PURE__ */ jsxRuntime.jsx(
1753
- "input",
1812
+ "textarea",
1754
1813
  {
1755
- type: "checkbox",
1756
- checked: termsAccepted,
1757
- onChange: (e) => setTermsAccepted(e.target.checked),
1758
- className: "h-4 w-4 shrink-0 mt-0.5 rounded border-border accent-primary cursor-pointer"
1814
+ id: "wiz-notes",
1815
+ placeholder: " ",
1816
+ rows: 3,
1817
+ value: responsible.notes,
1818
+ onChange: (e) => setR("notes", e.target.value),
1819
+ className: "peer block w-full resize-none rounded-lg border border-border bg-background px-3 pt-6 pb-3 text-base text-foreground font-ui transition-colors placeholder-transparent focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary"
1759
1820
  }
1760
1821
  ),
1761
- /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-sm font-sans text-foreground/80 leading-snug", children: [
1762
- "I have read and accept the",
1763
- " ",
1764
- /* @__PURE__ */ jsxRuntime.jsx(
1765
- "button",
1766
- {
1767
- type: "button",
1768
- onClick: () => setTermsModalOpen(true),
1769
- className: "underline underline-offset-2 text-primary hover:text-primary/80 transition-colors font-semibold",
1770
- children: "terms and conditions"
1771
- }
1772
- ),
1773
- " ",
1774
- "of the reservation."
1775
- ] })
1822
+ /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: "wiz-notes", className: "pointer-events-none absolute left-3 top-4 text-base text-muted-foreground font-ui transition-all duration-150 peer-focus:top-2 peer-focus:text-xs peer-focus:text-primary peer-not-placeholder-shown:top-2 peer-not-placeholder-shown:text-xs", children: "Notes (optional)" })
1776
1823
  ] })
1777
1824
  ] }),
1778
- /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: termsModalOpen, onOpenChange: setTermsModalOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "!max-w-[80vw] w-[80vw] max-h-[85vh] overflow-y-auto", children: [
1779
- /* @__PURE__ */ jsxRuntime.jsx(DialogHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { className: "font-heading text-xl", children: "Terms and Conditions" }) }),
1780
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4 text-sm font-sans text-foreground/80 leading-relaxed", children: [
1781
- /* @__PURE__ */ jsxRuntime.jsx("p", { children: 'These terms and conditions ("Terms") govern the booking of travel experiences offered through Planeta EXO ("Company"). By confirming a booking, you agree to these Terms in full.' }),
1782
- /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-bold text-foreground font-heading text-base", children: "1. Bookings and payments" }),
1783
- /* @__PURE__ */ jsxRuntime.jsx("p", { children: "A booking is confirmed upon receipt of the required deposit or full payment. The deposit amount is specified in your offer. The remaining balance must be paid by the balance due date stated in your offer." }),
1784
- /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-bold text-foreground font-heading text-base", children: "2. Cancellation policy" }),
1785
- /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Cancellations made more than 60 days before departure are eligible for a full refund of the deposit. Cancellations between 30 and 60 days forfeit 50% of the deposit. Cancellations within 30 days of departure are non-refundable." }),
1786
- /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-bold text-foreground font-heading text-base", children: "3. Changes and modifications" }),
1787
- /* @__PURE__ */ jsxRuntime.jsx("p", { children: "The Company reserves the right to modify itineraries due to weather, safety, or operational reasons. Equivalent alternatives will be offered wherever possible." }),
1788
- /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-bold text-foreground font-heading text-base", children: "4. Travel insurance" }),
1789
- /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Comprehensive travel insurance is strongly recommended. The Company is not liable for costs arising from trip interruption, medical emergencies, or personal loss." }),
1790
- /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-bold text-foreground font-heading text-base", children: "5. Liability" }),
1791
- /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Participation in adventure activities carries inherent risk. By booking, you acknowledge and accept these risks. The Company's liability is limited to the total booking amount." }),
1792
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-2", children: /* @__PURE__ */ jsxRuntime.jsx(
1793
- DialogClose,
1794
- {
1795
- render: /* @__PURE__ */ jsxRuntime.jsx(
1796
- "button",
1825
+ step === "travellers" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-5", children: [
1826
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
1827
+ /* @__PURE__ */ jsxRuntime.jsx(lucideReact.UsersIcon, { className: "w-5 h-5 text-primary shrink-0" }),
1828
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-bold text-foreground font-heading text-base", children: "Traveller details" })
1829
+ ] }),
1830
+ travellers.map((t, i) => {
1831
+ const isChild = i >= totalAdults;
1832
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-xl border border-border p-4 flex flex-col gap-3", children: [
1833
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between", children: [
1834
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm font-bold text-foreground font-heading", children: [
1835
+ "Traveller ",
1836
+ i + 1
1837
+ ] }),
1838
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: cn(
1839
+ "text-xs font-semibold font-heading rounded-full px-2.5 py-0.5",
1840
+ isChild ? "bg-orange-100 text-orange-700 dark:bg-orange-900/30 dark:text-orange-400" : "bg-primary/10 text-primary"
1841
+ ), children: isChild ? "Crian\xE7a" : "Adulto" })
1842
+ ] }),
1843
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2", children: [
1844
+ /* @__PURE__ */ jsxRuntime.jsx(FloatingInput, { label: "First name", required: true, value: t.firstName, onChange: (e) => setT(i, "firstName", e.target.value) }),
1845
+ /* @__PURE__ */ jsxRuntime.jsx(FloatingInput, { label: "Last name", required: true, value: t.lastName, onChange: (e) => setT(i, "lastName", e.target.value) })
1846
+ ] }),
1847
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-1 gap-3 sm:grid-cols-2", children: [
1848
+ /* @__PURE__ */ jsxRuntime.jsx(
1849
+ BirthDateField,
1797
1850
  {
1798
- type: "button",
1799
- className: "rounded-full bg-primary px-6 py-2.5 text-sm font-bold text-primary-foreground font-heading hover:bg-primary/90 transition-colors"
1851
+ label: "Date of birth",
1852
+ required: isChild,
1853
+ value: t.dateOfBirth,
1854
+ onChange: (d) => setTDob(i, d)
1800
1855
  }
1801
1856
  ),
1802
- children: "Close"
1803
- }
1804
- ) })
1805
- ] })
1806
- ] }) })
1807
- ] }),
1808
- error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-destructive font-sans", children: error }),
1809
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-2", children: [
1810
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
1811
- stepIndex > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
1812
- "button",
1857
+ /* @__PURE__ */ jsxRuntime.jsx(
1858
+ FloatingInput,
1859
+ {
1860
+ label: "Email",
1861
+ type: "email",
1862
+ value: t.email,
1863
+ onChange: (e) => setT(i, "email", e.target.value)
1864
+ }
1865
+ )
1866
+ ] })
1867
+ ] }, i);
1868
+ })
1869
+ ] }),
1870
+ step === "payment" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-5", children: [
1871
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-muted-foreground font-sans", children: "When you confirm, we will open secure online payment (Stripe). Choose deposit vs full amount below when applicable." }),
1872
+ depositInfo && /* @__PURE__ */ jsxRuntime.jsx(
1873
+ PaymentAmountSelector,
1813
1874
  {
1814
- type: "button",
1815
- onClick: goPrev,
1816
- className: "flex items-center gap-1.5 rounded-full border border-border px-5 py-2.5 text-sm text-foreground font-sans hover:bg-muted/50 transition-colors",
1817
- children: [
1818
- /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowLeftIcon, { className: "w-3.5 h-3.5" }),
1819
- "Back"
1820
- ]
1875
+ depositLabel,
1876
+ fullLabel,
1877
+ value: payAmount,
1878
+ onChange: setPayAmount
1821
1879
  }
1822
1880
  ),
1823
1881
  /* @__PURE__ */ jsxRuntime.jsx(
1824
- "button",
1882
+ PaymentMethodSelector,
1825
1883
  {
1826
- type: "button",
1827
- onClick: goNext,
1828
- className: cn(
1829
- "rounded-full bg-primary px-8 py-2.5 text-sm font-bold",
1830
- "text-primary-foreground font-heading transition-colors hover:bg-primary/90",
1831
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
1832
- ),
1833
- children: step === "payment" ? "Confirm booking" : "Next"
1884
+ methods: [
1885
+ { id: "stripe", label: "Credit / Debit card", description: "Secure payment via Stripe" },
1886
+ { id: "pix", label: "PIX", description: "Instant transfer \u2014 Brazil only" },
1887
+ { id: "bank", label: "Bank transfer", description: "Wire / TED / DOC" }
1888
+ ],
1889
+ value: payMethod,
1890
+ onChange: (v) => setPayMethod(v)
1834
1891
  }
1835
- )
1836
- ] }),
1837
- stepIndex === 0 && /* @__PURE__ */ jsxRuntime.jsx(
1838
- "button",
1839
- {
1840
- type: "button",
1841
- onClick: onCancel,
1842
- className: "text-sm text-muted-foreground font-sans hover:text-foreground transition-colors self-start underline underline-offset-2",
1843
- children: "Cancel"
1844
- }
1845
- )
1892
+ ),
1893
+ /* @__PURE__ */ jsxRuntime.jsx(
1894
+ TermsSection,
1895
+ {
1896
+ checked: termsAccepted,
1897
+ onChange: setTermsAccepted,
1898
+ label: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1899
+ "I have read and accept the",
1900
+ " ",
1901
+ /* @__PURE__ */ jsxRuntime.jsx(
1902
+ "button",
1903
+ {
1904
+ type: "button",
1905
+ onClick: () => setTermsModalOpen(true),
1906
+ className: "underline underline-offset-2 text-primary hover:text-primary/80 transition-colors font-semibold",
1907
+ children: "terms and conditions"
1908
+ }
1909
+ ),
1910
+ " ",
1911
+ "of the reservation."
1912
+ ] })
1913
+ }
1914
+ ),
1915
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog, { open: termsModalOpen, onOpenChange: setTermsModalOpen, children: /* @__PURE__ */ jsxRuntime.jsxs(DialogContent, { className: "!max-w-[80vw] w-[80vw] max-h-[85vh] overflow-y-auto", children: [
1916
+ /* @__PURE__ */ jsxRuntime.jsx(DialogHeader, { children: /* @__PURE__ */ jsxRuntime.jsx(DialogTitle, { className: "font-heading text-xl", children: "Terms and Conditions" }) }),
1917
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-4 text-sm font-sans text-foreground/80 leading-relaxed", children: [
1918
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: 'These terms and conditions ("Terms") govern the booking of travel experiences offered through Planeta EXO ("Company"). By confirming a booking, you agree to these Terms in full.' }),
1919
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-bold text-foreground font-heading text-base", children: "1. Bookings and payments" }),
1920
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: "A booking is confirmed upon receipt of the required deposit or full payment. The deposit amount is specified in your offer. The remaining balance must be paid by the balance due date stated in your offer." }),
1921
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-bold text-foreground font-heading text-base", children: "2. Cancellation policy" }),
1922
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Cancellations made more than 60 days before departure are eligible for a full refund of the deposit. Cancellations between 30 and 60 days forfeit 50% of the deposit. Cancellations within 30 days of departure are non-refundable." }),
1923
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-bold text-foreground font-heading text-base", children: "3. Changes and modifications" }),
1924
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: "The Company reserves the right to modify itineraries due to weather, safety, or operational reasons. Equivalent alternatives will be offered wherever possible." }),
1925
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-bold text-foreground font-heading text-base", children: "4. Travel insurance" }),
1926
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Comprehensive travel insurance is strongly recommended. The Company is not liable for costs arising from trip interruption, medical emergencies, or personal loss." }),
1927
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-bold text-foreground font-heading text-base", children: "5. Liability" }),
1928
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: "Participation in adventure activities carries inherent risk. By booking, you acknowledge and accept these risks. The Company's liability is limited to the total booking amount." }),
1929
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pt-2", children: /* @__PURE__ */ jsxRuntime.jsx(
1930
+ DialogClose,
1931
+ {
1932
+ render: /* @__PURE__ */ jsxRuntime.jsx(
1933
+ "button",
1934
+ {
1935
+ type: "button",
1936
+ className: "rounded-full bg-primary px-6 py-2.5 text-sm font-bold text-primary-foreground font-heading hover:bg-primary/90 transition-colors"
1937
+ }
1938
+ ),
1939
+ children: "Close"
1940
+ }
1941
+ ) })
1942
+ ] })
1943
+ ] }) })
1944
+ ] })
1846
1945
  ] })
1847
- ] })
1848
- ] });
1946
+ }
1947
+ );
1849
1948
  }
1850
1949
  function OfferAdventureCard({ adventure }) {
1851
1950
  return /* @__PURE__ */ jsxRuntime.jsx(AdventureCard, { adventure });
@@ -6692,6 +6791,7 @@ exports.BookingConfirmation = BookingConfirmation;
6692
6791
  exports.BookingConfirmationEmail = BookingConfirmationEmail;
6693
6792
  exports.BookingDetails = BookingDetails;
6694
6793
  exports.BookingForm = BookingForm;
6794
+ exports.BookingShell = BookingShell;
6695
6795
  exports.COUNTRIES = COUNTRIES;
6696
6796
  exports.CounterField = CounterField;
6697
6797
  exports.CountrySearchField = CountrySearchField;
@@ -6706,10 +6806,13 @@ exports.LeadCapturePopup = LeadCapturePopup;
6706
6806
  exports.MenuTrip = MenuTrip;
6707
6807
  exports.Offer = Offer;
6708
6808
  exports.OfferAdventureCard = OfferAdventureCard;
6809
+ exports.PaymentAmountSelector = PaymentAmountSelector;
6810
+ exports.PaymentMethodSelector = PaymentMethodSelector;
6709
6811
  exports.PhoneCountrySelect = PhoneCountrySelect;
6710
6812
  exports.PhotoGallery = PhotoGallery;
6711
6813
  exports.PricingTrip = PricingTrip;
6712
6814
  exports.SiteHeader = SiteHeader;
6815
+ exports.TermsSection = TermsSection;
6713
6816
  exports.ThemeToggle = ThemeToggle;
6714
6817
  exports.TripCard = TripCard;
6715
6818
  exports.TripHeader = TripHeader;