@voyant-travel/storefront-react 0.120.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +17 -0
- package/dist/client.d.ts +16 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +78 -0
- package/dist/components/storefront-settings-page.d.ts +5 -0
- package/dist/components/storefront-settings-page.d.ts.map +1 -0
- package/dist/components/storefront-settings-page.js +39 -0
- package/dist/customer-portal/client.d.ts +16 -0
- package/dist/customer-portal/client.d.ts.map +1 -0
- package/dist/customer-portal/client.js +78 -0
- package/dist/customer-portal/hooks/index.d.ts +12 -0
- package/dist/customer-portal/hooks/index.d.ts.map +1 -0
- package/dist/customer-portal/hooks/index.js +11 -0
- package/dist/customer-portal/hooks/use-customer-portal-booking-billing-contact.d.ts +18 -0
- package/dist/customer-portal/hooks/use-customer-portal-booking-billing-contact.d.ts.map +1 -0
- package/dist/customer-portal/hooks/use-customer-portal-booking-billing-contact.js +12 -0
- package/dist/customer-portal/hooks/use-customer-portal-booking-documents.d.ts +16 -0
- package/dist/customer-portal/hooks/use-customer-portal-booking-documents.d.ts.map +1 -0
- package/dist/customer-portal/hooks/use-customer-portal-booking-documents.js +12 -0
- package/dist/customer-portal/hooks/use-customer-portal-booking.d.ts +109 -0
- package/dist/customer-portal/hooks/use-customer-portal-booking.d.ts.map +1 -0
- package/dist/customer-portal/hooks/use-customer-portal-booking.js +12 -0
- package/dist/customer-portal/hooks/use-customer-portal-bookings.d.ts +22 -0
- package/dist/customer-portal/hooks/use-customer-portal-bookings.d.ts.map +1 -0
- package/dist/customer-portal/hooks/use-customer-portal-bookings.js +12 -0
- package/dist/customer-portal/hooks/use-customer-portal-companions.d.ts +42 -0
- package/dist/customer-portal/hooks/use-customer-portal-companions.d.ts.map +1 -0
- package/dist/customer-portal/hooks/use-customer-portal-companions.js +12 -0
- package/dist/customer-portal/hooks/use-customer-portal-contact-exists.d.ts +12 -0
- package/dist/customer-portal/hooks/use-customer-portal-contact-exists.d.ts.map +1 -0
- package/dist/customer-portal/hooks/use-customer-portal-contact-exists.js +12 -0
- package/dist/customer-portal/hooks/use-customer-portal-mutation.d.ts +419 -0
- package/dist/customer-portal/hooks/use-customer-portal-mutation.d.ts.map +1 -0
- package/dist/customer-portal/hooks/use-customer-portal-mutation.js +62 -0
- package/dist/customer-portal/hooks/use-customer-portal-phone-contact-exists.d.ts +13 -0
- package/dist/customer-portal/hooks/use-customer-portal-phone-contact-exists.d.ts.map +1 -0
- package/dist/customer-portal/hooks/use-customer-portal-phone-contact-exists.js +12 -0
- package/dist/customer-portal/hooks/use-customer-portal-profile-document-mutation.d.ts +69 -0
- package/dist/customer-portal/hooks/use-customer-portal-profile-document-mutation.d.ts.map +1 -0
- package/dist/customer-portal/hooks/use-customer-portal-profile-document-mutation.js +28 -0
- package/dist/customer-portal/hooks/use-customer-portal-profile-documents.d.ts +20 -0
- package/dist/customer-portal/hooks/use-customer-portal-profile-documents.d.ts.map +1 -0
- package/dist/customer-portal/hooks/use-customer-portal-profile-documents.js +12 -0
- package/dist/customer-portal/hooks/use-customer-portal-profile.d.ts +61 -0
- package/dist/customer-portal/hooks/use-customer-portal-profile.d.ts.map +1 -0
- package/dist/customer-portal/hooks/use-customer-portal-profile.js +12 -0
- package/dist/customer-portal/index.d.ts +9 -0
- package/dist/customer-portal/index.d.ts.map +1 -0
- package/dist/customer-portal/index.js +7 -0
- package/dist/customer-portal/operations.d.ts +595 -0
- package/dist/customer-portal/operations.d.ts.map +1 -0
- package/dist/customer-portal/operations.js +84 -0
- package/dist/customer-portal/provider.d.ts +2 -0
- package/dist/customer-portal/provider.d.ts.map +1 -0
- package/dist/customer-portal/provider.js +1 -0
- package/dist/customer-portal/query-keys.d.ts +21 -0
- package/dist/customer-portal/query-keys.d.ts.map +1 -0
- package/dist/customer-portal/query-keys.js +14 -0
- package/dist/customer-portal/query-options.d.ts +1148 -0
- package/dist/customer-portal/query-options.d.ts.map +1 -0
- package/dist/customer-portal/query-options.js +58 -0
- package/dist/customer-portal/schemas.d.ts +751 -0
- package/dist/customer-portal/schemas.d.ts.map +1 -0
- package/dist/customer-portal/schemas.js +21 -0
- package/dist/hooks/index.d.ts +12 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +11 -0
- package/dist/hooks/use-admin-storefront-settings.d.ts +290 -0
- package/dist/hooks/use-admin-storefront-settings.d.ts.map +1 -0
- package/dist/hooks/use-admin-storefront-settings.js +29 -0
- package/dist/hooks/use-storefront-departure-itinerary.d.ts +23 -0
- package/dist/hooks/use-storefront-departure-itinerary.d.ts.map +1 -0
- package/dist/hooks/use-storefront-departure-itinerary.js +12 -0
- package/dist/hooks/use-storefront-departure-price-preview-mutation.d.ts +244 -0
- package/dist/hooks/use-storefront-departure-price-preview-mutation.d.ts.map +1 -0
- package/dist/hooks/use-storefront-departure-price-preview-mutation.js +15 -0
- package/dist/hooks/use-storefront-departure.d.ts +51 -0
- package/dist/hooks/use-storefront-departure.d.ts.map +1 -0
- package/dist/hooks/use-storefront-departure.js +12 -0
- package/dist/hooks/use-storefront-offer-apply-mutation.d.ts +68 -0
- package/dist/hooks/use-storefront-offer-apply-mutation.d.ts.map +1 -0
- package/dist/hooks/use-storefront-offer-apply-mutation.js +15 -0
- package/dist/hooks/use-storefront-offer-redeem-mutation.d.ts +69 -0
- package/dist/hooks/use-storefront-offer-redeem-mutation.d.ts.map +1 -0
- package/dist/hooks/use-storefront-offer-redeem-mutation.js +12 -0
- package/dist/hooks/use-storefront-offer.d.ts +26 -0
- package/dist/hooks/use-storefront-offer.d.ts.map +1 -0
- package/dist/hooks/use-storefront-offer.js +12 -0
- package/dist/hooks/use-storefront-product-departures.d.ts +55 -0
- package/dist/hooks/use-storefront-product-departures.d.ts.map +1 -0
- package/dist/hooks/use-storefront-product-departures.js +12 -0
- package/dist/hooks/use-storefront-product-extensions.d.ts +47 -0
- package/dist/hooks/use-storefront-product-extensions.d.ts.map +1 -0
- package/dist/hooks/use-storefront-product-extensions.js +12 -0
- package/dist/hooks/use-storefront-product-offers.d.ts +26 -0
- package/dist/hooks/use-storefront-product-offers.d.ts.map +1 -0
- package/dist/hooks/use-storefront-product-offers.js +12 -0
- package/dist/hooks/use-storefront-settings.d.ts +101 -0
- package/dist/hooks/use-storefront-settings.d.ts.map +1 -0
- package/dist/hooks/use-storefront-settings.js +12 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/internal/storefront-settings-form.d.ts +50 -0
- package/dist/internal/storefront-settings-form.d.ts.map +1 -0
- package/dist/internal/storefront-settings-form.js +246 -0
- package/dist/internal/storefront-settings-payment-section.d.ts +12 -0
- package/dist/internal/storefront-settings-payment-section.d.ts.map +1 -0
- package/dist/internal/storefront-settings-payment-section.js +14 -0
- package/dist/internal/storefront-settings-sections.d.ts +23 -0
- package/dist/internal/storefront-settings-sections.d.ts.map +1 -0
- package/dist/internal/storefront-settings-sections.js +32 -0
- package/dist/operations.d.ts +827 -0
- package/dist/operations.d.ts.map +1 -0
- package/dist/operations.js +46 -0
- package/dist/operations.test.d.ts +2 -0
- package/dist/operations.test.d.ts.map +1 -0
- package/dist/operations.test.js +77 -0
- package/dist/provider.d.ts +2 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +1 -0
- package/dist/query-keys.d.ts +32 -0
- package/dist/query-keys.d.ts.map +1 -0
- package/dist/query-keys.js +15 -0
- package/dist/query-options.d.ts +1648 -0
- package/dist/query-options.d.ts.map +1 -0
- package/dist/query-options.js +52 -0
- package/dist/schemas.d.ts +576 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +11 -0
- package/dist/ui.d.ts +2 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +1 -0
- package/package.json +133 -0
- package/src/styles.css +1 -0
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { StorefrontSettingsPatchInput, StorefrontSettingsRecord } from "../index.js";
|
|
2
|
+
export type SupportLinkRow = {
|
|
3
|
+
rowKey: string;
|
|
4
|
+
label: string;
|
|
5
|
+
url: string;
|
|
6
|
+
};
|
|
7
|
+
export type PaymentMethodCode = NonNullable<StorefrontSettingsRecord["payment"]["defaultMethod"]>;
|
|
8
|
+
export type FormState = {
|
|
9
|
+
logoUrl: string;
|
|
10
|
+
faviconUrl: string;
|
|
11
|
+
brandMarkUrl: string;
|
|
12
|
+
primaryColor: string;
|
|
13
|
+
accentColor: string;
|
|
14
|
+
supportedLanguages: string;
|
|
15
|
+
supportEmail: string;
|
|
16
|
+
supportPhone: string;
|
|
17
|
+
supportLinks: SupportLinkRow[];
|
|
18
|
+
termsUrl: string;
|
|
19
|
+
privacyUrl: string;
|
|
20
|
+
cancellationUrl: string;
|
|
21
|
+
defaultContractTemplateId: string;
|
|
22
|
+
defaultLocale: string;
|
|
23
|
+
currencyDisplay: StorefrontSettingsRecord["localization"]["currencyDisplay"];
|
|
24
|
+
defaultMethod: PaymentMethodCode | "none";
|
|
25
|
+
enabledMethods: Record<PaymentMethodCode, boolean>;
|
|
26
|
+
paymentStructure: StorefrontSettingsRecord["payment"]["structure"];
|
|
27
|
+
depositPercent: string;
|
|
28
|
+
balanceDueDaysBeforeDeparture: string;
|
|
29
|
+
bankTransferDueDays: string;
|
|
30
|
+
bankProvider: string;
|
|
31
|
+
bankCurrency: string;
|
|
32
|
+
accountHolder: string;
|
|
33
|
+
bankName: string;
|
|
34
|
+
iban: string;
|
|
35
|
+
bic: string;
|
|
36
|
+
paymentReference: string;
|
|
37
|
+
bankInstructions: string;
|
|
38
|
+
};
|
|
39
|
+
export declare const paymentMethods: Array<{
|
|
40
|
+
code: PaymentMethodCode;
|
|
41
|
+
label: string;
|
|
42
|
+
}>;
|
|
43
|
+
export declare const loadingSectionKeys: readonly ["branding", "support", "legal", "payment"];
|
|
44
|
+
export declare const nextSupportLinkKey: () => string;
|
|
45
|
+
export declare const emptyForm: FormState;
|
|
46
|
+
export declare function toFormState(settings?: StorefrontSettingsRecord): FormState;
|
|
47
|
+
export declare function validateForm(form: FormState): "URLs must be valid http or https links." | "Brand colors must use #RGB or #RRGGBB format." | "Deposit percent must be between 0 and 100." | "Balance due days must be a whole number greater than or equal to 0." | "Bank transfer due days must be a whole number greater than or equal to 0." | "The default payment method must be enabled." | null;
|
|
48
|
+
export declare function toPayload(form: FormState): StorefrontSettingsPatchInput;
|
|
49
|
+
export declare function hasEmptySettings(settings?: StorefrontSettingsRecord): boolean;
|
|
50
|
+
//# sourceMappingURL=storefront-settings-form.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storefront-settings-form.d.ts","sourceRoot":"","sources":["../../src/internal/storefront-settings-form.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,4BAA4B,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAEzF,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;CACZ,CAAA;AAED,MAAM,MAAM,iBAAiB,GAAG,WAAW,CAAC,wBAAwB,CAAC,SAAS,CAAC,CAAC,eAAe,CAAC,CAAC,CAAA;AAEjG,MAAM,MAAM,SAAS,GAAG;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,cAAc,EAAE,CAAA;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,eAAe,EAAE,MAAM,CAAA;IACvB,yBAAyB,EAAE,MAAM,CAAA;IACjC,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,wBAAwB,CAAC,cAAc,CAAC,CAAC,iBAAiB,CAAC,CAAA;IAC5E,aAAa,EAAE,iBAAiB,GAAG,MAAM,CAAA;IACzC,cAAc,EAAE,MAAM,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAA;IAClD,gBAAgB,EAAE,wBAAwB,CAAC,SAAS,CAAC,CAAC,WAAW,CAAC,CAAA;IAClE,cAAc,EAAE,MAAM,CAAA;IACtB,6BAA6B,EAAE,MAAM,CAAA;IACrC,mBAAmB,EAAE,MAAM,CAAA;IAC3B,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,gBAAgB,EAAE,MAAM,CAAA;IACxB,gBAAgB,EAAE,MAAM,CAAA;CACzB,CAAA;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAM5E,CAAA;AAED,eAAO,MAAM,kBAAkB,sDAAuD,CAAA;AAGtF,eAAO,MAAM,kBAAkB,cAA2C,CAAA;AAE1E,eAAO,MAAM,SAAS,EAAE,SAoCvB,CAAA;AAqBD,wBAAgB,WAAW,CAAC,QAAQ,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAgD1E;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,2VAwC3C;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,SAAS,GAAG,4BAA4B,CAgGvE;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,CAAC,EAAE,wBAAwB,WAUnE"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
export const paymentMethods = [
|
|
2
|
+
{ code: "card", label: "Card" },
|
|
3
|
+
{ code: "bank_transfer", label: "Bank transfer" },
|
|
4
|
+
{ code: "cash", label: "Cash" },
|
|
5
|
+
{ code: "voucher", label: "Voucher" },
|
|
6
|
+
{ code: "invoice", label: "Invoice" },
|
|
7
|
+
];
|
|
8
|
+
export const loadingSectionKeys = ["branding", "support", "legal", "payment"];
|
|
9
|
+
let supportLinkSeq = 0;
|
|
10
|
+
export const nextSupportLinkKey = () => `support-link-${++supportLinkSeq}`;
|
|
11
|
+
export const emptyForm = {
|
|
12
|
+
logoUrl: "",
|
|
13
|
+
faviconUrl: "",
|
|
14
|
+
brandMarkUrl: "",
|
|
15
|
+
primaryColor: "",
|
|
16
|
+
accentColor: "",
|
|
17
|
+
supportedLanguages: "",
|
|
18
|
+
supportEmail: "",
|
|
19
|
+
supportPhone: "",
|
|
20
|
+
supportLinks: [],
|
|
21
|
+
termsUrl: "",
|
|
22
|
+
privacyUrl: "",
|
|
23
|
+
cancellationUrl: "",
|
|
24
|
+
defaultContractTemplateId: "",
|
|
25
|
+
defaultLocale: "",
|
|
26
|
+
currencyDisplay: "code",
|
|
27
|
+
defaultMethod: "none",
|
|
28
|
+
enabledMethods: {
|
|
29
|
+
card: false,
|
|
30
|
+
bank_transfer: false,
|
|
31
|
+
cash: false,
|
|
32
|
+
voucher: false,
|
|
33
|
+
invoice: false,
|
|
34
|
+
},
|
|
35
|
+
paymentStructure: "full",
|
|
36
|
+
depositPercent: "",
|
|
37
|
+
balanceDueDaysBeforeDeparture: "",
|
|
38
|
+
bankTransferDueDays: "",
|
|
39
|
+
bankProvider: "",
|
|
40
|
+
bankCurrency: "",
|
|
41
|
+
accountHolder: "",
|
|
42
|
+
bankName: "",
|
|
43
|
+
iban: "",
|
|
44
|
+
bic: "",
|
|
45
|
+
paymentReference: "",
|
|
46
|
+
bankInstructions: "",
|
|
47
|
+
};
|
|
48
|
+
function optional(value) {
|
|
49
|
+
const trimmed = value.trim();
|
|
50
|
+
return trimmed ? trimmed : null;
|
|
51
|
+
}
|
|
52
|
+
function urlLooksValid(value) {
|
|
53
|
+
if (!value.trim())
|
|
54
|
+
return true;
|
|
55
|
+
try {
|
|
56
|
+
const url = new URL(value);
|
|
57
|
+
return url.protocol === "http:" || url.protocol === "https:";
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function colorLooksValid(value) {
|
|
64
|
+
return !value.trim() || /^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/.test(value.trim());
|
|
65
|
+
}
|
|
66
|
+
export function toFormState(settings) {
|
|
67
|
+
if (!settings)
|
|
68
|
+
return emptyForm;
|
|
69
|
+
return {
|
|
70
|
+
logoUrl: settings.branding.logoUrl ?? "",
|
|
71
|
+
faviconUrl: settings.branding.faviconUrl ?? "",
|
|
72
|
+
brandMarkUrl: settings.branding.brandMarkUrl ?? "",
|
|
73
|
+
primaryColor: settings.branding.primaryColor ?? "",
|
|
74
|
+
accentColor: settings.branding.accentColor ?? "",
|
|
75
|
+
supportedLanguages: settings.branding.supportedLanguages.join(", "),
|
|
76
|
+
supportEmail: settings.support.email ?? "",
|
|
77
|
+
supportPhone: settings.support.phone ?? "",
|
|
78
|
+
supportLinks: settings.support.links.map((link) => ({
|
|
79
|
+
rowKey: nextSupportLinkKey(),
|
|
80
|
+
label: link.label,
|
|
81
|
+
url: link.url,
|
|
82
|
+
})),
|
|
83
|
+
termsUrl: settings.legal.termsUrl ?? "",
|
|
84
|
+
privacyUrl: settings.legal.privacyUrl ?? "",
|
|
85
|
+
cancellationUrl: settings.legal.cancellationUrl ?? "",
|
|
86
|
+
defaultContractTemplateId: settings.legal.defaultContractTemplateId ?? "",
|
|
87
|
+
defaultLocale: settings.localization.defaultLocale ?? "",
|
|
88
|
+
currencyDisplay: settings.localization.currencyDisplay,
|
|
89
|
+
defaultMethod: settings.payment.defaultMethod ?? "none",
|
|
90
|
+
enabledMethods: Object.fromEntries(paymentMethods.map((method) => [
|
|
91
|
+
method.code,
|
|
92
|
+
settings.payment.methods.some((stored) => stored.code === method.code && stored.enabled),
|
|
93
|
+
])),
|
|
94
|
+
paymentStructure: settings.payment.structure,
|
|
95
|
+
depositPercent: settings.payment.defaultSchedule?.depositPercent?.toString() ?? "",
|
|
96
|
+
balanceDueDaysBeforeDeparture: settings.payment.defaultSchedule?.balanceDueDaysBeforeDeparture?.toString() ?? "",
|
|
97
|
+
bankTransferDueDays: settings.payment.bankTransfer?.dueDays?.toString() ?? "",
|
|
98
|
+
bankProvider: settings.payment.bankTransfer?.account?.provider ?? "",
|
|
99
|
+
bankCurrency: settings.payment.bankTransfer?.account?.currency ?? "",
|
|
100
|
+
accountHolder: settings.payment.bankTransfer?.account?.beneficiary ??
|
|
101
|
+
settings.payment.bankTransfer?.accountHolder ??
|
|
102
|
+
"",
|
|
103
|
+
bankName: settings.payment.bankTransfer?.account?.bank ?? settings.payment.bankTransfer?.bankName ?? "",
|
|
104
|
+
iban: settings.payment.bankTransfer?.account?.iban ?? settings.payment.bankTransfer?.iban ?? "",
|
|
105
|
+
bic: settings.payment.bankTransfer?.bic ?? "",
|
|
106
|
+
paymentReference: settings.payment.bankTransfer?.paymentReference ?? "",
|
|
107
|
+
bankInstructions: settings.payment.bankTransfer?.instructions ?? "",
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
export function validateForm(form) {
|
|
111
|
+
const urls = [
|
|
112
|
+
form.logoUrl,
|
|
113
|
+
form.faviconUrl,
|
|
114
|
+
form.brandMarkUrl,
|
|
115
|
+
form.termsUrl,
|
|
116
|
+
form.privacyUrl,
|
|
117
|
+
form.cancellationUrl,
|
|
118
|
+
...form.supportLinks.map((link) => link.url),
|
|
119
|
+
];
|
|
120
|
+
if (urls.some((url) => !urlLooksValid(url))) {
|
|
121
|
+
return "URLs must be valid http or https links.";
|
|
122
|
+
}
|
|
123
|
+
if (!colorLooksValid(form.primaryColor) || !colorLooksValid(form.accentColor)) {
|
|
124
|
+
return "Brand colors must use #RGB or #RRGGBB format.";
|
|
125
|
+
}
|
|
126
|
+
const deposit = form.depositPercent ? Number(form.depositPercent) : null;
|
|
127
|
+
if (deposit !== null && (!Number.isFinite(deposit) || deposit < 0 || deposit > 100)) {
|
|
128
|
+
return "Deposit percent must be between 0 and 100.";
|
|
129
|
+
}
|
|
130
|
+
const balanceDue = form.balanceDueDaysBeforeDeparture
|
|
131
|
+
? Number(form.balanceDueDaysBeforeDeparture)
|
|
132
|
+
: null;
|
|
133
|
+
if (balanceDue !== null && (!Number.isInteger(balanceDue) || balanceDue < 0)) {
|
|
134
|
+
return "Balance due days must be a whole number greater than or equal to 0.";
|
|
135
|
+
}
|
|
136
|
+
const bankDueDays = form.bankTransferDueDays ? Number(form.bankTransferDueDays) : null;
|
|
137
|
+
if (bankDueDays !== null && (!Number.isInteger(bankDueDays) || bankDueDays < 0)) {
|
|
138
|
+
return "Bank transfer due days must be a whole number greater than or equal to 0.";
|
|
139
|
+
}
|
|
140
|
+
if (form.defaultMethod !== "none" && !form.enabledMethods[form.defaultMethod]) {
|
|
141
|
+
return "The default payment method must be enabled.";
|
|
142
|
+
}
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
export function toPayload(form) {
|
|
146
|
+
const supportLinks = form.supportLinks
|
|
147
|
+
.map((link) => ({ label: link.label.trim(), url: link.url.trim() }))
|
|
148
|
+
.filter((link) => link.label || link.url);
|
|
149
|
+
return {
|
|
150
|
+
branding: {
|
|
151
|
+
logoUrl: optional(form.logoUrl),
|
|
152
|
+
faviconUrl: optional(form.faviconUrl),
|
|
153
|
+
brandMarkUrl: optional(form.brandMarkUrl),
|
|
154
|
+
primaryColor: optional(form.primaryColor),
|
|
155
|
+
accentColor: optional(form.accentColor),
|
|
156
|
+
supportedLanguages: form.supportedLanguages
|
|
157
|
+
.split(",")
|
|
158
|
+
.map((value) => value.trim())
|
|
159
|
+
.filter(Boolean),
|
|
160
|
+
},
|
|
161
|
+
support: {
|
|
162
|
+
email: optional(form.supportEmail),
|
|
163
|
+
phone: optional(form.supportPhone),
|
|
164
|
+
links: supportLinks,
|
|
165
|
+
},
|
|
166
|
+
legal: {
|
|
167
|
+
termsUrl: optional(form.termsUrl),
|
|
168
|
+
privacyUrl: optional(form.privacyUrl),
|
|
169
|
+
cancellationUrl: optional(form.cancellationUrl),
|
|
170
|
+
defaultContractTemplateId: optional(form.defaultContractTemplateId),
|
|
171
|
+
},
|
|
172
|
+
localization: {
|
|
173
|
+
defaultLocale: optional(form.defaultLocale),
|
|
174
|
+
currencyDisplay: form.currencyDisplay,
|
|
175
|
+
},
|
|
176
|
+
payment: {
|
|
177
|
+
defaultMethod: form.defaultMethod === "none" ? null : form.defaultMethod,
|
|
178
|
+
methods: paymentMethods
|
|
179
|
+
.filter((method) => form.enabledMethods[method.code])
|
|
180
|
+
.map((method) => ({ code: method.code })),
|
|
181
|
+
structure: form.paymentStructure,
|
|
182
|
+
schedule: form.paymentStructure === "split" && form.depositPercent
|
|
183
|
+
? [
|
|
184
|
+
{
|
|
185
|
+
percent: Number(form.depositPercent),
|
|
186
|
+
dueInDays: 0,
|
|
187
|
+
dueCondition: "after_booking",
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
percent: 100 - Number(form.depositPercent),
|
|
191
|
+
dueInDays: form.balanceDueDaysBeforeDeparture
|
|
192
|
+
? Number(form.balanceDueDaysBeforeDeparture)
|
|
193
|
+
: 0,
|
|
194
|
+
dueCondition: "before_departure",
|
|
195
|
+
},
|
|
196
|
+
]
|
|
197
|
+
: [],
|
|
198
|
+
defaultSchedule: form.depositPercent || form.balanceDueDaysBeforeDeparture
|
|
199
|
+
? {
|
|
200
|
+
depositPercent: form.depositPercent ? Number(form.depositPercent) : null,
|
|
201
|
+
balanceDueDaysBeforeDeparture: form.balanceDueDaysBeforeDeparture
|
|
202
|
+
? Number(form.balanceDueDaysBeforeDeparture)
|
|
203
|
+
: null,
|
|
204
|
+
}
|
|
205
|
+
: null,
|
|
206
|
+
bankTransfer: form.bankTransferDueDays ||
|
|
207
|
+
form.bankProvider ||
|
|
208
|
+
form.bankCurrency ||
|
|
209
|
+
form.accountHolder ||
|
|
210
|
+
form.bankName ||
|
|
211
|
+
form.iban ||
|
|
212
|
+
form.bic ||
|
|
213
|
+
form.paymentReference ||
|
|
214
|
+
form.bankInstructions
|
|
215
|
+
? {
|
|
216
|
+
dueDays: form.bankTransferDueDays ? Number(form.bankTransferDueDays) : null,
|
|
217
|
+
account: form.iban && form.accountHolder && form.bankName
|
|
218
|
+
? {
|
|
219
|
+
provider: optional(form.bankProvider),
|
|
220
|
+
currency: optional(form.bankCurrency),
|
|
221
|
+
iban: form.iban.trim(),
|
|
222
|
+
beneficiary: form.accountHolder.trim(),
|
|
223
|
+
bank: form.bankName.trim(),
|
|
224
|
+
}
|
|
225
|
+
: null,
|
|
226
|
+
accountHolder: optional(form.accountHolder),
|
|
227
|
+
bankName: optional(form.bankName),
|
|
228
|
+
iban: optional(form.iban),
|
|
229
|
+
bic: optional(form.bic),
|
|
230
|
+
paymentReference: optional(form.paymentReference),
|
|
231
|
+
instructions: optional(form.bankInstructions),
|
|
232
|
+
}
|
|
233
|
+
: null,
|
|
234
|
+
},
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
export function hasEmptySettings(settings) {
|
|
238
|
+
if (!settings)
|
|
239
|
+
return true;
|
|
240
|
+
return (!settings.branding.logoUrl &&
|
|
241
|
+
!settings.support.email &&
|
|
242
|
+
!settings.support.phone &&
|
|
243
|
+
!settings.legal.termsUrl &&
|
|
244
|
+
!settings.payment.defaultMethod &&
|
|
245
|
+
settings.payment.methods.length === 0);
|
|
246
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type FormState } from "./storefront-settings-form.js";
|
|
2
|
+
type SetField = <K extends keyof FormState>(key: K, value: FormState[K]) => void;
|
|
3
|
+
export declare function PaymentSection({ form, setField }: {
|
|
4
|
+
form: FormState;
|
|
5
|
+
setField: SetField;
|
|
6
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export declare function StorefrontSettingsSaveButton({ isSaving, save, }: {
|
|
8
|
+
isSaving: boolean;
|
|
9
|
+
save: () => void;
|
|
10
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=storefront-settings-payment-section.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storefront-settings-payment-section.d.ts","sourceRoot":"","sources":["../../src/internal/storefront-settings-payment-section.tsx"],"names":[],"mappings":"AAoBA,OAAO,EAAE,KAAK,SAAS,EAAkB,MAAM,+BAA+B,CAAA;AAE9E,KAAK,QAAQ,GAAG,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;AAEhF,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,QAAQ,CAAA;CAAE,2CA2KzF;AAED,wBAAgB,4BAA4B,CAAC,EAC3C,QAAQ,EACR,IAAI,GACL,EAAE;IACD,QAAQ,EAAE,OAAO,CAAA;IACjB,IAAI,EAAE,MAAM,IAAI,CAAA;CACjB,2CASA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button, Card, CardContent, CardDescription, CardHeader, CardTitle, Checkbox, Input, Textarea, } from "@voyant-travel/ui/components";
|
|
3
|
+
import { Field, FieldGroup, FieldLabel, FieldLegend, FieldSet, } from "@voyant-travel/ui/components/field";
|
|
4
|
+
import { Loader2, Save } from "lucide-react";
|
|
5
|
+
import { paymentMethods } from "./storefront-settings-form.js";
|
|
6
|
+
export function PaymentSection({ form, setField }) {
|
|
7
|
+
return (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Payment defaults" }), _jsx(CardDescription, { children: "Default payment methods, schedules, and bank details." })] }), _jsx(CardContent, { children: _jsxs(FieldGroup, { children: [_jsxs(FieldSet, { children: [_jsx(FieldLegend, { children: "Payment methods" }), _jsx("div", { className: "grid grid-cols-1 gap-2 md:grid-cols-2", children: paymentMethods.map((method) => (_jsxs(Field, { orientation: "horizontal", children: [_jsx(Checkbox, { id: `storefront-payment-${method.code}`, checked: form.enabledMethods[method.code], onCheckedChange: (checked) => setField("enabledMethods", {
|
|
8
|
+
...form.enabledMethods,
|
|
9
|
+
[method.code]: checked === true,
|
|
10
|
+
}) }), _jsx(FieldLabel, { htmlFor: `storefront-payment-${method.code}`, children: method.label })] }, method.code))) })] }), _jsxs("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-3", children: [_jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-default-method", children: "Default method" }), _jsxs("select", { id: "storefront-default-method", className: "h-9 rounded-md border bg-background px-3 text-sm", value: form.defaultMethod, onChange: (event) => setField("defaultMethod", event.target.value), children: [_jsx("option", { value: "none", children: "None" }), paymentMethods.map((method) => (_jsx("option", { value: method.code, children: method.label }, method.code)))] })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-payment-structure", children: "Payment structure" }), _jsxs("select", { id: "storefront-payment-structure", className: "h-9 rounded-md border bg-background px-3 text-sm", value: form.paymentStructure, onChange: (event) => setField("paymentStructure", event.target.value), children: [_jsx("option", { value: "full", children: "Full payment" }), _jsx("option", { value: "split", children: "Deposit + balance" })] })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-deposit-percent", children: "Deposit percent" }), _jsx(Input, { id: "storefront-deposit-percent", type: "number", min: 0, max: 100, value: form.depositPercent, onChange: (event) => setField("depositPercent", event.target.value) })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-balance-due", children: "Balance due days" }), _jsx(Input, { id: "storefront-balance-due", type: "number", min: 0, value: form.balanceDueDaysBeforeDeparture, onChange: (event) => setField("balanceDueDaysBeforeDeparture", event.target.value) })] })] }), _jsxs(FieldSet, { children: [_jsx(FieldLegend, { children: "Bank transfer details" }), _jsxs("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2", children: [_jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-bank-provider", children: "Provider" }), _jsx(Input, { id: "storefront-bank-provider", value: form.bankProvider, onChange: (event) => setField("bankProvider", event.target.value) })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-bank-currency", children: "Currency" }), _jsx(Input, { id: "storefront-bank-currency", value: form.bankCurrency, onChange: (event) => setField("bankCurrency", event.target.value) })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-account-holder", children: "Account holder" }), _jsx(Input, { id: "storefront-account-holder", value: form.accountHolder, onChange: (event) => setField("accountHolder", event.target.value) })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-bank-name", children: "Bank name" }), _jsx(Input, { id: "storefront-bank-name", value: form.bankName, onChange: (event) => setField("bankName", event.target.value) })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-iban", children: "IBAN or account number" }), _jsx(Input, { id: "storefront-iban", value: form.iban, onChange: (event) => setField("iban", event.target.value) })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-bic", children: "BIC or routing code" }), _jsx(Input, { id: "storefront-bic", value: form.bic, onChange: (event) => setField("bic", event.target.value) })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-bank-due-days", children: "Due days" }), _jsx(Input, { id: "storefront-bank-due-days", type: "number", min: 0, value: form.bankTransferDueDays, onChange: (event) => setField("bankTransferDueDays", event.target.value) })] })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-payment-reference", children: "Payment reference" }), _jsx(Input, { id: "storefront-payment-reference", value: form.paymentReference, onChange: (event) => setField("paymentReference", event.target.value) })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-bank-instructions", children: "Instructions" }), _jsx(Textarea, { id: "storefront-bank-instructions", value: form.bankInstructions, onChange: (event) => setField("bankInstructions", event.target.value) })] })] })] }) })] }));
|
|
11
|
+
}
|
|
12
|
+
export function StorefrontSettingsSaveButton({ isSaving, save, }) {
|
|
13
|
+
return (_jsx("div", { className: "flex justify-end", children: _jsxs(Button, { type: "button", onClick: save, disabled: isSaving, children: [isSaving ? _jsx(Loader2, { className: "size-4 animate-spin" }) : _jsx(Save, { className: "size-4" }), "Save settings"] }) }));
|
|
14
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type FormState, type SupportLinkRow } from "./storefront-settings-form.js";
|
|
2
|
+
type SetField = <K extends keyof FormState>(key: K, value: FormState[K]) => void;
|
|
3
|
+
interface SettingsSectionProps {
|
|
4
|
+
form: FormState;
|
|
5
|
+
setField: SetField;
|
|
6
|
+
}
|
|
7
|
+
interface SupportSectionProps extends SettingsSectionProps {
|
|
8
|
+
updateSupportLink: (rowKey: string, patch: Partial<SupportLinkRow>) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function StorefrontSettingsLoadingSections(): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export declare function StorefrontSettingsErrorState({ error, refetch, }: {
|
|
12
|
+
error: unknown;
|
|
13
|
+
refetch: () => void;
|
|
14
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export declare function BrandingSection({ form, setField }: SettingsSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export declare function SupportSection({ form, setField, updateSupportLink }: SupportSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export declare function LegalLocalizationSection({ form, setField }: SettingsSectionProps): import("react/jsx-runtime").JSX.Element;
|
|
18
|
+
export declare function StorefrontSettingsSaveError({ localError, mutationError, }: {
|
|
19
|
+
localError: string | null;
|
|
20
|
+
mutationError: unknown;
|
|
21
|
+
}): import("react/jsx-runtime").JSX.Element | null;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=storefront-settings-sections.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storefront-settings-sections.d.ts","sourceRoot":"","sources":["../../src/internal/storefront-settings-sections.tsx"],"names":[],"mappings":"AAqBA,OAAO,EACL,KAAK,SAAS,EAGd,KAAK,cAAc,EACpB,MAAM,+BAA+B,CAAA;AAEtC,KAAK,QAAQ,GAAG,CAAC,CAAC,SAAS,MAAM,SAAS,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,IAAI,CAAA;AAEhF,UAAU,oBAAoB;IAC5B,IAAI,EAAE,SAAS,CAAA;IACf,QAAQ,EAAE,QAAQ,CAAA;CACnB;AAED,UAAU,mBAAoB,SAAQ,oBAAoB;IACxD,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,cAAc,CAAC,KAAK,IAAI,CAAA;CAC5E;AAED,wBAAgB,iCAAiC,4CAkBhD;AAED,wBAAgB,4BAA4B,CAAC,EAC3C,KAAK,EACL,OAAO,GACR,EAAE;IACD,KAAK,EAAE,OAAO,CAAA;IACd,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB,2CAmBA;AAED,wBAAgB,eAAe,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,oBAAoB,2CAoEvE;AAED,wBAAgB,cAAc,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,iBAAiB,EAAE,EAAE,mBAAmB,2CAwFxF;AAED,wBAAgB,wBAAwB,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,oBAAoB,2CAuEhF;AAED,wBAAgB,2BAA2B,CAAC,EAC1C,UAAU,EACV,aAAa,GACd,EAAE;IACD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,aAAa,EAAE,OAAO,CAAA;CACvB,kDAWA"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Button, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, Input, } from "@voyant-travel/ui/components";
|
|
3
|
+
import { Field, FieldDescription, FieldGroup, FieldLabel, FieldLegend, FieldSet, } from "@voyant-travel/ui/components/field";
|
|
4
|
+
import { Skeleton } from "@voyant-travel/ui/components/skeleton";
|
|
5
|
+
import { AlertCircle, Plus, Trash2 } from "lucide-react";
|
|
6
|
+
import { loadingSectionKeys, nextSupportLinkKey, } from "./storefront-settings-form.js";
|
|
7
|
+
export function StorefrontSettingsLoadingSections() {
|
|
8
|
+
return (_jsx("div", { className: "grid grid-cols-1 gap-4 xl:grid-cols-2", children: loadingSectionKeys.map((key) => (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(Skeleton, { className: "h-5 w-40" }), _jsx(Skeleton, { className: "h-4 w-64" })] }), _jsxs(CardContent, { className: "space-y-3", children: [_jsx(Skeleton, { className: "h-9 w-full" }), _jsx(Skeleton, { className: "h-9 w-full" }), _jsx(Skeleton, { className: "h-9 w-2/3" })] })] }, key))) }));
|
|
9
|
+
}
|
|
10
|
+
export function StorefrontSettingsErrorState({ error, refetch, }) {
|
|
11
|
+
return (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsxs(CardTitle, { className: "flex items-center gap-2", children: [_jsx(AlertCircle, { className: "size-5 text-destructive" }), "Could not load settings"] }), _jsx(CardDescription, { children: error instanceof Error ? error.message : "The storefront settings request failed." })] }), _jsx(CardFooter, { children: _jsx(Button, { type: "button", variant: "outline", onClick: refetch, children: "Try again" }) })] }));
|
|
12
|
+
}
|
|
13
|
+
export function BrandingSection({ form, setField }) {
|
|
14
|
+
return (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Branding" }), _jsx(CardDescription, { children: "Customer-facing assets and brand color tokens." })] }), _jsx(CardContent, { children: _jsxs(FieldGroup, { children: [_jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-logo-url", children: "Logo URL" }), _jsx(Input, { id: "storefront-logo-url", value: form.logoUrl, onChange: (event) => setField("logoUrl", event.target.value), placeholder: "https://cdn.example.com/logo.svg" })] }), _jsxs("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2", children: [_jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-favicon-url", children: "Favicon URL" }), _jsx(Input, { id: "storefront-favicon-url", value: form.faviconUrl, onChange: (event) => setField("faviconUrl", event.target.value) })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-brand-mark-url", children: "Brand mark URL" }), _jsx(Input, { id: "storefront-brand-mark-url", value: form.brandMarkUrl, onChange: (event) => setField("brandMarkUrl", event.target.value) })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-primary-color", children: "Primary color" }), _jsx(Input, { id: "storefront-primary-color", value: form.primaryColor, onChange: (event) => setField("primaryColor", event.target.value), placeholder: "#0f766e" })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-accent-color", children: "Accent color" }), _jsx(Input, { id: "storefront-accent-color", value: form.accentColor, onChange: (event) => setField("accentColor", event.target.value), placeholder: "#f59e0b" })] })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-supported-languages", children: "Supported languages" }), _jsx(Input, { id: "storefront-supported-languages", value: form.supportedLanguages, onChange: (event) => setField("supportedLanguages", event.target.value), placeholder: "en, ro, fr-FR" }), _jsx(FieldDescription, { children: "Use comma-separated BCP 47 language tags." })] })] }) })] }));
|
|
15
|
+
}
|
|
16
|
+
export function SupportSection({ form, setField, updateSupportLink }) {
|
|
17
|
+
return (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Support" }), _jsx(CardDescription, { children: "Contact channels shown to storefront customers." })] }), _jsx(CardContent, { children: _jsxs(FieldGroup, { children: [_jsxs("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2", children: [_jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-support-email", children: "Email" }), _jsx(Input, { id: "storefront-support-email", type: "email", value: form.supportEmail, onChange: (event) => setField("supportEmail", event.target.value) })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-support-phone", children: "Phone" }), _jsx(Input, { id: "storefront-support-phone", value: form.supportPhone, onChange: (event) => setField("supportPhone", event.target.value) })] })] }), _jsxs(FieldSet, { children: [_jsx(FieldLegend, { children: "Contact links" }), _jsxs("div", { className: "space-y-2", children: [form.supportLinks.map((link) => (_jsxs("div", { className: "grid grid-cols-1 gap-2 md:grid-cols-[minmax(0,1fr)_minmax(0,1fr)_auto]", children: [_jsx(Input, { value: link.label, onChange: (event) => updateSupportLink(link.rowKey, { label: event.target.value }), placeholder: "WhatsApp", "aria-label": "Contact link label" }), _jsx(Input, { value: link.url, onChange: (event) => updateSupportLink(link.rowKey, { url: event.target.value }), placeholder: "https://example.com/contact", "aria-label": "Contact link URL" }), _jsx(Button, { type: "button", variant: "ghost", size: "icon", onClick: () => setField("supportLinks", form.supportLinks.filter((row) => row.rowKey !== link.rowKey)), "aria-label": "Remove contact link", children: _jsx(Trash2, { className: "size-4" }) })] }, link.rowKey))), _jsxs(Button, { type: "button", variant: "outline", size: "sm", onClick: () => setField("supportLinks", [
|
|
18
|
+
...form.supportLinks,
|
|
19
|
+
{ rowKey: nextSupportLinkKey(), label: "", url: "" },
|
|
20
|
+
]), children: [_jsx(Plus, { className: "size-4" }), "Add link"] })] })] })] }) })] }));
|
|
21
|
+
}
|
|
22
|
+
export function LegalLocalizationSection({ form, setField }) {
|
|
23
|
+
return (_jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Legal and localization" }), _jsx(CardDescription, { children: "Policy links and default display preferences." })] }), _jsx(CardContent, { children: _jsx(FieldGroup, { children: _jsxs("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2", children: [_jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-terms-url", children: "Terms URL" }), _jsx(Input, { id: "storefront-terms-url", value: form.termsUrl, onChange: (event) => setField("termsUrl", event.target.value) })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-privacy-url", children: "Privacy URL" }), _jsx(Input, { id: "storefront-privacy-url", value: form.privacyUrl, onChange: (event) => setField("privacyUrl", event.target.value) })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-cancellation-url", children: "Cancellation URL" }), _jsx(Input, { id: "storefront-cancellation-url", value: form.cancellationUrl, onChange: (event) => setField("cancellationUrl", event.target.value) })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-contract-template", children: "Contract template ID" }), _jsx(Input, { id: "storefront-contract-template", value: form.defaultContractTemplateId, onChange: (event) => setField("defaultContractTemplateId", event.target.value) })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-default-locale", children: "Default locale" }), _jsx(Input, { id: "storefront-default-locale", value: form.defaultLocale, onChange: (event) => setField("defaultLocale", event.target.value), placeholder: "en-US" })] }), _jsxs(Field, { children: [_jsx(FieldLabel, { htmlFor: "storefront-currency-display", children: "Currency display" }), _jsxs("select", { id: "storefront-currency-display", className: "h-9 rounded-md border bg-background px-3 text-sm", value: form.currencyDisplay, onChange: (event) => setField("currencyDisplay", event.target.value), children: [_jsx("option", { value: "code", children: "Code" }), _jsx("option", { value: "symbol", children: "Symbol" }), _jsx("option", { value: "name", children: "Name" })] })] })] }) }) })] }));
|
|
24
|
+
}
|
|
25
|
+
export function StorefrontSettingsSaveError({ localError, mutationError, }) {
|
|
26
|
+
if (!localError && !mutationError)
|
|
27
|
+
return null;
|
|
28
|
+
return (_jsx("p", { className: "rounded-md border border-destructive/30 bg-destructive/5 p-3 text-sm text-destructive", children: localError ??
|
|
29
|
+
(mutationError instanceof Error
|
|
30
|
+
? mutationError.message
|
|
31
|
+
: "Failed to save storefront settings.") }));
|
|
32
|
+
}
|