@reblu/site-blocks 0.30.0 → 0.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/README.md +236 -5
- package/dist/client.cjs +632 -0
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +105 -3
- package/dist/client.d.ts +105 -3
- package/dist/client.js +629 -0
- package/dist/client.js.map +1 -1
- package/dist/full-invoice-fields-DMX0sjPG.d.cts +140 -0
- package/dist/full-invoice-fields-DMX0sjPG.d.ts +140 -0
- package/dist/index.cjs +956 -349
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +223 -130
- package/dist/index.d.ts +223 -130
- package/dist/index.js +943 -350
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/dist/_heading-BsNbc1wc.d.cts +0 -4
- package/dist/_heading-BsNbc1wc.d.ts +0 -4
package/dist/client.js
CHANGED
|
@@ -1550,13 +1550,642 @@ function WithdrawalRequestForm({
|
|
|
1550
1550
|
}
|
|
1551
1551
|
);
|
|
1552
1552
|
}
|
|
1553
|
+
|
|
1554
|
+
// src/components/course-guest-checkout-form.tsx
|
|
1555
|
+
import { useId as useId5, useState as useState9 } from "react";
|
|
1556
|
+
import { cn as cn14 } from "@reblu/site-ui/utils";
|
|
1557
|
+
|
|
1558
|
+
// src/lib/course-guest-checkout.ts
|
|
1559
|
+
function toAcademyCheckoutInvoiceFields(value, overCap, issuesInvoices = true) {
|
|
1560
|
+
if (!issuesInvoices) return {};
|
|
1561
|
+
if (!value.wantsFullInvoice && !overCap) return {};
|
|
1562
|
+
const billing = {
|
|
1563
|
+
billingName: value.billingName.trim(),
|
|
1564
|
+
billingNif: value.billingNif.trim(),
|
|
1565
|
+
billingIdType: value.billingIdType,
|
|
1566
|
+
...value.billingIdType === "NIF" ? {} : { billingIdCountry: value.billingIdCountry },
|
|
1567
|
+
billingAddress: {
|
|
1568
|
+
street: value.street.trim(),
|
|
1569
|
+
postalCode: value.postalCode.trim(),
|
|
1570
|
+
city: value.city.trim(),
|
|
1571
|
+
country: value.country
|
|
1572
|
+
}
|
|
1573
|
+
};
|
|
1574
|
+
return { ...value.wantsFullInvoice ? { wantsFullInvoice: true } : {}, billing };
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1577
|
+
// src/components/checkout-pay-action.tsx
|
|
1578
|
+
import { cn as cn11 } from "@reblu/site-ui/utils";
|
|
1579
|
+
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1580
|
+
function CheckoutPayAction({
|
|
1581
|
+
label,
|
|
1582
|
+
notice,
|
|
1583
|
+
submitting = false,
|
|
1584
|
+
submittingLabel = "Procesando\u2026",
|
|
1585
|
+
disabled = false,
|
|
1586
|
+
id = "checkout-pay",
|
|
1587
|
+
className,
|
|
1588
|
+
buttonClassName,
|
|
1589
|
+
noticeClassName
|
|
1590
|
+
}) {
|
|
1591
|
+
const noticeId = `${id}-notice`;
|
|
1592
|
+
const isDisabled = submitting || disabled;
|
|
1593
|
+
return /* @__PURE__ */ jsxs9("div", { "data-slot": "checkout-pay-action", className: cn11("space-y-3", className), children: [
|
|
1594
|
+
/* @__PURE__ */ jsx11(
|
|
1595
|
+
"button",
|
|
1596
|
+
{
|
|
1597
|
+
type: "submit",
|
|
1598
|
+
disabled: isDisabled,
|
|
1599
|
+
"aria-busy": submitting || void 0,
|
|
1600
|
+
"aria-describedby": notice ? noticeId : void 0,
|
|
1601
|
+
className: buttonClassName ?? cn11(
|
|
1602
|
+
"flex w-full items-center justify-center gap-2 rounded-xl px-4 py-3 text-base font-semibold transition-all",
|
|
1603
|
+
isDisabled ? "cursor-not-allowed bg-muted text-muted-foreground" : "cursor-pointer bg-primary text-primary-foreground hover:bg-primary/90"
|
|
1604
|
+
),
|
|
1605
|
+
children: submitting ? submittingLabel : label
|
|
1606
|
+
}
|
|
1607
|
+
),
|
|
1608
|
+
notice ? /* @__PURE__ */ jsx11("p", { id: noticeId, "data-slot": "checkout-pay-notice", className: noticeClassName ?? "text-sm text-muted-foreground", children: notice }) : null
|
|
1609
|
+
] });
|
|
1610
|
+
}
|
|
1611
|
+
|
|
1612
|
+
// src/components/checkout-terms-acceptance.tsx
|
|
1613
|
+
import { cn as cn12 } from "@reblu/site-ui/utils";
|
|
1614
|
+
import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1615
|
+
function splitTermsLabel(label) {
|
|
1616
|
+
const at = label.indexOf("{terms}");
|
|
1617
|
+
return at === -1 ? [`${label} `, ""] : [label.slice(0, at), label.slice(at + "{terms}".length)];
|
|
1618
|
+
}
|
|
1619
|
+
function CheckoutTermsAcceptance({
|
|
1620
|
+
copy,
|
|
1621
|
+
termsHref,
|
|
1622
|
+
checked,
|
|
1623
|
+
onCheckedChange,
|
|
1624
|
+
error,
|
|
1625
|
+
newTabHint = "(se abre en una pesta\xF1a nueva)",
|
|
1626
|
+
id,
|
|
1627
|
+
className
|
|
1628
|
+
}) {
|
|
1629
|
+
if (!copy.termsVersion) return null;
|
|
1630
|
+
const boxId = id ?? "checkout-terms";
|
|
1631
|
+
const errorId = `${boxId}-error`;
|
|
1632
|
+
const [before, after] = splitTermsLabel(copy.termsCheckboxLabel).map(
|
|
1633
|
+
(part) => part.replaceAll("{tenant}", copy.tenantName)
|
|
1634
|
+
);
|
|
1635
|
+
const newTab = copy.isTermsLinkNewTab;
|
|
1636
|
+
return /* @__PURE__ */ jsxs10("div", { "data-slot": "checkout-terms", className: cn12("space-y-1", className), children: [
|
|
1637
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-start gap-3", children: [
|
|
1638
|
+
/* @__PURE__ */ jsx12(
|
|
1639
|
+
"input",
|
|
1640
|
+
{
|
|
1641
|
+
id: boxId,
|
|
1642
|
+
type: "checkbox",
|
|
1643
|
+
required: true,
|
|
1644
|
+
checked,
|
|
1645
|
+
onChange: (e) => onCheckedChange(e.target.checked),
|
|
1646
|
+
"aria-invalid": error ? true : void 0,
|
|
1647
|
+
"aria-describedby": error ? errorId : void 0,
|
|
1648
|
+
className: "mt-0.5 size-5 shrink-0 cursor-pointer accent-primary"
|
|
1649
|
+
}
|
|
1650
|
+
),
|
|
1651
|
+
/* @__PURE__ */ jsxs10("label", { htmlFor: boxId, className: "text-sm leading-relaxed", children: [
|
|
1652
|
+
before,
|
|
1653
|
+
/* @__PURE__ */ jsxs10(
|
|
1654
|
+
"a",
|
|
1655
|
+
{
|
|
1656
|
+
href: copy.termsLinkUrl ?? termsHref,
|
|
1657
|
+
...newTab ? { target: "_blank", rel: "noopener noreferrer" } : {},
|
|
1658
|
+
className: "font-medium underline underline-offset-2 hover:text-primary",
|
|
1659
|
+
children: [
|
|
1660
|
+
copy.termsLinkText,
|
|
1661
|
+
newTab ? /* @__PURE__ */ jsxs10(Fragment4, { children: [
|
|
1662
|
+
" ",
|
|
1663
|
+
/* @__PURE__ */ jsx12("span", { className: "sr-only", children: newTabHint })
|
|
1664
|
+
] }) : null
|
|
1665
|
+
]
|
|
1666
|
+
}
|
|
1667
|
+
),
|
|
1668
|
+
after
|
|
1669
|
+
] })
|
|
1670
|
+
] }),
|
|
1671
|
+
error ? /* @__PURE__ */ jsx12("p", { id: errorId, className: "pl-8 text-sm text-destructive", children: error }) : null
|
|
1672
|
+
] });
|
|
1673
|
+
}
|
|
1674
|
+
function toCheckoutTermsFields(copy, accepted) {
|
|
1675
|
+
const version = copy?.termsVersion;
|
|
1676
|
+
return version ? { acceptsTerms: accepted, termsVersionId: version.id } : {};
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1679
|
+
// src/components/full-invoice-fields.tsx
|
|
1680
|
+
import { cn as cn13 } from "@reblu/site-ui/utils";
|
|
1681
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1682
|
+
var EMPTY_FULL_INVOICE_VALUE = {
|
|
1683
|
+
wantsFullInvoice: false,
|
|
1684
|
+
billingIdType: "NIF",
|
|
1685
|
+
billingIdCountry: "",
|
|
1686
|
+
billingNif: "",
|
|
1687
|
+
billingName: "",
|
|
1688
|
+
street: "",
|
|
1689
|
+
postalCode: "",
|
|
1690
|
+
city: "",
|
|
1691
|
+
country: "ES"
|
|
1692
|
+
};
|
|
1693
|
+
var DEFAULT_LABELS5 = {
|
|
1694
|
+
toggle: "\xBFQuieres factura completa?",
|
|
1695
|
+
underCapNotice: "Para una factura completa necesitas tu NIF/NIE o un documento de identificaci\xF3n. Si no, recibir\xE1s una factura simplificada.",
|
|
1696
|
+
overCapNotice: "El importe del pedido supera el m\xE1ximo de la factura simplificada: para completar la compra, indica tu NIF/NIE o un documento de identificaci\xF3n, tu nombre y tu direcci\xF3n de facturaci\xF3n.",
|
|
1697
|
+
idType: "Tipo de documento",
|
|
1698
|
+
idCountry: "Pa\xEDs que expidi\xF3 el documento",
|
|
1699
|
+
chooseCountry: "Elige un pa\xEDs",
|
|
1700
|
+
spanishNif: "NIF / NIE / CIF",
|
|
1701
|
+
documentNumber: "N\xFAmero de documento",
|
|
1702
|
+
name: "Nombre o raz\xF3n social",
|
|
1703
|
+
street: "Direcci\xF3n",
|
|
1704
|
+
postalCode: "C\xF3digo postal",
|
|
1705
|
+
city: "Ciudad",
|
|
1706
|
+
country: "Pa\xEDs",
|
|
1707
|
+
idTypeOptions: {
|
|
1708
|
+
NIF: "NIF / NIE / CIF (Espa\xF1a)",
|
|
1709
|
+
"02": "NIF-IVA intracomunitario (otro pa\xEDs de la UE)",
|
|
1710
|
+
"03": "Pasaporte",
|
|
1711
|
+
"04": "Documento oficial de identidad de tu pa\xEDs de residencia",
|
|
1712
|
+
"05": "Certificado de residencia",
|
|
1713
|
+
"06": "Otro documento acreditativo"
|
|
1714
|
+
}
|
|
1715
|
+
};
|
|
1716
|
+
var ID_TYPES = ["NIF", "02", "03", "04", "05", "06"];
|
|
1717
|
+
var DEFAULT_INVOICE_COUNTRIES = [
|
|
1718
|
+
{ code: "ES", name: "Espa\xF1a" },
|
|
1719
|
+
{ code: "DE", name: "Alemania" },
|
|
1720
|
+
{ code: "AD", name: "Andorra" },
|
|
1721
|
+
{ code: "AR", name: "Argentina" },
|
|
1722
|
+
{ code: "AT", name: "Austria" },
|
|
1723
|
+
{ code: "BE", name: "B\xE9lgica" },
|
|
1724
|
+
{ code: "BG", name: "Bulgaria" },
|
|
1725
|
+
{ code: "CY", name: "Chipre" },
|
|
1726
|
+
{ code: "CO", name: "Colombia" },
|
|
1727
|
+
{ code: "HR", name: "Croacia" },
|
|
1728
|
+
{ code: "DK", name: "Dinamarca" },
|
|
1729
|
+
{ code: "SK", name: "Eslovaquia" },
|
|
1730
|
+
{ code: "SI", name: "Eslovenia" },
|
|
1731
|
+
{ code: "US", name: "Estados Unidos" },
|
|
1732
|
+
{ code: "EE", name: "Estonia" },
|
|
1733
|
+
{ code: "FI", name: "Finlandia" },
|
|
1734
|
+
{ code: "FR", name: "Francia" },
|
|
1735
|
+
{ code: "GR", name: "Grecia" },
|
|
1736
|
+
{ code: "HU", name: "Hungr\xEDa" },
|
|
1737
|
+
{ code: "IE", name: "Irlanda" },
|
|
1738
|
+
{ code: "IT", name: "Italia" },
|
|
1739
|
+
{ code: "LV", name: "Letonia" },
|
|
1740
|
+
{ code: "LT", name: "Lituania" },
|
|
1741
|
+
{ code: "LU", name: "Luxemburgo" },
|
|
1742
|
+
{ code: "MT", name: "Malta" },
|
|
1743
|
+
{ code: "MA", name: "Marruecos" },
|
|
1744
|
+
{ code: "MX", name: "M\xE9xico" },
|
|
1745
|
+
{ code: "NL", name: "Pa\xEDses Bajos" },
|
|
1746
|
+
{ code: "PL", name: "Polonia" },
|
|
1747
|
+
{ code: "PT", name: "Portugal" },
|
|
1748
|
+
{ code: "GB", name: "Reino Unido" },
|
|
1749
|
+
{ code: "CZ", name: "Rep\xFAblica Checa" },
|
|
1750
|
+
{ code: "RO", name: "Ruman\xEDa" },
|
|
1751
|
+
{ code: "SE", name: "Suecia" },
|
|
1752
|
+
{ code: "CH", name: "Suiza" },
|
|
1753
|
+
{ code: "VE", name: "Venezuela" }
|
|
1754
|
+
];
|
|
1755
|
+
function isOverSimplifiedInvoiceCap(totalCents, capCents) {
|
|
1756
|
+
return capCents != null && totalCents > capCents;
|
|
1757
|
+
}
|
|
1758
|
+
var FIELD_CLASS3 = "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm focus:border-primary focus:outline-none focus:ring-2 focus:ring-primary/20";
|
|
1759
|
+
function FullInvoiceFields({
|
|
1760
|
+
value,
|
|
1761
|
+
onChange,
|
|
1762
|
+
overCap,
|
|
1763
|
+
issuesInvoices = true,
|
|
1764
|
+
errors = {},
|
|
1765
|
+
countries = DEFAULT_INVOICE_COUNTRIES,
|
|
1766
|
+
labels,
|
|
1767
|
+
className
|
|
1768
|
+
}) {
|
|
1769
|
+
if (!issuesInvoices) return null;
|
|
1770
|
+
const t = { ...DEFAULT_LABELS5, ...labels };
|
|
1771
|
+
const showFields = value.wantsFullInvoice || overCap;
|
|
1772
|
+
const isSpanishNif = value.billingIdType === "NIF";
|
|
1773
|
+
const set = (key, next) => onChange({ ...value, [key]: next });
|
|
1774
|
+
const error = (key) => errors[key] ? /* @__PURE__ */ jsx13("p", { id: `full-invoice-${key}-error`, className: "text-sm text-destructive", children: errors[key] }) : null;
|
|
1775
|
+
const invalid = (key) => errors[key] ? { "aria-invalid": true, "aria-describedby": `full-invoice-${key}-error` } : {};
|
|
1776
|
+
return /* @__PURE__ */ jsxs11("section", { className: cn13("space-y-4", className), "data-slot": "full-invoice-fields", children: [
|
|
1777
|
+
overCap ? /* @__PURE__ */ jsx13("p", { role: "note", className: "rounded-lg border border-border p-4 text-sm", children: t.overCapNotice }) : /* @__PURE__ */ jsxs11("div", { className: "space-y-1", children: [
|
|
1778
|
+
/* @__PURE__ */ jsxs11("label", { className: "flex items-center gap-2 text-sm font-medium", children: [
|
|
1779
|
+
/* @__PURE__ */ jsx13(
|
|
1780
|
+
"input",
|
|
1781
|
+
{
|
|
1782
|
+
type: "checkbox",
|
|
1783
|
+
checked: value.wantsFullInvoice,
|
|
1784
|
+
onChange: (e) => set("wantsFullInvoice", e.target.checked)
|
|
1785
|
+
}
|
|
1786
|
+
),
|
|
1787
|
+
t.toggle
|
|
1788
|
+
] }),
|
|
1789
|
+
/* @__PURE__ */ jsx13("p", { className: "text-sm text-muted-foreground", children: t.underCapNotice })
|
|
1790
|
+
] }),
|
|
1791
|
+
showFields && /* @__PURE__ */ jsxs11("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
|
|
1792
|
+
/* @__PURE__ */ jsxs11("div", { className: "space-y-1", children: [
|
|
1793
|
+
/* @__PURE__ */ jsx13("label", { htmlFor: "full-invoice-id-type", className: "text-sm font-medium", children: t.idType }),
|
|
1794
|
+
/* @__PURE__ */ jsx13(
|
|
1795
|
+
"select",
|
|
1796
|
+
{
|
|
1797
|
+
id: "full-invoice-id-type",
|
|
1798
|
+
className: FIELD_CLASS3,
|
|
1799
|
+
required: true,
|
|
1800
|
+
value: value.billingIdType,
|
|
1801
|
+
onChange: (e) => set("billingIdType", e.target.value),
|
|
1802
|
+
...invalid("billingIdType"),
|
|
1803
|
+
children: ID_TYPES.map((type) => /* @__PURE__ */ jsx13("option", { value: type, children: t.idTypeOptions[type] }, type))
|
|
1804
|
+
}
|
|
1805
|
+
),
|
|
1806
|
+
error("billingIdType")
|
|
1807
|
+
] }),
|
|
1808
|
+
!isSpanishNif && /* @__PURE__ */ jsxs11("div", { className: "space-y-1", children: [
|
|
1809
|
+
/* @__PURE__ */ jsx13("label", { htmlFor: "full-invoice-id-country", className: "text-sm font-medium", children: t.idCountry }),
|
|
1810
|
+
/* @__PURE__ */ jsxs11(
|
|
1811
|
+
"select",
|
|
1812
|
+
{
|
|
1813
|
+
id: "full-invoice-id-country",
|
|
1814
|
+
className: FIELD_CLASS3,
|
|
1815
|
+
required: true,
|
|
1816
|
+
value: value.billingIdCountry,
|
|
1817
|
+
onChange: (e) => set("billingIdCountry", e.target.value),
|
|
1818
|
+
...invalid("billingIdCountry"),
|
|
1819
|
+
children: [
|
|
1820
|
+
/* @__PURE__ */ jsx13("option", { value: "", disabled: true, children: t.chooseCountry }),
|
|
1821
|
+
countries.map((c) => /* @__PURE__ */ jsx13("option", { value: c.code, children: c.name }, c.code))
|
|
1822
|
+
]
|
|
1823
|
+
}
|
|
1824
|
+
),
|
|
1825
|
+
error("billingIdCountry")
|
|
1826
|
+
] }),
|
|
1827
|
+
/* @__PURE__ */ jsxs11("div", { className: "space-y-1", children: [
|
|
1828
|
+
/* @__PURE__ */ jsx13("label", { htmlFor: "full-invoice-nif", className: "text-sm font-medium", children: isSpanishNif ? t.spanishNif : t.documentNumber }),
|
|
1829
|
+
/* @__PURE__ */ jsx13(
|
|
1830
|
+
"input",
|
|
1831
|
+
{
|
|
1832
|
+
id: "full-invoice-nif",
|
|
1833
|
+
className: FIELD_CLASS3,
|
|
1834
|
+
required: true,
|
|
1835
|
+
value: value.billingNif,
|
|
1836
|
+
onChange: (e) => set("billingNif", e.target.value),
|
|
1837
|
+
...invalid("billingNif")
|
|
1838
|
+
}
|
|
1839
|
+
),
|
|
1840
|
+
error("billingNif")
|
|
1841
|
+
] }),
|
|
1842
|
+
/* @__PURE__ */ jsxs11("div", { className: "space-y-1", children: [
|
|
1843
|
+
/* @__PURE__ */ jsx13("label", { htmlFor: "full-invoice-name", className: "text-sm font-medium", children: t.name }),
|
|
1844
|
+
/* @__PURE__ */ jsx13(
|
|
1845
|
+
"input",
|
|
1846
|
+
{
|
|
1847
|
+
id: "full-invoice-name",
|
|
1848
|
+
className: FIELD_CLASS3,
|
|
1849
|
+
required: true,
|
|
1850
|
+
value: value.billingName,
|
|
1851
|
+
onChange: (e) => set("billingName", e.target.value),
|
|
1852
|
+
...invalid("billingName")
|
|
1853
|
+
}
|
|
1854
|
+
),
|
|
1855
|
+
error("billingName")
|
|
1856
|
+
] }),
|
|
1857
|
+
/* @__PURE__ */ jsxs11("div", { className: "space-y-1 sm:col-span-2", children: [
|
|
1858
|
+
/* @__PURE__ */ jsx13("label", { htmlFor: "full-invoice-street", className: "text-sm font-medium", children: t.street }),
|
|
1859
|
+
/* @__PURE__ */ jsx13(
|
|
1860
|
+
"input",
|
|
1861
|
+
{
|
|
1862
|
+
id: "full-invoice-street",
|
|
1863
|
+
className: FIELD_CLASS3,
|
|
1864
|
+
required: true,
|
|
1865
|
+
value: value.street,
|
|
1866
|
+
onChange: (e) => set("street", e.target.value),
|
|
1867
|
+
...invalid("address")
|
|
1868
|
+
}
|
|
1869
|
+
)
|
|
1870
|
+
] }),
|
|
1871
|
+
/* @__PURE__ */ jsxs11("div", { className: "space-y-1", children: [
|
|
1872
|
+
/* @__PURE__ */ jsx13("label", { htmlFor: "full-invoice-postal-code", className: "text-sm font-medium", children: t.postalCode }),
|
|
1873
|
+
/* @__PURE__ */ jsx13(
|
|
1874
|
+
"input",
|
|
1875
|
+
{
|
|
1876
|
+
id: "full-invoice-postal-code",
|
|
1877
|
+
className: FIELD_CLASS3,
|
|
1878
|
+
required: true,
|
|
1879
|
+
value: value.postalCode,
|
|
1880
|
+
onChange: (e) => set("postalCode", e.target.value)
|
|
1881
|
+
}
|
|
1882
|
+
)
|
|
1883
|
+
] }),
|
|
1884
|
+
/* @__PURE__ */ jsxs11("div", { className: "space-y-1", children: [
|
|
1885
|
+
/* @__PURE__ */ jsx13("label", { htmlFor: "full-invoice-city", className: "text-sm font-medium", children: t.city }),
|
|
1886
|
+
/* @__PURE__ */ jsx13(
|
|
1887
|
+
"input",
|
|
1888
|
+
{
|
|
1889
|
+
id: "full-invoice-city",
|
|
1890
|
+
className: FIELD_CLASS3,
|
|
1891
|
+
required: true,
|
|
1892
|
+
value: value.city,
|
|
1893
|
+
onChange: (e) => set("city", e.target.value)
|
|
1894
|
+
}
|
|
1895
|
+
)
|
|
1896
|
+
] }),
|
|
1897
|
+
/* @__PURE__ */ jsxs11("div", { className: "space-y-1", children: [
|
|
1898
|
+
/* @__PURE__ */ jsx13("label", { htmlFor: "full-invoice-country", className: "text-sm font-medium", children: t.country }),
|
|
1899
|
+
/* @__PURE__ */ jsx13(
|
|
1900
|
+
"select",
|
|
1901
|
+
{
|
|
1902
|
+
id: "full-invoice-country",
|
|
1903
|
+
className: FIELD_CLASS3,
|
|
1904
|
+
required: true,
|
|
1905
|
+
value: value.country,
|
|
1906
|
+
onChange: (e) => set("country", e.target.value),
|
|
1907
|
+
children: countries.map((c) => /* @__PURE__ */ jsx13("option", { value: c.code, children: c.name }, c.code))
|
|
1908
|
+
}
|
|
1909
|
+
)
|
|
1910
|
+
] }),
|
|
1911
|
+
/* @__PURE__ */ jsx13("div", { className: "sm:col-span-2", children: error("address") })
|
|
1912
|
+
] })
|
|
1913
|
+
] });
|
|
1914
|
+
}
|
|
1915
|
+
|
|
1916
|
+
// src/components/course-guest-checkout-form.tsx
|
|
1917
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1918
|
+
var DEFAULT_COURSE_GUEST_CHECKOUT_FORM_LABELS = {
|
|
1919
|
+
firstNameLabel: "Nombre",
|
|
1920
|
+
lastNameLabel: "Apellidos",
|
|
1921
|
+
emailLabel: "Email",
|
|
1922
|
+
total: (total) => `Total (impuestos incluidos): ${total}`,
|
|
1923
|
+
submit: "Continuar al pago",
|
|
1924
|
+
submitting: "Procesando\u2026",
|
|
1925
|
+
firstNameRequired: "Indica tu nombre.",
|
|
1926
|
+
lastNameRequired: "Indica tus apellidos.",
|
|
1927
|
+
emailInvalid: "Introduce un email v\xE1lido.",
|
|
1928
|
+
termsRequired: "Para continuar, acepta las condiciones.",
|
|
1929
|
+
consentRequired: "Para continuar, marca esta casilla.",
|
|
1930
|
+
requestRequiredNotice: "Este curso se solicita antes de pagar. Completa la solicitud.",
|
|
1931
|
+
genericError: "No hemos podido iniciar el pago. Int\xE9ntalo de nuevo."
|
|
1932
|
+
};
|
|
1933
|
+
var DEFAULT_COURSE_GUEST_CHECKOUT_ERROR_MESSAGES = {
|
|
1934
|
+
INVALID_INPUT: "Revisa los datos introducidos.",
|
|
1935
|
+
RATE_LIMITED: "Demasiados intentos. Espera unos minutos e int\xE9ntalo de nuevo.",
|
|
1936
|
+
COURSE_NOT_FOUND: "Este curso ya no est\xE1 disponible.",
|
|
1937
|
+
SALES_CLOSED: "Este curso no est\xE1 a la venta en este momento.",
|
|
1938
|
+
ENROLLMENT_REQUEST_REQUIRED: "Este curso se solicita antes de pagar.",
|
|
1939
|
+
INVOICING_NOT_READY: "No se puede completar la compra en este momento. Int\xE9ntalo m\xE1s tarde.",
|
|
1940
|
+
TERMS_NOT_ACCEPTED: "Para continuar, acepta las condiciones.",
|
|
1941
|
+
TERMS_VERSION_CHANGED: "Las condiciones se han actualizado. Recarga la p\xE1gina y vuelve a aceptarlas.",
|
|
1942
|
+
CONSENT_REQUIRED: "Para continuar, marca la casilla del curso.",
|
|
1943
|
+
CONSENT_VERSION_CHANGED: "El texto de la casilla ha cambiado. Recarga la p\xE1gina y vuelve a marcarla.",
|
|
1944
|
+
INVALID_BILLING: "Revisa los datos de facturaci\xF3n."
|
|
1945
|
+
};
|
|
1946
|
+
var EMAIL_PATTERN3 = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
1947
|
+
var FIELD_CLASS4 = "w-full rounded-lg border bg-background px-3 py-2 text-sm transition focus:outline-none focus:ring-2 focus:ring-primary/20";
|
|
1948
|
+
async function postToRoute3(endpoint, input) {
|
|
1949
|
+
try {
|
|
1950
|
+
const res = await fetch(endpoint, {
|
|
1951
|
+
method: "POST",
|
|
1952
|
+
headers: { "Content-Type": "application/json" },
|
|
1953
|
+
body: JSON.stringify(input)
|
|
1954
|
+
});
|
|
1955
|
+
const json = await res.json().catch(() => null);
|
|
1956
|
+
if (res.ok && json?.data) return { ok: true, data: json.data };
|
|
1957
|
+
return {
|
|
1958
|
+
ok: false,
|
|
1959
|
+
status: res.status,
|
|
1960
|
+
...typeof json?.code === "string" ? { code: json.code } : {},
|
|
1961
|
+
...json?.details !== void 0 ? { details: json.details } : {}
|
|
1962
|
+
};
|
|
1963
|
+
} catch {
|
|
1964
|
+
return { ok: false, status: 0 };
|
|
1965
|
+
}
|
|
1966
|
+
}
|
|
1967
|
+
function fieldErrorsOf(details) {
|
|
1968
|
+
const errors = details?.fieldErrors;
|
|
1969
|
+
if (typeof errors !== "object" || errors === null) return {};
|
|
1970
|
+
return Object.fromEntries(
|
|
1971
|
+
Object.entries(errors).filter(
|
|
1972
|
+
(entry) => typeof entry[1] === "string"
|
|
1973
|
+
)
|
|
1974
|
+
);
|
|
1975
|
+
}
|
|
1976
|
+
function toInvoiceErrors(fieldErrors) {
|
|
1977
|
+
const out = {};
|
|
1978
|
+
for (const key of ["billingIdType", "billingIdCountry", "billingNif", "billingName"]) {
|
|
1979
|
+
if (fieldErrors[key]) out[key] = fieldErrors[key];
|
|
1980
|
+
}
|
|
1981
|
+
if (fieldErrors.billingAddress) out.address = fieldErrors.billingAddress;
|
|
1982
|
+
return out;
|
|
1983
|
+
}
|
|
1984
|
+
function CourseGuestCheckoutForm({
|
|
1985
|
+
course,
|
|
1986
|
+
copy,
|
|
1987
|
+
termsHref,
|
|
1988
|
+
requestForm,
|
|
1989
|
+
issuesInvoices = true,
|
|
1990
|
+
simplifiedInvoiceCapCents = null,
|
|
1991
|
+
submit,
|
|
1992
|
+
endpoint = "/api/academy/checkout",
|
|
1993
|
+
onRedirect,
|
|
1994
|
+
onError,
|
|
1995
|
+
labels,
|
|
1996
|
+
errorMessages,
|
|
1997
|
+
invoiceLabels,
|
|
1998
|
+
invoiceCountries,
|
|
1999
|
+
currencyCode,
|
|
2000
|
+
locale,
|
|
2001
|
+
className
|
|
2002
|
+
}) {
|
|
2003
|
+
const t = {
|
|
2004
|
+
...DEFAULT_COURSE_GUEST_CHECKOUT_FORM_LABELS,
|
|
2005
|
+
...labels
|
|
2006
|
+
};
|
|
2007
|
+
const messages = { ...DEFAULT_COURSE_GUEST_CHECKOUT_ERROR_MESSAGES, ...errorMessages };
|
|
2008
|
+
const id = useId5();
|
|
2009
|
+
const [firstName, setFirstName] = useState9("");
|
|
2010
|
+
const [lastName, setLastName] = useState9("");
|
|
2011
|
+
const [email, setEmail] = useState9("");
|
|
2012
|
+
const [acceptsTerms, setAcceptsTerms] = useState9(false);
|
|
2013
|
+
const [acceptsConsent, setAcceptsConsent] = useState9(false);
|
|
2014
|
+
const [invoice, setInvoice] = useState9(EMPTY_FULL_INVOICE_VALUE);
|
|
2015
|
+
const [errors, setErrors] = useState9({});
|
|
2016
|
+
const [invoiceErrors, setInvoiceErrors] = useState9({});
|
|
2017
|
+
const [formError, setFormError] = useState9(null);
|
|
2018
|
+
const [submitting, setSubmitting] = useState9(false);
|
|
2019
|
+
const [needsRequest, setNeedsRequest] = useState9(false);
|
|
2020
|
+
const consent = course.withdrawalConsent;
|
|
2021
|
+
const hasTerms = Boolean(copy.termsVersion);
|
|
2022
|
+
const overCap = isOverSimplifiedInvoiceCap(course.priceCents, simplifiedInvoiceCapCents);
|
|
2023
|
+
const formattedTotal = formatPrice(course.priceCents, currencyCode, locale);
|
|
2024
|
+
const notice = copy.payNotice ? copy.payNotice.replaceAll("{total}", formattedTotal).replaceAll("{tenant}", copy.tenantName) : null;
|
|
2025
|
+
if (needsRequest) {
|
|
2026
|
+
return /* @__PURE__ */ jsxs12("div", { "data-slot": "course-guest-checkout-request", className: cn14("space-y-4", className), children: [
|
|
2027
|
+
t.requestRequiredNotice ? /* @__PURE__ */ jsx14("p", { className: "text-sm text-muted-foreground", children: t.requestRequiredNotice }) : null,
|
|
2028
|
+
requestForm
|
|
2029
|
+
] });
|
|
2030
|
+
}
|
|
2031
|
+
async function handleSubmit(event) {
|
|
2032
|
+
event.preventDefault();
|
|
2033
|
+
if (submitting) return;
|
|
2034
|
+
setFormError(null);
|
|
2035
|
+
setInvoiceErrors({});
|
|
2036
|
+
const next = {};
|
|
2037
|
+
if (!firstName.trim()) next.firstName = t.firstNameRequired;
|
|
2038
|
+
if (!lastName.trim()) next.lastName = t.lastNameRequired;
|
|
2039
|
+
if (!EMAIL_PATTERN3.test(email.trim())) next.email = t.emailInvalid;
|
|
2040
|
+
if (hasTerms && !acceptsTerms) next.terms = t.termsRequired;
|
|
2041
|
+
if (consent && !acceptsConsent) next.consent = t.consentRequired;
|
|
2042
|
+
setErrors(next);
|
|
2043
|
+
if (Object.keys(next).length > 0) return;
|
|
2044
|
+
const input = {
|
|
2045
|
+
courseSlug: course.slug,
|
|
2046
|
+
firstName: firstName.trim(),
|
|
2047
|
+
lastName: lastName.trim(),
|
|
2048
|
+
email: email.trim(),
|
|
2049
|
+
...toCheckoutTermsFields(copy, acceptsTerms),
|
|
2050
|
+
...consent ? { acceptsWithdrawalWaiver: acceptsConsent, withdrawalWaiverVersion: consent.version } : {},
|
|
2051
|
+
...toAcademyCheckoutInvoiceFields(invoice, overCap, issuesInvoices)
|
|
2052
|
+
};
|
|
2053
|
+
setSubmitting(true);
|
|
2054
|
+
try {
|
|
2055
|
+
const result = await (submit ?? ((body) => postToRoute3(endpoint, body)))(input).catch(
|
|
2056
|
+
() => ({ ok: false, status: 0 })
|
|
2057
|
+
);
|
|
2058
|
+
if (result.ok) {
|
|
2059
|
+
;
|
|
2060
|
+
(onRedirect ?? ((url) => window.location.assign(url)))(result.data.url);
|
|
2061
|
+
return;
|
|
2062
|
+
}
|
|
2063
|
+
onError?.(result);
|
|
2064
|
+
if (result.code === "ENROLLMENT_REQUEST_REQUIRED") {
|
|
2065
|
+
setNeedsRequest(true);
|
|
2066
|
+
return;
|
|
2067
|
+
}
|
|
2068
|
+
if (result.code === "INVALID_BILLING")
|
|
2069
|
+
setInvoiceErrors(toInvoiceErrors(fieldErrorsOf(result.details)));
|
|
2070
|
+
const code = result.code;
|
|
2071
|
+
setFormError(code && messages[code] || t.genericError);
|
|
2072
|
+
} finally {
|
|
2073
|
+
setSubmitting(false);
|
|
2074
|
+
}
|
|
2075
|
+
}
|
|
2076
|
+
const fieldError = (field) => errors[field] ? /* @__PURE__ */ jsx14("p", { id: `${id}-${field}-error`, className: "text-xs text-destructive", children: errors[field] }) : null;
|
|
2077
|
+
const invalid = (field) => errors[field] ? { "aria-invalid": true, "aria-describedby": `${id}-${field}-error` } : {};
|
|
2078
|
+
const border = (field) => errors[field] ? "border-destructive" : "border-border";
|
|
2079
|
+
const textField = (field, label, value, onChange, autoComplete) => /* @__PURE__ */ jsxs12("div", { className: "space-y-1", children: [
|
|
2080
|
+
/* @__PURE__ */ jsx14("label", { htmlFor: `${id}-${field}`, className: "text-sm font-medium", children: label }),
|
|
2081
|
+
/* @__PURE__ */ jsx14(
|
|
2082
|
+
"input",
|
|
2083
|
+
{
|
|
2084
|
+
id: `${id}-${field}`,
|
|
2085
|
+
type: field === "email" ? "email" : "text",
|
|
2086
|
+
autoComplete,
|
|
2087
|
+
maxLength: field === "email" ? 254 : 200,
|
|
2088
|
+
value,
|
|
2089
|
+
onChange: (e) => onChange(e.target.value),
|
|
2090
|
+
...invalid(field),
|
|
2091
|
+
className: cn14(FIELD_CLASS4, border(field))
|
|
2092
|
+
}
|
|
2093
|
+
),
|
|
2094
|
+
fieldError(field)
|
|
2095
|
+
] });
|
|
2096
|
+
return /* @__PURE__ */ jsxs12(
|
|
2097
|
+
"form",
|
|
2098
|
+
{
|
|
2099
|
+
noValidate: true,
|
|
2100
|
+
onSubmit: handleSubmit,
|
|
2101
|
+
"data-slot": "course-guest-checkout-form",
|
|
2102
|
+
className: cn14("space-y-6", className),
|
|
2103
|
+
children: [
|
|
2104
|
+
/* @__PURE__ */ jsxs12("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2", children: [
|
|
2105
|
+
textField("firstName", t.firstNameLabel, firstName, setFirstName, "given-name"),
|
|
2106
|
+
textField("lastName", t.lastNameLabel, lastName, setLastName, "family-name"),
|
|
2107
|
+
/* @__PURE__ */ jsx14("div", { className: "sm:col-span-2", children: textField("email", t.emailLabel, email, setEmail, "email") })
|
|
2108
|
+
] }),
|
|
2109
|
+
/* @__PURE__ */ jsx14(
|
|
2110
|
+
FullInvoiceFields,
|
|
2111
|
+
{
|
|
2112
|
+
value: invoice,
|
|
2113
|
+
onChange: setInvoice,
|
|
2114
|
+
overCap,
|
|
2115
|
+
issuesInvoices,
|
|
2116
|
+
errors: invoiceErrors,
|
|
2117
|
+
countries: invoiceCountries,
|
|
2118
|
+
labels: {
|
|
2119
|
+
...copy.fullInvoiceCheckboxLabel ? { toggle: copy.fullInvoiceCheckboxLabel } : {},
|
|
2120
|
+
...copy.fullInvoiceHelpText ? { underCapNotice: copy.fullInvoiceHelpText } : {},
|
|
2121
|
+
...invoiceLabels
|
|
2122
|
+
}
|
|
2123
|
+
}
|
|
2124
|
+
),
|
|
2125
|
+
/* @__PURE__ */ jsxs12("div", { className: "space-y-3", children: [
|
|
2126
|
+
/* @__PURE__ */ jsx14(
|
|
2127
|
+
CheckoutTermsAcceptance,
|
|
2128
|
+
{
|
|
2129
|
+
copy,
|
|
2130
|
+
termsHref,
|
|
2131
|
+
checked: acceptsTerms,
|
|
2132
|
+
onCheckedChange: setAcceptsTerms,
|
|
2133
|
+
error: errors.terms,
|
|
2134
|
+
id: `${id}-terms`
|
|
2135
|
+
}
|
|
2136
|
+
),
|
|
2137
|
+
consent ? /* @__PURE__ */ jsxs12(
|
|
2138
|
+
"div",
|
|
2139
|
+
{
|
|
2140
|
+
"data-slot": "course-guest-checkout-consent",
|
|
2141
|
+
"data-kind": consent.kind,
|
|
2142
|
+
className: "space-y-1",
|
|
2143
|
+
children: [
|
|
2144
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex items-start gap-3", children: [
|
|
2145
|
+
/* @__PURE__ */ jsx14(
|
|
2146
|
+
"input",
|
|
2147
|
+
{
|
|
2148
|
+
id: `${id}-consent`,
|
|
2149
|
+
type: "checkbox",
|
|
2150
|
+
checked: acceptsConsent,
|
|
2151
|
+
onChange: (e) => setAcceptsConsent(e.target.checked),
|
|
2152
|
+
...invalid("consent"),
|
|
2153
|
+
className: "mt-0.5 size-5 shrink-0 cursor-pointer accent-primary"
|
|
2154
|
+
}
|
|
2155
|
+
),
|
|
2156
|
+
/* @__PURE__ */ jsx14("label", { htmlFor: `${id}-consent`, className: "text-sm leading-relaxed", children: consent.text })
|
|
2157
|
+
] }),
|
|
2158
|
+
errors.consent ? /* @__PURE__ */ jsx14("p", { id: `${id}-consent-error`, className: "pl-8 text-sm text-destructive", children: errors.consent }) : null
|
|
2159
|
+
]
|
|
2160
|
+
}
|
|
2161
|
+
) : null
|
|
2162
|
+
] }),
|
|
2163
|
+
/* @__PURE__ */ jsx14("p", { "data-slot": "course-guest-checkout-total", className: "text-base font-semibold", children: t.total(formattedTotal) }),
|
|
2164
|
+
formError ? /* @__PURE__ */ jsx14("p", { role: "alert", className: "text-sm text-destructive", children: formError }) : null,
|
|
2165
|
+
/* @__PURE__ */ jsx14(
|
|
2166
|
+
CheckoutPayAction,
|
|
2167
|
+
{
|
|
2168
|
+
label: copy.continueToPaymentLabel ?? t.submit,
|
|
2169
|
+
notice,
|
|
2170
|
+
submitting,
|
|
2171
|
+
submittingLabel: t.submitting,
|
|
2172
|
+
id: `${id}-pay`
|
|
2173
|
+
}
|
|
2174
|
+
)
|
|
2175
|
+
]
|
|
2176
|
+
}
|
|
2177
|
+
);
|
|
2178
|
+
}
|
|
1553
2179
|
export {
|
|
1554
2180
|
AddToCartButton,
|
|
1555
2181
|
CartIcon,
|
|
1556
2182
|
Collection,
|
|
2183
|
+
CourseGuestCheckoutForm,
|
|
1557
2184
|
CourseSyllabus,
|
|
1558
2185
|
DATA_REQUEST_FIELD_LIMITS,
|
|
1559
2186
|
DATA_REQUEST_TYPES,
|
|
2187
|
+
DEFAULT_COURSE_GUEST_CHECKOUT_ERROR_MESSAGES,
|
|
2188
|
+
DEFAULT_COURSE_GUEST_CHECKOUT_FORM_LABELS,
|
|
1560
2189
|
DEFAULT_COURSE_SYLLABUS_LABELS,
|
|
1561
2190
|
DEFAULT_DATA_REQUEST_FORM_LABELS,
|
|
1562
2191
|
DEFAULT_PRODUCT_CAROUSEL_LABELS,
|