@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.
Files changed (136) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +17 -0
  3. package/dist/client.d.ts +16 -0
  4. package/dist/client.d.ts.map +1 -0
  5. package/dist/client.js +78 -0
  6. package/dist/components/storefront-settings-page.d.ts +5 -0
  7. package/dist/components/storefront-settings-page.d.ts.map +1 -0
  8. package/dist/components/storefront-settings-page.js +39 -0
  9. package/dist/customer-portal/client.d.ts +16 -0
  10. package/dist/customer-portal/client.d.ts.map +1 -0
  11. package/dist/customer-portal/client.js +78 -0
  12. package/dist/customer-portal/hooks/index.d.ts +12 -0
  13. package/dist/customer-portal/hooks/index.d.ts.map +1 -0
  14. package/dist/customer-portal/hooks/index.js +11 -0
  15. package/dist/customer-portal/hooks/use-customer-portal-booking-billing-contact.d.ts +18 -0
  16. package/dist/customer-portal/hooks/use-customer-portal-booking-billing-contact.d.ts.map +1 -0
  17. package/dist/customer-portal/hooks/use-customer-portal-booking-billing-contact.js +12 -0
  18. package/dist/customer-portal/hooks/use-customer-portal-booking-documents.d.ts +16 -0
  19. package/dist/customer-portal/hooks/use-customer-portal-booking-documents.d.ts.map +1 -0
  20. package/dist/customer-portal/hooks/use-customer-portal-booking-documents.js +12 -0
  21. package/dist/customer-portal/hooks/use-customer-portal-booking.d.ts +109 -0
  22. package/dist/customer-portal/hooks/use-customer-portal-booking.d.ts.map +1 -0
  23. package/dist/customer-portal/hooks/use-customer-portal-booking.js +12 -0
  24. package/dist/customer-portal/hooks/use-customer-portal-bookings.d.ts +22 -0
  25. package/dist/customer-portal/hooks/use-customer-portal-bookings.d.ts.map +1 -0
  26. package/dist/customer-portal/hooks/use-customer-portal-bookings.js +12 -0
  27. package/dist/customer-portal/hooks/use-customer-portal-companions.d.ts +42 -0
  28. package/dist/customer-portal/hooks/use-customer-portal-companions.d.ts.map +1 -0
  29. package/dist/customer-portal/hooks/use-customer-portal-companions.js +12 -0
  30. package/dist/customer-portal/hooks/use-customer-portal-contact-exists.d.ts +12 -0
  31. package/dist/customer-portal/hooks/use-customer-portal-contact-exists.d.ts.map +1 -0
  32. package/dist/customer-portal/hooks/use-customer-portal-contact-exists.js +12 -0
  33. package/dist/customer-portal/hooks/use-customer-portal-mutation.d.ts +419 -0
  34. package/dist/customer-portal/hooks/use-customer-portal-mutation.d.ts.map +1 -0
  35. package/dist/customer-portal/hooks/use-customer-portal-mutation.js +62 -0
  36. package/dist/customer-portal/hooks/use-customer-portal-phone-contact-exists.d.ts +13 -0
  37. package/dist/customer-portal/hooks/use-customer-portal-phone-contact-exists.d.ts.map +1 -0
  38. package/dist/customer-portal/hooks/use-customer-portal-phone-contact-exists.js +12 -0
  39. package/dist/customer-portal/hooks/use-customer-portal-profile-document-mutation.d.ts +69 -0
  40. package/dist/customer-portal/hooks/use-customer-portal-profile-document-mutation.d.ts.map +1 -0
  41. package/dist/customer-portal/hooks/use-customer-portal-profile-document-mutation.js +28 -0
  42. package/dist/customer-portal/hooks/use-customer-portal-profile-documents.d.ts +20 -0
  43. package/dist/customer-portal/hooks/use-customer-portal-profile-documents.d.ts.map +1 -0
  44. package/dist/customer-portal/hooks/use-customer-portal-profile-documents.js +12 -0
  45. package/dist/customer-portal/hooks/use-customer-portal-profile.d.ts +61 -0
  46. package/dist/customer-portal/hooks/use-customer-portal-profile.d.ts.map +1 -0
  47. package/dist/customer-portal/hooks/use-customer-portal-profile.js +12 -0
  48. package/dist/customer-portal/index.d.ts +9 -0
  49. package/dist/customer-portal/index.d.ts.map +1 -0
  50. package/dist/customer-portal/index.js +7 -0
  51. package/dist/customer-portal/operations.d.ts +595 -0
  52. package/dist/customer-portal/operations.d.ts.map +1 -0
  53. package/dist/customer-portal/operations.js +84 -0
  54. package/dist/customer-portal/provider.d.ts +2 -0
  55. package/dist/customer-portal/provider.d.ts.map +1 -0
  56. package/dist/customer-portal/provider.js +1 -0
  57. package/dist/customer-portal/query-keys.d.ts +21 -0
  58. package/dist/customer-portal/query-keys.d.ts.map +1 -0
  59. package/dist/customer-portal/query-keys.js +14 -0
  60. package/dist/customer-portal/query-options.d.ts +1148 -0
  61. package/dist/customer-portal/query-options.d.ts.map +1 -0
  62. package/dist/customer-portal/query-options.js +58 -0
  63. package/dist/customer-portal/schemas.d.ts +751 -0
  64. package/dist/customer-portal/schemas.d.ts.map +1 -0
  65. package/dist/customer-portal/schemas.js +21 -0
  66. package/dist/hooks/index.d.ts +12 -0
  67. package/dist/hooks/index.d.ts.map +1 -0
  68. package/dist/hooks/index.js +11 -0
  69. package/dist/hooks/use-admin-storefront-settings.d.ts +290 -0
  70. package/dist/hooks/use-admin-storefront-settings.d.ts.map +1 -0
  71. package/dist/hooks/use-admin-storefront-settings.js +29 -0
  72. package/dist/hooks/use-storefront-departure-itinerary.d.ts +23 -0
  73. package/dist/hooks/use-storefront-departure-itinerary.d.ts.map +1 -0
  74. package/dist/hooks/use-storefront-departure-itinerary.js +12 -0
  75. package/dist/hooks/use-storefront-departure-price-preview-mutation.d.ts +244 -0
  76. package/dist/hooks/use-storefront-departure-price-preview-mutation.d.ts.map +1 -0
  77. package/dist/hooks/use-storefront-departure-price-preview-mutation.js +15 -0
  78. package/dist/hooks/use-storefront-departure.d.ts +51 -0
  79. package/dist/hooks/use-storefront-departure.d.ts.map +1 -0
  80. package/dist/hooks/use-storefront-departure.js +12 -0
  81. package/dist/hooks/use-storefront-offer-apply-mutation.d.ts +68 -0
  82. package/dist/hooks/use-storefront-offer-apply-mutation.d.ts.map +1 -0
  83. package/dist/hooks/use-storefront-offer-apply-mutation.js +15 -0
  84. package/dist/hooks/use-storefront-offer-redeem-mutation.d.ts +69 -0
  85. package/dist/hooks/use-storefront-offer-redeem-mutation.d.ts.map +1 -0
  86. package/dist/hooks/use-storefront-offer-redeem-mutation.js +12 -0
  87. package/dist/hooks/use-storefront-offer.d.ts +26 -0
  88. package/dist/hooks/use-storefront-offer.d.ts.map +1 -0
  89. package/dist/hooks/use-storefront-offer.js +12 -0
  90. package/dist/hooks/use-storefront-product-departures.d.ts +55 -0
  91. package/dist/hooks/use-storefront-product-departures.d.ts.map +1 -0
  92. package/dist/hooks/use-storefront-product-departures.js +12 -0
  93. package/dist/hooks/use-storefront-product-extensions.d.ts +47 -0
  94. package/dist/hooks/use-storefront-product-extensions.d.ts.map +1 -0
  95. package/dist/hooks/use-storefront-product-extensions.js +12 -0
  96. package/dist/hooks/use-storefront-product-offers.d.ts +26 -0
  97. package/dist/hooks/use-storefront-product-offers.d.ts.map +1 -0
  98. package/dist/hooks/use-storefront-product-offers.js +12 -0
  99. package/dist/hooks/use-storefront-settings.d.ts +101 -0
  100. package/dist/hooks/use-storefront-settings.d.ts.map +1 -0
  101. package/dist/hooks/use-storefront-settings.js +12 -0
  102. package/dist/index.d.ts +8 -0
  103. package/dist/index.d.ts.map +1 -0
  104. package/dist/index.js +7 -0
  105. package/dist/internal/storefront-settings-form.d.ts +50 -0
  106. package/dist/internal/storefront-settings-form.d.ts.map +1 -0
  107. package/dist/internal/storefront-settings-form.js +246 -0
  108. package/dist/internal/storefront-settings-payment-section.d.ts +12 -0
  109. package/dist/internal/storefront-settings-payment-section.d.ts.map +1 -0
  110. package/dist/internal/storefront-settings-payment-section.js +14 -0
  111. package/dist/internal/storefront-settings-sections.d.ts +23 -0
  112. package/dist/internal/storefront-settings-sections.d.ts.map +1 -0
  113. package/dist/internal/storefront-settings-sections.js +32 -0
  114. package/dist/operations.d.ts +827 -0
  115. package/dist/operations.d.ts.map +1 -0
  116. package/dist/operations.js +46 -0
  117. package/dist/operations.test.d.ts +2 -0
  118. package/dist/operations.test.d.ts.map +1 -0
  119. package/dist/operations.test.js +77 -0
  120. package/dist/provider.d.ts +2 -0
  121. package/dist/provider.d.ts.map +1 -0
  122. package/dist/provider.js +1 -0
  123. package/dist/query-keys.d.ts +32 -0
  124. package/dist/query-keys.d.ts.map +1 -0
  125. package/dist/query-keys.js +15 -0
  126. package/dist/query-options.d.ts +1648 -0
  127. package/dist/query-options.d.ts.map +1 -0
  128. package/dist/query-options.js +52 -0
  129. package/dist/schemas.d.ts +576 -0
  130. package/dist/schemas.d.ts.map +1 -0
  131. package/dist/schemas.js +11 -0
  132. package/dist/ui.d.ts +2 -0
  133. package/dist/ui.d.ts.map +1 -0
  134. package/dist/ui.js +1 -0
  135. package/package.json +133 -0
  136. 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
+ }