@open-mercato/checkout 0.8.1-develop.7207.1.901ef7e47a → 0.8.1-develop.7218.1.9f22882799
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/modules/checkout/components/LinkTemplateForm.js +28 -10
- package/dist/modules/checkout/components/LinkTemplateForm.js.map +2 -2
- package/package.json +5 -5
- package/src/modules/checkout/components/LinkTemplateForm.tsx +41 -14
- package/src/modules/checkout/components/__tests__/LinkTemplateForm.localeDecimalSeparator.test.tsx +68 -38
|
@@ -64,6 +64,12 @@ function readNumberInputValue(value) {
|
|
|
64
64
|
if (typeof value === "string") return value;
|
|
65
65
|
return "";
|
|
66
66
|
}
|
|
67
|
+
function toSubmittedAmount(value, locale) {
|
|
68
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : null;
|
|
69
|
+
if (typeof value !== "string") return null;
|
|
70
|
+
if (!value.trim()) return null;
|
|
71
|
+
return parseLocaleNumber(value, locale);
|
|
72
|
+
}
|
|
67
73
|
function readBoolean(value, fallback = false) {
|
|
68
74
|
return typeof value === "boolean" ? value : fallback;
|
|
69
75
|
}
|
|
@@ -133,12 +139,12 @@ function normalizePriceListItems(value) {
|
|
|
133
139
|
if (!isRecord(item)) return null;
|
|
134
140
|
const id = readString(item.id).trim();
|
|
135
141
|
const description = readString(item.description);
|
|
136
|
-
const amount =
|
|
142
|
+
const amount = typeof item.amount === "number" || typeof item.amount === "string" ? item.amount : 0;
|
|
137
143
|
const currencyCode = readString(item.currencyCode).trim().toUpperCase();
|
|
138
144
|
return {
|
|
139
145
|
id: id || `item_${Date.now()}`,
|
|
140
146
|
description,
|
|
141
|
-
amount
|
|
147
|
+
amount,
|
|
142
148
|
currencyCode: currencyCode || "USD"
|
|
143
149
|
};
|
|
144
150
|
}).filter((item) => item !== null);
|
|
@@ -306,7 +312,6 @@ function PriceListEditor({
|
|
|
306
312
|
error
|
|
307
313
|
}) {
|
|
308
314
|
const t = useT();
|
|
309
|
-
const locale = useLocale();
|
|
310
315
|
const items = Array.isArray(value) ? value : [];
|
|
311
316
|
const updateItem = React.useCallback(
|
|
312
317
|
(index, patch) => {
|
|
@@ -364,7 +369,11 @@ function PriceListEditor({
|
|
|
364
369
|
inputMode: "decimal",
|
|
365
370
|
value: readNumberInputValue(item.amount),
|
|
366
371
|
onChange: (event) => updateItem(index, {
|
|
367
|
-
|
|
372
|
+
// Stays raw while editing — re-parsing and re-serializing on every
|
|
373
|
+
// keystroke would drop an in-progress decimal separator (e.g. typing
|
|
374
|
+
// "110,70" collapses to "11070" the instant the comma is typed,
|
|
375
|
+
// issue #5828). Converted to a number at submit time instead.
|
|
376
|
+
amount: event.target.value
|
|
368
377
|
}),
|
|
369
378
|
placeholder: "0.00",
|
|
370
379
|
"aria-label": t("checkout.linkTemplateForm.priceList.aria.amount", { index: index + 1 }),
|
|
@@ -402,7 +411,6 @@ function PriceListEditor({
|
|
|
402
411
|
}
|
|
403
412
|
function PricingSection({ values, setValue, errors }) {
|
|
404
413
|
const t = useT();
|
|
405
|
-
const locale = useLocale();
|
|
406
414
|
const pricingMode = readString(values.pricingMode) || "fixed";
|
|
407
415
|
const pricingModeError = readError(errors, "pricingMode");
|
|
408
416
|
const fixedPriceAmountError = readError(errors, "fixedPriceAmount");
|
|
@@ -443,7 +451,7 @@ function PricingSection({ values, setValue, errors }) {
|
|
|
443
451
|
type: "text",
|
|
444
452
|
inputMode: "decimal",
|
|
445
453
|
value: readNumberInputValue(values.fixedPriceAmount),
|
|
446
|
-
onChange: (event) => setValue("fixedPriceAmount",
|
|
454
|
+
onChange: (event) => setValue("fixedPriceAmount", event.target.value),
|
|
447
455
|
placeholder: "150",
|
|
448
456
|
className: errorInputClassName(fixedPriceAmountError),
|
|
449
457
|
"aria-invalid": Boolean(fixedPriceAmountError)
|
|
@@ -469,7 +477,7 @@ function PricingSection({ values, setValue, errors }) {
|
|
|
469
477
|
type: "text",
|
|
470
478
|
inputMode: "decimal",
|
|
471
479
|
value: readNumberInputValue(values.fixedPriceOriginalAmount),
|
|
472
|
-
onChange: (event) => setValue("fixedPriceOriginalAmount",
|
|
480
|
+
onChange: (event) => setValue("fixedPriceOriginalAmount", event.target.value),
|
|
473
481
|
placeholder: "200",
|
|
474
482
|
className: errorInputClassName(fixedPriceOriginalAmountError),
|
|
475
483
|
"aria-invalid": Boolean(fixedPriceOriginalAmountError)
|
|
@@ -496,7 +504,7 @@ function PricingSection({ values, setValue, errors }) {
|
|
|
496
504
|
type: "text",
|
|
497
505
|
inputMode: "decimal",
|
|
498
506
|
value: readNumberInputValue(values.customAmountMin),
|
|
499
|
-
onChange: (event) => setValue("customAmountMin",
|
|
507
|
+
onChange: (event) => setValue("customAmountMin", event.target.value),
|
|
500
508
|
placeholder: "10",
|
|
501
509
|
className: errorInputClassName(customAmountMinError),
|
|
502
510
|
"aria-invalid": Boolean(customAmountMinError)
|
|
@@ -508,7 +516,7 @@ function PricingSection({ values, setValue, errors }) {
|
|
|
508
516
|
type: "text",
|
|
509
517
|
inputMode: "decimal",
|
|
510
518
|
value: readNumberInputValue(values.customAmountMax),
|
|
511
|
-
onChange: (event) => setValue("customAmountMax",
|
|
519
|
+
onChange: (event) => setValue("customAmountMax", event.target.value),
|
|
512
520
|
placeholder: "500",
|
|
513
521
|
className: errorInputClassName(customAmountMaxError),
|
|
514
522
|
"aria-invalid": Boolean(customAmountMaxError)
|
|
@@ -1139,6 +1147,7 @@ function SettingsSection({ values, setValue, errors }) {
|
|
|
1139
1147
|
}
|
|
1140
1148
|
function LinkTemplateForm({ mode, recordId }) {
|
|
1141
1149
|
const t = useT();
|
|
1150
|
+
const locale = useLocale();
|
|
1142
1151
|
const searchParams = useSearchParams();
|
|
1143
1152
|
const entityId = mode === "link" ? CHECKOUT_ENTITY_IDS.link : CHECKOUT_ENTITY_IDS.template;
|
|
1144
1153
|
const templateId = React.useMemo(() => {
|
|
@@ -1440,6 +1449,14 @@ function LinkTemplateForm({ mode, recordId }) {
|
|
|
1440
1449
|
const payload = {
|
|
1441
1450
|
...values,
|
|
1442
1451
|
status: submitIntent === "publish" ? "active" : values.status,
|
|
1452
|
+
fixedPriceAmount: toSubmittedAmount(values.fixedPriceAmount, locale),
|
|
1453
|
+
fixedPriceOriginalAmount: toSubmittedAmount(values.fixedPriceOriginalAmount, locale),
|
|
1454
|
+
customAmountMin: toSubmittedAmount(values.customAmountMin, locale),
|
|
1455
|
+
customAmountMax: toSubmittedAmount(values.customAmountMax, locale),
|
|
1456
|
+
priceListItems: normalizePriceListItems(values.priceListItems).map((item) => ({
|
|
1457
|
+
...item,
|
|
1458
|
+
amount: toSubmittedAmount(item.amount, locale) ?? Number.NaN
|
|
1459
|
+
})),
|
|
1443
1460
|
customFields: collectCustomFieldValues(values)
|
|
1444
1461
|
};
|
|
1445
1462
|
const endpoint = `/api/checkout/${mode === "link" ? "links" : "templates"}${recordId ? `/${encodeURIComponent(recordId)}` : ""}`;
|
|
@@ -1520,6 +1537,7 @@ export {
|
|
|
1520
1537
|
LinkTemplateForm,
|
|
1521
1538
|
PriceListEditor,
|
|
1522
1539
|
PricingSection,
|
|
1523
|
-
LinkTemplateForm_default as default
|
|
1540
|
+
LinkTemplateForm_default as default,
|
|
1541
|
+
toSubmittedAmount
|
|
1524
1542
|
};
|
|
1525
1543
|
//# sourceMappingURL=LinkTemplateForm.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/checkout/components/LinkTemplateForm.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useSearchParams } from 'next/navigation'\nimport { useT, useLocale, type TranslateFn } from '@open-mercato/shared/lib/i18n/context'\nimport { parseLocaleNumber } from '@open-mercato/shared/lib/number'\nimport {\n AlertTriangle,\n BadgeCheck,\n CircleDollarSign,\n Eye,\n FileCheck2,\n FileText,\n IdCard,\n MessageSquare,\n Plus,\n Send,\n Shield,\n Sparkles,\n Trash2,\n WalletCards,\n} from 'lucide-react'\nimport { slugify } from '@open-mercato/shared/lib/slugify'\nimport { CrudForm, type CrudField, type CrudFormGroup, type CrudFormGroupComponentProps } from '@open-mercato/ui/backend/CrudForm'\nimport { ComboboxInput, type ComboboxOption } from '@open-mercato/ui/backend/inputs'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { RecordNotFoundState } from '@open-mercato/ui/backend/detail'\nimport { SwitchableMarkdownInput } from '@open-mercato/ui/backend/inputs'\nimport { apiCall, apiCallOrThrow, readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { ColorPicker } from '@open-mercato/ui/primitives/color-picker'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { PasswordInput } from '@open-mercato/ui/primitives/password-input'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { Alert, AlertDescription, AlertTitle } from '@open-mercato/ui/primitives/alert'\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@open-mercato/ui/primitives/tabs'\nimport { CHECKOUT_ENTITY_IDS } from '../lib/constants'\nimport { getLocalizedDefaultCheckoutCustomerFields } from '../lib/defaults'\nimport type { CustomerFieldDefinitionInput, PriceListItemInput } from '../data/validators'\nimport { getGatewayProviderConfigurationMessageKey } from '../lib/gatewayProviderAvailability'\nimport { readCustomerFieldsSectionError } from '../lib/customerFieldErrors'\nimport { isRecordNotFoundError } from '../lib/recordNotFound'\nimport { CheckoutCurrencySelect } from './CheckoutCurrencySelect'\nimport { CustomerFieldsEditor } from './CustomerFieldsEditor'\nimport { GatewaySettingsFields } from './GatewaySettingsFields'\nimport { LogoUploadField } from './LogoUploadField'\n\ntype Props = {\n mode: 'link' | 'template'\n recordId?: string\n}\n\ntype FormValues = Record<string, unknown>\n\ntype ProviderDescriptor = {\n providerKey: string\n label: string\n isConfigured?: boolean\n requiresConfiguration?: boolean\n configurationStatus?: 'configured' | 'missing_credentials' | 'disabled' | 'unmanaged' | null\n}\n\ntype TemplateSummary = {\n id: string\n name: string\n title?: string | null\n pricingMode?: string | null\n gatewayProviderKey?: string | null\n}\n\ntype LegalDocumentValue = {\n title: string\n markdown: string\n required: boolean\n}\n\ntype LegalDocumentsValue = {\n terms: LegalDocumentValue\n privacyPolicy: LegalDocumentValue\n}\n\ntype PriceListItem = PriceListItemInput\n\nconst DEFAULT_COLORS = {\n primaryColor: '#1E3A8A',\n secondaryColor: '#F59E0B',\n backgroundColor: '#F8F4EE',\n} as const\n\nconst SETTINGS_TABS_LIST_CLASS = 'h-auto w-full justify-start overflow-x-auto rounded-none border-b border-border bg-transparent p-0'\nconst SETTINGS_TABS_TRIGGER_CLASS = 'mr-8 h-auto rounded-none border-b-2 border-transparent bg-transparent px-0 py-2.5 text-sm font-medium text-muted-foreground shadow-none transition-colors hover:bg-transparent hover:text-foreground aria-selected:border-accent-indigo aria-selected:bg-transparent aria-selected:text-foreground aria-selected:shadow-none last:mr-0'\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction readString(value: unknown): string {\n return typeof value === 'string' ? value : ''\n}\n\nfunction readNumberInputValue(value: unknown): string {\n if (typeof value === 'number' && Number.isFinite(value)) return String(value)\n if (typeof value === 'string') return value\n return ''\n}\n\nfunction readBoolean(value: unknown, fallback = false): boolean {\n return typeof value === 'boolean' ? value : fallback\n}\n\nfunction cloneDefaultCustomerFields(t?: TranslateFn): CustomerFieldDefinitionInput[] {\n return getLocalizedDefaultCheckoutCustomerFields(t).map((field) => ({\n ...field,\n placeholder: typeof field.placeholder === 'string' ? field.placeholder : undefined,\n }))\n}\n\nfunction createDefaultLegalDocuments(): LegalDocumentsValue {\n return {\n terms: { title: '', markdown: '', required: false },\n privacyPolicy: { title: '', markdown: '', required: false },\n }\n}\n\nfunction createDefaultValues(t?: TranslateFn): FormValues {\n return {\n name: '',\n title: '',\n subtitle: '',\n description: '',\n slug: '',\n logoAttachmentId: null,\n logoUrl: null,\n ...DEFAULT_COLORS,\n themeMode: 'auto',\n displayCustomFieldsOnPage: false,\n pricingMode: 'fixed',\n fixedPriceAmount: null,\n fixedPriceCurrencyCode: 'USD',\n fixedPriceIncludesTax: true,\n fixedPriceOriginalAmount: null,\n customAmountMin: null,\n customAmountMax: null,\n customAmountCurrencyCode: 'USD',\n priceListItems: [],\n gatewayProviderKey: '',\n gatewaySettings: {},\n templateId: null,\n customFieldsetCode: null,\n collectCustomerDetails: true,\n customerFieldsSchema: cloneDefaultCustomerFields(t),\n legalDocuments: createDefaultLegalDocuments(),\n status: 'draft',\n maxCompletions: null,\n password: '',\n successTitle: '',\n successMessage: '',\n cancelTitle: '',\n cancelMessage: '',\n errorTitle: '',\n errorMessage: '',\n startEmailSubject: '',\n startEmailBody: '',\n sendStartEmail: true,\n successEmailSubject: '',\n successEmailBody: '',\n sendSuccessEmail: true,\n errorEmailSubject: '',\n errorEmailBody: '',\n sendErrorEmail: true,\n }\n}\n\nfunction normalizePriceListItems(value: unknown): PriceListItem[] {\n if (!Array.isArray(value)) return []\n return value\n .map((item) => {\n if (!isRecord(item)) return null\n const id = readString(item.id).trim()\n const description = readString(item.description)\n const amount = Number(item.amount ?? 0)\n const currencyCode = readString(item.currencyCode).trim().toUpperCase()\n return {\n id: id || `item_${Date.now()}`,\n description,\n amount: Number.isFinite(amount) ? amount : 0,\n currencyCode: currencyCode || 'USD',\n }\n })\n .filter((item): item is PriceListItem => item !== null)\n}\n\nfunction normalizeCustomerFields(value: unknown, t?: TranslateFn): CustomerFieldDefinitionInput[] {\n if (!Array.isArray(value)) return cloneDefaultCustomerFields(t)\n return value.reduce<CustomerFieldDefinitionInput[]>((result, field, index) => {\n if (!isRecord(field)) return result\n const key = readString(field.key).trim()\n const label = readString(field.label).trim()\n const kind = readString(field.kind)\n if (!key || !label) return result\n if (!['text', 'multiline', 'boolean', 'select', 'radio'].includes(kind)) return result\n const options = Array.isArray(field.options)\n ? field.options.reduce<Array<{ value: string; label: string }>>((optionResult, option) => {\n if (!isRecord(option)) return optionResult\n const valuePart = readString(option.value).trim()\n const labelPart = readString(option.label).trim()\n if (!valuePart || !labelPart) return optionResult\n optionResult.push({ value: valuePart, label: labelPart })\n return optionResult\n }, [])\n : []\n result.push({\n key,\n label,\n kind: kind as CustomerFieldDefinitionInput['kind'],\n required: readBoolean(field.required),\n fixed: readBoolean(field.fixed),\n placeholder: readString(field.placeholder).trim() || undefined,\n options,\n sortOrder: typeof field.sortOrder === 'number' ? field.sortOrder : index,\n })\n return result\n }, [])\n}\n\nfunction readCustomerFields(value: unknown, t?: TranslateFn): CustomerFieldDefinitionInput[] {\n return Array.isArray(value) ? value as CustomerFieldDefinitionInput[] : cloneDefaultCustomerFields(t)\n}\n\nfunction normalizeLegalDocuments(value: unknown): LegalDocumentsValue {\n const defaults = createDefaultLegalDocuments()\n if (!isRecord(value)) return defaults\n const normalizeDocument = (raw: unknown, fallback: LegalDocumentValue): LegalDocumentValue => {\n if (!isRecord(raw)) return fallback\n return {\n title: readString(raw.title),\n markdown: readString(raw.markdown),\n required: readBoolean(raw.required),\n }\n }\n return {\n terms: normalizeDocument(value.terms, defaults.terms),\n privacyPolicy: normalizeDocument(value.privacyPolicy, defaults.privacyPolicy),\n }\n}\n\nfunction normalizeFormValues(value: FormValues | null | undefined, t?: TranslateFn): FormValues {\n const defaults = createDefaultValues(t)\n const source = isRecord(value) ? value : {}\n const customFields = isRecord(source.customFields) ? source.customFields : {}\n\n const prefixedCustomFieldValues = Object.fromEntries(\n Object.entries(customFields).map(([key, fieldValue]) => [`cf_${key}`, fieldValue]),\n )\n\n return {\n ...defaults,\n ...source,\n ...prefixedCustomFieldValues,\n logoAttachmentId: readString(source.logoAttachmentId).trim() || null,\n logoUrl: readString(source.logoUrl).trim() || null,\n primaryColor: readString(source.primaryColor).trim() || defaults.primaryColor,\n secondaryColor: readString(source.secondaryColor).trim() || defaults.secondaryColor,\n backgroundColor: readString(source.backgroundColor).trim() || defaults.backgroundColor,\n gatewayProviderKey: readString(source.gatewayProviderKey).trim(),\n gatewaySettings: isRecord(source.gatewaySettings) ? source.gatewaySettings : {},\n customFieldsetCode: readString(source.customFieldsetCode).trim() || null,\n collectCustomerDetails: readBoolean(source.collectCustomerDetails, true),\n customerFieldsSchema: normalizeCustomerFields(source.customerFieldsSchema, t),\n legalDocuments: normalizeLegalDocuments(source.legalDocuments),\n priceListItems: normalizePriceListItems(source.priceListItems),\n fixedPriceCurrencyCode: readString(source.fixedPriceCurrencyCode).trim().toUpperCase() || 'USD',\n customAmountCurrencyCode: readString(source.customAmountCurrencyCode).trim().toUpperCase() || 'USD',\n sendStartEmail: readBoolean(source.sendStartEmail, true),\n sendSuccessEmail: readBoolean(source.sendSuccessEmail, true),\n sendErrorEmail: readBoolean(source.sendErrorEmail, true),\n }\n}\n\nfunction readError(errors: Record<string, string>, path: string): string | undefined {\n if (!path) return undefined\n if (errors[path]) return errors[path]\n const prefix = `${path}.`\n const nestedEntry = Object.entries(errors).find(([key]) => key.startsWith(prefix))\n return nestedEntry?.[1]\n}\n\nfunction readDirectError(errors: Record<string, string>, path: string): string | undefined {\n if (!path) return undefined\n return errors[path]\n}\n\nfunction readAnyError(errors: Record<string, string>, ...paths: string[]): string | undefined {\n for (const path of paths) {\n const error = readError(errors, path)\n if (error) return error\n }\n return undefined\n}\n\nfunction toTemplateOption(template: TemplateSummary): ComboboxOption {\n const title = typeof template.title === 'string' ? template.title.trim() : ''\n const provider = typeof template.gatewayProviderKey === 'string' ? template.gatewayProviderKey.trim() : ''\n const parts = [title, provider].filter((part) => part.length > 0)\n return {\n value: template.id,\n label: template.name,\n description: parts.length > 0 ? parts.join(' \u2022 ') : null,\n }\n}\n\nfunction errorInputClassName(error?: string): string | undefined {\n return error ? 'border-destructive aria-invalid:ring-destructive' : undefined\n}\n\nfunction SectionLabel({\n label,\n hint,\n error,\n required,\n children,\n}: {\n label: string\n hint?: string\n error?: string\n required?: boolean\n children: React.ReactNode\n}) {\n return (\n <div className=\"space-y-2\">\n <div className=\"space-y-1\">\n <Label className=\"gap-0\">\n {label}\n {required ? <span className=\"text-destructive\"> *</span> : null}\n </Label>\n {hint ? <p className=\"text-xs text-muted-foreground\">{hint}</p> : null}\n {error ? <p className=\"text-xs text-destructive\">{error}</p> : null}\n </div>\n {children}\n </div>\n )\n}\n\nfunction ColorField({\n label,\n value,\n onChange,\n error,\n}: {\n label: string\n value: string\n onChange: (next: string) => void\n error?: string\n}) {\n const pickerValue = /^#([0-9a-fA-F]{6})$/.test(value) ? value : '#000000'\n return (\n <SectionLabel label={label} error={error}>\n <div className=\"flex items-center gap-3\">\n <ColorPicker\n value={pickerValue}\n onChange={(next) => onChange(next.toUpperCase())}\n aria-label={label}\n />\n <Input\n value={value}\n onChange={(event) => onChange(event.target.value.toUpperCase())}\n placeholder=\"#1E3A8A\"\n className={error ? `min-w-0 ${errorInputClassName(error)}` : 'min-w-0'}\n aria-invalid={Boolean(error)}\n />\n </div>\n </SectionLabel>\n )\n}\n\nexport function PriceListEditor({\n value,\n onChange,\n error,\n}: {\n value: PriceListItem[]\n onChange: (next: PriceListItem[]) => void\n error?: string\n}) {\n const t = useT()\n const locale = useLocale()\n const items = Array.isArray(value) ? value : []\n\n const updateItem = React.useCallback(\n (index: number, patch: Partial<PriceListItem>) => {\n onChange(items.map((item, currentIndex) => (currentIndex === index ? { ...item, ...patch } : item)))\n },\n [items, onChange],\n )\n\n const addItem = React.useCallback(() => {\n onChange([\n ...items,\n {\n id: `item_${items.length + 1}`,\n description: '',\n amount: 0,\n currencyCode: items[0]?.currencyCode ?? 'USD',\n },\n ])\n }, [items, onChange])\n\n return (\n <div className=\"space-y-4\">\n <Alert status=\"information\">\n <AlertDescription>\n {t('checkout.linkTemplateForm.priceList.notices.singleCurrency')}\n </AlertDescription>\n </Alert>\n {error ? <p className=\"text-xs text-destructive\">{error}</p> : null}\n\n <div className=\"overflow-hidden rounded-xl border border-border/70 bg-background\">\n {items.length > 0 ? (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full min-w-[760px] table-fixed\">\n <thead className=\"border-b bg-muted/30\">\n <tr className=\"text-left text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n <th className=\"px-3 py-2 w-[22%]\">{t('checkout.linkTemplateForm.priceList.columns.itemCode')}</th>\n <th className=\"px-3 py-2\">{t('checkout.linkTemplateForm.priceList.columns.description')}</th>\n <th className=\"px-3 py-2 w-[16%]\">{t('checkout.linkTemplateForm.priceList.columns.amount')}</th>\n <th className=\"px-3 py-2 w-[24%]\">{t('checkout.linkTemplateForm.priceList.columns.currency')}</th>\n <th className=\"px-3 py-2 w-[110px] text-right\">{t('checkout.linkTemplateForm.priceList.columns.actions')}</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border/70\">\n {items.map((item, index) => (\n <tr key={`${item.id}:${index}`} className=\"align-top\">\n <td className=\"px-3 py-2\">\n <Input\n value={item.id}\n onChange={(event) => updateItem(index, { id: event.target.value })}\n placeholder={t('checkout.linkTemplateForm.priceList.placeholders.itemCode')}\n aria-label={t('checkout.linkTemplateForm.priceList.aria.itemCode', { index: index + 1 })}\n className=\"h-8\"\n />\n </td>\n <td className=\"px-3 py-2\">\n <Input\n value={item.description}\n onChange={(event) => updateItem(index, { description: event.target.value })}\n placeholder={t('checkout.linkTemplateForm.priceList.placeholders.description')}\n aria-label={t('checkout.linkTemplateForm.priceList.aria.description', { index: index + 1 })}\n className=\"h-8\"\n />\n </td>\n <td className=\"px-3 py-2\">\n <Input\n type=\"text\"\n inputMode=\"decimal\"\n value={readNumberInputValue(item.amount)}\n onChange={(event) =>\n updateItem(index, {\n amount: parseLocaleNumber(event.target.value, locale) ?? Number.NaN,\n })\n }\n placeholder=\"0.00\"\n aria-label={t('checkout.linkTemplateForm.priceList.aria.amount', { index: index + 1 })}\n className=\"h-8\"\n />\n </td>\n <td className=\"px-3 py-2\">\n <CheckoutCurrencySelect\n value={item.currencyCode}\n onChange={(next) => updateItem(index, { currencyCode: next })}\n placeholder={t('checkout.currencySelect.placeholder')}\n />\n </td>\n <td className=\"px-3 py-2 text-right\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => onChange(items.filter((_, currentIndex) => currentIndex !== index))}\n >\n <Trash2 className=\"mr-2 h-4 w-4\" />\n {t('checkout.common.actions.remove')}\n </Button>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n ) : (\n <div className=\"px-4 py-8\">\n <Alert status=\"information\">\n <AlertDescription>\n {t('checkout.linkTemplateForm.priceList.notices.empty')}\n </AlertDescription>\n </Alert>\n </div>\n )}\n </div>\n\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={addItem}>\n <Plus className=\"mr-2 h-4 w-4\" />\n {t('checkout.linkTemplateForm.priceList.actions.addItem')}\n </Button>\n </div>\n )\n}\n\nexport function PricingSection({ values, setValue, errors }: CrudFormGroupComponentProps) {\n const t = useT()\n const locale = useLocale()\n const pricingMode = readString(values.pricingMode) || 'fixed'\n const pricingModeError = readError(errors, 'pricingMode')\n const fixedPriceAmountError = readError(errors, 'fixedPriceAmount')\n const fixedPriceCurrencyError = readError(errors, 'fixedPriceCurrencyCode')\n const fixedPriceOriginalAmountError = readError(errors, 'fixedPriceOriginalAmount')\n const customAmountMinError = readError(errors, 'customAmountMin')\n const customAmountMaxError = readError(errors, 'customAmountMax')\n const customAmountCurrencyError = readError(errors, 'customAmountCurrencyCode')\n const priceListItemsError = readError(errors, 'priceListItems')\n\n return (\n <div className=\"space-y-4\">\n {pricingModeError ? <p className=\"text-xs text-destructive\">{pricingModeError}</p> : null}\n <div className=\"flex flex-wrap gap-2\">\n {[\n { id: 'fixed', label: t('checkout.linkTemplateForm.pricing.modes.fixed'), icon: CircleDollarSign },\n { id: 'custom_amount', label: t('checkout.linkTemplateForm.pricing.modes.customAmount'), icon: WalletCards },\n { id: 'price_list', label: t('checkout.linkTemplateForm.pricing.modes.priceList'), icon: FileText },\n ].map((mode) => {\n const Icon = mode.icon\n const active = pricingMode === mode.id\n return (\n <Button\n key={mode.id}\n type=\"button\"\n variant={active ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setValue('pricingMode', mode.id)}\n >\n <Icon className=\"mr-2 h-4 w-4\" />\n {mode.label}\n </Button>\n )\n })}\n </div>\n\n {pricingMode === 'fixed' ? (\n <div className=\"grid gap-4 md:grid-cols-2\">\n <SectionLabel label={t('checkout.linkTemplateForm.pricing.fields.amount')} error={fixedPriceAmountError} required>\n <Input\n type=\"text\"\n inputMode=\"decimal\"\n value={readNumberInputValue(values.fixedPriceAmount)}\n onChange={(event) => setValue('fixedPriceAmount', parseLocaleNumber(event.target.value, locale))}\n placeholder=\"150\"\n className={errorInputClassName(fixedPriceAmountError)}\n aria-invalid={Boolean(fixedPriceAmountError)}\n />\n </SectionLabel>\n\n <SectionLabel label={t('checkout.linkTemplateForm.pricing.fields.currency')} error={fixedPriceCurrencyError} required>\n <CheckoutCurrencySelect\n value={readString(values.fixedPriceCurrencyCode) || 'USD'}\n onChange={(next) => setValue('fixedPriceCurrencyCode', next)}\n placeholder={t('checkout.currencySelect.placeholder')}\n />\n </SectionLabel>\n\n <SectionLabel\n label={t('checkout.linkTemplateForm.pricing.fields.compareAtPrice')}\n hint={t('checkout.linkTemplateForm.pricing.hints.compareAtPrice')}\n error={fixedPriceOriginalAmountError}\n >\n <Input\n type=\"text\"\n inputMode=\"decimal\"\n value={readNumberInputValue(values.fixedPriceOriginalAmount)}\n onChange={(event) => setValue('fixedPriceOriginalAmount', parseLocaleNumber(event.target.value, locale))}\n placeholder=\"200\"\n className={errorInputClassName(fixedPriceOriginalAmountError)}\n aria-invalid={Boolean(fixedPriceOriginalAmountError)}\n />\n </SectionLabel>\n\n <div className=\"flex items-end\">\n <label className=\"flex items-center gap-2 rounded-lg border border-border/70 bg-muted/30 px-3 py-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={readBoolean(values.fixedPriceIncludesTax, true)}\n onChange={(event) => setValue('fixedPriceIncludesTax', event.target.checked)}\n />\n {t('checkout.linkTemplateForm.pricing.fields.includesTax')}\n </label>\n </div>\n </div>\n ) : null}\n\n {pricingMode === 'custom_amount' ? (\n <div className=\"grid gap-4 md:grid-cols-3\">\n <SectionLabel label={t('checkout.linkTemplateForm.pricing.fields.minimumAmount')} error={customAmountMinError} required>\n <Input\n type=\"text\"\n inputMode=\"decimal\"\n value={readNumberInputValue(values.customAmountMin)}\n onChange={(event) => setValue('customAmountMin', parseLocaleNumber(event.target.value, locale))}\n placeholder=\"10\"\n className={errorInputClassName(customAmountMinError)}\n aria-invalid={Boolean(customAmountMinError)}\n />\n </SectionLabel>\n\n <SectionLabel label={t('checkout.linkTemplateForm.pricing.fields.maximumAmount')} error={customAmountMaxError} required>\n <Input\n type=\"text\"\n inputMode=\"decimal\"\n value={readNumberInputValue(values.customAmountMax)}\n onChange={(event) => setValue('customAmountMax', parseLocaleNumber(event.target.value, locale))}\n placeholder=\"500\"\n className={errorInputClassName(customAmountMaxError)}\n aria-invalid={Boolean(customAmountMaxError)}\n />\n </SectionLabel>\n\n <SectionLabel label={t('checkout.linkTemplateForm.pricing.fields.currency')} error={customAmountCurrencyError} required>\n <CheckoutCurrencySelect\n value={readString(values.customAmountCurrencyCode) || 'USD'}\n onChange={(next) => setValue('customAmountCurrencyCode', next)}\n placeholder={t('checkout.currencySelect.placeholder')}\n />\n </SectionLabel>\n </div>\n ) : null}\n\n {pricingMode === 'price_list' ? (\n <PriceListEditor\n value={normalizePriceListItems(values.priceListItems)}\n onChange={(next) => setValue('priceListItems', next)}\n error={priceListItemsError}\n />\n ) : null}\n </div>\n )\n}\n\nfunction GeneralSection({\n values,\n setValue,\n errors,\n mode,\n templateOptions,\n loadTemplateSuggestions,\n applyTemplate,\n isApplyingTemplate,\n}: CrudFormGroupComponentProps & {\n mode: 'link' | 'template'\n templateOptions: ComboboxOption[]\n loadTemplateSuggestions: (query?: string) => Promise<ComboboxOption[]>\n applyTemplate: (templateId: string | null) => Promise<void>\n isApplyingTemplate: boolean\n}) {\n const t = useT()\n const fallbackSlug = slugify(\n readString(values.title).trim().length > 0\n ? readString(values.title)\n : readString(values.name),\n ) || 'pay-link'\n const currentSlug = readString(values.slug)\n const resolvedSlug = currentSlug.trim() || fallbackSlug\n const currentTemplateId = readString(values.templateId).trim()\n const nameError = readError(errors, 'name')\n const titleError = readError(errors, 'title')\n const subtitleError = readError(errors, 'subtitle')\n const descriptionError = readError(errors, 'description')\n const slugError = readError(errors, 'slug')\n const templateError = readError(errors, 'templateId')\n\n return (\n <div className=\"space-y-4\">\n {mode === 'link' ? (\n <SectionLabel\n label={t('checkout.linkTemplateForm.general.fields.template')}\n hint={t('checkout.linkTemplateForm.general.hints.template')}\n error={templateError}\n >\n <div className=\"space-y-3\">\n <ComboboxInput\n value={currentTemplateId}\n suggestions={templateOptions}\n loadSuggestions={loadTemplateSuggestions}\n resolveLabel={(value) => templateOptions.find((option) => option.value === value)?.label ?? value}\n resolveDescription={(value) => templateOptions.find((option) => option.value === value)?.description}\n onChange={(nextValue) => {\n const normalized = nextValue.trim()\n setValue('templateId', normalized || null)\n void applyTemplate(normalized || null)\n }}\n placeholder={t('checkout.linkTemplateForm.general.placeholders.template')}\n disabled={isApplyingTemplate}\n allowCustomValues={false}\n />\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n disabled={isApplyingTemplate || currentTemplateId.length === 0}\n onClick={() => {\n setValue('templateId', null)\n void applyTemplate(null)\n }}\n >\n {t('checkout.linkTemplateForm.general.actions.clearTemplate')}\n </Button>\n {isApplyingTemplate ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('checkout.linkTemplateForm.general.status.applyingTemplate')}\n </p>\n ) : (\n <p className=\"text-xs text-muted-foreground\">\n {t('checkout.linkTemplateForm.general.notices.templateReplacement')}\n </p>\n )}\n </div>\n </div>\n </SectionLabel>\n ) : null}\n\n <SectionLabel label={t('checkout.linkTemplateForm.general.fields.name')} error={nameError} required>\n <Input\n value={readString(values.name)}\n onChange={(event) => setValue('name', event.target.value)}\n placeholder={t('checkout.linkTemplateForm.general.placeholders.name')}\n className={errorInputClassName(nameError)}\n aria-invalid={Boolean(nameError)}\n />\n </SectionLabel>\n\n <SectionLabel label={t('checkout.linkTemplateForm.general.fields.title')} error={titleError}>\n <Input\n value={readString(values.title)}\n onChange={(event) => setValue('title', event.target.value)}\n placeholder={t('checkout.linkTemplateForm.general.placeholders.title')}\n className={errorInputClassName(titleError)}\n aria-invalid={Boolean(titleError)}\n />\n </SectionLabel>\n\n <SectionLabel label={t('checkout.linkTemplateForm.general.fields.subtitle')} error={subtitleError}>\n <Input\n value={readString(values.subtitle)}\n onChange={(event) => setValue('subtitle', event.target.value)}\n placeholder={t('checkout.linkTemplateForm.general.placeholders.subtitle')}\n className={errorInputClassName(subtitleError)}\n aria-invalid={Boolean(subtitleError)}\n />\n </SectionLabel>\n\n <SectionLabel label={t('checkout.linkTemplateForm.general.fields.description')} hint={t('checkout.linkTemplateForm.general.hints.description')} error={descriptionError}>\n <SwitchableMarkdownInput\n value={readString(values.description)}\n onChange={(next) => setValue('description', next)}\n isMarkdownEnabled\n height={220}\n placeholder={t('checkout.linkTemplateForm.general.placeholders.description')}\n />\n </SectionLabel>\n\n {mode === 'link' ? (\n <SectionLabel label={t('checkout.linkTemplateForm.general.fields.slug')} hint={t('checkout.linkTemplateForm.general.hints.slug')} error={slugError}>\n <div className=\"space-y-2\">\n <div className=\"flex gap-2\">\n <Input\n value={currentSlug}\n onChange={(event) => setValue('slug', event.target.value)}\n placeholder={t('checkout.linkTemplateForm.general.placeholders.slug')}\n className={errorInputClassName(slugError)}\n aria-invalid={Boolean(slugError)}\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setValue('slug', fallbackSlug)}\n >\n <Sparkles className=\"mr-2 h-4 w-4\" />\n {t('checkout.linkTemplateForm.general.actions.generateSlug')}\n </Button>\n </div>\n <p className=\"text-xs text-muted-foreground\">{t('checkout.linkTemplateForm.general.slugPreview', { slug: resolvedSlug })}</p>\n </div>\n </SectionLabel>\n ) : null}\n </div>\n )\n}\n\nfunction AppearanceSection({\n values,\n setValue,\n errors,\n entityId,\n attachmentRecordId,\n}: CrudFormGroupComponentProps & { entityId: string; attachmentRecordId: string }) {\n const t = useT()\n const logoError = readAnyError(errors, 'logoAttachmentId', 'logoUrl')\n const primaryColorError = readError(errors, 'primaryColor')\n const secondaryColorError = readError(errors, 'secondaryColor')\n const backgroundColorError = readError(errors, 'backgroundColor')\n const themeModeError = readError(errors, 'themeMode')\n const displayCustomFieldsError = readError(errors, 'displayCustomFieldsOnPage')\n\n return (\n <div className=\"space-y-4\">\n <LogoUploadField\n entityId={entityId}\n recordId={attachmentRecordId}\n attachmentId={readString(values.logoAttachmentId) || null}\n logoUrl={readString(values.logoUrl) || null}\n error={logoError}\n onChange={(next) => {\n setValue('logoAttachmentId', next.logoAttachmentId)\n setValue('logoUrl', next.logoUrl)\n }}\n />\n\n <div className=\"space-y-4\">\n <ColorField\n label={t('checkout.linkTemplateForm.appearance.fields.primaryColor')}\n value={readString(values.primaryColor) || DEFAULT_COLORS.primaryColor}\n onChange={(next) => setValue('primaryColor', next)}\n error={primaryColorError}\n />\n <ColorField\n label={t('checkout.linkTemplateForm.appearance.fields.secondaryColor')}\n value={readString(values.secondaryColor) || DEFAULT_COLORS.secondaryColor}\n onChange={(next) => setValue('secondaryColor', next)}\n error={secondaryColorError}\n />\n <ColorField\n label={t('checkout.linkTemplateForm.appearance.fields.backgroundColor')}\n value={readString(values.backgroundColor) || DEFAULT_COLORS.backgroundColor}\n onChange={(next) => setValue('backgroundColor', next)}\n error={backgroundColorError}\n />\n </div>\n\n <SectionLabel label={t('checkout.linkTemplateForm.appearance.fields.themeMode')} error={themeModeError}>\n <select\n className={themeModeError\n ? `w-full rounded-md border bg-background px-3 py-2 text-sm ${errorInputClassName(themeModeError)}`\n : 'w-full rounded-md border bg-background px-3 py-2 text-sm'}\n value={readString(values.themeMode) || 'auto'}\n onChange={(event) => setValue('themeMode', event.target.value)}\n aria-invalid={Boolean(themeModeError)}\n >\n <option value=\"auto\">{t('checkout.linkTemplateForm.appearance.themeModes.auto')}</option>\n <option value=\"light\">{t('checkout.linkTemplateForm.appearance.themeModes.light')}</option>\n <option value=\"dark\">{t('checkout.linkTemplateForm.appearance.themeModes.dark')}</option>\n </select>\n </SectionLabel>\n\n <label className=\"flex items-center gap-2 rounded-lg border border-border/70 bg-muted/30 px-3 py-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={readBoolean(values.displayCustomFieldsOnPage)}\n onChange={(event) => setValue('displayCustomFieldsOnPage', event.target.checked)}\n />\n {t('checkout.linkTemplateForm.appearance.fields.displayCustomFields')}\n </label>\n {displayCustomFieldsError ? <p className=\"text-xs text-destructive\">{displayCustomFieldsError}</p> : null}\n </div>\n )\n}\n\nfunction PaymentSection({ values, setValue, errors, providers }: CrudFormGroupComponentProps & { providers: ProviderDescriptor[] }) {\n const t = useT()\n const selectedProviderKey = readString(values.gatewayProviderKey)\n const selectedProvider = providers.find((provider) => provider.providerKey === selectedProviderKey)\n const gatewayProviderError = readError(errors, 'gatewayProviderKey')\n ?? (() => {\n const messageKey = getGatewayProviderConfigurationMessageKey(selectedProvider)\n return messageKey ? t(messageKey) : undefined\n })()\n const gatewaySettingsError = readError(errors, 'gatewaySettings')\n\n return (\n <div className=\"space-y-4\">\n <SectionLabel label={t('checkout.linkTemplateForm.payment.fields.gatewayProvider')} error={gatewayProviderError} required>\n <select\n className={gatewayProviderError\n ? `w-full rounded-md border bg-background px-3 py-2 text-sm ${errorInputClassName(gatewayProviderError)}`\n : 'w-full rounded-md border bg-background px-3 py-2 text-sm'}\n value={readString(values.gatewayProviderKey)}\n onChange={(event) => setValue('gatewayProviderKey', event.target.value)}\n aria-invalid={Boolean(gatewayProviderError)}\n >\n <option value=\"\">{t('checkout.linkTemplateForm.payment.placeholders.provider')}</option>\n {providers.map((provider) => (\n <option\n key={provider.providerKey}\n value={provider.providerKey}\n disabled={provider.isConfigured === false}\n >\n {provider.isConfigured === false\n ? `${provider.label} ${t('checkout.linkTemplateForm.payment.providerUnavailableSuffix')}`\n : provider.label}\n </option>\n ))}\n </select>\n </SectionLabel>\n\n <GatewaySettingsFields\n providerKey={readString(values.gatewayProviderKey) || null}\n value={isRecord(values.gatewaySettings) ? values.gatewaySettings : {}}\n onChange={(next) => setValue('gatewaySettings', next)}\n />\n {gatewaySettingsError ? <p className=\"text-xs text-destructive\">{gatewaySettingsError}</p> : null}\n </div>\n )\n}\n\nfunction CustomerDetailsSection({ values, setValue, errors }: CrudFormGroupComponentProps) {\n const t = useT()\n const collectCustomerDetails = readBoolean(values.collectCustomerDetails, true)\n const collectCustomerDetailsError = readError(errors, 'collectCustomerDetails')\n const customerFieldsError = readCustomerFieldsSectionError(errors)\n\n return (\n <div className=\"space-y-4\">\n <label className=\"flex items-start gap-3 rounded-xl border border-border/70 bg-muted/30 px-4 py-3 text-sm\">\n <input\n type=\"checkbox\"\n checked={collectCustomerDetails}\n onChange={(event) => setValue('collectCustomerDetails', event.target.checked)}\n />\n <span className=\"space-y-1\">\n <span className=\"flex items-center gap-2 font-medium\">\n <IdCard className=\"h-4 w-4\" />\n {t('checkout.linkTemplateForm.customerDetails.title')}\n </span>\n <span className=\"block text-muted-foreground\">\n {t('checkout.linkTemplateForm.customerDetails.description')}\n </span>\n </span>\n </label>\n {collectCustomerDetailsError ? <p className=\"text-xs text-destructive\">{collectCustomerDetailsError}</p> : null}\n\n {collectCustomerDetails ? (\n <>\n <Alert status=\"information\">\n <AlertDescription>\n {t('checkout.linkTemplateForm.customerDetails.notices.simpleLink')}\n </AlertDescription>\n </Alert>\n {customerFieldsError ? <p className=\"text-xs text-destructive\">{customerFieldsError}</p> : null}\n <CustomerFieldsEditor\n value={readCustomerFields(values.customerFieldsSchema, t)}\n onChange={(next) => setValue('customerFieldsSchema', next)}\n errors={errors}\n />\n </>\n ) : (\n <Alert status=\"information\">\n <AlertDescription>\n {t('checkout.linkTemplateForm.customerDetails.notices.disabled')}\n </AlertDescription>\n </Alert>\n )}\n </div>\n )\n}\n\nfunction LegalSection({ values, setValue, errors }: CrudFormGroupComponentProps) {\n const t = useT()\n const [tab, setTab] = React.useState<'terms' | 'privacyPolicy'>('terms')\n const legalDocuments = normalizeLegalDocuments(values.legalDocuments)\n const termsTitleError = readAnyError(errors, 'legalDocuments.terms.title', 'legalDocuments.terms')\n const termsMarkdownError = readAnyError(errors, 'legalDocuments.terms.markdown', 'legalDocuments.terms')\n const privacyTitleError = readAnyError(errors, 'legalDocuments.privacyPolicy.title', 'legalDocuments.privacyPolicy')\n const privacyMarkdownError = readAnyError(errors, 'legalDocuments.privacyPolicy.markdown', 'legalDocuments.privacyPolicy')\n\n const patchDocument = React.useCallback(\n (key: 'terms' | 'privacyPolicy', patch: Partial<LegalDocumentValue>) => {\n setValue('legalDocuments', {\n ...legalDocuments,\n [key]: {\n ...legalDocuments[key],\n ...patch,\n },\n })\n },\n [legalDocuments, setValue],\n )\n\n return (\n <div className=\"space-y-4\">\n <Alert status=\"information\">\n <AlertDescription>\n {t('checkout.linkTemplateForm.legal.notice')}\n </AlertDescription>\n </Alert>\n\n <Tabs value={tab} onValueChange={(next) => setTab(next as 'terms' | 'privacyPolicy')}>\n <TabsList className={SETTINGS_TABS_LIST_CLASS}>\n <TabsTrigger value=\"terms\" className={SETTINGS_TABS_TRIGGER_CLASS}>\n <Shield className=\"mr-2 h-4 w-4\" />\n {t('checkout.linkTemplateForm.legal.tabs.terms')}\n </TabsTrigger>\n <TabsTrigger value=\"privacyPolicy\" className={SETTINGS_TABS_TRIGGER_CLASS}>\n <FileCheck2 className=\"mr-2 h-4 w-4\" />\n {t('checkout.linkTemplateForm.legal.tabs.privacy')}\n </TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"terms\" className=\"space-y-4\">\n <SectionLabel label={t('checkout.linkTemplateForm.legal.fields.termsTitle')} error={termsTitleError}>\n <Input\n value={legalDocuments.terms.title}\n onChange={(event) => patchDocument('terms', { title: event.target.value })}\n placeholder={t('checkout.linkTemplateForm.legal.placeholders.termsTitle')}\n className={errorInputClassName(termsTitleError)}\n aria-invalid={Boolean(termsTitleError)}\n />\n </SectionLabel>\n <SectionLabel label={t('checkout.linkTemplateForm.legal.fields.termsBody')} error={termsMarkdownError}>\n <SwitchableMarkdownInput\n value={legalDocuments.terms.markdown}\n onChange={(next) => patchDocument('terms', { markdown: next })}\n isMarkdownEnabled\n height={220}\n placeholder={t('checkout.linkTemplateForm.legal.placeholders.termsBody')}\n />\n </SectionLabel>\n <label className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={legalDocuments.terms.required}\n onChange={(event) => patchDocument('terms', { required: event.target.checked })}\n />\n {t('checkout.linkTemplateForm.legal.fields.acceptanceRequired')}\n </label>\n </TabsContent>\n\n <TabsContent value=\"privacyPolicy\" className=\"space-y-4\">\n <SectionLabel label={t('checkout.linkTemplateForm.legal.fields.privacyTitle')} error={privacyTitleError}>\n <Input\n value={legalDocuments.privacyPolicy.title}\n onChange={(event) => patchDocument('privacyPolicy', { title: event.target.value })}\n placeholder={t('checkout.linkTemplateForm.legal.placeholders.privacyTitle')}\n className={errorInputClassName(privacyTitleError)}\n aria-invalid={Boolean(privacyTitleError)}\n />\n </SectionLabel>\n <SectionLabel label={t('checkout.linkTemplateForm.legal.fields.privacyBody')} error={privacyMarkdownError}>\n <SwitchableMarkdownInput\n value={legalDocuments.privacyPolicy.markdown}\n onChange={(next) => patchDocument('privacyPolicy', { markdown: next })}\n isMarkdownEnabled\n height={220}\n placeholder={t('checkout.linkTemplateForm.legal.placeholders.privacyBody')}\n />\n </SectionLabel>\n <label className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={legalDocuments.privacyPolicy.required}\n onChange={(event) => patchDocument('privacyPolicy', { required: event.target.checked })}\n />\n {t('checkout.linkTemplateForm.legal.fields.acceptanceRequired')}\n </label>\n </TabsContent>\n </Tabs>\n </div>\n )\n}\n\nfunction MessagesSection({ values, setValue, errors }: CrudFormGroupComponentProps) {\n const t = useT()\n const [tab, setTab] = React.useState<'success' | 'cancel' | 'error'>('success')\n\n const config = {\n success: {\n titleKey: 'successTitle',\n bodyKey: 'successMessage',\n titlePlaceholder: t('checkout.linkTemplateForm.messages.placeholders.successTitle'),\n bodyPlaceholder: t('checkout.linkTemplateForm.messages.placeholders.successBody'),\n label: t('checkout.linkTemplateForm.messages.tabs.success'),\n },\n cancel: {\n titleKey: 'cancelTitle',\n bodyKey: 'cancelMessage',\n titlePlaceholder: t('checkout.linkTemplateForm.messages.placeholders.cancelTitle'),\n bodyPlaceholder: t('checkout.linkTemplateForm.messages.placeholders.cancelBody'),\n label: t('checkout.linkTemplateForm.messages.tabs.cancel'),\n },\n error: {\n titleKey: 'errorTitle',\n bodyKey: 'errorMessage',\n titlePlaceholder: t('checkout.linkTemplateForm.messages.placeholders.errorTitle'),\n bodyPlaceholder: t('checkout.linkTemplateForm.messages.placeholders.errorBody'),\n label: t('checkout.linkTemplateForm.messages.tabs.error'),\n },\n } as const\n\n return (\n <div className=\"space-y-4\">\n <Alert status=\"information\">\n <AlertDescription>\n {t('checkout.linkTemplateForm.messages.notice')}\n </AlertDescription>\n </Alert>\n\n <Tabs value={tab} onValueChange={(next) => setTab(next as 'success' | 'cancel' | 'error')}>\n <TabsList className={SETTINGS_TABS_LIST_CLASS}>\n {(['success', 'cancel', 'error'] as const).map((item) => (\n <TabsTrigger key={item} value={item} className={SETTINGS_TABS_TRIGGER_CLASS}>\n <MessageSquare className=\"mr-2 h-4 w-4\" />\n {config[item].label}\n </TabsTrigger>\n ))}\n </TabsList>\n\n {(['success', 'cancel', 'error'] as const).map((item) => (\n <TabsContent key={item} value={item} className=\"space-y-4\">\n <SectionLabel label={t('checkout.linkTemplateForm.messages.labels.title', { state: config[item].label })} error={readError(errors, config[item].titleKey)}>\n <Input\n value={readString(values[config[item].titleKey])}\n onChange={(event) => setValue(config[item].titleKey, event.target.value)}\n placeholder={config[item].titlePlaceholder}\n className={errorInputClassName(readError(errors, config[item].titleKey))}\n aria-invalid={Boolean(readError(errors, config[item].titleKey))}\n />\n </SectionLabel>\n <SectionLabel label={t('checkout.linkTemplateForm.messages.labels.body', { state: config[item].label })} error={readError(errors, config[item].bodyKey)}>\n <SwitchableMarkdownInput\n value={readString(values[config[item].bodyKey])}\n onChange={(next) => setValue(config[item].bodyKey, next)}\n isMarkdownEnabled\n height={220}\n placeholder={config[item].bodyPlaceholder}\n />\n </SectionLabel>\n </TabsContent>\n ))}\n </Tabs>\n </div>\n )\n}\n\nfunction VariableHint() {\n const t = useT()\n const variables = ['{{firstName}}', '{{amount}}', '{{currencyCode}}', '{{linkTitle}}', '{{transactionId}}', '{{errorMessage}}']\n return (\n <div className=\"space-y-2\">\n <p className=\"text-xs text-muted-foreground\">{t('checkout.linkTemplateForm.emails.variableHint')}</p>\n <div className=\"flex flex-wrap gap-2\">\n {variables.map((variable) => (\n <span\n key={variable}\n className=\"rounded-full border border-border/70 bg-background px-2 py-1 text-xs text-muted-foreground\"\n >\n {variable}\n </span>\n ))}\n </div>\n </div>\n )\n}\n\nfunction EmailsSection({ values, setValue, errors }: CrudFormGroupComponentProps) {\n const t = useT()\n const [tab, setTab] = React.useState<'start' | 'success' | 'error'>('start')\n\n const config = {\n start: {\n enabledKey: 'sendStartEmail',\n subjectKey: 'startEmailSubject',\n bodyKey: 'startEmailBody',\n title: t('checkout.linkTemplateForm.emails.tabs.start'),\n Icon: Send,\n subjectPlaceholder: t('checkout.linkTemplateForm.emails.placeholders.startSubject'),\n bodyPlaceholder: t('checkout.linkTemplateForm.emails.placeholders.startBody'),\n },\n success: {\n enabledKey: 'sendSuccessEmail',\n subjectKey: 'successEmailSubject',\n bodyKey: 'successEmailBody',\n title: t('checkout.linkTemplateForm.emails.tabs.success'),\n Icon: BadgeCheck,\n subjectPlaceholder: t('checkout.linkTemplateForm.emails.placeholders.successSubject'),\n bodyPlaceholder: t('checkout.linkTemplateForm.emails.placeholders.successBody'),\n },\n error: {\n enabledKey: 'sendErrorEmail',\n subjectKey: 'errorEmailSubject',\n bodyKey: 'errorEmailBody',\n title: t('checkout.linkTemplateForm.emails.tabs.error'),\n Icon: AlertTriangle,\n subjectPlaceholder: t('checkout.linkTemplateForm.emails.placeholders.errorSubject'),\n bodyPlaceholder: t('checkout.linkTemplateForm.emails.placeholders.errorBody'),\n },\n } as const\n\n return (\n <div className=\"space-y-4\">\n <Alert status=\"information\">\n <AlertDescription>\n {t('checkout.linkTemplateForm.emails.notice')}\n </AlertDescription>\n </Alert>\n <VariableHint />\n\n <Tabs value={tab} onValueChange={(next) => setTab(next as 'start' | 'success' | 'error')}>\n <TabsList className={SETTINGS_TABS_LIST_CLASS}>\n {(['start', 'success', 'error'] as const).map((item) => {\n const Icon = config[item].Icon\n return (\n <TabsTrigger key={item} value={item} className={SETTINGS_TABS_TRIGGER_CLASS}>\n <Icon className=\"mr-2 h-4 w-4\" />\n {config[item].title}\n </TabsTrigger>\n )\n })}\n </TabsList>\n\n {(['start', 'success', 'error'] as const).map((item) => (\n <TabsContent key={item} value={item} className=\"space-y-4\">\n <label className=\"flex items-center gap-2 rounded-lg border border-border/70 bg-muted/30 px-3 py-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={readBoolean(values[config[item].enabledKey], true)}\n onChange={(event) => setValue(config[item].enabledKey, event.target.checked)}\n />\n {t('checkout.linkTemplateForm.emails.sendToCustomer')}\n </label>\n\n <SectionLabel label={t('checkout.linkTemplateForm.emails.labels.subject', { state: config[item].title })} error={readError(errors, config[item].subjectKey)}>\n <Input\n value={readString(values[config[item].subjectKey])}\n onChange={(event) => setValue(config[item].subjectKey, event.target.value)}\n placeholder={config[item].subjectPlaceholder}\n className={errorInputClassName(readError(errors, config[item].subjectKey))}\n aria-invalid={Boolean(readError(errors, config[item].subjectKey))}\n />\n </SectionLabel>\n\n <SectionLabel label={t('checkout.linkTemplateForm.emails.labels.body', { state: config[item].title })} error={readError(errors, config[item].bodyKey)}>\n <SwitchableMarkdownInput\n value={readString(values[config[item].bodyKey])}\n onChange={(next) => setValue(config[item].bodyKey, next)}\n isMarkdownEnabled\n height={220}\n placeholder={config[item].bodyPlaceholder}\n />\n </SectionLabel>\n </TabsContent>\n ))}\n </Tabs>\n </div>\n )\n}\n\nfunction SettingsSection({ values, setValue, errors }: CrudFormGroupComponentProps) {\n const t = useT()\n const status = readString(values.status) || 'draft'\n const statusError = readError(errors, 'status')\n const maxCompletionsError = readError(errors, 'maxCompletions')\n const passwordError = readError(errors, 'password')\n\n return (\n <div className=\"space-y-4\">\n <SectionLabel label={t('checkout.linkTemplateForm.settings.fields.status')} error={statusError}>\n <div className=\"flex flex-wrap gap-2\">\n {[\n { id: 'draft', label: t('checkout.common.status.draft') },\n { id: 'active', label: t('checkout.common.status.active') },\n { id: 'inactive', label: t('checkout.common.status.inactive') },\n ].map((option) => (\n <Button\n key={option.id}\n type=\"button\"\n variant={status === option.id ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setValue('status', option.id)}\n >\n {option.label}\n </Button>\n ))}\n </div>\n </SectionLabel>\n\n <SectionLabel label={t('checkout.linkTemplateForm.settings.fields.maxCompletions')} hint={t('checkout.linkTemplateForm.settings.hints.maxCompletions')} error={maxCompletionsError}>\n <Input\n type=\"number\"\n min=\"1\"\n step=\"1\"\n value={readNumberInputValue(values.maxCompletions)}\n onChange={(event) => setValue('maxCompletions', event.target.value ? Number(event.target.value) : null)}\n placeholder={t('checkout.linkTemplateForm.settings.placeholders.unlimited')}\n className={errorInputClassName(maxCompletionsError)}\n aria-invalid={Boolean(maxCompletionsError)}\n />\n </SectionLabel>\n\n <SectionLabel label={t('checkout.linkTemplateForm.settings.fields.password')} hint={t('checkout.linkTemplateForm.settings.hints.password')} error={passwordError}>\n <PasswordInput\n value={readString(values.password)}\n onChange={(event) => setValue('password', event.target.value)}\n placeholder={t('checkout.linkTemplateForm.settings.placeholders.password')}\n className={errorInputClassName(passwordError)}\n aria-invalid={Boolean(passwordError)}\n />\n </SectionLabel>\n </div>\n )\n}\n\nexport function LinkTemplateForm({ mode, recordId }: Props) {\n const t = useT()\n const searchParams = useSearchParams()\n const entityId = mode === 'link' ? CHECKOUT_ENTITY_IDS.link : CHECKOUT_ENTITY_IDS.template\n const templateId = React.useMemo(() => {\n const raw = searchParams.get('templateId')\n return raw && raw.trim().length > 0 ? raw : null\n }, [searchParams])\n const attachmentDraftRecordId = React.useMemo(\n () => recordId ?? (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function' ? crypto.randomUUID() : `draft-${Date.now()}`),\n [recordId],\n )\n const initialLogoAttachmentIdRef = React.useRef<string | null>(null)\n const [providers, setProviders] = React.useState<ProviderDescriptor[]>([])\n const [templateOptions, setTemplateOptions] = React.useState<ComboboxOption[]>([])\n const [isApplyingTemplate, setIsApplyingTemplate] = React.useState(false)\n const [formInstanceKey, setFormInstanceKey] = React.useState(0)\n const [initialValues, setInitialValues] = React.useState<FormValues | null>(\n recordId ? null : normalizeFormValues(createDefaultValues(t), t),\n )\n const [notFound, setNotFound] = React.useState(false)\n\n const replaceInitialValues = React.useCallback((nextValues: FormValues) => {\n setInitialValues(nextValues)\n setFormInstanceKey((current) => current + 1)\n }, [])\n\n React.useEffect(() => {\n initialLogoAttachmentIdRef.current = initialValues && typeof initialValues.logoAttachmentId === 'string'\n ? initialValues.logoAttachmentId\n : null\n }, [initialValues])\n\n React.useEffect(() => {\n let active = true\n void readApiResultOrThrow<{ items: ProviderDescriptor[] }>('/api/payment_gateways/providers')\n .then((result) => {\n if (!active) return\n setProviders(Array.isArray(result.items) ? result.items : [])\n })\n .catch(() => {\n if (active) setProviders([])\n })\n return () => {\n active = false\n }\n }, [])\n\n const rememberTemplateOptions = React.useCallback((items: TemplateSummary[] | ComboboxOption[]) => {\n setTemplateOptions((current) => {\n const next = new Map(current.map((option) => [option.value, option]))\n items.forEach((item) => {\n if ('value' in item) {\n next.set(item.value, item)\n return\n }\n const option = toTemplateOption(item)\n next.set(option.value, option)\n })\n return Array.from(next.values())\n })\n }, [])\n\n const loadTemplateSuggestions = React.useCallback(async (query?: string): Promise<ComboboxOption[]> => {\n const params = new URLSearchParams({\n page: '1',\n pageSize: '25',\n })\n if (query && query.trim().length > 0) {\n params.set('search', query.trim())\n }\n const result = await readApiResultOrThrow<{ items: TemplateSummary[] }>(`/api/checkout/templates?${params.toString()}`)\n const options = Array.isArray(result.items) ? result.items.map(toTemplateOption) : []\n rememberTemplateOptions(options)\n return options\n }, [rememberTemplateOptions])\n\n const applyTemplate = React.useCallback(async (nextTemplateId: string | null) => {\n if (recordId || mode !== 'link') return\n if (!nextTemplateId) {\n replaceInitialValues(normalizeFormValues(createDefaultValues(t), t))\n return\n }\n setIsApplyingTemplate(true)\n try {\n const result = await readApiResultOrThrow<FormValues>(`/api/checkout/templates/${encodeURIComponent(nextTemplateId)}`)\n rememberTemplateOptions([{\n id: nextTemplateId,\n name: readString(result.name),\n title: readString(result.title) || null,\n gatewayProviderKey: readString(result.gatewayProviderKey) || null,\n pricingMode: readString(result.pricingMode) || null,\n }])\n replaceInitialValues(\n normalizeFormValues({\n ...result,\n slug: '',\n templateId: nextTemplateId,\n }, t),\n )\n } finally {\n setIsApplyingTemplate(false)\n }\n }, [mode, recordId, rememberTemplateOptions, replaceInitialValues, t])\n\n React.useEffect(() => {\n if (mode !== 'link' || recordId) return\n void loadTemplateSuggestions()\n .catch(() => null)\n }, [loadTemplateSuggestions, mode, recordId])\n\n React.useEffect(() => {\n if (!recordId) return\n let active = true\n setNotFound(false)\n void readApiResultOrThrow<FormValues>(`/api/checkout/${mode === 'link' ? 'links' : 'templates'}/${encodeURIComponent(recordId)}`)\n .then((result) => {\n if (!active) return\n replaceInitialValues(normalizeFormValues(result, t))\n })\n .catch((error) => {\n if (!active) return\n if (isRecordNotFoundError(error)) {\n setNotFound(true)\n return\n }\n replaceInitialValues(normalizeFormValues({}, t))\n })\n return () => {\n active = false\n }\n }, [mode, recordId, replaceInitialValues, t])\n\n React.useEffect(() => {\n if (recordId || mode !== 'link' || !templateId) return\n void applyTemplate(templateId).catch(() => null)\n }, [applyTemplate, mode, recordId, templateId])\n\n React.useEffect(() => {\n const currentTemplateId = readString(initialValues?.templateId).trim()\n if (mode !== 'link' || !currentTemplateId) return\n if (templateOptions.some((option) => option.value === currentTemplateId)) return\n\n let active = true\n void readApiResultOrThrow<FormValues>(`/api/checkout/templates/${encodeURIComponent(currentTemplateId)}`)\n .then((result) => {\n if (!active) return\n rememberTemplateOptions([{\n id: currentTemplateId,\n name: readString(result.name),\n title: readString(result.title) || null,\n gatewayProviderKey: readString(result.gatewayProviderKey) || null,\n pricingMode: readString(result.pricingMode) || null,\n }])\n })\n .catch(() => null)\n\n return () => {\n active = false\n }\n }, [initialValues?.templateId, mode, rememberTemplateOptions, templateOptions])\n\n const fields = React.useMemo<CrudField[]>(() => [], [])\n\n const groups = React.useMemo<CrudFormGroup[]>(() => [\n {\n id: 'general',\n title: t('checkout.linkTemplateForm.groups.general'),\n column: 1,\n component: (ctx) => (\n <GeneralSection\n {...ctx}\n mode={mode}\n templateOptions={templateOptions}\n loadTemplateSuggestions={loadTemplateSuggestions}\n applyTemplate={applyTemplate}\n isApplyingTemplate={isApplyingTemplate}\n />\n ),\n },\n {\n id: 'payment',\n title: t('checkout.linkTemplateForm.groups.payment'),\n column: 2,\n component: (ctx) => <PaymentSection {...ctx} providers={providers} />,\n },\n {\n id: 'pricing',\n title: t('checkout.linkTemplateForm.groups.pricing'),\n column: 1,\n component: (ctx) => <PricingSection {...ctx} />,\n },\n {\n id: 'appearance',\n title: t('checkout.linkTemplateForm.groups.appearance'),\n column: 2,\n component: (ctx) => (\n <AppearanceSection\n {...ctx}\n entityId={entityId}\n attachmentRecordId={attachmentDraftRecordId}\n />\n ),\n },\n {\n id: 'customerFields',\n title: t('checkout.linkTemplateForm.groups.customerFields'),\n column: 1,\n component: (ctx) => <CustomerDetailsSection {...ctx} />,\n },\n {\n id: 'settings',\n title: t('checkout.linkTemplateForm.groups.settings'),\n column: 2,\n component: (ctx) => <SettingsSection {...ctx} />,\n },\n {\n id: 'legal',\n title: t('checkout.linkTemplateForm.groups.legal'),\n column: 1,\n component: (ctx) => <LegalSection {...ctx} />,\n },\n {\n id: 'messages',\n title: t('checkout.linkTemplateForm.groups.messages'),\n column: 1,\n component: (ctx) => <MessagesSection {...ctx} />,\n },\n {\n id: 'emails',\n title: t('checkout.linkTemplateForm.groups.emails'),\n column: 1,\n component: (ctx) => <EmailsSection {...ctx} />,\n },\n { id: 'customFields', title: t('checkout.linkTemplateForm.groups.customFields'), column: 2, kind: 'customFields' },\n ], [applyTemplate, attachmentDraftRecordId, entityId, isApplyingTemplate, loadTemplateSuggestions, mode, providers, t, templateOptions])\n\n const isLocked = mode === 'link' && Boolean(recordId) && readBoolean(initialValues?.isLocked)\n const formId = React.useMemo(\n () => `checkout-${mode}-editor-${recordId ?? 'new'}`,\n [mode, recordId],\n )\n const lockedNotice = isLocked ? (\n <Alert status=\"warning\">\n <AlertTitle>{t('checkout.linkTemplateForm.locked.title')}</AlertTitle>\n <AlertDescription>{t('checkout.linkTemplateForm.locked.description')}</AlertDescription>\n </Alert>\n ) : undefined\n const lockedOverlay = isLocked ? (\n <div className=\"mx-auto mt-6 max-w-md rounded-xl border border-status-warning-border bg-background/95 px-5 py-4 text-center shadow-sm\">\n <div className=\"mx-auto mb-3 flex h-10 w-10 items-center justify-center rounded-full bg-status-warning-bg text-status-warning-icon\">\n <Shield className=\"h-5 w-5\" />\n </div>\n <p className=\"text-sm font-semibold text-foreground\">\n {t('checkout.linkTemplateForm.locked.overlayTitle')}\n </p>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {t('checkout.linkTemplateForm.locked.overlayDescription')}\n </p>\n </div>\n ) : undefined\n\n const listHref = mode === 'link' ? '/backend/checkout/pay-links' : '/backend/checkout/templates'\n\n if (notFound) {\n return (\n <Page>\n <PageBody>\n <RecordNotFoundState\n label={t(mode === 'link'\n ? 'checkout.linkTemplateForm.notFound.link.title'\n : 'checkout.linkTemplateForm.notFound.template.title')}\n description={t(mode === 'link'\n ? 'checkout.linkTemplateForm.notFound.link.description'\n : 'checkout.linkTemplateForm.notFound.template.description')}\n backHref={listHref}\n />\n </PageBody>\n </Page>\n )\n }\n\n return (\n <Page>\n <PageBody>\n {initialValues ? (\n <CrudForm<FormValues>\n key={formInstanceKey}\n formId={formId}\n title={recordId\n ? t(mode === 'link' ? 'checkout.linkTemplateForm.titles.editLink' : 'checkout.linkTemplateForm.titles.editTemplate')\n : t(mode === 'link' ? 'checkout.linkTemplateForm.titles.createLink' : 'checkout.linkTemplateForm.titles.createTemplate')}\n titleHeadingLevel={1}\n backHref={mode === 'link' ? '/backend/checkout/pay-links' : '/backend/checkout/templates'}\n cancelHref={mode === 'link' ? '/backend/checkout/pay-links' : '/backend/checkout/templates'}\n fields={fields}\n groups={groups}\n extraActions={recordId ? (\n <>\n {isLocked ? (\n <Button asChild type=\"button\" variant=\"outline\">\n <a\n href={mode === 'link'\n ? `/pay/${encodeURIComponent(readString(initialValues.slug))}?preview=true`\n : `/backend/checkout/templates/${encodeURIComponent(recordId)}/preview`}\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n <Eye className=\"mr-2 h-4 w-4\" />\n {t('checkout.common.actions.preview')}\n </a>\n </Button>\n ) : (\n <Button\n type=\"submit\"\n form={formId}\n variant=\"outline\"\n name=\"submitIntent\"\n value=\"preview\"\n >\n <Eye className=\"mr-2 h-4 w-4\" />\n {t('checkout.common.actions.preview')}\n </Button>\n )}\n {mode === 'link' && recordId && !isLocked ? (\n <Button\n type=\"submit\"\n form={formId}\n name=\"submitIntent\"\n value=\"publish\"\n >\n <BadgeCheck className=\"mr-2 h-4 w-4\" />\n {t('checkout.common.actions.saveAndPublish')}\n </Button>\n ) : null}\n </>\n ) : null}\n entityId={entityId}\n customFieldsetBindings={{ [entityId]: { valueKey: 'customFieldsetCode' } }}\n initialValues={initialValues}\n contentHeader={lockedNotice}\n readOnly={isLocked}\n readOnlyOverlay={lockedOverlay}\n deleteVisible={Boolean(recordId)}\n onSubmit={async (values, context) => {\n const submitIntent = context?.submitter?.value === 'preview'\n ? 'preview'\n : context?.submitter?.value === 'publish'\n ? 'publish'\n : 'save'\n const shouldOpenPreview = submitIntent === 'preview'\n const payload = {\n ...values,\n status: submitIntent === 'publish' ? 'active' : values.status,\n customFields: collectCustomFieldValues(values),\n }\n const endpoint = `/api/checkout/${mode === 'link' ? 'links' : 'templates'}${recordId ? `/${encodeURIComponent(recordId)}` : ''}`\n let response: { id?: string; slug?: string; ok?: boolean }\n try {\n response = await withScopedApiRequestHeaders(\n recordId ? buildOptimisticLockHeader(readString(initialValues?.updatedAt) || null) : {},\n () => readApiResultOrThrow<{ id?: string; slug?: string; ok?: boolean }>(endpoint, {\n method: recordId ? 'PUT' : 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n }),\n )\n } catch (error) {\n if (surfaceRecordConflict(error, t)) return\n if (recordId && isRecordNotFoundError(error)) {\n setNotFound(true)\n return\n }\n throw error\n }\n const targetId = recordId ?? (typeof response?.id === 'string' ? response.id : null)\n const logoAttachmentId = readString(values.logoAttachmentId)\n if (\n !recordId &&\n targetId &&\n logoAttachmentId &&\n logoAttachmentId !== initialLogoAttachmentIdRef.current\n ) {\n await apiCall('/api/attachments/transfer', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n entityId,\n attachmentIds: [logoAttachmentId],\n fromRecordId: attachmentDraftRecordId,\n toRecordId: targetId,\n }),\n })\n }\n if (shouldOpenPreview) {\n if (mode === 'link') {\n const savedSlug = typeof response?.slug === 'string' && response.slug.trim().length > 0\n ? response.slug.trim()\n : readString(values.slug).trim() || readString(initialValues.slug).trim()\n if (savedSlug) {\n window.open(`/pay/${encodeURIComponent(savedSlug)}?preview=true`, '_blank', 'noopener,noreferrer')\n return\n }\n } else if (targetId) {\n window.open(\n `/backend/checkout/templates/${encodeURIComponent(targetId)}/preview`,\n '_blank',\n 'noopener,noreferrer',\n )\n return\n }\n }\n window.location.href = mode === 'link'\n ? `/backend/checkout/pay-links?flash=${encodeURIComponent(\n t(submitIntent === 'publish' ? 'checkout.admin.payLinks.flash.published' : 'checkout.common.flash.saved'),\n )}&type=success`\n : `/backend/checkout/templates?flash=${encodeURIComponent(t('checkout.common.flash.saved'))}&type=success`\n }}\n onDelete={recordId ? async () => {\n try {\n await withScopedApiRequestHeaders(\n buildOptimisticLockHeader(readString(initialValues?.updatedAt) || null),\n () => apiCallOrThrow(`/api/checkout/${mode === 'link' ? 'links' : 'templates'}/${encodeURIComponent(recordId)}`, { method: 'DELETE' }),\n )\n } catch (error) {\n if (surfaceRecordConflict(error, t)) return\n if (isRecordNotFoundError(error)) {\n setNotFound(true)\n return\n }\n throw error\n }\n window.location.href = mode === 'link'\n ? `/backend/checkout/pay-links?flash=${encodeURIComponent(t('checkout.common.flash.deleted'))}&type=success`\n : `/backend/checkout/templates?flash=${encodeURIComponent(t('checkout.common.flash.deleted'))}&type=success`\n } : undefined}\n />\n ) : null}\n </PageBody>\n </Page>\n )\n}\n\nexport default LinkTemplateForm\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useSearchParams } from 'next/navigation'\nimport { useT, useLocale, type TranslateFn } from '@open-mercato/shared/lib/i18n/context'\nimport { parseLocaleNumber } from '@open-mercato/shared/lib/number'\nimport {\n AlertTriangle,\n BadgeCheck,\n CircleDollarSign,\n Eye,\n FileCheck2,\n FileText,\n IdCard,\n MessageSquare,\n Plus,\n Send,\n Shield,\n Sparkles,\n Trash2,\n WalletCards,\n} from 'lucide-react'\nimport { slugify } from '@open-mercato/shared/lib/slugify'\nimport { CrudForm, type CrudField, type CrudFormGroup, type CrudFormGroupComponentProps } from '@open-mercato/ui/backend/CrudForm'\nimport { ComboboxInput, type ComboboxOption } from '@open-mercato/ui/backend/inputs'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { RecordNotFoundState } from '@open-mercato/ui/backend/detail'\nimport { SwitchableMarkdownInput } from '@open-mercato/ui/backend/inputs'\nimport { apiCall, apiCallOrThrow, readApiResultOrThrow, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { ColorPicker } from '@open-mercato/ui/primitives/color-picker'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { PasswordInput } from '@open-mercato/ui/primitives/password-input'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { Alert, AlertDescription, AlertTitle } from '@open-mercato/ui/primitives/alert'\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@open-mercato/ui/primitives/tabs'\nimport { CHECKOUT_ENTITY_IDS } from '../lib/constants'\nimport { getLocalizedDefaultCheckoutCustomerFields } from '../lib/defaults'\nimport type { CustomerFieldDefinitionInput, PriceListItemInput } from '../data/validators'\nimport { getGatewayProviderConfigurationMessageKey } from '../lib/gatewayProviderAvailability'\nimport { readCustomerFieldsSectionError } from '../lib/customerFieldErrors'\nimport { isRecordNotFoundError } from '../lib/recordNotFound'\nimport { CheckoutCurrencySelect } from './CheckoutCurrencySelect'\nimport { CustomerFieldsEditor } from './CustomerFieldsEditor'\nimport { GatewaySettingsFields } from './GatewaySettingsFields'\nimport { LogoUploadField } from './LogoUploadField'\n\ntype Props = {\n mode: 'link' | 'template'\n recordId?: string\n}\n\ntype FormValues = Record<string, unknown>\n\ntype ProviderDescriptor = {\n providerKey: string\n label: string\n isConfigured?: boolean\n requiresConfiguration?: boolean\n configurationStatus?: 'configured' | 'missing_credentials' | 'disabled' | 'unmanaged' | null\n}\n\ntype TemplateSummary = {\n id: string\n name: string\n title?: string | null\n pricingMode?: string | null\n gatewayProviderKey?: string | null\n}\n\ntype LegalDocumentValue = {\n title: string\n markdown: string\n required: boolean\n}\n\ntype LegalDocumentsValue = {\n terms: LegalDocumentValue\n privacyPolicy: LegalDocumentValue\n}\n\ntype PriceListItem = PriceListItemInput\n// `amount` stays a raw locale-typed string while a row is being edited (issue #5828) \u2014\n// converted to a number only at submit time.\ntype PriceListEditorItem = Omit<PriceListItem, 'amount'> & { amount: number | string }\n\nconst DEFAULT_COLORS = {\n primaryColor: '#1E3A8A',\n secondaryColor: '#F59E0B',\n backgroundColor: '#F8F4EE',\n} as const\n\nconst SETTINGS_TABS_LIST_CLASS = 'h-auto w-full justify-start overflow-x-auto rounded-none border-b border-border bg-transparent p-0'\nconst SETTINGS_TABS_TRIGGER_CLASS = 'mr-8 h-auto rounded-none border-b-2 border-transparent bg-transparent px-0 py-2.5 text-sm font-medium text-muted-foreground shadow-none transition-colors hover:bg-transparent hover:text-foreground aria-selected:border-accent-indigo aria-selected:bg-transparent aria-selected:text-foreground aria-selected:shadow-none last:mr-0'\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return Boolean(value) && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction readString(value: unknown): string {\n return typeof value === 'string' ? value : ''\n}\n\nfunction readNumberInputValue(value: unknown): string {\n if (typeof value === 'number' && Number.isFinite(value)) return String(value)\n if (typeof value === 'string') return value\n return ''\n}\n\n// Money fields stay a raw locale-typed string while being edited (issue #5828) so an\n// in-progress decimal separator is never dropped mid-keystroke; this converts to the\n// canonical number the API expects right before submission.\nexport function toSubmittedAmount(value: unknown, locale?: string): number | null {\n if (typeof value === 'number') return Number.isFinite(value) ? value : null\n if (typeof value !== 'string') return null\n if (!value.trim()) return null\n return parseLocaleNumber(value, locale)\n}\n\nfunction readBoolean(value: unknown, fallback = false): boolean {\n return typeof value === 'boolean' ? value : fallback\n}\n\nfunction cloneDefaultCustomerFields(t?: TranslateFn): CustomerFieldDefinitionInput[] {\n return getLocalizedDefaultCheckoutCustomerFields(t).map((field) => ({\n ...field,\n placeholder: typeof field.placeholder === 'string' ? field.placeholder : undefined,\n }))\n}\n\nfunction createDefaultLegalDocuments(): LegalDocumentsValue {\n return {\n terms: { title: '', markdown: '', required: false },\n privacyPolicy: { title: '', markdown: '', required: false },\n }\n}\n\nfunction createDefaultValues(t?: TranslateFn): FormValues {\n return {\n name: '',\n title: '',\n subtitle: '',\n description: '',\n slug: '',\n logoAttachmentId: null,\n logoUrl: null,\n ...DEFAULT_COLORS,\n themeMode: 'auto',\n displayCustomFieldsOnPage: false,\n pricingMode: 'fixed',\n fixedPriceAmount: null,\n fixedPriceCurrencyCode: 'USD',\n fixedPriceIncludesTax: true,\n fixedPriceOriginalAmount: null,\n customAmountMin: null,\n customAmountMax: null,\n customAmountCurrencyCode: 'USD',\n priceListItems: [],\n gatewayProviderKey: '',\n gatewaySettings: {},\n templateId: null,\n customFieldsetCode: null,\n collectCustomerDetails: true,\n customerFieldsSchema: cloneDefaultCustomerFields(t),\n legalDocuments: createDefaultLegalDocuments(),\n status: 'draft',\n maxCompletions: null,\n password: '',\n successTitle: '',\n successMessage: '',\n cancelTitle: '',\n cancelMessage: '',\n errorTitle: '',\n errorMessage: '',\n startEmailSubject: '',\n startEmailBody: '',\n sendStartEmail: true,\n successEmailSubject: '',\n successEmailBody: '',\n sendSuccessEmail: true,\n errorEmailSubject: '',\n errorEmailBody: '',\n sendErrorEmail: true,\n }\n}\n\nfunction normalizePriceListItems(value: unknown): PriceListEditorItem[] {\n if (!Array.isArray(value)) return []\n return value\n .map((item) => {\n if (!isRecord(item)) return null\n const id = readString(item.id).trim()\n const description = readString(item.description)\n // Preserve a string amount as-is \u2014 a row mid-edit carries the raw locale-typed text\n // (issue #5828); re-coercing it with `Number()` here would corrupt it on every render.\n const amount =\n typeof item.amount === 'number' || typeof item.amount === 'string' ? item.amount : 0\n const currencyCode = readString(item.currencyCode).trim().toUpperCase()\n return {\n id: id || `item_${Date.now()}`,\n description,\n amount,\n currencyCode: currencyCode || 'USD',\n }\n })\n .filter((item): item is PriceListEditorItem => item !== null)\n}\n\nfunction normalizeCustomerFields(value: unknown, t?: TranslateFn): CustomerFieldDefinitionInput[] {\n if (!Array.isArray(value)) return cloneDefaultCustomerFields(t)\n return value.reduce<CustomerFieldDefinitionInput[]>((result, field, index) => {\n if (!isRecord(field)) return result\n const key = readString(field.key).trim()\n const label = readString(field.label).trim()\n const kind = readString(field.kind)\n if (!key || !label) return result\n if (!['text', 'multiline', 'boolean', 'select', 'radio'].includes(kind)) return result\n const options = Array.isArray(field.options)\n ? field.options.reduce<Array<{ value: string; label: string }>>((optionResult, option) => {\n if (!isRecord(option)) return optionResult\n const valuePart = readString(option.value).trim()\n const labelPart = readString(option.label).trim()\n if (!valuePart || !labelPart) return optionResult\n optionResult.push({ value: valuePart, label: labelPart })\n return optionResult\n }, [])\n : []\n result.push({\n key,\n label,\n kind: kind as CustomerFieldDefinitionInput['kind'],\n required: readBoolean(field.required),\n fixed: readBoolean(field.fixed),\n placeholder: readString(field.placeholder).trim() || undefined,\n options,\n sortOrder: typeof field.sortOrder === 'number' ? field.sortOrder : index,\n })\n return result\n }, [])\n}\n\nfunction readCustomerFields(value: unknown, t?: TranslateFn): CustomerFieldDefinitionInput[] {\n return Array.isArray(value) ? value as CustomerFieldDefinitionInput[] : cloneDefaultCustomerFields(t)\n}\n\nfunction normalizeLegalDocuments(value: unknown): LegalDocumentsValue {\n const defaults = createDefaultLegalDocuments()\n if (!isRecord(value)) return defaults\n const normalizeDocument = (raw: unknown, fallback: LegalDocumentValue): LegalDocumentValue => {\n if (!isRecord(raw)) return fallback\n return {\n title: readString(raw.title),\n markdown: readString(raw.markdown),\n required: readBoolean(raw.required),\n }\n }\n return {\n terms: normalizeDocument(value.terms, defaults.terms),\n privacyPolicy: normalizeDocument(value.privacyPolicy, defaults.privacyPolicy),\n }\n}\n\nfunction normalizeFormValues(value: FormValues | null | undefined, t?: TranslateFn): FormValues {\n const defaults = createDefaultValues(t)\n const source = isRecord(value) ? value : {}\n const customFields = isRecord(source.customFields) ? source.customFields : {}\n\n const prefixedCustomFieldValues = Object.fromEntries(\n Object.entries(customFields).map(([key, fieldValue]) => [`cf_${key}`, fieldValue]),\n )\n\n return {\n ...defaults,\n ...source,\n ...prefixedCustomFieldValues,\n logoAttachmentId: readString(source.logoAttachmentId).trim() || null,\n logoUrl: readString(source.logoUrl).trim() || null,\n primaryColor: readString(source.primaryColor).trim() || defaults.primaryColor,\n secondaryColor: readString(source.secondaryColor).trim() || defaults.secondaryColor,\n backgroundColor: readString(source.backgroundColor).trim() || defaults.backgroundColor,\n gatewayProviderKey: readString(source.gatewayProviderKey).trim(),\n gatewaySettings: isRecord(source.gatewaySettings) ? source.gatewaySettings : {},\n customFieldsetCode: readString(source.customFieldsetCode).trim() || null,\n collectCustomerDetails: readBoolean(source.collectCustomerDetails, true),\n customerFieldsSchema: normalizeCustomerFields(source.customerFieldsSchema, t),\n legalDocuments: normalizeLegalDocuments(source.legalDocuments),\n priceListItems: normalizePriceListItems(source.priceListItems),\n fixedPriceCurrencyCode: readString(source.fixedPriceCurrencyCode).trim().toUpperCase() || 'USD',\n customAmountCurrencyCode: readString(source.customAmountCurrencyCode).trim().toUpperCase() || 'USD',\n sendStartEmail: readBoolean(source.sendStartEmail, true),\n sendSuccessEmail: readBoolean(source.sendSuccessEmail, true),\n sendErrorEmail: readBoolean(source.sendErrorEmail, true),\n }\n}\n\nfunction readError(errors: Record<string, string>, path: string): string | undefined {\n if (!path) return undefined\n if (errors[path]) return errors[path]\n const prefix = `${path}.`\n const nestedEntry = Object.entries(errors).find(([key]) => key.startsWith(prefix))\n return nestedEntry?.[1]\n}\n\nfunction readDirectError(errors: Record<string, string>, path: string): string | undefined {\n if (!path) return undefined\n return errors[path]\n}\n\nfunction readAnyError(errors: Record<string, string>, ...paths: string[]): string | undefined {\n for (const path of paths) {\n const error = readError(errors, path)\n if (error) return error\n }\n return undefined\n}\n\nfunction toTemplateOption(template: TemplateSummary): ComboboxOption {\n const title = typeof template.title === 'string' ? template.title.trim() : ''\n const provider = typeof template.gatewayProviderKey === 'string' ? template.gatewayProviderKey.trim() : ''\n const parts = [title, provider].filter((part) => part.length > 0)\n return {\n value: template.id,\n label: template.name,\n description: parts.length > 0 ? parts.join(' \u2022 ') : null,\n }\n}\n\nfunction errorInputClassName(error?: string): string | undefined {\n return error ? 'border-destructive aria-invalid:ring-destructive' : undefined\n}\n\nfunction SectionLabel({\n label,\n hint,\n error,\n required,\n children,\n}: {\n label: string\n hint?: string\n error?: string\n required?: boolean\n children: React.ReactNode\n}) {\n return (\n <div className=\"space-y-2\">\n <div className=\"space-y-1\">\n <Label className=\"gap-0\">\n {label}\n {required ? <span className=\"text-destructive\"> *</span> : null}\n </Label>\n {hint ? <p className=\"text-xs text-muted-foreground\">{hint}</p> : null}\n {error ? <p className=\"text-xs text-destructive\">{error}</p> : null}\n </div>\n {children}\n </div>\n )\n}\n\nfunction ColorField({\n label,\n value,\n onChange,\n error,\n}: {\n label: string\n value: string\n onChange: (next: string) => void\n error?: string\n}) {\n const pickerValue = /^#([0-9a-fA-F]{6})$/.test(value) ? value : '#000000'\n return (\n <SectionLabel label={label} error={error}>\n <div className=\"flex items-center gap-3\">\n <ColorPicker\n value={pickerValue}\n onChange={(next) => onChange(next.toUpperCase())}\n aria-label={label}\n />\n <Input\n value={value}\n onChange={(event) => onChange(event.target.value.toUpperCase())}\n placeholder=\"#1E3A8A\"\n className={error ? `min-w-0 ${errorInputClassName(error)}` : 'min-w-0'}\n aria-invalid={Boolean(error)}\n />\n </div>\n </SectionLabel>\n )\n}\n\nexport function PriceListEditor({\n value,\n onChange,\n error,\n}: {\n value: PriceListEditorItem[]\n onChange: (next: PriceListEditorItem[]) => void\n error?: string\n}) {\n const t = useT()\n const items = Array.isArray(value) ? value : []\n\n const updateItem = React.useCallback(\n (index: number, patch: Partial<PriceListEditorItem>) => {\n onChange(items.map((item, currentIndex) => (currentIndex === index ? { ...item, ...patch } : item)))\n },\n [items, onChange],\n )\n\n const addItem = React.useCallback(() => {\n onChange([\n ...items,\n {\n id: `item_${items.length + 1}`,\n description: '',\n amount: 0,\n currencyCode: items[0]?.currencyCode ?? 'USD',\n },\n ])\n }, [items, onChange])\n\n return (\n <div className=\"space-y-4\">\n <Alert status=\"information\">\n <AlertDescription>\n {t('checkout.linkTemplateForm.priceList.notices.singleCurrency')}\n </AlertDescription>\n </Alert>\n {error ? <p className=\"text-xs text-destructive\">{error}</p> : null}\n\n <div className=\"overflow-hidden rounded-xl border border-border/70 bg-background\">\n {items.length > 0 ? (\n <div className=\"overflow-x-auto\">\n <table className=\"w-full min-w-[760px] table-fixed\">\n <thead className=\"border-b bg-muted/30\">\n <tr className=\"text-left text-xs font-semibold uppercase tracking-wide text-muted-foreground\">\n <th className=\"px-3 py-2 w-[22%]\">{t('checkout.linkTemplateForm.priceList.columns.itemCode')}</th>\n <th className=\"px-3 py-2\">{t('checkout.linkTemplateForm.priceList.columns.description')}</th>\n <th className=\"px-3 py-2 w-[16%]\">{t('checkout.linkTemplateForm.priceList.columns.amount')}</th>\n <th className=\"px-3 py-2 w-[24%]\">{t('checkout.linkTemplateForm.priceList.columns.currency')}</th>\n <th className=\"px-3 py-2 w-[110px] text-right\">{t('checkout.linkTemplateForm.priceList.columns.actions')}</th>\n </tr>\n </thead>\n <tbody className=\"divide-y divide-border/70\">\n {items.map((item, index) => (\n <tr key={`${item.id}:${index}`} className=\"align-top\">\n <td className=\"px-3 py-2\">\n <Input\n value={item.id}\n onChange={(event) => updateItem(index, { id: event.target.value })}\n placeholder={t('checkout.linkTemplateForm.priceList.placeholders.itemCode')}\n aria-label={t('checkout.linkTemplateForm.priceList.aria.itemCode', { index: index + 1 })}\n className=\"h-8\"\n />\n </td>\n <td className=\"px-3 py-2\">\n <Input\n value={item.description}\n onChange={(event) => updateItem(index, { description: event.target.value })}\n placeholder={t('checkout.linkTemplateForm.priceList.placeholders.description')}\n aria-label={t('checkout.linkTemplateForm.priceList.aria.description', { index: index + 1 })}\n className=\"h-8\"\n />\n </td>\n <td className=\"px-3 py-2\">\n <Input\n type=\"text\"\n inputMode=\"decimal\"\n value={readNumberInputValue(item.amount)}\n onChange={(event) =>\n updateItem(index, {\n // Stays raw while editing \u2014 re-parsing and re-serializing on every\n // keystroke would drop an in-progress decimal separator (e.g. typing\n // \"110,70\" collapses to \"11070\" the instant the comma is typed,\n // issue #5828). Converted to a number at submit time instead.\n amount: event.target.value,\n })\n }\n placeholder=\"0.00\"\n aria-label={t('checkout.linkTemplateForm.priceList.aria.amount', { index: index + 1 })}\n className=\"h-8\"\n />\n </td>\n <td className=\"px-3 py-2\">\n <CheckoutCurrencySelect\n value={item.currencyCode}\n onChange={(next) => updateItem(index, { currencyCode: next })}\n placeholder={t('checkout.currencySelect.placeholder')}\n />\n </td>\n <td className=\"px-3 py-2 text-right\">\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => onChange(items.filter((_, currentIndex) => currentIndex !== index))}\n >\n <Trash2 className=\"mr-2 h-4 w-4\" />\n {t('checkout.common.actions.remove')}\n </Button>\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n ) : (\n <div className=\"px-4 py-8\">\n <Alert status=\"information\">\n <AlertDescription>\n {t('checkout.linkTemplateForm.priceList.notices.empty')}\n </AlertDescription>\n </Alert>\n </div>\n )}\n </div>\n\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={addItem}>\n <Plus className=\"mr-2 h-4 w-4\" />\n {t('checkout.linkTemplateForm.priceList.actions.addItem')}\n </Button>\n </div>\n )\n}\n\nexport function PricingSection({ values, setValue, errors }: CrudFormGroupComponentProps) {\n const t = useT()\n const pricingMode = readString(values.pricingMode) || 'fixed'\n const pricingModeError = readError(errors, 'pricingMode')\n const fixedPriceAmountError = readError(errors, 'fixedPriceAmount')\n const fixedPriceCurrencyError = readError(errors, 'fixedPriceCurrencyCode')\n const fixedPriceOriginalAmountError = readError(errors, 'fixedPriceOriginalAmount')\n const customAmountMinError = readError(errors, 'customAmountMin')\n const customAmountMaxError = readError(errors, 'customAmountMax')\n const customAmountCurrencyError = readError(errors, 'customAmountCurrencyCode')\n const priceListItemsError = readError(errors, 'priceListItems')\n\n return (\n <div className=\"space-y-4\">\n {pricingModeError ? <p className=\"text-xs text-destructive\">{pricingModeError}</p> : null}\n <div className=\"flex flex-wrap gap-2\">\n {[\n { id: 'fixed', label: t('checkout.linkTemplateForm.pricing.modes.fixed'), icon: CircleDollarSign },\n { id: 'custom_amount', label: t('checkout.linkTemplateForm.pricing.modes.customAmount'), icon: WalletCards },\n { id: 'price_list', label: t('checkout.linkTemplateForm.pricing.modes.priceList'), icon: FileText },\n ].map((mode) => {\n const Icon = mode.icon\n const active = pricingMode === mode.id\n return (\n <Button\n key={mode.id}\n type=\"button\"\n variant={active ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setValue('pricingMode', mode.id)}\n >\n <Icon className=\"mr-2 h-4 w-4\" />\n {mode.label}\n </Button>\n )\n })}\n </div>\n\n {pricingMode === 'fixed' ? (\n <div className=\"grid gap-4 md:grid-cols-2\">\n <SectionLabel label={t('checkout.linkTemplateForm.pricing.fields.amount')} error={fixedPriceAmountError} required>\n <Input\n type=\"text\"\n inputMode=\"decimal\"\n value={readNumberInputValue(values.fixedPriceAmount)}\n onChange={(event) => setValue('fixedPriceAmount', event.target.value)}\n placeholder=\"150\"\n className={errorInputClassName(fixedPriceAmountError)}\n aria-invalid={Boolean(fixedPriceAmountError)}\n />\n </SectionLabel>\n\n <SectionLabel label={t('checkout.linkTemplateForm.pricing.fields.currency')} error={fixedPriceCurrencyError} required>\n <CheckoutCurrencySelect\n value={readString(values.fixedPriceCurrencyCode) || 'USD'}\n onChange={(next) => setValue('fixedPriceCurrencyCode', next)}\n placeholder={t('checkout.currencySelect.placeholder')}\n />\n </SectionLabel>\n\n <SectionLabel\n label={t('checkout.linkTemplateForm.pricing.fields.compareAtPrice')}\n hint={t('checkout.linkTemplateForm.pricing.hints.compareAtPrice')}\n error={fixedPriceOriginalAmountError}\n >\n <Input\n type=\"text\"\n inputMode=\"decimal\"\n value={readNumberInputValue(values.fixedPriceOriginalAmount)}\n onChange={(event) => setValue('fixedPriceOriginalAmount', event.target.value)}\n placeholder=\"200\"\n className={errorInputClassName(fixedPriceOriginalAmountError)}\n aria-invalid={Boolean(fixedPriceOriginalAmountError)}\n />\n </SectionLabel>\n\n <div className=\"flex items-end\">\n <label className=\"flex items-center gap-2 rounded-lg border border-border/70 bg-muted/30 px-3 py-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={readBoolean(values.fixedPriceIncludesTax, true)}\n onChange={(event) => setValue('fixedPriceIncludesTax', event.target.checked)}\n />\n {t('checkout.linkTemplateForm.pricing.fields.includesTax')}\n </label>\n </div>\n </div>\n ) : null}\n\n {pricingMode === 'custom_amount' ? (\n <div className=\"grid gap-4 md:grid-cols-3\">\n <SectionLabel label={t('checkout.linkTemplateForm.pricing.fields.minimumAmount')} error={customAmountMinError} required>\n <Input\n type=\"text\"\n inputMode=\"decimal\"\n value={readNumberInputValue(values.customAmountMin)}\n onChange={(event) => setValue('customAmountMin', event.target.value)}\n placeholder=\"10\"\n className={errorInputClassName(customAmountMinError)}\n aria-invalid={Boolean(customAmountMinError)}\n />\n </SectionLabel>\n\n <SectionLabel label={t('checkout.linkTemplateForm.pricing.fields.maximumAmount')} error={customAmountMaxError} required>\n <Input\n type=\"text\"\n inputMode=\"decimal\"\n value={readNumberInputValue(values.customAmountMax)}\n onChange={(event) => setValue('customAmountMax', event.target.value)}\n placeholder=\"500\"\n className={errorInputClassName(customAmountMaxError)}\n aria-invalid={Boolean(customAmountMaxError)}\n />\n </SectionLabel>\n\n <SectionLabel label={t('checkout.linkTemplateForm.pricing.fields.currency')} error={customAmountCurrencyError} required>\n <CheckoutCurrencySelect\n value={readString(values.customAmountCurrencyCode) || 'USD'}\n onChange={(next) => setValue('customAmountCurrencyCode', next)}\n placeholder={t('checkout.currencySelect.placeholder')}\n />\n </SectionLabel>\n </div>\n ) : null}\n\n {pricingMode === 'price_list' ? (\n <PriceListEditor\n value={normalizePriceListItems(values.priceListItems)}\n onChange={(next) => setValue('priceListItems', next)}\n error={priceListItemsError}\n />\n ) : null}\n </div>\n )\n}\n\nfunction GeneralSection({\n values,\n setValue,\n errors,\n mode,\n templateOptions,\n loadTemplateSuggestions,\n applyTemplate,\n isApplyingTemplate,\n}: CrudFormGroupComponentProps & {\n mode: 'link' | 'template'\n templateOptions: ComboboxOption[]\n loadTemplateSuggestions: (query?: string) => Promise<ComboboxOption[]>\n applyTemplate: (templateId: string | null) => Promise<void>\n isApplyingTemplate: boolean\n}) {\n const t = useT()\n const fallbackSlug = slugify(\n readString(values.title).trim().length > 0\n ? readString(values.title)\n : readString(values.name),\n ) || 'pay-link'\n const currentSlug = readString(values.slug)\n const resolvedSlug = currentSlug.trim() || fallbackSlug\n const currentTemplateId = readString(values.templateId).trim()\n const nameError = readError(errors, 'name')\n const titleError = readError(errors, 'title')\n const subtitleError = readError(errors, 'subtitle')\n const descriptionError = readError(errors, 'description')\n const slugError = readError(errors, 'slug')\n const templateError = readError(errors, 'templateId')\n\n return (\n <div className=\"space-y-4\">\n {mode === 'link' ? (\n <SectionLabel\n label={t('checkout.linkTemplateForm.general.fields.template')}\n hint={t('checkout.linkTemplateForm.general.hints.template')}\n error={templateError}\n >\n <div className=\"space-y-3\">\n <ComboboxInput\n value={currentTemplateId}\n suggestions={templateOptions}\n loadSuggestions={loadTemplateSuggestions}\n resolveLabel={(value) => templateOptions.find((option) => option.value === value)?.label ?? value}\n resolveDescription={(value) => templateOptions.find((option) => option.value === value)?.description}\n onChange={(nextValue) => {\n const normalized = nextValue.trim()\n setValue('templateId', normalized || null)\n void applyTemplate(normalized || null)\n }}\n placeholder={t('checkout.linkTemplateForm.general.placeholders.template')}\n disabled={isApplyingTemplate}\n allowCustomValues={false}\n />\n <div className=\"flex flex-wrap items-center gap-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n disabled={isApplyingTemplate || currentTemplateId.length === 0}\n onClick={() => {\n setValue('templateId', null)\n void applyTemplate(null)\n }}\n >\n {t('checkout.linkTemplateForm.general.actions.clearTemplate')}\n </Button>\n {isApplyingTemplate ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('checkout.linkTemplateForm.general.status.applyingTemplate')}\n </p>\n ) : (\n <p className=\"text-xs text-muted-foreground\">\n {t('checkout.linkTemplateForm.general.notices.templateReplacement')}\n </p>\n )}\n </div>\n </div>\n </SectionLabel>\n ) : null}\n\n <SectionLabel label={t('checkout.linkTemplateForm.general.fields.name')} error={nameError} required>\n <Input\n value={readString(values.name)}\n onChange={(event) => setValue('name', event.target.value)}\n placeholder={t('checkout.linkTemplateForm.general.placeholders.name')}\n className={errorInputClassName(nameError)}\n aria-invalid={Boolean(nameError)}\n />\n </SectionLabel>\n\n <SectionLabel label={t('checkout.linkTemplateForm.general.fields.title')} error={titleError}>\n <Input\n value={readString(values.title)}\n onChange={(event) => setValue('title', event.target.value)}\n placeholder={t('checkout.linkTemplateForm.general.placeholders.title')}\n className={errorInputClassName(titleError)}\n aria-invalid={Boolean(titleError)}\n />\n </SectionLabel>\n\n <SectionLabel label={t('checkout.linkTemplateForm.general.fields.subtitle')} error={subtitleError}>\n <Input\n value={readString(values.subtitle)}\n onChange={(event) => setValue('subtitle', event.target.value)}\n placeholder={t('checkout.linkTemplateForm.general.placeholders.subtitle')}\n className={errorInputClassName(subtitleError)}\n aria-invalid={Boolean(subtitleError)}\n />\n </SectionLabel>\n\n <SectionLabel label={t('checkout.linkTemplateForm.general.fields.description')} hint={t('checkout.linkTemplateForm.general.hints.description')} error={descriptionError}>\n <SwitchableMarkdownInput\n value={readString(values.description)}\n onChange={(next) => setValue('description', next)}\n isMarkdownEnabled\n height={220}\n placeholder={t('checkout.linkTemplateForm.general.placeholders.description')}\n />\n </SectionLabel>\n\n {mode === 'link' ? (\n <SectionLabel label={t('checkout.linkTemplateForm.general.fields.slug')} hint={t('checkout.linkTemplateForm.general.hints.slug')} error={slugError}>\n <div className=\"space-y-2\">\n <div className=\"flex gap-2\">\n <Input\n value={currentSlug}\n onChange={(event) => setValue('slug', event.target.value)}\n placeholder={t('checkout.linkTemplateForm.general.placeholders.slug')}\n className={errorInputClassName(slugError)}\n aria-invalid={Boolean(slugError)}\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => setValue('slug', fallbackSlug)}\n >\n <Sparkles className=\"mr-2 h-4 w-4\" />\n {t('checkout.linkTemplateForm.general.actions.generateSlug')}\n </Button>\n </div>\n <p className=\"text-xs text-muted-foreground\">{t('checkout.linkTemplateForm.general.slugPreview', { slug: resolvedSlug })}</p>\n </div>\n </SectionLabel>\n ) : null}\n </div>\n )\n}\n\nfunction AppearanceSection({\n values,\n setValue,\n errors,\n entityId,\n attachmentRecordId,\n}: CrudFormGroupComponentProps & { entityId: string; attachmentRecordId: string }) {\n const t = useT()\n const logoError = readAnyError(errors, 'logoAttachmentId', 'logoUrl')\n const primaryColorError = readError(errors, 'primaryColor')\n const secondaryColorError = readError(errors, 'secondaryColor')\n const backgroundColorError = readError(errors, 'backgroundColor')\n const themeModeError = readError(errors, 'themeMode')\n const displayCustomFieldsError = readError(errors, 'displayCustomFieldsOnPage')\n\n return (\n <div className=\"space-y-4\">\n <LogoUploadField\n entityId={entityId}\n recordId={attachmentRecordId}\n attachmentId={readString(values.logoAttachmentId) || null}\n logoUrl={readString(values.logoUrl) || null}\n error={logoError}\n onChange={(next) => {\n setValue('logoAttachmentId', next.logoAttachmentId)\n setValue('logoUrl', next.logoUrl)\n }}\n />\n\n <div className=\"space-y-4\">\n <ColorField\n label={t('checkout.linkTemplateForm.appearance.fields.primaryColor')}\n value={readString(values.primaryColor) || DEFAULT_COLORS.primaryColor}\n onChange={(next) => setValue('primaryColor', next)}\n error={primaryColorError}\n />\n <ColorField\n label={t('checkout.linkTemplateForm.appearance.fields.secondaryColor')}\n value={readString(values.secondaryColor) || DEFAULT_COLORS.secondaryColor}\n onChange={(next) => setValue('secondaryColor', next)}\n error={secondaryColorError}\n />\n <ColorField\n label={t('checkout.linkTemplateForm.appearance.fields.backgroundColor')}\n value={readString(values.backgroundColor) || DEFAULT_COLORS.backgroundColor}\n onChange={(next) => setValue('backgroundColor', next)}\n error={backgroundColorError}\n />\n </div>\n\n <SectionLabel label={t('checkout.linkTemplateForm.appearance.fields.themeMode')} error={themeModeError}>\n <select\n className={themeModeError\n ? `w-full rounded-md border bg-background px-3 py-2 text-sm ${errorInputClassName(themeModeError)}`\n : 'w-full rounded-md border bg-background px-3 py-2 text-sm'}\n value={readString(values.themeMode) || 'auto'}\n onChange={(event) => setValue('themeMode', event.target.value)}\n aria-invalid={Boolean(themeModeError)}\n >\n <option value=\"auto\">{t('checkout.linkTemplateForm.appearance.themeModes.auto')}</option>\n <option value=\"light\">{t('checkout.linkTemplateForm.appearance.themeModes.light')}</option>\n <option value=\"dark\">{t('checkout.linkTemplateForm.appearance.themeModes.dark')}</option>\n </select>\n </SectionLabel>\n\n <label className=\"flex items-center gap-2 rounded-lg border border-border/70 bg-muted/30 px-3 py-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={readBoolean(values.displayCustomFieldsOnPage)}\n onChange={(event) => setValue('displayCustomFieldsOnPage', event.target.checked)}\n />\n {t('checkout.linkTemplateForm.appearance.fields.displayCustomFields')}\n </label>\n {displayCustomFieldsError ? <p className=\"text-xs text-destructive\">{displayCustomFieldsError}</p> : null}\n </div>\n )\n}\n\nfunction PaymentSection({ values, setValue, errors, providers }: CrudFormGroupComponentProps & { providers: ProviderDescriptor[] }) {\n const t = useT()\n const selectedProviderKey = readString(values.gatewayProviderKey)\n const selectedProvider = providers.find((provider) => provider.providerKey === selectedProviderKey)\n const gatewayProviderError = readError(errors, 'gatewayProviderKey')\n ?? (() => {\n const messageKey = getGatewayProviderConfigurationMessageKey(selectedProvider)\n return messageKey ? t(messageKey) : undefined\n })()\n const gatewaySettingsError = readError(errors, 'gatewaySettings')\n\n return (\n <div className=\"space-y-4\">\n <SectionLabel label={t('checkout.linkTemplateForm.payment.fields.gatewayProvider')} error={gatewayProviderError} required>\n <select\n className={gatewayProviderError\n ? `w-full rounded-md border bg-background px-3 py-2 text-sm ${errorInputClassName(gatewayProviderError)}`\n : 'w-full rounded-md border bg-background px-3 py-2 text-sm'}\n value={readString(values.gatewayProviderKey)}\n onChange={(event) => setValue('gatewayProviderKey', event.target.value)}\n aria-invalid={Boolean(gatewayProviderError)}\n >\n <option value=\"\">{t('checkout.linkTemplateForm.payment.placeholders.provider')}</option>\n {providers.map((provider) => (\n <option\n key={provider.providerKey}\n value={provider.providerKey}\n disabled={provider.isConfigured === false}\n >\n {provider.isConfigured === false\n ? `${provider.label} ${t('checkout.linkTemplateForm.payment.providerUnavailableSuffix')}`\n : provider.label}\n </option>\n ))}\n </select>\n </SectionLabel>\n\n <GatewaySettingsFields\n providerKey={readString(values.gatewayProviderKey) || null}\n value={isRecord(values.gatewaySettings) ? values.gatewaySettings : {}}\n onChange={(next) => setValue('gatewaySettings', next)}\n />\n {gatewaySettingsError ? <p className=\"text-xs text-destructive\">{gatewaySettingsError}</p> : null}\n </div>\n )\n}\n\nfunction CustomerDetailsSection({ values, setValue, errors }: CrudFormGroupComponentProps) {\n const t = useT()\n const collectCustomerDetails = readBoolean(values.collectCustomerDetails, true)\n const collectCustomerDetailsError = readError(errors, 'collectCustomerDetails')\n const customerFieldsError = readCustomerFieldsSectionError(errors)\n\n return (\n <div className=\"space-y-4\">\n <label className=\"flex items-start gap-3 rounded-xl border border-border/70 bg-muted/30 px-4 py-3 text-sm\">\n <input\n type=\"checkbox\"\n checked={collectCustomerDetails}\n onChange={(event) => setValue('collectCustomerDetails', event.target.checked)}\n />\n <span className=\"space-y-1\">\n <span className=\"flex items-center gap-2 font-medium\">\n <IdCard className=\"h-4 w-4\" />\n {t('checkout.linkTemplateForm.customerDetails.title')}\n </span>\n <span className=\"block text-muted-foreground\">\n {t('checkout.linkTemplateForm.customerDetails.description')}\n </span>\n </span>\n </label>\n {collectCustomerDetailsError ? <p className=\"text-xs text-destructive\">{collectCustomerDetailsError}</p> : null}\n\n {collectCustomerDetails ? (\n <>\n <Alert status=\"information\">\n <AlertDescription>\n {t('checkout.linkTemplateForm.customerDetails.notices.simpleLink')}\n </AlertDescription>\n </Alert>\n {customerFieldsError ? <p className=\"text-xs text-destructive\">{customerFieldsError}</p> : null}\n <CustomerFieldsEditor\n value={readCustomerFields(values.customerFieldsSchema, t)}\n onChange={(next) => setValue('customerFieldsSchema', next)}\n errors={errors}\n />\n </>\n ) : (\n <Alert status=\"information\">\n <AlertDescription>\n {t('checkout.linkTemplateForm.customerDetails.notices.disabled')}\n </AlertDescription>\n </Alert>\n )}\n </div>\n )\n}\n\nfunction LegalSection({ values, setValue, errors }: CrudFormGroupComponentProps) {\n const t = useT()\n const [tab, setTab] = React.useState<'terms' | 'privacyPolicy'>('terms')\n const legalDocuments = normalizeLegalDocuments(values.legalDocuments)\n const termsTitleError = readAnyError(errors, 'legalDocuments.terms.title', 'legalDocuments.terms')\n const termsMarkdownError = readAnyError(errors, 'legalDocuments.terms.markdown', 'legalDocuments.terms')\n const privacyTitleError = readAnyError(errors, 'legalDocuments.privacyPolicy.title', 'legalDocuments.privacyPolicy')\n const privacyMarkdownError = readAnyError(errors, 'legalDocuments.privacyPolicy.markdown', 'legalDocuments.privacyPolicy')\n\n const patchDocument = React.useCallback(\n (key: 'terms' | 'privacyPolicy', patch: Partial<LegalDocumentValue>) => {\n setValue('legalDocuments', {\n ...legalDocuments,\n [key]: {\n ...legalDocuments[key],\n ...patch,\n },\n })\n },\n [legalDocuments, setValue],\n )\n\n return (\n <div className=\"space-y-4\">\n <Alert status=\"information\">\n <AlertDescription>\n {t('checkout.linkTemplateForm.legal.notice')}\n </AlertDescription>\n </Alert>\n\n <Tabs value={tab} onValueChange={(next) => setTab(next as 'terms' | 'privacyPolicy')}>\n <TabsList className={SETTINGS_TABS_LIST_CLASS}>\n <TabsTrigger value=\"terms\" className={SETTINGS_TABS_TRIGGER_CLASS}>\n <Shield className=\"mr-2 h-4 w-4\" />\n {t('checkout.linkTemplateForm.legal.tabs.terms')}\n </TabsTrigger>\n <TabsTrigger value=\"privacyPolicy\" className={SETTINGS_TABS_TRIGGER_CLASS}>\n <FileCheck2 className=\"mr-2 h-4 w-4\" />\n {t('checkout.linkTemplateForm.legal.tabs.privacy')}\n </TabsTrigger>\n </TabsList>\n\n <TabsContent value=\"terms\" className=\"space-y-4\">\n <SectionLabel label={t('checkout.linkTemplateForm.legal.fields.termsTitle')} error={termsTitleError}>\n <Input\n value={legalDocuments.terms.title}\n onChange={(event) => patchDocument('terms', { title: event.target.value })}\n placeholder={t('checkout.linkTemplateForm.legal.placeholders.termsTitle')}\n className={errorInputClassName(termsTitleError)}\n aria-invalid={Boolean(termsTitleError)}\n />\n </SectionLabel>\n <SectionLabel label={t('checkout.linkTemplateForm.legal.fields.termsBody')} error={termsMarkdownError}>\n <SwitchableMarkdownInput\n value={legalDocuments.terms.markdown}\n onChange={(next) => patchDocument('terms', { markdown: next })}\n isMarkdownEnabled\n height={220}\n placeholder={t('checkout.linkTemplateForm.legal.placeholders.termsBody')}\n />\n </SectionLabel>\n <label className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={legalDocuments.terms.required}\n onChange={(event) => patchDocument('terms', { required: event.target.checked })}\n />\n {t('checkout.linkTemplateForm.legal.fields.acceptanceRequired')}\n </label>\n </TabsContent>\n\n <TabsContent value=\"privacyPolicy\" className=\"space-y-4\">\n <SectionLabel label={t('checkout.linkTemplateForm.legal.fields.privacyTitle')} error={privacyTitleError}>\n <Input\n value={legalDocuments.privacyPolicy.title}\n onChange={(event) => patchDocument('privacyPolicy', { title: event.target.value })}\n placeholder={t('checkout.linkTemplateForm.legal.placeholders.privacyTitle')}\n className={errorInputClassName(privacyTitleError)}\n aria-invalid={Boolean(privacyTitleError)}\n />\n </SectionLabel>\n <SectionLabel label={t('checkout.linkTemplateForm.legal.fields.privacyBody')} error={privacyMarkdownError}>\n <SwitchableMarkdownInput\n value={legalDocuments.privacyPolicy.markdown}\n onChange={(next) => patchDocument('privacyPolicy', { markdown: next })}\n isMarkdownEnabled\n height={220}\n placeholder={t('checkout.linkTemplateForm.legal.placeholders.privacyBody')}\n />\n </SectionLabel>\n <label className=\"flex items-center gap-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={legalDocuments.privacyPolicy.required}\n onChange={(event) => patchDocument('privacyPolicy', { required: event.target.checked })}\n />\n {t('checkout.linkTemplateForm.legal.fields.acceptanceRequired')}\n </label>\n </TabsContent>\n </Tabs>\n </div>\n )\n}\n\nfunction MessagesSection({ values, setValue, errors }: CrudFormGroupComponentProps) {\n const t = useT()\n const [tab, setTab] = React.useState<'success' | 'cancel' | 'error'>('success')\n\n const config = {\n success: {\n titleKey: 'successTitle',\n bodyKey: 'successMessage',\n titlePlaceholder: t('checkout.linkTemplateForm.messages.placeholders.successTitle'),\n bodyPlaceholder: t('checkout.linkTemplateForm.messages.placeholders.successBody'),\n label: t('checkout.linkTemplateForm.messages.tabs.success'),\n },\n cancel: {\n titleKey: 'cancelTitle',\n bodyKey: 'cancelMessage',\n titlePlaceholder: t('checkout.linkTemplateForm.messages.placeholders.cancelTitle'),\n bodyPlaceholder: t('checkout.linkTemplateForm.messages.placeholders.cancelBody'),\n label: t('checkout.linkTemplateForm.messages.tabs.cancel'),\n },\n error: {\n titleKey: 'errorTitle',\n bodyKey: 'errorMessage',\n titlePlaceholder: t('checkout.linkTemplateForm.messages.placeholders.errorTitle'),\n bodyPlaceholder: t('checkout.linkTemplateForm.messages.placeholders.errorBody'),\n label: t('checkout.linkTemplateForm.messages.tabs.error'),\n },\n } as const\n\n return (\n <div className=\"space-y-4\">\n <Alert status=\"information\">\n <AlertDescription>\n {t('checkout.linkTemplateForm.messages.notice')}\n </AlertDescription>\n </Alert>\n\n <Tabs value={tab} onValueChange={(next) => setTab(next as 'success' | 'cancel' | 'error')}>\n <TabsList className={SETTINGS_TABS_LIST_CLASS}>\n {(['success', 'cancel', 'error'] as const).map((item) => (\n <TabsTrigger key={item} value={item} className={SETTINGS_TABS_TRIGGER_CLASS}>\n <MessageSquare className=\"mr-2 h-4 w-4\" />\n {config[item].label}\n </TabsTrigger>\n ))}\n </TabsList>\n\n {(['success', 'cancel', 'error'] as const).map((item) => (\n <TabsContent key={item} value={item} className=\"space-y-4\">\n <SectionLabel label={t('checkout.linkTemplateForm.messages.labels.title', { state: config[item].label })} error={readError(errors, config[item].titleKey)}>\n <Input\n value={readString(values[config[item].titleKey])}\n onChange={(event) => setValue(config[item].titleKey, event.target.value)}\n placeholder={config[item].titlePlaceholder}\n className={errorInputClassName(readError(errors, config[item].titleKey))}\n aria-invalid={Boolean(readError(errors, config[item].titleKey))}\n />\n </SectionLabel>\n <SectionLabel label={t('checkout.linkTemplateForm.messages.labels.body', { state: config[item].label })} error={readError(errors, config[item].bodyKey)}>\n <SwitchableMarkdownInput\n value={readString(values[config[item].bodyKey])}\n onChange={(next) => setValue(config[item].bodyKey, next)}\n isMarkdownEnabled\n height={220}\n placeholder={config[item].bodyPlaceholder}\n />\n </SectionLabel>\n </TabsContent>\n ))}\n </Tabs>\n </div>\n )\n}\n\nfunction VariableHint() {\n const t = useT()\n const variables = ['{{firstName}}', '{{amount}}', '{{currencyCode}}', '{{linkTitle}}', '{{transactionId}}', '{{errorMessage}}']\n return (\n <div className=\"space-y-2\">\n <p className=\"text-xs text-muted-foreground\">{t('checkout.linkTemplateForm.emails.variableHint')}</p>\n <div className=\"flex flex-wrap gap-2\">\n {variables.map((variable) => (\n <span\n key={variable}\n className=\"rounded-full border border-border/70 bg-background px-2 py-1 text-xs text-muted-foreground\"\n >\n {variable}\n </span>\n ))}\n </div>\n </div>\n )\n}\n\nfunction EmailsSection({ values, setValue, errors }: CrudFormGroupComponentProps) {\n const t = useT()\n const [tab, setTab] = React.useState<'start' | 'success' | 'error'>('start')\n\n const config = {\n start: {\n enabledKey: 'sendStartEmail',\n subjectKey: 'startEmailSubject',\n bodyKey: 'startEmailBody',\n title: t('checkout.linkTemplateForm.emails.tabs.start'),\n Icon: Send,\n subjectPlaceholder: t('checkout.linkTemplateForm.emails.placeholders.startSubject'),\n bodyPlaceholder: t('checkout.linkTemplateForm.emails.placeholders.startBody'),\n },\n success: {\n enabledKey: 'sendSuccessEmail',\n subjectKey: 'successEmailSubject',\n bodyKey: 'successEmailBody',\n title: t('checkout.linkTemplateForm.emails.tabs.success'),\n Icon: BadgeCheck,\n subjectPlaceholder: t('checkout.linkTemplateForm.emails.placeholders.successSubject'),\n bodyPlaceholder: t('checkout.linkTemplateForm.emails.placeholders.successBody'),\n },\n error: {\n enabledKey: 'sendErrorEmail',\n subjectKey: 'errorEmailSubject',\n bodyKey: 'errorEmailBody',\n title: t('checkout.linkTemplateForm.emails.tabs.error'),\n Icon: AlertTriangle,\n subjectPlaceholder: t('checkout.linkTemplateForm.emails.placeholders.errorSubject'),\n bodyPlaceholder: t('checkout.linkTemplateForm.emails.placeholders.errorBody'),\n },\n } as const\n\n return (\n <div className=\"space-y-4\">\n <Alert status=\"information\">\n <AlertDescription>\n {t('checkout.linkTemplateForm.emails.notice')}\n </AlertDescription>\n </Alert>\n <VariableHint />\n\n <Tabs value={tab} onValueChange={(next) => setTab(next as 'start' | 'success' | 'error')}>\n <TabsList className={SETTINGS_TABS_LIST_CLASS}>\n {(['start', 'success', 'error'] as const).map((item) => {\n const Icon = config[item].Icon\n return (\n <TabsTrigger key={item} value={item} className={SETTINGS_TABS_TRIGGER_CLASS}>\n <Icon className=\"mr-2 h-4 w-4\" />\n {config[item].title}\n </TabsTrigger>\n )\n })}\n </TabsList>\n\n {(['start', 'success', 'error'] as const).map((item) => (\n <TabsContent key={item} value={item} className=\"space-y-4\">\n <label className=\"flex items-center gap-2 rounded-lg border border-border/70 bg-muted/30 px-3 py-2 text-sm\">\n <input\n type=\"checkbox\"\n checked={readBoolean(values[config[item].enabledKey], true)}\n onChange={(event) => setValue(config[item].enabledKey, event.target.checked)}\n />\n {t('checkout.linkTemplateForm.emails.sendToCustomer')}\n </label>\n\n <SectionLabel label={t('checkout.linkTemplateForm.emails.labels.subject', { state: config[item].title })} error={readError(errors, config[item].subjectKey)}>\n <Input\n value={readString(values[config[item].subjectKey])}\n onChange={(event) => setValue(config[item].subjectKey, event.target.value)}\n placeholder={config[item].subjectPlaceholder}\n className={errorInputClassName(readError(errors, config[item].subjectKey))}\n aria-invalid={Boolean(readError(errors, config[item].subjectKey))}\n />\n </SectionLabel>\n\n <SectionLabel label={t('checkout.linkTemplateForm.emails.labels.body', { state: config[item].title })} error={readError(errors, config[item].bodyKey)}>\n <SwitchableMarkdownInput\n value={readString(values[config[item].bodyKey])}\n onChange={(next) => setValue(config[item].bodyKey, next)}\n isMarkdownEnabled\n height={220}\n placeholder={config[item].bodyPlaceholder}\n />\n </SectionLabel>\n </TabsContent>\n ))}\n </Tabs>\n </div>\n )\n}\n\nfunction SettingsSection({ values, setValue, errors }: CrudFormGroupComponentProps) {\n const t = useT()\n const status = readString(values.status) || 'draft'\n const statusError = readError(errors, 'status')\n const maxCompletionsError = readError(errors, 'maxCompletions')\n const passwordError = readError(errors, 'password')\n\n return (\n <div className=\"space-y-4\">\n <SectionLabel label={t('checkout.linkTemplateForm.settings.fields.status')} error={statusError}>\n <div className=\"flex flex-wrap gap-2\">\n {[\n { id: 'draft', label: t('checkout.common.status.draft') },\n { id: 'active', label: t('checkout.common.status.active') },\n { id: 'inactive', label: t('checkout.common.status.inactive') },\n ].map((option) => (\n <Button\n key={option.id}\n type=\"button\"\n variant={status === option.id ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setValue('status', option.id)}\n >\n {option.label}\n </Button>\n ))}\n </div>\n </SectionLabel>\n\n <SectionLabel label={t('checkout.linkTemplateForm.settings.fields.maxCompletions')} hint={t('checkout.linkTemplateForm.settings.hints.maxCompletions')} error={maxCompletionsError}>\n <Input\n type=\"number\"\n min=\"1\"\n step=\"1\"\n value={readNumberInputValue(values.maxCompletions)}\n onChange={(event) => setValue('maxCompletions', event.target.value ? Number(event.target.value) : null)}\n placeholder={t('checkout.linkTemplateForm.settings.placeholders.unlimited')}\n className={errorInputClassName(maxCompletionsError)}\n aria-invalid={Boolean(maxCompletionsError)}\n />\n </SectionLabel>\n\n <SectionLabel label={t('checkout.linkTemplateForm.settings.fields.password')} hint={t('checkout.linkTemplateForm.settings.hints.password')} error={passwordError}>\n <PasswordInput\n value={readString(values.password)}\n onChange={(event) => setValue('password', event.target.value)}\n placeholder={t('checkout.linkTemplateForm.settings.placeholders.password')}\n className={errorInputClassName(passwordError)}\n aria-invalid={Boolean(passwordError)}\n />\n </SectionLabel>\n </div>\n )\n}\n\nexport function LinkTemplateForm({ mode, recordId }: Props) {\n const t = useT()\n const locale = useLocale()\n const searchParams = useSearchParams()\n const entityId = mode === 'link' ? CHECKOUT_ENTITY_IDS.link : CHECKOUT_ENTITY_IDS.template\n const templateId = React.useMemo(() => {\n const raw = searchParams.get('templateId')\n return raw && raw.trim().length > 0 ? raw : null\n }, [searchParams])\n const attachmentDraftRecordId = React.useMemo(\n () => recordId ?? (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function' ? crypto.randomUUID() : `draft-${Date.now()}`),\n [recordId],\n )\n const initialLogoAttachmentIdRef = React.useRef<string | null>(null)\n const [providers, setProviders] = React.useState<ProviderDescriptor[]>([])\n const [templateOptions, setTemplateOptions] = React.useState<ComboboxOption[]>([])\n const [isApplyingTemplate, setIsApplyingTemplate] = React.useState(false)\n const [formInstanceKey, setFormInstanceKey] = React.useState(0)\n const [initialValues, setInitialValues] = React.useState<FormValues | null>(\n recordId ? null : normalizeFormValues(createDefaultValues(t), t),\n )\n const [notFound, setNotFound] = React.useState(false)\n\n const replaceInitialValues = React.useCallback((nextValues: FormValues) => {\n setInitialValues(nextValues)\n setFormInstanceKey((current) => current + 1)\n }, [])\n\n React.useEffect(() => {\n initialLogoAttachmentIdRef.current = initialValues && typeof initialValues.logoAttachmentId === 'string'\n ? initialValues.logoAttachmentId\n : null\n }, [initialValues])\n\n React.useEffect(() => {\n let active = true\n void readApiResultOrThrow<{ items: ProviderDescriptor[] }>('/api/payment_gateways/providers')\n .then((result) => {\n if (!active) return\n setProviders(Array.isArray(result.items) ? result.items : [])\n })\n .catch(() => {\n if (active) setProviders([])\n })\n return () => {\n active = false\n }\n }, [])\n\n const rememberTemplateOptions = React.useCallback((items: TemplateSummary[] | ComboboxOption[]) => {\n setTemplateOptions((current) => {\n const next = new Map(current.map((option) => [option.value, option]))\n items.forEach((item) => {\n if ('value' in item) {\n next.set(item.value, item)\n return\n }\n const option = toTemplateOption(item)\n next.set(option.value, option)\n })\n return Array.from(next.values())\n })\n }, [])\n\n const loadTemplateSuggestions = React.useCallback(async (query?: string): Promise<ComboboxOption[]> => {\n const params = new URLSearchParams({\n page: '1',\n pageSize: '25',\n })\n if (query && query.trim().length > 0) {\n params.set('search', query.trim())\n }\n const result = await readApiResultOrThrow<{ items: TemplateSummary[] }>(`/api/checkout/templates?${params.toString()}`)\n const options = Array.isArray(result.items) ? result.items.map(toTemplateOption) : []\n rememberTemplateOptions(options)\n return options\n }, [rememberTemplateOptions])\n\n const applyTemplate = React.useCallback(async (nextTemplateId: string | null) => {\n if (recordId || mode !== 'link') return\n if (!nextTemplateId) {\n replaceInitialValues(normalizeFormValues(createDefaultValues(t), t))\n return\n }\n setIsApplyingTemplate(true)\n try {\n const result = await readApiResultOrThrow<FormValues>(`/api/checkout/templates/${encodeURIComponent(nextTemplateId)}`)\n rememberTemplateOptions([{\n id: nextTemplateId,\n name: readString(result.name),\n title: readString(result.title) || null,\n gatewayProviderKey: readString(result.gatewayProviderKey) || null,\n pricingMode: readString(result.pricingMode) || null,\n }])\n replaceInitialValues(\n normalizeFormValues({\n ...result,\n slug: '',\n templateId: nextTemplateId,\n }, t),\n )\n } finally {\n setIsApplyingTemplate(false)\n }\n }, [mode, recordId, rememberTemplateOptions, replaceInitialValues, t])\n\n React.useEffect(() => {\n if (mode !== 'link' || recordId) return\n void loadTemplateSuggestions()\n .catch(() => null)\n }, [loadTemplateSuggestions, mode, recordId])\n\n React.useEffect(() => {\n if (!recordId) return\n let active = true\n setNotFound(false)\n void readApiResultOrThrow<FormValues>(`/api/checkout/${mode === 'link' ? 'links' : 'templates'}/${encodeURIComponent(recordId)}`)\n .then((result) => {\n if (!active) return\n replaceInitialValues(normalizeFormValues(result, t))\n })\n .catch((error) => {\n if (!active) return\n if (isRecordNotFoundError(error)) {\n setNotFound(true)\n return\n }\n replaceInitialValues(normalizeFormValues({}, t))\n })\n return () => {\n active = false\n }\n }, [mode, recordId, replaceInitialValues, t])\n\n React.useEffect(() => {\n if (recordId || mode !== 'link' || !templateId) return\n void applyTemplate(templateId).catch(() => null)\n }, [applyTemplate, mode, recordId, templateId])\n\n React.useEffect(() => {\n const currentTemplateId = readString(initialValues?.templateId).trim()\n if (mode !== 'link' || !currentTemplateId) return\n if (templateOptions.some((option) => option.value === currentTemplateId)) return\n\n let active = true\n void readApiResultOrThrow<FormValues>(`/api/checkout/templates/${encodeURIComponent(currentTemplateId)}`)\n .then((result) => {\n if (!active) return\n rememberTemplateOptions([{\n id: currentTemplateId,\n name: readString(result.name),\n title: readString(result.title) || null,\n gatewayProviderKey: readString(result.gatewayProviderKey) || null,\n pricingMode: readString(result.pricingMode) || null,\n }])\n })\n .catch(() => null)\n\n return () => {\n active = false\n }\n }, [initialValues?.templateId, mode, rememberTemplateOptions, templateOptions])\n\n const fields = React.useMemo<CrudField[]>(() => [], [])\n\n const groups = React.useMemo<CrudFormGroup[]>(() => [\n {\n id: 'general',\n title: t('checkout.linkTemplateForm.groups.general'),\n column: 1,\n component: (ctx) => (\n <GeneralSection\n {...ctx}\n mode={mode}\n templateOptions={templateOptions}\n loadTemplateSuggestions={loadTemplateSuggestions}\n applyTemplate={applyTemplate}\n isApplyingTemplate={isApplyingTemplate}\n />\n ),\n },\n {\n id: 'payment',\n title: t('checkout.linkTemplateForm.groups.payment'),\n column: 2,\n component: (ctx) => <PaymentSection {...ctx} providers={providers} />,\n },\n {\n id: 'pricing',\n title: t('checkout.linkTemplateForm.groups.pricing'),\n column: 1,\n component: (ctx) => <PricingSection {...ctx} />,\n },\n {\n id: 'appearance',\n title: t('checkout.linkTemplateForm.groups.appearance'),\n column: 2,\n component: (ctx) => (\n <AppearanceSection\n {...ctx}\n entityId={entityId}\n attachmentRecordId={attachmentDraftRecordId}\n />\n ),\n },\n {\n id: 'customerFields',\n title: t('checkout.linkTemplateForm.groups.customerFields'),\n column: 1,\n component: (ctx) => <CustomerDetailsSection {...ctx} />,\n },\n {\n id: 'settings',\n title: t('checkout.linkTemplateForm.groups.settings'),\n column: 2,\n component: (ctx) => <SettingsSection {...ctx} />,\n },\n {\n id: 'legal',\n title: t('checkout.linkTemplateForm.groups.legal'),\n column: 1,\n component: (ctx) => <LegalSection {...ctx} />,\n },\n {\n id: 'messages',\n title: t('checkout.linkTemplateForm.groups.messages'),\n column: 1,\n component: (ctx) => <MessagesSection {...ctx} />,\n },\n {\n id: 'emails',\n title: t('checkout.linkTemplateForm.groups.emails'),\n column: 1,\n component: (ctx) => <EmailsSection {...ctx} />,\n },\n { id: 'customFields', title: t('checkout.linkTemplateForm.groups.customFields'), column: 2, kind: 'customFields' },\n ], [applyTemplate, attachmentDraftRecordId, entityId, isApplyingTemplate, loadTemplateSuggestions, mode, providers, t, templateOptions])\n\n const isLocked = mode === 'link' && Boolean(recordId) && readBoolean(initialValues?.isLocked)\n const formId = React.useMemo(\n () => `checkout-${mode}-editor-${recordId ?? 'new'}`,\n [mode, recordId],\n )\n const lockedNotice = isLocked ? (\n <Alert status=\"warning\">\n <AlertTitle>{t('checkout.linkTemplateForm.locked.title')}</AlertTitle>\n <AlertDescription>{t('checkout.linkTemplateForm.locked.description')}</AlertDescription>\n </Alert>\n ) : undefined\n const lockedOverlay = isLocked ? (\n <div className=\"mx-auto mt-6 max-w-md rounded-xl border border-status-warning-border bg-background/95 px-5 py-4 text-center shadow-sm\">\n <div className=\"mx-auto mb-3 flex h-10 w-10 items-center justify-center rounded-full bg-status-warning-bg text-status-warning-icon\">\n <Shield className=\"h-5 w-5\" />\n </div>\n <p className=\"text-sm font-semibold text-foreground\">\n {t('checkout.linkTemplateForm.locked.overlayTitle')}\n </p>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {t('checkout.linkTemplateForm.locked.overlayDescription')}\n </p>\n </div>\n ) : undefined\n\n const listHref = mode === 'link' ? '/backend/checkout/pay-links' : '/backend/checkout/templates'\n\n if (notFound) {\n return (\n <Page>\n <PageBody>\n <RecordNotFoundState\n label={t(mode === 'link'\n ? 'checkout.linkTemplateForm.notFound.link.title'\n : 'checkout.linkTemplateForm.notFound.template.title')}\n description={t(mode === 'link'\n ? 'checkout.linkTemplateForm.notFound.link.description'\n : 'checkout.linkTemplateForm.notFound.template.description')}\n backHref={listHref}\n />\n </PageBody>\n </Page>\n )\n }\n\n return (\n <Page>\n <PageBody>\n {initialValues ? (\n <CrudForm<FormValues>\n key={formInstanceKey}\n formId={formId}\n title={recordId\n ? t(mode === 'link' ? 'checkout.linkTemplateForm.titles.editLink' : 'checkout.linkTemplateForm.titles.editTemplate')\n : t(mode === 'link' ? 'checkout.linkTemplateForm.titles.createLink' : 'checkout.linkTemplateForm.titles.createTemplate')}\n titleHeadingLevel={1}\n backHref={mode === 'link' ? '/backend/checkout/pay-links' : '/backend/checkout/templates'}\n cancelHref={mode === 'link' ? '/backend/checkout/pay-links' : '/backend/checkout/templates'}\n fields={fields}\n groups={groups}\n extraActions={recordId ? (\n <>\n {isLocked ? (\n <Button asChild type=\"button\" variant=\"outline\">\n <a\n href={mode === 'link'\n ? `/pay/${encodeURIComponent(readString(initialValues.slug))}?preview=true`\n : `/backend/checkout/templates/${encodeURIComponent(recordId)}/preview`}\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n <Eye className=\"mr-2 h-4 w-4\" />\n {t('checkout.common.actions.preview')}\n </a>\n </Button>\n ) : (\n <Button\n type=\"submit\"\n form={formId}\n variant=\"outline\"\n name=\"submitIntent\"\n value=\"preview\"\n >\n <Eye className=\"mr-2 h-4 w-4\" />\n {t('checkout.common.actions.preview')}\n </Button>\n )}\n {mode === 'link' && recordId && !isLocked ? (\n <Button\n type=\"submit\"\n form={formId}\n name=\"submitIntent\"\n value=\"publish\"\n >\n <BadgeCheck className=\"mr-2 h-4 w-4\" />\n {t('checkout.common.actions.saveAndPublish')}\n </Button>\n ) : null}\n </>\n ) : null}\n entityId={entityId}\n customFieldsetBindings={{ [entityId]: { valueKey: 'customFieldsetCode' } }}\n initialValues={initialValues}\n contentHeader={lockedNotice}\n readOnly={isLocked}\n readOnlyOverlay={lockedOverlay}\n deleteVisible={Boolean(recordId)}\n onSubmit={async (values, context) => {\n const submitIntent = context?.submitter?.value === 'preview'\n ? 'preview'\n : context?.submitter?.value === 'publish'\n ? 'publish'\n : 'save'\n const shouldOpenPreview = submitIntent === 'preview'\n const payload = {\n ...values,\n status: submitIntent === 'publish' ? 'active' : values.status,\n fixedPriceAmount: toSubmittedAmount(values.fixedPriceAmount, locale),\n fixedPriceOriginalAmount: toSubmittedAmount(values.fixedPriceOriginalAmount, locale),\n customAmountMin: toSubmittedAmount(values.customAmountMin, locale),\n customAmountMax: toSubmittedAmount(values.customAmountMax, locale),\n priceListItems: normalizePriceListItems(values.priceListItems).map((item) => ({\n ...item,\n amount: toSubmittedAmount(item.amount, locale) ?? Number.NaN,\n })),\n customFields: collectCustomFieldValues(values),\n }\n const endpoint = `/api/checkout/${mode === 'link' ? 'links' : 'templates'}${recordId ? `/${encodeURIComponent(recordId)}` : ''}`\n let response: { id?: string; slug?: string; ok?: boolean }\n try {\n response = await withScopedApiRequestHeaders(\n recordId ? buildOptimisticLockHeader(readString(initialValues?.updatedAt) || null) : {},\n () => readApiResultOrThrow<{ id?: string; slug?: string; ok?: boolean }>(endpoint, {\n method: recordId ? 'PUT' : 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(payload),\n }),\n )\n } catch (error) {\n if (surfaceRecordConflict(error, t)) return\n if (recordId && isRecordNotFoundError(error)) {\n setNotFound(true)\n return\n }\n throw error\n }\n const targetId = recordId ?? (typeof response?.id === 'string' ? response.id : null)\n const logoAttachmentId = readString(values.logoAttachmentId)\n if (\n !recordId &&\n targetId &&\n logoAttachmentId &&\n logoAttachmentId !== initialLogoAttachmentIdRef.current\n ) {\n await apiCall('/api/attachments/transfer', {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n entityId,\n attachmentIds: [logoAttachmentId],\n fromRecordId: attachmentDraftRecordId,\n toRecordId: targetId,\n }),\n })\n }\n if (shouldOpenPreview) {\n if (mode === 'link') {\n const savedSlug = typeof response?.slug === 'string' && response.slug.trim().length > 0\n ? response.slug.trim()\n : readString(values.slug).trim() || readString(initialValues.slug).trim()\n if (savedSlug) {\n window.open(`/pay/${encodeURIComponent(savedSlug)}?preview=true`, '_blank', 'noopener,noreferrer')\n return\n }\n } else if (targetId) {\n window.open(\n `/backend/checkout/templates/${encodeURIComponent(targetId)}/preview`,\n '_blank',\n 'noopener,noreferrer',\n )\n return\n }\n }\n window.location.href = mode === 'link'\n ? `/backend/checkout/pay-links?flash=${encodeURIComponent(\n t(submitIntent === 'publish' ? 'checkout.admin.payLinks.flash.published' : 'checkout.common.flash.saved'),\n )}&type=success`\n : `/backend/checkout/templates?flash=${encodeURIComponent(t('checkout.common.flash.saved'))}&type=success`\n }}\n onDelete={recordId ? async () => {\n try {\n await withScopedApiRequestHeaders(\n buildOptimisticLockHeader(readString(initialValues?.updatedAt) || null),\n () => apiCallOrThrow(`/api/checkout/${mode === 'link' ? 'links' : 'templates'}/${encodeURIComponent(recordId)}`, { method: 'DELETE' }),\n )\n } catch (error) {\n if (surfaceRecordConflict(error, t)) return\n if (isRecordNotFoundError(error)) {\n setNotFound(true)\n return\n }\n throw error\n }\n window.location.href = mode === 'link'\n ? `/backend/checkout/pay-links?flash=${encodeURIComponent(t('checkout.common.flash.deleted'))}&type=success`\n : `/backend/checkout/templates?flash=${encodeURIComponent(t('checkout.common.flash.deleted'))}&type=success`\n } : undefined}\n />\n ) : null}\n </PageBody>\n </Page>\n )\n}\n\nexport default LinkTemplateForm\n"],
|
|
5
|
+
"mappings": ";AA8VQ,SAymBA,UAvmBc,KAFd;AA5VR,YAAY,WAAW;AACvB,SAAS,uBAAuB;AAChC,SAAS,MAAM,iBAAmC;AAClD,SAAS,yBAAyB;AAClC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,eAAe;AACxB,SAAS,gBAAsF;AAC/F,SAAS,qBAA0C;AACnD,SAAS,MAAM,gBAAgB;AAC/B,SAAS,2BAA2B;AACpC,SAAS,+BAA+B;AACxC,SAAS,SAAS,gBAAgB,sBAAsB,mCAAmC;AAC3F,SAAS,iCAAiC;AAC1C,SAAS,6BAA6B;AACtC,SAAS,gCAAgC;AACzC,SAAS,cAAc;AACvB,SAAS,mBAAmB;AAC5B,SAAS,aAAa;AACtB,SAAS,qBAAqB;AAC9B,SAAS,aAAa;AACtB,SAAS,OAAO,kBAAkB,kBAAkB;AACpD,SAAS,MAAM,aAAa,UAAU,mBAAmB;AACzD,SAAS,2BAA2B;AACpC,SAAS,iDAAiD;AAE1D,SAAS,iDAAiD;AAC1D,SAAS,sCAAsC;AAC/C,SAAS,6BAA6B;AACtC,SAAS,8BAA8B;AACvC,SAAS,4BAA4B;AACrC,SAAS,6BAA6B;AACtC,SAAS,uBAAuB;AAyChC,MAAM,iBAAiB;AAAA,EACrB,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,iBAAiB;AACnB;AAEA,MAAM,2BAA2B;AACjC,MAAM,8BAA8B;AAEpC,SAAS,SAAS,OAAkD;AAClE,SAAO,QAAQ,KAAK,KAAK,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,WAAW,OAAwB;AAC1C,SAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;AAEA,SAAS,qBAAqB,OAAwB;AACpD,MAAI,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,EAAG,QAAO,OAAO,KAAK;AAC5E,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,SAAO;AACT;AAKO,SAAS,kBAAkB,OAAgB,QAAgC;AAChF,MAAI,OAAO,UAAU,SAAU,QAAO,OAAO,SAAS,KAAK,IAAI,QAAQ;AACvE,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,CAAC,MAAM,KAAK,EAAG,QAAO;AAC1B,SAAO,kBAAkB,OAAO,MAAM;AACxC;AAEA,SAAS,YAAY,OAAgB,WAAW,OAAgB;AAC9D,SAAO,OAAO,UAAU,YAAY,QAAQ;AAC9C;AAEA,SAAS,2BAA2B,GAAiD;AACnF,SAAO,0CAA0C,CAAC,EAAE,IAAI,CAAC,WAAW;AAAA,IAClE,GAAG;AAAA,IACH,aAAa,OAAO,MAAM,gBAAgB,WAAW,MAAM,cAAc;AAAA,EAC3E,EAAE;AACJ;AAEA,SAAS,8BAAmD;AAC1D,SAAO;AAAA,IACL,OAAO,EAAE,OAAO,IAAI,UAAU,IAAI,UAAU,MAAM;AAAA,IAClD,eAAe,EAAE,OAAO,IAAI,UAAU,IAAI,UAAU,MAAM;AAAA,EAC5D;AACF;AAEA,SAAS,oBAAoB,GAA6B;AACxD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,UAAU;AAAA,IACV,aAAa;AAAA,IACb,MAAM;AAAA,IACN,kBAAkB;AAAA,IAClB,SAAS;AAAA,IACT,GAAG;AAAA,IACH,WAAW;AAAA,IACX,2BAA2B;AAAA,IAC3B,aAAa;AAAA,IACb,kBAAkB;AAAA,IAClB,wBAAwB;AAAA,IACxB,uBAAuB;AAAA,IACvB,0BAA0B;AAAA,IAC1B,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,0BAA0B;AAAA,IAC1B,gBAAgB,CAAC;AAAA,IACjB,oBAAoB;AAAA,IACpB,iBAAiB,CAAC;AAAA,IAClB,YAAY;AAAA,IACZ,oBAAoB;AAAA,IACpB,wBAAwB;AAAA,IACxB,sBAAsB,2BAA2B,CAAC;AAAA,IAClD,gBAAgB,4BAA4B;AAAA,IAC5C,QAAQ;AAAA,IACR,gBAAgB;AAAA,IAChB,UAAU;AAAA,IACV,cAAc;AAAA,IACd,gBAAgB;AAAA,IAChB,aAAa;AAAA,IACb,eAAe;AAAA,IACf,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,qBAAqB;AAAA,IACrB,kBAAkB;AAAA,IAClB,kBAAkB;AAAA,IAClB,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,EAClB;AACF;AAEA,SAAS,wBAAwB,OAAuC;AACtE,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO,CAAC;AACnC,SAAO,MACJ,IAAI,CAAC,SAAS;AACb,QAAI,CAAC,SAAS,IAAI,EAAG,QAAO;AAC5B,UAAM,KAAK,WAAW,KAAK,EAAE,EAAE,KAAK;AACpC,UAAM,cAAc,WAAW,KAAK,WAAW;AAG/C,UAAM,SACJ,OAAO,KAAK,WAAW,YAAY,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;AACrF,UAAM,eAAe,WAAW,KAAK,YAAY,EAAE,KAAK,EAAE,YAAY;AACtE,WAAO;AAAA,MACL,IAAI,MAAM,QAAQ,KAAK,IAAI,CAAC;AAAA,MAC5B;AAAA,MACA;AAAA,MACA,cAAc,gBAAgB;AAAA,IAChC;AAAA,EACF,CAAC,EACA,OAAO,CAAC,SAAsC,SAAS,IAAI;AAChE;AAEA,SAAS,wBAAwB,OAAgB,GAAiD;AAChG,MAAI,CAAC,MAAM,QAAQ,KAAK,EAAG,QAAO,2BAA2B,CAAC;AAC9D,SAAO,MAAM,OAAuC,CAAC,QAAQ,OAAO,UAAU;AAC5E,QAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,UAAM,MAAM,WAAW,MAAM,GAAG,EAAE,KAAK;AACvC,UAAM,QAAQ,WAAW,MAAM,KAAK,EAAE,KAAK;AAC3C,UAAM,OAAO,WAAW,MAAM,IAAI;AAClC,QAAI,CAAC,OAAO,CAAC,MAAO,QAAO;AAC3B,QAAI,CAAC,CAAC,QAAQ,aAAa,WAAW,UAAU,OAAO,EAAE,SAAS,IAAI,EAAG,QAAO;AAChF,UAAM,UAAU,MAAM,QAAQ,MAAM,OAAO,IACvC,MAAM,QAAQ,OAAgD,CAAC,cAAc,WAAW;AACtF,UAAI,CAAC,SAAS,MAAM,EAAG,QAAO;AAC9B,YAAM,YAAY,WAAW,OAAO,KAAK,EAAE,KAAK;AAChD,YAAM,YAAY,WAAW,OAAO,KAAK,EAAE,KAAK;AAChD,UAAI,CAAC,aAAa,CAAC,UAAW,QAAO;AACrC,mBAAa,KAAK,EAAE,OAAO,WAAW,OAAO,UAAU,CAAC;AACxD,aAAO;AAAA,IACT,GAAG,CAAC,CAAC,IACL,CAAC;AACL,WAAO,KAAK;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAU,YAAY,MAAM,QAAQ;AAAA,MACpC,OAAO,YAAY,MAAM,KAAK;AAAA,MAC9B,aAAa,WAAW,MAAM,WAAW,EAAE,KAAK,KAAK;AAAA,MACrD;AAAA,MACA,WAAW,OAAO,MAAM,cAAc,WAAW,MAAM,YAAY;AAAA,IACrE,CAAC;AACD,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AACP;AAEA,SAAS,mBAAmB,OAAgB,GAAiD;AAC3F,SAAO,MAAM,QAAQ,KAAK,IAAI,QAA0C,2BAA2B,CAAC;AACtG;AAEA,SAAS,wBAAwB,OAAqC;AACpE,QAAM,WAAW,4BAA4B;AAC7C,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,QAAM,oBAAoB,CAAC,KAAc,aAAqD;AAC5F,QAAI,CAAC,SAAS,GAAG,EAAG,QAAO;AAC3B,WAAO;AAAA,MACL,OAAO,WAAW,IAAI,KAAK;AAAA,MAC3B,UAAU,WAAW,IAAI,QAAQ;AAAA,MACjC,UAAU,YAAY,IAAI,QAAQ;AAAA,IACpC;AAAA,EACF;AACA,SAAO;AAAA,IACL,OAAO,kBAAkB,MAAM,OAAO,SAAS,KAAK;AAAA,IACpD,eAAe,kBAAkB,MAAM,eAAe,SAAS,aAAa;AAAA,EAC9E;AACF;AAEA,SAAS,oBAAoB,OAAsC,GAA6B;AAC9F,QAAM,WAAW,oBAAoB,CAAC;AACtC,QAAM,SAAS,SAAS,KAAK,IAAI,QAAQ,CAAC;AAC1C,QAAM,eAAe,SAAS,OAAO,YAAY,IAAI,OAAO,eAAe,CAAC;AAE5E,QAAM,4BAA4B,OAAO;AAAA,IACvC,OAAO,QAAQ,YAAY,EAAE,IAAI,CAAC,CAAC,KAAK,UAAU,MAAM,CAAC,MAAM,GAAG,IAAI,UAAU,CAAC;AAAA,EACnF;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,kBAAkB,WAAW,OAAO,gBAAgB,EAAE,KAAK,KAAK;AAAA,IAChE,SAAS,WAAW,OAAO,OAAO,EAAE,KAAK,KAAK;AAAA,IAC9C,cAAc,WAAW,OAAO,YAAY,EAAE,KAAK,KAAK,SAAS;AAAA,IACjE,gBAAgB,WAAW,OAAO,cAAc,EAAE,KAAK,KAAK,SAAS;AAAA,IACrE,iBAAiB,WAAW,OAAO,eAAe,EAAE,KAAK,KAAK,SAAS;AAAA,IACvE,oBAAoB,WAAW,OAAO,kBAAkB,EAAE,KAAK;AAAA,IAC/D,iBAAiB,SAAS,OAAO,eAAe,IAAI,OAAO,kBAAkB,CAAC;AAAA,IAC9E,oBAAoB,WAAW,OAAO,kBAAkB,EAAE,KAAK,KAAK;AAAA,IACpE,wBAAwB,YAAY,OAAO,wBAAwB,IAAI;AAAA,IACvE,sBAAsB,wBAAwB,OAAO,sBAAsB,CAAC;AAAA,IAC5E,gBAAgB,wBAAwB,OAAO,cAAc;AAAA,IAC7D,gBAAgB,wBAAwB,OAAO,cAAc;AAAA,IAC7D,wBAAwB,WAAW,OAAO,sBAAsB,EAAE,KAAK,EAAE,YAAY,KAAK;AAAA,IAC1F,0BAA0B,WAAW,OAAO,wBAAwB,EAAE,KAAK,EAAE,YAAY,KAAK;AAAA,IAC9F,gBAAgB,YAAY,OAAO,gBAAgB,IAAI;AAAA,IACvD,kBAAkB,YAAY,OAAO,kBAAkB,IAAI;AAAA,IAC3D,gBAAgB,YAAY,OAAO,gBAAgB,IAAI;AAAA,EACzD;AACF;AAEA,SAAS,UAAU,QAAgC,MAAkC;AACnF,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI,OAAO,IAAI,EAAG,QAAO,OAAO,IAAI;AACpC,QAAM,SAAS,GAAG,IAAI;AACtB,QAAM,cAAc,OAAO,QAAQ,MAAM,EAAE,KAAK,CAAC,CAAC,GAAG,MAAM,IAAI,WAAW,MAAM,CAAC;AACjF,SAAO,cAAc,CAAC;AACxB;AAEA,SAAS,gBAAgB,QAAgC,MAAkC;AACzF,MAAI,CAAC,KAAM,QAAO;AAClB,SAAO,OAAO,IAAI;AACpB;AAEA,SAAS,aAAa,WAAmC,OAAqC;AAC5F,aAAW,QAAQ,OAAO;AACxB,UAAM,QAAQ,UAAU,QAAQ,IAAI;AACpC,QAAI,MAAO,QAAO;AAAA,EACpB;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,UAA2C;AACnE,QAAM,QAAQ,OAAO,SAAS,UAAU,WAAW,SAAS,MAAM,KAAK,IAAI;AAC3E,QAAM,WAAW,OAAO,SAAS,uBAAuB,WAAW,SAAS,mBAAmB,KAAK,IAAI;AACxG,QAAM,QAAQ,CAAC,OAAO,QAAQ,EAAE,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC;AAChE,SAAO;AAAA,IACL,OAAO,SAAS;AAAA,IAChB,OAAO,SAAS;AAAA,IAChB,aAAa,MAAM,SAAS,IAAI,MAAM,KAAK,UAAK,IAAI;AAAA,EACtD;AACF;AAEA,SAAS,oBAAoB,OAAoC;AAC/D,SAAO,QAAQ,qDAAqD;AACtE;AAEA,SAAS,aAAa;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMG;AACD,SACE,qBAAC,SAAI,WAAU,aACb;AAAA,yBAAC,SAAI,WAAU,aACb;AAAA,2BAAC,SAAM,WAAU,SACd;AAAA;AAAA,QACA,WAAW,oBAAC,UAAK,WAAU,oBAAmB,gBAAE,IAAU;AAAA,SAC7D;AAAA,MACC,OAAO,oBAAC,OAAE,WAAU,iCAAiC,gBAAK,IAAO;AAAA,MACjE,QAAQ,oBAAC,OAAE,WAAU,4BAA4B,iBAAM,IAAO;AAAA,OACjE;AAAA,IACC;AAAA,KACH;AAEJ;AAEA,SAAS,WAAW;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,QAAM,cAAc,sBAAsB,KAAK,KAAK,IAAI,QAAQ;AAChE,SACE,oBAAC,gBAAa,OAAc,OAC1B,+BAAC,SAAI,WAAU,2BACb;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,OAAO;AAAA,QACP,UAAU,CAAC,SAAS,SAAS,KAAK,YAAY,CAAC;AAAA,QAC/C,cAAY;AAAA;AAAA,IACd;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,UAAU,CAAC,UAAU,SAAS,MAAM,OAAO,MAAM,YAAY,CAAC;AAAA,QAC9D,aAAY;AAAA,QACZ,WAAW,QAAQ,WAAW,oBAAoB,KAAK,CAAC,KAAK;AAAA,QAC7D,gBAAc,QAAQ,KAAK;AAAA;AAAA,IAC7B;AAAA,KACF,GACF;AAEJ;AAEO,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,IAAI,KAAK;AACf,QAAM,QAAQ,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC;AAE9C,QAAM,aAAa,MAAM;AAAA,IACvB,CAAC,OAAe,UAAwC;AACtD,eAAS,MAAM,IAAI,CAAC,MAAM,iBAAkB,iBAAiB,QAAQ,EAAE,GAAG,MAAM,GAAG,MAAM,IAAI,IAAK,CAAC;AAAA,IACrG;AAAA,IACA,CAAC,OAAO,QAAQ;AAAA,EAClB;AAEA,QAAM,UAAU,MAAM,YAAY,MAAM;AACtC,aAAS;AAAA,MACP,GAAG;AAAA,MACH;AAAA,QACE,IAAI,QAAQ,MAAM,SAAS,CAAC;AAAA,QAC5B,aAAa;AAAA,QACb,QAAQ;AAAA,QACR,cAAc,MAAM,CAAC,GAAG,gBAAgB;AAAA,MAC1C;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,OAAO,QAAQ,CAAC;AAEpB,SACE,qBAAC,SAAI,WAAU,aACb;AAAA,wBAAC,SAAM,QAAO,eACZ,8BAAC,oBACE,YAAE,4DAA4D,GACjE,GACF;AAAA,IACC,QAAQ,oBAAC,OAAE,WAAU,4BAA4B,iBAAM,IAAO;AAAA,IAE/D,oBAAC,SAAI,WAAU,oEACZ,gBAAM,SAAS,IACd,oBAAC,SAAI,WAAU,mBACb,+BAAC,WAAM,WAAU,oCACf;AAAA,0BAAC,WAAM,WAAU,wBACf,+BAAC,QAAG,WAAU,iFACZ;AAAA,4BAAC,QAAG,WAAU,qBAAqB,YAAE,sDAAsD,GAAE;AAAA,QAC7F,oBAAC,QAAG,WAAU,aAAa,YAAE,yDAAyD,GAAE;AAAA,QACxF,oBAAC,QAAG,WAAU,qBAAqB,YAAE,oDAAoD,GAAE;AAAA,QAC3F,oBAAC,QAAG,WAAU,qBAAqB,YAAE,sDAAsD,GAAE;AAAA,QAC7F,oBAAC,QAAG,WAAU,kCAAkC,YAAE,qDAAqD,GAAE;AAAA,SAC3G,GACF;AAAA,MACA,oBAAC,WAAM,WAAU,6BACd,gBAAM,IAAI,CAAC,MAAM,UAChB,qBAAC,QAA+B,WAAU,aACxC;AAAA,4BAAC,QAAG,WAAU,aACZ;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,KAAK;AAAA,YACZ,UAAU,CAAC,UAAU,WAAW,OAAO,EAAE,IAAI,MAAM,OAAO,MAAM,CAAC;AAAA,YACjE,aAAa,EAAE,2DAA2D;AAAA,YAC1E,cAAY,EAAE,qDAAqD,EAAE,OAAO,QAAQ,EAAE,CAAC;AAAA,YACvF,WAAU;AAAA;AAAA,QACZ,GACF;AAAA,QACA,oBAAC,QAAG,WAAU,aACZ;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,KAAK;AAAA,YACZ,UAAU,CAAC,UAAU,WAAW,OAAO,EAAE,aAAa,MAAM,OAAO,MAAM,CAAC;AAAA,YAC1E,aAAa,EAAE,8DAA8D;AAAA,YAC7E,cAAY,EAAE,wDAAwD,EAAE,OAAO,QAAQ,EAAE,CAAC;AAAA,YAC1F,WAAU;AAAA;AAAA,QACZ,GACF;AAAA,QACA,oBAAC,QAAG,WAAU,aACZ;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAU;AAAA,YACV,OAAO,qBAAqB,KAAK,MAAM;AAAA,YACvC,UAAU,CAAC,UACT,WAAW,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,cAKhB,QAAQ,MAAM,OAAO;AAAA,YACvB,CAAC;AAAA,YAEH,aAAY;AAAA,YACZ,cAAY,EAAE,mDAAmD,EAAE,OAAO,QAAQ,EAAE,CAAC;AAAA,YACrF,WAAU;AAAA;AAAA,QACZ,GACF;AAAA,QACA,oBAAC,QAAG,WAAU,aACZ;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,KAAK;AAAA,YACZ,UAAU,CAAC,SAAS,WAAW,OAAO,EAAE,cAAc,KAAK,CAAC;AAAA,YAC5D,aAAa,EAAE,qCAAqC;AAAA;AAAA,QACtD,GACF;AAAA,QACA,oBAAC,QAAG,WAAU,wBACZ;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,SAAS,MAAM,SAAS,MAAM,OAAO,CAAC,GAAG,iBAAiB,iBAAiB,KAAK,CAAC;AAAA,YAEjF;AAAA,kCAAC,UAAO,WAAU,gBAAe;AAAA,cAChC,EAAE,gCAAgC;AAAA;AAAA;AAAA,QACrC,GACF;AAAA,WAvDO,GAAG,KAAK,EAAE,IAAI,KAAK,EAwD5B,CACD,GACH;AAAA,OACF,GACF,IAEA,oBAAC,SAAI,WAAU,aACb,8BAAC,SAAM,QAAO,eACZ,8BAAC,oBACE,YAAE,mDAAmD,GACxD,GACF,GACF,GAEJ;AAAA,IAEA,qBAAC,UAAO,MAAK,UAAS,SAAQ,WAAU,MAAK,MAAK,SAAS,SACzD;AAAA,0BAAC,QAAK,WAAU,gBAAe;AAAA,MAC9B,EAAE,qDAAqD;AAAA,OAC1D;AAAA,KACF;AAEJ;AAEO,SAAS,eAAe,EAAE,QAAQ,UAAU,OAAO,GAAgC;AACxF,QAAM,IAAI,KAAK;AACf,QAAM,cAAc,WAAW,OAAO,WAAW,KAAK;AACtD,QAAM,mBAAmB,UAAU,QAAQ,aAAa;AACxD,QAAM,wBAAwB,UAAU,QAAQ,kBAAkB;AAClE,QAAM,0BAA0B,UAAU,QAAQ,wBAAwB;AAC1E,QAAM,gCAAgC,UAAU,QAAQ,0BAA0B;AAClF,QAAM,uBAAuB,UAAU,QAAQ,iBAAiB;AAChE,QAAM,uBAAuB,UAAU,QAAQ,iBAAiB;AAChE,QAAM,4BAA4B,UAAU,QAAQ,0BAA0B;AAC9E,QAAM,sBAAsB,UAAU,QAAQ,gBAAgB;AAE9D,SACE,qBAAC,SAAI,WAAU,aACZ;AAAA,uBAAmB,oBAAC,OAAE,WAAU,4BAA4B,4BAAiB,IAAO;AAAA,IACrF,oBAAC,SAAI,WAAU,wBACZ;AAAA,MACC,EAAE,IAAI,SAAS,OAAO,EAAE,+CAA+C,GAAG,MAAM,iBAAiB;AAAA,MACjG,EAAE,IAAI,iBAAiB,OAAO,EAAE,sDAAsD,GAAG,MAAM,YAAY;AAAA,MAC3G,EAAE,IAAI,cAAc,OAAO,EAAE,mDAAmD,GAAG,MAAM,SAAS;AAAA,IACpG,EAAE,IAAI,CAAC,SAAS;AACd,YAAM,OAAO,KAAK;AAClB,YAAM,SAAS,gBAAgB,KAAK;AACpC,aACE;AAAA,QAAC;AAAA;AAAA,UAEC,MAAK;AAAA,UACL,SAAS,SAAS,YAAY;AAAA,UAC9B,MAAK;AAAA,UACL,SAAS,MAAM,SAAS,eAAe,KAAK,EAAE;AAAA,UAE9C;AAAA,gCAAC,QAAK,WAAU,gBAAe;AAAA,YAC9B,KAAK;AAAA;AAAA;AAAA,QAPD,KAAK;AAAA,MAQZ;AAAA,IAEJ,CAAC,GACH;AAAA,IAEC,gBAAgB,UACf,qBAAC,SAAI,WAAU,6BACb;AAAA,0BAAC,gBAAa,OAAO,EAAE,iDAAiD,GAAG,OAAO,uBAAuB,UAAQ,MAC/G;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,OAAO,qBAAqB,OAAO,gBAAgB;AAAA,UACnD,UAAU,CAAC,UAAU,SAAS,oBAAoB,MAAM,OAAO,KAAK;AAAA,UACpE,aAAY;AAAA,UACZ,WAAW,oBAAoB,qBAAqB;AAAA,UACpD,gBAAc,QAAQ,qBAAqB;AAAA;AAAA,MAC7C,GACF;AAAA,MAEA,oBAAC,gBAAa,OAAO,EAAE,mDAAmD,GAAG,OAAO,yBAAyB,UAAQ,MACnH;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,WAAW,OAAO,sBAAsB,KAAK;AAAA,UACpD,UAAU,CAAC,SAAS,SAAS,0BAA0B,IAAI;AAAA,UAC3D,aAAa,EAAE,qCAAqC;AAAA;AAAA,MACtD,GACF;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,EAAE,yDAAyD;AAAA,UAClE,MAAM,EAAE,wDAAwD;AAAA,UAChE,OAAO;AAAA,UAEP;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,OAAO,qBAAqB,OAAO,wBAAwB;AAAA,cAC3D,UAAU,CAAC,UAAU,SAAS,4BAA4B,MAAM,OAAO,KAAK;AAAA,cAC5E,aAAY;AAAA,cACZ,WAAW,oBAAoB,6BAA6B;AAAA,cAC5D,gBAAc,QAAQ,6BAA6B;AAAA;AAAA,UACrD;AAAA;AAAA,MACF;AAAA,MAEA,oBAAC,SAAI,WAAU,kBACb,+BAAC,WAAM,WAAU,4FACf;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS,YAAY,OAAO,uBAAuB,IAAI;AAAA,YACvD,UAAU,CAAC,UAAU,SAAS,yBAAyB,MAAM,OAAO,OAAO;AAAA;AAAA,QAC7E;AAAA,QACC,EAAE,sDAAsD;AAAA,SAC3D,GACF;AAAA,OACF,IACE;AAAA,IAEH,gBAAgB,kBACf,qBAAC,SAAI,WAAU,6BACb;AAAA,0BAAC,gBAAa,OAAO,EAAE,wDAAwD,GAAG,OAAO,sBAAsB,UAAQ,MACrH;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,OAAO,qBAAqB,OAAO,eAAe;AAAA,UAClD,UAAU,CAAC,UAAU,SAAS,mBAAmB,MAAM,OAAO,KAAK;AAAA,UACnE,aAAY;AAAA,UACZ,WAAW,oBAAoB,oBAAoB;AAAA,UACnD,gBAAc,QAAQ,oBAAoB;AAAA;AAAA,MAC5C,GACF;AAAA,MAEA,oBAAC,gBAAa,OAAO,EAAE,wDAAwD,GAAG,OAAO,sBAAsB,UAAQ,MACrH;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,OAAO,qBAAqB,OAAO,eAAe;AAAA,UAClD,UAAU,CAAC,UAAU,SAAS,mBAAmB,MAAM,OAAO,KAAK;AAAA,UACnE,aAAY;AAAA,UACZ,WAAW,oBAAoB,oBAAoB;AAAA,UACnD,gBAAc,QAAQ,oBAAoB;AAAA;AAAA,MAC5C,GACF;AAAA,MAEA,oBAAC,gBAAa,OAAO,EAAE,mDAAmD,GAAG,OAAO,2BAA2B,UAAQ,MACrH;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,WAAW,OAAO,wBAAwB,KAAK;AAAA,UACtD,UAAU,CAAC,SAAS,SAAS,4BAA4B,IAAI;AAAA,UAC7D,aAAa,EAAE,qCAAqC;AAAA;AAAA,MACtD,GACF;AAAA,OACF,IACE;AAAA,IAEH,gBAAgB,eACf;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,wBAAwB,OAAO,cAAc;AAAA,QACpD,UAAU,CAAC,SAAS,SAAS,kBAAkB,IAAI;AAAA,QACnD,OAAO;AAAA;AAAA,IACT,IACE;AAAA,KACN;AAEJ;AAEA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAMG;AACD,QAAM,IAAI,KAAK;AACf,QAAM,eAAe;AAAA,IACnB,WAAW,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,IACrC,WAAW,OAAO,KAAK,IACvB,WAAW,OAAO,IAAI;AAAA,EAC5B,KAAK;AACL,QAAM,cAAc,WAAW,OAAO,IAAI;AAC1C,QAAM,eAAe,YAAY,KAAK,KAAK;AAC3C,QAAM,oBAAoB,WAAW,OAAO,UAAU,EAAE,KAAK;AAC7D,QAAM,YAAY,UAAU,QAAQ,MAAM;AAC1C,QAAM,aAAa,UAAU,QAAQ,OAAO;AAC5C,QAAM,gBAAgB,UAAU,QAAQ,UAAU;AAClD,QAAM,mBAAmB,UAAU,QAAQ,aAAa;AACxD,QAAM,YAAY,UAAU,QAAQ,MAAM;AAC1C,QAAM,gBAAgB,UAAU,QAAQ,YAAY;AAEpD,SACE,qBAAC,SAAI,WAAU,aACZ;AAAA,aAAS,SACR;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,mDAAmD;AAAA,QAC5D,MAAM,EAAE,kDAAkD;AAAA,QAC1D,OAAO;AAAA,QAEP,+BAAC,SAAI,WAAU,aACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAO;AAAA,cACP,aAAa;AAAA,cACb,iBAAiB;AAAA,cACjB,cAAc,CAAC,UAAU,gBAAgB,KAAK,CAAC,WAAW,OAAO,UAAU,KAAK,GAAG,SAAS;AAAA,cAC5F,oBAAoB,CAAC,UAAU,gBAAgB,KAAK,CAAC,WAAW,OAAO,UAAU,KAAK,GAAG;AAAA,cACzF,UAAU,CAAC,cAAc;AACvB,sBAAM,aAAa,UAAU,KAAK;AAClC,yBAAS,cAAc,cAAc,IAAI;AACzC,qBAAK,cAAc,cAAc,IAAI;AAAA,cACvC;AAAA,cACA,aAAa,EAAE,yDAAyD;AAAA,cACxE,UAAU;AAAA,cACV,mBAAmB;AAAA;AAAA,UACrB;AAAA,UACA,qBAAC,SAAI,WAAU,qCACb;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,SAAQ;AAAA,gBACR,UAAU,sBAAsB,kBAAkB,WAAW;AAAA,gBAC7D,SAAS,MAAM;AACb,2BAAS,cAAc,IAAI;AAC3B,uBAAK,cAAc,IAAI;AAAA,gBACzB;AAAA,gBAEC,YAAE,yDAAyD;AAAA;AAAA,YAC9D;AAAA,YACC,qBACC,oBAAC,OAAE,WAAU,iCACV,YAAE,2DAA2D,GAChE,IAEA,oBAAC,OAAE,WAAU,iCACV,YAAE,+DAA+D,GACpE;AAAA,aAEJ;AAAA,WACF;AAAA;AAAA,IACF,IACE;AAAA,IAEJ,oBAAC,gBAAa,OAAO,EAAE,+CAA+C,GAAG,OAAO,WAAW,UAAQ,MACjG;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,WAAW,OAAO,IAAI;AAAA,QAC7B,UAAU,CAAC,UAAU,SAAS,QAAQ,MAAM,OAAO,KAAK;AAAA,QACxD,aAAa,EAAE,qDAAqD;AAAA,QACpE,WAAW,oBAAoB,SAAS;AAAA,QACxC,gBAAc,QAAQ,SAAS;AAAA;AAAA,IACjC,GACF;AAAA,IAEA,oBAAC,gBAAa,OAAO,EAAE,gDAAgD,GAAG,OAAO,YAC/E;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,WAAW,OAAO,KAAK;AAAA,QAC9B,UAAU,CAAC,UAAU,SAAS,SAAS,MAAM,OAAO,KAAK;AAAA,QACzD,aAAa,EAAE,sDAAsD;AAAA,QACrE,WAAW,oBAAoB,UAAU;AAAA,QACzC,gBAAc,QAAQ,UAAU;AAAA;AAAA,IAClC,GACF;AAAA,IAEA,oBAAC,gBAAa,OAAO,EAAE,mDAAmD,GAAG,OAAO,eAClF;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,WAAW,OAAO,QAAQ;AAAA,QACjC,UAAU,CAAC,UAAU,SAAS,YAAY,MAAM,OAAO,KAAK;AAAA,QAC5D,aAAa,EAAE,yDAAyD;AAAA,QACxE,WAAW,oBAAoB,aAAa;AAAA,QAC5C,gBAAc,QAAQ,aAAa;AAAA;AAAA,IACrC,GACF;AAAA,IAEA,oBAAC,gBAAa,OAAO,EAAE,sDAAsD,GAAG,MAAM,EAAE,qDAAqD,GAAG,OAAO,kBACrJ;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,WAAW,OAAO,WAAW;AAAA,QACpC,UAAU,CAAC,SAAS,SAAS,eAAe,IAAI;AAAA,QAChD,mBAAiB;AAAA,QACjB,QAAQ;AAAA,QACR,aAAa,EAAE,4DAA4D;AAAA;AAAA,IAC7E,GACF;AAAA,IAEC,SAAS,SACR,oBAAC,gBAAa,OAAO,EAAE,+CAA+C,GAAG,MAAM,EAAE,8CAA8C,GAAG,OAAO,WACvI,+BAAC,SAAI,WAAU,aACb;AAAA,2BAAC,SAAI,WAAU,cACb;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,YACP,UAAU,CAAC,UAAU,SAAS,QAAQ,MAAM,OAAO,KAAK;AAAA,YACxD,aAAa,EAAE,qDAAqD;AAAA,YACpE,WAAW,oBAAoB,SAAS;AAAA,YACxC,gBAAc,QAAQ,SAAS;AAAA;AAAA,QACjC;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,SAAS,MAAM,SAAS,QAAQ,YAAY;AAAA,YAE5C;AAAA,kCAAC,YAAS,WAAU,gBAAe;AAAA,cAClC,EAAE,wDAAwD;AAAA;AAAA;AAAA,QAC7D;AAAA,SACF;AAAA,MACA,oBAAC,OAAE,WAAU,iCAAiC,YAAE,iDAAiD,EAAE,MAAM,aAAa,CAAC,GAAE;AAAA,OAC3H,GACF,IACE;AAAA,KACN;AAEJ;AAEA,SAAS,kBAAkB;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAmF;AACjF,QAAM,IAAI,KAAK;AACf,QAAM,YAAY,aAAa,QAAQ,oBAAoB,SAAS;AACpE,QAAM,oBAAoB,UAAU,QAAQ,cAAc;AAC1D,QAAM,sBAAsB,UAAU,QAAQ,gBAAgB;AAC9D,QAAM,uBAAuB,UAAU,QAAQ,iBAAiB;AAChE,QAAM,iBAAiB,UAAU,QAAQ,WAAW;AACpD,QAAM,2BAA2B,UAAU,QAAQ,2BAA2B;AAE9E,SACE,qBAAC,SAAI,WAAU,aACb;AAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,UAAU;AAAA,QACV,cAAc,WAAW,OAAO,gBAAgB,KAAK;AAAA,QACrD,SAAS,WAAW,OAAO,OAAO,KAAK;AAAA,QACvC,OAAO;AAAA,QACP,UAAU,CAAC,SAAS;AAClB,mBAAS,oBAAoB,KAAK,gBAAgB;AAClD,mBAAS,WAAW,KAAK,OAAO;AAAA,QAClC;AAAA;AAAA,IACF;AAAA,IAEA,qBAAC,SAAI,WAAU,aACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,EAAE,0DAA0D;AAAA,UACnE,OAAO,WAAW,OAAO,YAAY,KAAK,eAAe;AAAA,UACzD,UAAU,CAAC,SAAS,SAAS,gBAAgB,IAAI;AAAA,UACjD,OAAO;AAAA;AAAA,MACT;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,EAAE,4DAA4D;AAAA,UACrE,OAAO,WAAW,OAAO,cAAc,KAAK,eAAe;AAAA,UAC3D,UAAU,CAAC,SAAS,SAAS,kBAAkB,IAAI;AAAA,UACnD,OAAO;AAAA;AAAA,MACT;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,EAAE,6DAA6D;AAAA,UACtE,OAAO,WAAW,OAAO,eAAe,KAAK,eAAe;AAAA,UAC5D,UAAU,CAAC,SAAS,SAAS,mBAAmB,IAAI;AAAA,UACpD,OAAO;AAAA;AAAA,MACT;AAAA,OACF;AAAA,IAEA,oBAAC,gBAAa,OAAO,EAAE,uDAAuD,GAAG,OAAO,gBACtF;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,iBACP,4DAA4D,oBAAoB,cAAc,CAAC,KAC/F;AAAA,QACJ,OAAO,WAAW,OAAO,SAAS,KAAK;AAAA,QACvC,UAAU,CAAC,UAAU,SAAS,aAAa,MAAM,OAAO,KAAK;AAAA,QAC7D,gBAAc,QAAQ,cAAc;AAAA,QAEpC;AAAA,8BAAC,YAAO,OAAM,QAAQ,YAAE,sDAAsD,GAAE;AAAA,UAChF,oBAAC,YAAO,OAAM,SAAS,YAAE,uDAAuD,GAAE;AAAA,UAClF,oBAAC,YAAO,OAAM,QAAQ,YAAE,sDAAsD,GAAE;AAAA;AAAA;AAAA,IAClF,GACF;AAAA,IAEA,qBAAC,WAAM,WAAU,4FACf;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS,YAAY,OAAO,yBAAyB;AAAA,UACrD,UAAU,CAAC,UAAU,SAAS,6BAA6B,MAAM,OAAO,OAAO;AAAA;AAAA,MACjF;AAAA,MACC,EAAE,iEAAiE;AAAA,OACtE;AAAA,IACC,2BAA2B,oBAAC,OAAE,WAAU,4BAA4B,oCAAyB,IAAO;AAAA,KACvG;AAEJ;AAEA,SAAS,eAAe,EAAE,QAAQ,UAAU,QAAQ,UAAU,GAAsE;AAClI,QAAM,IAAI,KAAK;AACf,QAAM,sBAAsB,WAAW,OAAO,kBAAkB;AAChE,QAAM,mBAAmB,UAAU,KAAK,CAAC,aAAa,SAAS,gBAAgB,mBAAmB;AAClG,QAAM,uBAAuB,UAAU,QAAQ,oBAAoB,MAC7D,MAAM;AACR,UAAM,aAAa,0CAA0C,gBAAgB;AAC7E,WAAO,aAAa,EAAE,UAAU,IAAI;AAAA,EACtC,GAAG;AACL,QAAM,uBAAuB,UAAU,QAAQ,iBAAiB;AAEhE,SACE,qBAAC,SAAI,WAAU,aACb;AAAA,wBAAC,gBAAa,OAAO,EAAE,0DAA0D,GAAG,OAAO,sBAAsB,UAAQ,MACvH;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,uBACP,4DAA4D,oBAAoB,oBAAoB,CAAC,KACrG;AAAA,QACJ,OAAO,WAAW,OAAO,kBAAkB;AAAA,QAC3C,UAAU,CAAC,UAAU,SAAS,sBAAsB,MAAM,OAAO,KAAK;AAAA,QACtE,gBAAc,QAAQ,oBAAoB;AAAA,QAE1C;AAAA,8BAAC,YAAO,OAAM,IAAI,YAAE,yDAAyD,GAAE;AAAA,UAC9E,UAAU,IAAI,CAAC,aACd;AAAA,YAAC;AAAA;AAAA,cAEC,OAAO,SAAS;AAAA,cAChB,UAAU,SAAS,iBAAiB;AAAA,cAEnC,mBAAS,iBAAiB,QACvB,GAAG,SAAS,KAAK,IAAI,EAAE,6DAA6D,CAAC,KACrF,SAAS;AAAA;AAAA,YANR,SAAS;AAAA,UAOhB,CACD;AAAA;AAAA;AAAA,IACH,GACF;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,aAAa,WAAW,OAAO,kBAAkB,KAAK;AAAA,QACtD,OAAO,SAAS,OAAO,eAAe,IAAI,OAAO,kBAAkB,CAAC;AAAA,QACpE,UAAU,CAAC,SAAS,SAAS,mBAAmB,IAAI;AAAA;AAAA,IACtD;AAAA,IACC,uBAAuB,oBAAC,OAAE,WAAU,4BAA4B,gCAAqB,IAAO;AAAA,KAC/F;AAEJ;AAEA,SAAS,uBAAuB,EAAE,QAAQ,UAAU,OAAO,GAAgC;AACzF,QAAM,IAAI,KAAK;AACf,QAAM,yBAAyB,YAAY,OAAO,wBAAwB,IAAI;AAC9E,QAAM,8BAA8B,UAAU,QAAQ,wBAAwB;AAC9E,QAAM,sBAAsB,+BAA+B,MAAM;AAEjE,SACE,qBAAC,SAAI,WAAU,aACb;AAAA,yBAAC,WAAM,WAAU,2FACf;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS;AAAA,UACT,UAAU,CAAC,UAAU,SAAS,0BAA0B,MAAM,OAAO,OAAO;AAAA;AAAA,MAC9E;AAAA,MACA,qBAAC,UAAK,WAAU,aACd;AAAA,6BAAC,UAAK,WAAU,uCACd;AAAA,8BAAC,UAAO,WAAU,WAAU;AAAA,UAC3B,EAAE,iDAAiD;AAAA,WACtD;AAAA,QACA,oBAAC,UAAK,WAAU,+BACb,YAAE,uDAAuD,GAC5D;AAAA,SACF;AAAA,OACF;AAAA,IACC,8BAA8B,oBAAC,OAAE,WAAU,4BAA4B,uCAA4B,IAAO;AAAA,IAE1G,yBACC,iCACE;AAAA,0BAAC,SAAM,QAAO,eACZ,8BAAC,oBACE,YAAE,8DAA8D,GACnE,GACF;AAAA,MACC,sBAAsB,oBAAC,OAAE,WAAU,4BAA4B,+BAAoB,IAAO;AAAA,MAC3F;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,mBAAmB,OAAO,sBAAsB,CAAC;AAAA,UACxD,UAAU,CAAC,SAAS,SAAS,wBAAwB,IAAI;AAAA,UACzD;AAAA;AAAA,MACF;AAAA,OACF,IAEA,oBAAC,SAAM,QAAO,eACZ,8BAAC,oBACE,YAAE,4DAA4D,GACjE,GACF;AAAA,KAEJ;AAEJ;AAEA,SAAS,aAAa,EAAE,QAAQ,UAAU,OAAO,GAAgC;AAC/E,QAAM,IAAI,KAAK;AACf,QAAM,CAAC,KAAK,MAAM,IAAI,MAAM,SAAoC,OAAO;AACvE,QAAM,iBAAiB,wBAAwB,OAAO,cAAc;AACpE,QAAM,kBAAkB,aAAa,QAAQ,8BAA8B,sBAAsB;AACjG,QAAM,qBAAqB,aAAa,QAAQ,iCAAiC,sBAAsB;AACvG,QAAM,oBAAoB,aAAa,QAAQ,sCAAsC,8BAA8B;AACnH,QAAM,uBAAuB,aAAa,QAAQ,yCAAyC,8BAA8B;AAEzH,QAAM,gBAAgB,MAAM;AAAA,IAC1B,CAAC,KAAgC,UAAuC;AACtE,eAAS,kBAAkB;AAAA,QACzB,GAAG;AAAA,QACH,CAAC,GAAG,GAAG;AAAA,UACL,GAAG,eAAe,GAAG;AAAA,UACrB,GAAG;AAAA,QACL;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IACA,CAAC,gBAAgB,QAAQ;AAAA,EAC3B;AAEA,SACE,qBAAC,SAAI,WAAU,aACb;AAAA,wBAAC,SAAM,QAAO,eACZ,8BAAC,oBACE,YAAE,wCAAwC,GAC7C,GACF;AAAA,IAEA,qBAAC,QAAK,OAAO,KAAK,eAAe,CAAC,SAAS,OAAO,IAAiC,GACjF;AAAA,2BAAC,YAAS,WAAW,0BACnB;AAAA,6BAAC,eAAY,OAAM,SAAQ,WAAW,6BACpC;AAAA,8BAAC,UAAO,WAAU,gBAAe;AAAA,UAChC,EAAE,4CAA4C;AAAA,WACjD;AAAA,QACA,qBAAC,eAAY,OAAM,iBAAgB,WAAW,6BAC5C;AAAA,8BAAC,cAAW,WAAU,gBAAe;AAAA,UACpC,EAAE,8CAA8C;AAAA,WACnD;AAAA,SACF;AAAA,MAEA,qBAAC,eAAY,OAAM,SAAQ,WAAU,aACnC;AAAA,4BAAC,gBAAa,OAAO,EAAE,mDAAmD,GAAG,OAAO,iBAClF;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,eAAe,MAAM;AAAA,YAC5B,UAAU,CAAC,UAAU,cAAc,SAAS,EAAE,OAAO,MAAM,OAAO,MAAM,CAAC;AAAA,YACzE,aAAa,EAAE,yDAAyD;AAAA,YACxE,WAAW,oBAAoB,eAAe;AAAA,YAC9C,gBAAc,QAAQ,eAAe;AAAA;AAAA,QACvC,GACF;AAAA,QACA,oBAAC,gBAAa,OAAO,EAAE,kDAAkD,GAAG,OAAO,oBACjF;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,eAAe,MAAM;AAAA,YAC5B,UAAU,CAAC,SAAS,cAAc,SAAS,EAAE,UAAU,KAAK,CAAC;AAAA,YAC7D,mBAAiB;AAAA,YACjB,QAAQ;AAAA,YACR,aAAa,EAAE,wDAAwD;AAAA;AAAA,QACzE,GACF;AAAA,QACA,qBAAC,WAAM,WAAU,mCACf;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAS,eAAe,MAAM;AAAA,cAC9B,UAAU,CAAC,UAAU,cAAc,SAAS,EAAE,UAAU,MAAM,OAAO,QAAQ,CAAC;AAAA;AAAA,UAChF;AAAA,UACC,EAAE,2DAA2D;AAAA,WAChE;AAAA,SACF;AAAA,MAEA,qBAAC,eAAY,OAAM,iBAAgB,WAAU,aAC3C;AAAA,4BAAC,gBAAa,OAAO,EAAE,qDAAqD,GAAG,OAAO,mBACpF;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,eAAe,cAAc;AAAA,YACpC,UAAU,CAAC,UAAU,cAAc,iBAAiB,EAAE,OAAO,MAAM,OAAO,MAAM,CAAC;AAAA,YACjF,aAAa,EAAE,2DAA2D;AAAA,YAC1E,WAAW,oBAAoB,iBAAiB;AAAA,YAChD,gBAAc,QAAQ,iBAAiB;AAAA;AAAA,QACzC,GACF;AAAA,QACA,oBAAC,gBAAa,OAAO,EAAE,oDAAoD,GAAG,OAAO,sBACnF;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,eAAe,cAAc;AAAA,YACpC,UAAU,CAAC,SAAS,cAAc,iBAAiB,EAAE,UAAU,KAAK,CAAC;AAAA,YACrE,mBAAiB;AAAA,YACjB,QAAQ;AAAA,YACR,aAAa,EAAE,0DAA0D;AAAA;AAAA,QAC3E,GACF;AAAA,QACA,qBAAC,WAAM,WAAU,mCACf;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAS,eAAe,cAAc;AAAA,cACtC,UAAU,CAAC,UAAU,cAAc,iBAAiB,EAAE,UAAU,MAAM,OAAO,QAAQ,CAAC;AAAA;AAAA,UACxF;AAAA,UACC,EAAE,2DAA2D;AAAA,WAChE;AAAA,SACF;AAAA,OACF;AAAA,KACF;AAEJ;AAEA,SAAS,gBAAgB,EAAE,QAAQ,UAAU,OAAO,GAAgC;AAClF,QAAM,IAAI,KAAK;AACf,QAAM,CAAC,KAAK,MAAM,IAAI,MAAM,SAAyC,SAAS;AAE9E,QAAM,SAAS;AAAA,IACb,SAAS;AAAA,MACP,UAAU;AAAA,MACV,SAAS;AAAA,MACT,kBAAkB,EAAE,8DAA8D;AAAA,MAClF,iBAAiB,EAAE,6DAA6D;AAAA,MAChF,OAAO,EAAE,iDAAiD;AAAA,IAC5D;AAAA,IACA,QAAQ;AAAA,MACN,UAAU;AAAA,MACV,SAAS;AAAA,MACT,kBAAkB,EAAE,6DAA6D;AAAA,MACjF,iBAAiB,EAAE,4DAA4D;AAAA,MAC/E,OAAO,EAAE,gDAAgD;AAAA,IAC3D;AAAA,IACA,OAAO;AAAA,MACL,UAAU;AAAA,MACV,SAAS;AAAA,MACT,kBAAkB,EAAE,4DAA4D;AAAA,MAChF,iBAAiB,EAAE,2DAA2D;AAAA,MAC9E,OAAO,EAAE,+CAA+C;AAAA,IAC1D;AAAA,EACF;AAEA,SACE,qBAAC,SAAI,WAAU,aACb;AAAA,wBAAC,SAAM,QAAO,eACZ,8BAAC,oBACE,YAAE,2CAA2C,GAChD,GACF;AAAA,IAEA,qBAAC,QAAK,OAAO,KAAK,eAAe,CAAC,SAAS,OAAO,IAAsC,GACtF;AAAA,0BAAC,YAAS,WAAW,0BACjB,WAAC,WAAW,UAAU,OAAO,EAAY,IAAI,CAAC,SAC9C,qBAAC,eAAuB,OAAO,MAAM,WAAW,6BAC9C;AAAA,4BAAC,iBAAc,WAAU,gBAAe;AAAA,QACvC,OAAO,IAAI,EAAE;AAAA,WAFE,IAGlB,CACD,GACH;AAAA,MAEE,CAAC,WAAW,UAAU,OAAO,EAAY,IAAI,CAAC,SAC9C,qBAAC,eAAuB,OAAO,MAAM,WAAU,aAC7C;AAAA,4BAAC,gBAAa,OAAO,EAAE,mDAAmD,EAAE,OAAO,OAAO,IAAI,EAAE,MAAM,CAAC,GAAG,OAAO,UAAU,QAAQ,OAAO,IAAI,EAAE,QAAQ,GACtJ;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,WAAW,OAAO,OAAO,IAAI,EAAE,QAAQ,CAAC;AAAA,YAC/C,UAAU,CAAC,UAAU,SAAS,OAAO,IAAI,EAAE,UAAU,MAAM,OAAO,KAAK;AAAA,YACvE,aAAa,OAAO,IAAI,EAAE;AAAA,YAC1B,WAAW,oBAAoB,UAAU,QAAQ,OAAO,IAAI,EAAE,QAAQ,CAAC;AAAA,YACvE,gBAAc,QAAQ,UAAU,QAAQ,OAAO,IAAI,EAAE,QAAQ,CAAC;AAAA;AAAA,QAChE,GACF;AAAA,QACA,oBAAC,gBAAa,OAAO,EAAE,kDAAkD,EAAE,OAAO,OAAO,IAAI,EAAE,MAAM,CAAC,GAAG,OAAO,UAAU,QAAQ,OAAO,IAAI,EAAE,OAAO,GACpJ;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,WAAW,OAAO,OAAO,IAAI,EAAE,OAAO,CAAC;AAAA,YAC9C,UAAU,CAAC,SAAS,SAAS,OAAO,IAAI,EAAE,SAAS,IAAI;AAAA,YACvD,mBAAiB;AAAA,YACjB,QAAQ;AAAA,YACR,aAAa,OAAO,IAAI,EAAE;AAAA;AAAA,QAC5B,GACF;AAAA,WAlBgB,IAmBlB,CACD;AAAA,OACH;AAAA,KACF;AAEJ;AAEA,SAAS,eAAe;AACtB,QAAM,IAAI,KAAK;AACf,QAAM,YAAY,CAAC,iBAAiB,cAAc,oBAAoB,iBAAiB,qBAAqB,kBAAkB;AAC9H,SACE,qBAAC,SAAI,WAAU,aACb;AAAA,wBAAC,OAAE,WAAU,iCAAiC,YAAE,+CAA+C,GAAE;AAAA,IACjG,oBAAC,SAAI,WAAU,wBACd,oBAAU,IAAI,CAAC,aACd;AAAA,MAAC;AAAA;AAAA,QAEC,WAAU;AAAA,QAET;AAAA;AAAA,MAHI;AAAA,IAIP,CACD,GACD;AAAA,KACF;AAEJ;AAEA,SAAS,cAAc,EAAE,QAAQ,UAAU,OAAO,GAAgC;AAChF,QAAM,IAAI,KAAK;AACf,QAAM,CAAC,KAAK,MAAM,IAAI,MAAM,SAAwC,OAAO;AAE3E,QAAM,SAAS;AAAA,IACb,OAAO;AAAA,MACL,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,OAAO,EAAE,6CAA6C;AAAA,MACtD,MAAM;AAAA,MACN,oBAAoB,EAAE,4DAA4D;AAAA,MAClF,iBAAiB,EAAE,yDAAyD;AAAA,IAC9E;AAAA,IACA,SAAS;AAAA,MACP,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,OAAO,EAAE,+CAA+C;AAAA,MACxD,MAAM;AAAA,MACN,oBAAoB,EAAE,8DAA8D;AAAA,MACpF,iBAAiB,EAAE,2DAA2D;AAAA,IAChF;AAAA,IACA,OAAO;AAAA,MACL,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,OAAO,EAAE,6CAA6C;AAAA,MACtD,MAAM;AAAA,MACN,oBAAoB,EAAE,4DAA4D;AAAA,MAClF,iBAAiB,EAAE,yDAAyD;AAAA,IAC9E;AAAA,EACF;AAEA,SACE,qBAAC,SAAI,WAAU,aACb;AAAA,wBAAC,SAAM,QAAO,eACZ,8BAAC,oBACE,YAAE,yCAAyC,GAC9C,GACF;AAAA,IACA,oBAAC,gBAAa;AAAA,IAEd,qBAAC,QAAK,OAAO,KAAK,eAAe,CAAC,SAAS,OAAO,IAAqC,GACrF;AAAA,0BAAC,YAAS,WAAW,0BACjB,WAAC,SAAS,WAAW,OAAO,EAAY,IAAI,CAAC,SAAS;AACtD,cAAM,OAAO,OAAO,IAAI,EAAE;AAC1B,eACE,qBAAC,eAAuB,OAAO,MAAM,WAAW,6BAC9C;AAAA,8BAAC,QAAK,WAAU,gBAAe;AAAA,UAC9B,OAAO,IAAI,EAAE;AAAA,aAFE,IAGlB;AAAA,MAEJ,CAAC,GACH;AAAA,MAEE,CAAC,SAAS,WAAW,OAAO,EAAY,IAAI,CAAC,SAC7C,qBAAC,eAAuB,OAAO,MAAM,WAAU,aAC7C;AAAA,6BAAC,WAAM,WAAU,4FACf;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAS,YAAY,OAAO,OAAO,IAAI,EAAE,UAAU,GAAG,IAAI;AAAA,cAC1D,UAAU,CAAC,UAAU,SAAS,OAAO,IAAI,EAAE,YAAY,MAAM,OAAO,OAAO;AAAA;AAAA,UAC7E;AAAA,UACC,EAAE,iDAAiD;AAAA,WACtD;AAAA,QAEA,oBAAC,gBAAa,OAAO,EAAE,mDAAmD,EAAE,OAAO,OAAO,IAAI,EAAE,MAAM,CAAC,GAAG,OAAO,UAAU,QAAQ,OAAO,IAAI,EAAE,UAAU,GACxJ;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,WAAW,OAAO,OAAO,IAAI,EAAE,UAAU,CAAC;AAAA,YACjD,UAAU,CAAC,UAAU,SAAS,OAAO,IAAI,EAAE,YAAY,MAAM,OAAO,KAAK;AAAA,YACzE,aAAa,OAAO,IAAI,EAAE;AAAA,YAC1B,WAAW,oBAAoB,UAAU,QAAQ,OAAO,IAAI,EAAE,UAAU,CAAC;AAAA,YACzE,gBAAc,QAAQ,UAAU,QAAQ,OAAO,IAAI,EAAE,UAAU,CAAC;AAAA;AAAA,QAClE,GACF;AAAA,QAEA,oBAAC,gBAAa,OAAO,EAAE,gDAAgD,EAAE,OAAO,OAAO,IAAI,EAAE,MAAM,CAAC,GAAG,OAAO,UAAU,QAAQ,OAAO,IAAI,EAAE,OAAO,GAClJ;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,WAAW,OAAO,OAAO,IAAI,EAAE,OAAO,CAAC;AAAA,YAC9C,UAAU,CAAC,SAAS,SAAS,OAAO,IAAI,EAAE,SAAS,IAAI;AAAA,YACvD,mBAAiB;AAAA,YACjB,QAAQ;AAAA,YACR,aAAa,OAAO,IAAI,EAAE;AAAA;AAAA,QAC5B,GACF;AAAA,WA5BgB,IA6BlB,CACD;AAAA,OACH;AAAA,KACF;AAEJ;AAEA,SAAS,gBAAgB,EAAE,QAAQ,UAAU,OAAO,GAAgC;AAClF,QAAM,IAAI,KAAK;AACf,QAAM,SAAS,WAAW,OAAO,MAAM,KAAK;AAC5C,QAAM,cAAc,UAAU,QAAQ,QAAQ;AAC9C,QAAM,sBAAsB,UAAU,QAAQ,gBAAgB;AAC9D,QAAM,gBAAgB,UAAU,QAAQ,UAAU;AAElD,SACE,qBAAC,SAAI,WAAU,aACb;AAAA,wBAAC,gBAAa,OAAO,EAAE,kDAAkD,GAAG,OAAO,aACjF,8BAAC,SAAI,WAAU,wBACZ;AAAA,MACC,EAAE,IAAI,SAAS,OAAO,EAAE,8BAA8B,EAAE;AAAA,MACxD,EAAE,IAAI,UAAU,OAAO,EAAE,+BAA+B,EAAE;AAAA,MAC1D,EAAE,IAAI,YAAY,OAAO,EAAE,iCAAiC,EAAE;AAAA,IAChE,EAAE,IAAI,CAAC,WACL;AAAA,MAAC;AAAA;AAAA,QAEC,MAAK;AAAA,QACL,SAAS,WAAW,OAAO,KAAK,YAAY;AAAA,QAC5C,MAAK;AAAA,QACL,SAAS,MAAM,SAAS,UAAU,OAAO,EAAE;AAAA,QAE1C,iBAAO;AAAA;AAAA,MANH,OAAO;AAAA,IAOd,CACD,GACH,GACF;AAAA,IAEA,oBAAC,gBAAa,OAAO,EAAE,0DAA0D,GAAG,MAAM,EAAE,yDAAyD,GAAG,OAAO,qBAC7J;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,KAAI;AAAA,QACJ,MAAK;AAAA,QACL,OAAO,qBAAqB,OAAO,cAAc;AAAA,QACjD,UAAU,CAAC,UAAU,SAAS,kBAAkB,MAAM,OAAO,QAAQ,OAAO,MAAM,OAAO,KAAK,IAAI,IAAI;AAAA,QACtG,aAAa,EAAE,2DAA2D;AAAA,QAC1E,WAAW,oBAAoB,mBAAmB;AAAA,QAClD,gBAAc,QAAQ,mBAAmB;AAAA;AAAA,IAC3C,GACF;AAAA,IAEA,oBAAC,gBAAa,OAAO,EAAE,oDAAoD,GAAG,MAAM,EAAE,mDAAmD,GAAG,OAAO,eACjJ;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,WAAW,OAAO,QAAQ;AAAA,QACjC,UAAU,CAAC,UAAU,SAAS,YAAY,MAAM,OAAO,KAAK;AAAA,QAC5D,aAAa,EAAE,0DAA0D;AAAA,QACzE,WAAW,oBAAoB,aAAa;AAAA,QAC5C,gBAAc,QAAQ,aAAa;AAAA;AAAA,IACrC,GACF;AAAA,KACF;AAEJ;AAEO,SAAS,iBAAiB,EAAE,MAAM,SAAS,GAAU;AAC1D,QAAM,IAAI,KAAK;AACf,QAAM,SAAS,UAAU;AACzB,QAAM,eAAe,gBAAgB;AACrC,QAAM,WAAW,SAAS,SAAS,oBAAoB,OAAO,oBAAoB;AAClF,QAAM,aAAa,MAAM,QAAQ,MAAM;AACrC,UAAM,MAAM,aAAa,IAAI,YAAY;AACzC,WAAO,OAAO,IAAI,KAAK,EAAE,SAAS,IAAI,MAAM;AAAA,EAC9C,GAAG,CAAC,YAAY,CAAC;AACjB,QAAM,0BAA0B,MAAM;AAAA,IACpC,MAAM,aAAa,OAAO,WAAW,eAAe,OAAO,OAAO,eAAe,aAAa,OAAO,WAAW,IAAI,SAAS,KAAK,IAAI,CAAC;AAAA,IACvI,CAAC,QAAQ;AAAA,EACX;AACA,QAAM,6BAA6B,MAAM,OAAsB,IAAI;AACnE,QAAM,CAAC,WAAW,YAAY,IAAI,MAAM,SAA+B,CAAC,CAAC;AACzE,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,MAAM,SAA2B,CAAC,CAAC;AACjF,QAAM,CAAC,oBAAoB,qBAAqB,IAAI,MAAM,SAAS,KAAK;AACxE,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,MAAM,SAAS,CAAC;AAC9D,QAAM,CAAC,eAAe,gBAAgB,IAAI,MAAM;AAAA,IAC9C,WAAW,OAAO,oBAAoB,oBAAoB,CAAC,GAAG,CAAC;AAAA,EACjE;AACA,QAAM,CAAC,UAAU,WAAW,IAAI,MAAM,SAAS,KAAK;AAEpD,QAAM,uBAAuB,MAAM,YAAY,CAAC,eAA2B;AACzE,qBAAiB,UAAU;AAC3B,uBAAmB,CAAC,YAAY,UAAU,CAAC;AAAA,EAC7C,GAAG,CAAC,CAAC;AAEL,QAAM,UAAU,MAAM;AACpB,+BAA2B,UAAU,iBAAiB,OAAO,cAAc,qBAAqB,WAC5F,cAAc,mBACd;AAAA,EACN,GAAG,CAAC,aAAa,CAAC;AAElB,QAAM,UAAU,MAAM;AACpB,QAAI,SAAS;AACb,SAAK,qBAAsD,iCAAiC,EACzF,KAAK,CAAC,WAAW;AAChB,UAAI,CAAC,OAAQ;AACb,mBAAa,MAAM,QAAQ,OAAO,KAAK,IAAI,OAAO,QAAQ,CAAC,CAAC;AAAA,IAC9D,CAAC,EACA,MAAM,MAAM;AACX,UAAI,OAAQ,cAAa,CAAC,CAAC;AAAA,IAC7B,CAAC;AACH,WAAO,MAAM;AACX,eAAS;AAAA,IACX;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,0BAA0B,MAAM,YAAY,CAAC,UAAgD;AACjG,uBAAmB,CAAC,YAAY;AAC9B,YAAM,OAAO,IAAI,IAAI,QAAQ,IAAI,CAAC,WAAW,CAAC,OAAO,OAAO,MAAM,CAAC,CAAC;AACpE,YAAM,QAAQ,CAAC,SAAS;AACtB,YAAI,WAAW,MAAM;AACnB,eAAK,IAAI,KAAK,OAAO,IAAI;AACzB;AAAA,QACF;AACA,cAAM,SAAS,iBAAiB,IAAI;AACpC,aAAK,IAAI,OAAO,OAAO,MAAM;AAAA,MAC/B,CAAC;AACD,aAAO,MAAM,KAAK,KAAK,OAAO,CAAC;AAAA,IACjC,CAAC;AAAA,EACH,GAAG,CAAC,CAAC;AAEL,QAAM,0BAA0B,MAAM,YAAY,OAAO,UAA8C;AACrG,UAAM,SAAS,IAAI,gBAAgB;AAAA,MACjC,MAAM;AAAA,MACN,UAAU;AAAA,IACZ,CAAC;AACD,QAAI,SAAS,MAAM,KAAK,EAAE,SAAS,GAAG;AACpC,aAAO,IAAI,UAAU,MAAM,KAAK,CAAC;AAAA,IACnC;AACA,UAAM,SAAS,MAAM,qBAAmD,2BAA2B,OAAO,SAAS,CAAC,EAAE;AACtH,UAAM,UAAU,MAAM,QAAQ,OAAO,KAAK,IAAI,OAAO,MAAM,IAAI,gBAAgB,IAAI,CAAC;AACpF,4BAAwB,OAAO;AAC/B,WAAO;AAAA,EACT,GAAG,CAAC,uBAAuB,CAAC;AAE5B,QAAM,gBAAgB,MAAM,YAAY,OAAO,mBAAkC;AAC/E,QAAI,YAAY,SAAS,OAAQ;AACjC,QAAI,CAAC,gBAAgB;AACnB,2BAAqB,oBAAoB,oBAAoB,CAAC,GAAG,CAAC,CAAC;AACnE;AAAA,IACF;AACA,0BAAsB,IAAI;AAC1B,QAAI;AACF,YAAM,SAAS,MAAM,qBAAiC,2BAA2B,mBAAmB,cAAc,CAAC,EAAE;AACrH,8BAAwB,CAAC;AAAA,QACvB,IAAI;AAAA,QACJ,MAAM,WAAW,OAAO,IAAI;AAAA,QAC5B,OAAO,WAAW,OAAO,KAAK,KAAK;AAAA,QACnC,oBAAoB,WAAW,OAAO,kBAAkB,KAAK;AAAA,QAC7D,aAAa,WAAW,OAAO,WAAW,KAAK;AAAA,MACjD,CAAC,CAAC;AACF;AAAA,QACE,oBAAoB;AAAA,UAClB,GAAG;AAAA,UACH,MAAM;AAAA,UACN,YAAY;AAAA,QACd,GAAG,CAAC;AAAA,MACN;AAAA,IACF,UAAE;AACA,4BAAsB,KAAK;AAAA,IAC7B;AAAA,EACF,GAAG,CAAC,MAAM,UAAU,yBAAyB,sBAAsB,CAAC,CAAC;AAErE,QAAM,UAAU,MAAM;AACpB,QAAI,SAAS,UAAU,SAAU;AACjC,SAAK,wBAAwB,EAC1B,MAAM,MAAM,IAAI;AAAA,EACrB,GAAG,CAAC,yBAAyB,MAAM,QAAQ,CAAC;AAE5C,QAAM,UAAU,MAAM;AACpB,QAAI,CAAC,SAAU;AACf,QAAI,SAAS;AACb,gBAAY,KAAK;AACjB,SAAK,qBAAiC,iBAAiB,SAAS,SAAS,UAAU,WAAW,IAAI,mBAAmB,QAAQ,CAAC,EAAE,EAC7H,KAAK,CAAC,WAAW;AAChB,UAAI,CAAC,OAAQ;AACb,2BAAqB,oBAAoB,QAAQ,CAAC,CAAC;AAAA,IACrD,CAAC,EACA,MAAM,CAAC,UAAU;AAChB,UAAI,CAAC,OAAQ;AACb,UAAI,sBAAsB,KAAK,GAAG;AAChC,oBAAY,IAAI;AAChB;AAAA,MACF;AACA,2BAAqB,oBAAoB,CAAC,GAAG,CAAC,CAAC;AAAA,IACjD,CAAC;AACH,WAAO,MAAM;AACX,eAAS;AAAA,IACX;AAAA,EACF,GAAG,CAAC,MAAM,UAAU,sBAAsB,CAAC,CAAC;AAE5C,QAAM,UAAU,MAAM;AACpB,QAAI,YAAY,SAAS,UAAU,CAAC,WAAY;AAChD,SAAK,cAAc,UAAU,EAAE,MAAM,MAAM,IAAI;AAAA,EACjD,GAAG,CAAC,eAAe,MAAM,UAAU,UAAU,CAAC;AAE9C,QAAM,UAAU,MAAM;AACpB,UAAM,oBAAoB,WAAW,eAAe,UAAU,EAAE,KAAK;AACrE,QAAI,SAAS,UAAU,CAAC,kBAAmB;AAC3C,QAAI,gBAAgB,KAAK,CAAC,WAAW,OAAO,UAAU,iBAAiB,EAAG;AAE1E,QAAI,SAAS;AACb,SAAK,qBAAiC,2BAA2B,mBAAmB,iBAAiB,CAAC,EAAE,EACrG,KAAK,CAAC,WAAW;AAChB,UAAI,CAAC,OAAQ;AACb,8BAAwB,CAAC;AAAA,QACvB,IAAI;AAAA,QACJ,MAAM,WAAW,OAAO,IAAI;AAAA,QAC5B,OAAO,WAAW,OAAO,KAAK,KAAK;AAAA,QACnC,oBAAoB,WAAW,OAAO,kBAAkB,KAAK;AAAA,QAC7D,aAAa,WAAW,OAAO,WAAW,KAAK;AAAA,MACjD,CAAC,CAAC;AAAA,IACJ,CAAC,EACA,MAAM,MAAM,IAAI;AAEnB,WAAO,MAAM;AACX,eAAS;AAAA,IACX;AAAA,EACF,GAAG,CAAC,eAAe,YAAY,MAAM,yBAAyB,eAAe,CAAC;AAE9E,QAAM,SAAS,MAAM,QAAqB,MAAM,CAAC,GAAG,CAAC,CAAC;AAEtD,QAAM,SAAS,MAAM,QAAyB,MAAM;AAAA,IAClD;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,EAAE,0CAA0C;AAAA,MACnD,QAAQ;AAAA,MACR,WAAW,CAAC,QACV;AAAA,QAAC;AAAA;AAAA,UACE,GAAG;AAAA,UACJ;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,MACF;AAAA,IAEJ;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,EAAE,0CAA0C;AAAA,MACnD,QAAQ;AAAA,MACR,WAAW,CAAC,QAAQ,oBAAC,kBAAgB,GAAG,KAAK,WAAsB;AAAA,IACrE;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,EAAE,0CAA0C;AAAA,MACnD,QAAQ;AAAA,MACR,WAAW,CAAC,QAAQ,oBAAC,kBAAgB,GAAG,KAAK;AAAA,IAC/C;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,EAAE,6CAA6C;AAAA,MACtD,QAAQ;AAAA,MACR,WAAW,CAAC,QACV;AAAA,QAAC;AAAA;AAAA,UACE,GAAG;AAAA,UACJ;AAAA,UACA,oBAAoB;AAAA;AAAA,MACtB;AAAA,IAEJ;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,EAAE,iDAAiD;AAAA,MAC1D,QAAQ;AAAA,MACR,WAAW,CAAC,QAAQ,oBAAC,0BAAwB,GAAG,KAAK;AAAA,IACvD;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,EAAE,2CAA2C;AAAA,MACpD,QAAQ;AAAA,MACR,WAAW,CAAC,QAAQ,oBAAC,mBAAiB,GAAG,KAAK;AAAA,IAChD;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,EAAE,wCAAwC;AAAA,MACjD,QAAQ;AAAA,MACR,WAAW,CAAC,QAAQ,oBAAC,gBAAc,GAAG,KAAK;AAAA,IAC7C;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,EAAE,2CAA2C;AAAA,MACpD,QAAQ;AAAA,MACR,WAAW,CAAC,QAAQ,oBAAC,mBAAiB,GAAG,KAAK;AAAA,IAChD;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,EAAE,yCAAyC;AAAA,MAClD,QAAQ;AAAA,MACR,WAAW,CAAC,QAAQ,oBAAC,iBAAe,GAAG,KAAK;AAAA,IAC9C;AAAA,IACA,EAAE,IAAI,gBAAgB,OAAO,EAAE,+CAA+C,GAAG,QAAQ,GAAG,MAAM,eAAe;AAAA,EACnH,GAAG,CAAC,eAAe,yBAAyB,UAAU,oBAAoB,yBAAyB,MAAM,WAAW,GAAG,eAAe,CAAC;AAEvI,QAAM,WAAW,SAAS,UAAU,QAAQ,QAAQ,KAAK,YAAY,eAAe,QAAQ;AAC5F,QAAM,SAAS,MAAM;AAAA,IACnB,MAAM,YAAY,IAAI,WAAW,YAAY,KAAK;AAAA,IAClD,CAAC,MAAM,QAAQ;AAAA,EACjB;AACA,QAAM,eAAe,WACnB,qBAAC,SAAM,QAAO,WACZ;AAAA,wBAAC,cAAY,YAAE,wCAAwC,GAAE;AAAA,IACzD,oBAAC,oBAAkB,YAAE,8CAA8C,GAAE;AAAA,KACvE,IACE;AACJ,QAAM,gBAAgB,WACpB,qBAAC,SAAI,WAAU,yHACb;AAAA,wBAAC,SAAI,WAAU,sHACb,8BAAC,UAAO,WAAU,WAAU,GAC9B;AAAA,IACA,oBAAC,OAAE,WAAU,yCACV,YAAE,+CAA+C,GACpD;AAAA,IACA,oBAAC,OAAE,WAAU,sCACV,YAAE,qDAAqD,GAC1D;AAAA,KACF,IACE;AAEJ,QAAM,WAAW,SAAS,SAAS,gCAAgC;AAEnE,MAAI,UAAU;AACZ,WACE,oBAAC,QACC,8BAAC,YACC;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,SAAS,SACd,kDACA,mDAAmD;AAAA,QACvD,aAAa,EAAE,SAAS,SACpB,wDACA,yDAAyD;AAAA,QAC7D,UAAU;AAAA;AAAA,IACZ,GACF,GACF;AAAA,EAEJ;AAEA,SACE,oBAAC,QACC,8BAAC,YACE,0BACC;AAAA,IAAC;AAAA;AAAA,MAEC;AAAA,MACA,OAAO,WACH,EAAE,SAAS,SAAS,8CAA8C,+CAA+C,IACjH,EAAE,SAAS,SAAS,gDAAgD,iDAAiD;AAAA,MACzH,mBAAmB;AAAA,MACnB,UAAU,SAAS,SAAS,gCAAgC;AAAA,MAC5D,YAAY,SAAS,SAAS,gCAAgC;AAAA,MAC9D;AAAA,MACA;AAAA,MACA,cAAc,WACZ,iCACG;AAAA,mBACC,oBAAC,UAAO,SAAO,MAAC,MAAK,UAAS,SAAQ,WACpC;AAAA,UAAC;AAAA;AAAA,YACC,MAAM,SAAS,SACX,QAAQ,mBAAmB,WAAW,cAAc,IAAI,CAAC,CAAC,kBAC1D,+BAA+B,mBAAmB,QAAQ,CAAC;AAAA,YAC/D,QAAO;AAAA,YACP,KAAI;AAAA,YAEJ;AAAA,kCAAC,OAAI,WAAU,gBAAe;AAAA,cAC7B,EAAE,iCAAiC;AAAA;AAAA;AAAA,QACtC,GACF,IAEA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,MAAM;AAAA,YACN,SAAQ;AAAA,YACR,MAAK;AAAA,YACL,OAAM;AAAA,YAEN;AAAA,kCAAC,OAAI,WAAU,gBAAe;AAAA,cAC7B,EAAE,iCAAiC;AAAA;AAAA;AAAA,QACtC;AAAA,QAED,SAAS,UAAU,YAAY,CAAC,WAC/B;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,MAAM;AAAA,YACN,MAAK;AAAA,YACL,OAAM;AAAA,YAEN;AAAA,kCAAC,cAAW,WAAU,gBAAe;AAAA,cACpC,EAAE,wCAAwC;AAAA;AAAA;AAAA,QAC7C,IACE;AAAA,SACN,IACE;AAAA,MACJ;AAAA,MACA,wBAAwB,EAAE,CAAC,QAAQ,GAAG,EAAE,UAAU,qBAAqB,EAAE;AAAA,MACzE;AAAA,MACA,eAAe;AAAA,MACf,UAAU;AAAA,MACV,iBAAiB;AAAA,MACjB,eAAe,QAAQ,QAAQ;AAAA,MAC/B,UAAU,OAAO,QAAQ,YAAY;AACnC,cAAM,eAAe,SAAS,WAAW,UAAU,YAC/C,YACA,SAAS,WAAW,UAAU,YAC5B,YACA;AACN,cAAM,oBAAoB,iBAAiB;AAC3C,cAAM,UAAU;AAAA,UACd,GAAG;AAAA,UACH,QAAQ,iBAAiB,YAAY,WAAW,OAAO;AAAA,UACvD,kBAAkB,kBAAkB,OAAO,kBAAkB,MAAM;AAAA,UACnE,0BAA0B,kBAAkB,OAAO,0BAA0B,MAAM;AAAA,UACnF,iBAAiB,kBAAkB,OAAO,iBAAiB,MAAM;AAAA,UACjE,iBAAiB,kBAAkB,OAAO,iBAAiB,MAAM;AAAA,UACjE,gBAAgB,wBAAwB,OAAO,cAAc,EAAE,IAAI,CAAC,UAAU;AAAA,YAC5E,GAAG;AAAA,YACH,QAAQ,kBAAkB,KAAK,QAAQ,MAAM,KAAK,OAAO;AAAA,UAC3D,EAAE;AAAA,UACF,cAAc,yBAAyB,MAAM;AAAA,QAC/C;AACA,cAAM,WAAW,iBAAiB,SAAS,SAAS,UAAU,WAAW,GAAG,WAAW,IAAI,mBAAmB,QAAQ,CAAC,KAAK,EAAE;AAC9H,YAAI;AACJ,YAAI;AACF,qBAAW,MAAM;AAAA,YACf,WAAW,0BAA0B,WAAW,eAAe,SAAS,KAAK,IAAI,IAAI,CAAC;AAAA,YACtF,MAAM,qBAAmE,UAAU;AAAA,cACjF,QAAQ,WAAW,QAAQ;AAAA,cAC3B,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,cAC9C,MAAM,KAAK,UAAU,OAAO;AAAA,YAC9B,CAAC;AAAA,UACH;AAAA,QACF,SAAS,OAAO;AACd,cAAI,sBAAsB,OAAO,CAAC,EAAG;AACrC,cAAI,YAAY,sBAAsB,KAAK,GAAG;AAC5C,wBAAY,IAAI;AAChB;AAAA,UACF;AACA,gBAAM;AAAA,QACR;AACA,cAAM,WAAW,aAAa,OAAO,UAAU,OAAO,WAAW,SAAS,KAAK;AAC/E,cAAM,mBAAmB,WAAW,OAAO,gBAAgB;AAC3D,YACE,CAAC,YACD,YACA,oBACA,qBAAqB,2BAA2B,SAChD;AACA,gBAAM,QAAQ,6BAA6B;AAAA,YACzC,QAAQ;AAAA,YACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,YAC9C,MAAM,KAAK,UAAU;AAAA,cACnB;AAAA,cACA,eAAe,CAAC,gBAAgB;AAAA,cAChC,cAAc;AAAA,cACd,YAAY;AAAA,YACd,CAAC;AAAA,UACH,CAAC;AAAA,QACH;AACA,YAAI,mBAAmB;AACrB,cAAI,SAAS,QAAQ;AACnB,kBAAM,YAAY,OAAO,UAAU,SAAS,YAAY,SAAS,KAAK,KAAK,EAAE,SAAS,IAClF,SAAS,KAAK,KAAK,IACnB,WAAW,OAAO,IAAI,EAAE,KAAK,KAAK,WAAW,cAAc,IAAI,EAAE,KAAK;AAC1E,gBAAI,WAAW;AACb,qBAAO,KAAK,QAAQ,mBAAmB,SAAS,CAAC,iBAAiB,UAAU,qBAAqB;AACjG;AAAA,YACF;AAAA,UACF,WAAW,UAAU;AACnB,mBAAO;AAAA,cACL,+BAA+B,mBAAmB,QAAQ,CAAC;AAAA,cAC3D;AAAA,cACA;AAAA,YACF;AACA;AAAA,UACF;AAAA,QACF;AACA,eAAO,SAAS,OAAO,SAAS,SAC5B,qCAAqC;AAAA,UACrC,EAAE,iBAAiB,YAAY,4CAA4C,6BAA6B;AAAA,QAC1G,CAAC,kBACC,qCAAqC,mBAAmB,EAAE,6BAA6B,CAAC,CAAC;AAAA,MAC/F;AAAA,MACA,UAAU,WAAW,YAAY;AAC/B,YAAI;AACF,gBAAM;AAAA,YACJ,0BAA0B,WAAW,eAAe,SAAS,KAAK,IAAI;AAAA,YACtE,MAAM,eAAe,iBAAiB,SAAS,SAAS,UAAU,WAAW,IAAI,mBAAmB,QAAQ,CAAC,IAAI,EAAE,QAAQ,SAAS,CAAC;AAAA,UACvI;AAAA,QACF,SAAS,OAAO;AACd,cAAI,sBAAsB,OAAO,CAAC,EAAG;AACrC,cAAI,sBAAsB,KAAK,GAAG;AAChC,wBAAY,IAAI;AAChB;AAAA,UACF;AACA,gBAAM;AAAA,QACR;AACA,eAAO,SAAS,OAAO,SAAS,SAC5B,qCAAqC,mBAAmB,EAAE,+BAA+B,CAAC,CAAC,kBAC3F,qCAAqC,mBAAmB,EAAE,+BAA+B,CAAC,CAAC;AAAA,MACjG,IAAI;AAAA;AAAA,IA5JC;AAAA,EA6JP,IACE,MACN,GACF;AAEJ;AAEA,IAAO,2BAAQ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-mercato/checkout",
|
|
3
|
-
"version": "0.8.1-develop.
|
|
3
|
+
"version": "0.8.1-develop.7218.1.9f22882799",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -62,18 +62,18 @@
|
|
|
62
62
|
}
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
|
-
"@open-mercato/core": "0.8.1-develop.
|
|
66
|
-
"@open-mercato/ui": "0.8.1-develop.
|
|
65
|
+
"@open-mercato/core": "0.8.1-develop.7218.1.9f22882799",
|
|
66
|
+
"@open-mercato/ui": "0.8.1-develop.7218.1.9f22882799",
|
|
67
67
|
"bcryptjs": "^3.0.3"
|
|
68
68
|
},
|
|
69
69
|
"peerDependencies": {
|
|
70
70
|
"@mikro-orm/postgresql": "^7.0.14",
|
|
71
|
-
"@open-mercato/shared": "0.8.1-develop.
|
|
71
|
+
"@open-mercato/shared": "0.8.1-develop.7218.1.9f22882799",
|
|
72
72
|
"react": "^19.0.0",
|
|
73
73
|
"react-dom": "^19.0.0"
|
|
74
74
|
},
|
|
75
75
|
"devDependencies": {
|
|
76
|
-
"@open-mercato/shared": "0.8.1-develop.
|
|
76
|
+
"@open-mercato/shared": "0.8.1-develop.7218.1.9f22882799",
|
|
77
77
|
"@types/jest": "^30.0.0",
|
|
78
78
|
"@types/react": "^19.2.18",
|
|
79
79
|
"@types/react-dom": "^19.2.5",
|
|
@@ -83,6 +83,9 @@ type LegalDocumentsValue = {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
type PriceListItem = PriceListItemInput
|
|
86
|
+
// `amount` stays a raw locale-typed string while a row is being edited (issue #5828) —
|
|
87
|
+
// converted to a number only at submit time.
|
|
88
|
+
type PriceListEditorItem = Omit<PriceListItem, 'amount'> & { amount: number | string }
|
|
86
89
|
|
|
87
90
|
const DEFAULT_COLORS = {
|
|
88
91
|
primaryColor: '#1E3A8A',
|
|
@@ -107,6 +110,16 @@ function readNumberInputValue(value: unknown): string {
|
|
|
107
110
|
return ''
|
|
108
111
|
}
|
|
109
112
|
|
|
113
|
+
// Money fields stay a raw locale-typed string while being edited (issue #5828) so an
|
|
114
|
+
// in-progress decimal separator is never dropped mid-keystroke; this converts to the
|
|
115
|
+
// canonical number the API expects right before submission.
|
|
116
|
+
export function toSubmittedAmount(value: unknown, locale?: string): number | null {
|
|
117
|
+
if (typeof value === 'number') return Number.isFinite(value) ? value : null
|
|
118
|
+
if (typeof value !== 'string') return null
|
|
119
|
+
if (!value.trim()) return null
|
|
120
|
+
return parseLocaleNumber(value, locale)
|
|
121
|
+
}
|
|
122
|
+
|
|
110
123
|
function readBoolean(value: unknown, fallback = false): boolean {
|
|
111
124
|
return typeof value === 'boolean' ? value : fallback
|
|
112
125
|
}
|
|
@@ -174,23 +187,26 @@ function createDefaultValues(t?: TranslateFn): FormValues {
|
|
|
174
187
|
}
|
|
175
188
|
}
|
|
176
189
|
|
|
177
|
-
function normalizePriceListItems(value: unknown):
|
|
190
|
+
function normalizePriceListItems(value: unknown): PriceListEditorItem[] {
|
|
178
191
|
if (!Array.isArray(value)) return []
|
|
179
192
|
return value
|
|
180
193
|
.map((item) => {
|
|
181
194
|
if (!isRecord(item)) return null
|
|
182
195
|
const id = readString(item.id).trim()
|
|
183
196
|
const description = readString(item.description)
|
|
184
|
-
|
|
197
|
+
// Preserve a string amount as-is — a row mid-edit carries the raw locale-typed text
|
|
198
|
+
// (issue #5828); re-coercing it with `Number()` here would corrupt it on every render.
|
|
199
|
+
const amount =
|
|
200
|
+
typeof item.amount === 'number' || typeof item.amount === 'string' ? item.amount : 0
|
|
185
201
|
const currencyCode = readString(item.currencyCode).trim().toUpperCase()
|
|
186
202
|
return {
|
|
187
203
|
id: id || `item_${Date.now()}`,
|
|
188
204
|
description,
|
|
189
|
-
amount
|
|
205
|
+
amount,
|
|
190
206
|
currencyCode: currencyCode || 'USD',
|
|
191
207
|
}
|
|
192
208
|
})
|
|
193
|
-
.filter((item): item is
|
|
209
|
+
.filter((item): item is PriceListEditorItem => item !== null)
|
|
194
210
|
}
|
|
195
211
|
|
|
196
212
|
function normalizeCustomerFields(value: unknown, t?: TranslateFn): CustomerFieldDefinitionInput[] {
|
|
@@ -381,16 +397,15 @@ export function PriceListEditor({
|
|
|
381
397
|
onChange,
|
|
382
398
|
error,
|
|
383
399
|
}: {
|
|
384
|
-
value:
|
|
385
|
-
onChange: (next:
|
|
400
|
+
value: PriceListEditorItem[]
|
|
401
|
+
onChange: (next: PriceListEditorItem[]) => void
|
|
386
402
|
error?: string
|
|
387
403
|
}) {
|
|
388
404
|
const t = useT()
|
|
389
|
-
const locale = useLocale()
|
|
390
405
|
const items = Array.isArray(value) ? value : []
|
|
391
406
|
|
|
392
407
|
const updateItem = React.useCallback(
|
|
393
|
-
(index: number, patch: Partial<
|
|
408
|
+
(index: number, patch: Partial<PriceListEditorItem>) => {
|
|
394
409
|
onChange(items.map((item, currentIndex) => (currentIndex === index ? { ...item, ...patch } : item)))
|
|
395
410
|
},
|
|
396
411
|
[items, onChange],
|
|
@@ -458,7 +473,11 @@ export function PriceListEditor({
|
|
|
458
473
|
value={readNumberInputValue(item.amount)}
|
|
459
474
|
onChange={(event) =>
|
|
460
475
|
updateItem(index, {
|
|
461
|
-
|
|
476
|
+
// Stays raw while editing — re-parsing and re-serializing on every
|
|
477
|
+
// keystroke would drop an in-progress decimal separator (e.g. typing
|
|
478
|
+
// "110,70" collapses to "11070" the instant the comma is typed,
|
|
479
|
+
// issue #5828). Converted to a number at submit time instead.
|
|
480
|
+
amount: event.target.value,
|
|
462
481
|
})
|
|
463
482
|
}
|
|
464
483
|
placeholder="0.00"
|
|
@@ -510,7 +529,6 @@ export function PriceListEditor({
|
|
|
510
529
|
|
|
511
530
|
export function PricingSection({ values, setValue, errors }: CrudFormGroupComponentProps) {
|
|
512
531
|
const t = useT()
|
|
513
|
-
const locale = useLocale()
|
|
514
532
|
const pricingMode = readString(values.pricingMode) || 'fixed'
|
|
515
533
|
const pricingModeError = readError(errors, 'pricingMode')
|
|
516
534
|
const fixedPriceAmountError = readError(errors, 'fixedPriceAmount')
|
|
@@ -554,7 +572,7 @@ export function PricingSection({ values, setValue, errors }: CrudFormGroupCompon
|
|
|
554
572
|
type="text"
|
|
555
573
|
inputMode="decimal"
|
|
556
574
|
value={readNumberInputValue(values.fixedPriceAmount)}
|
|
557
|
-
onChange={(event) => setValue('fixedPriceAmount',
|
|
575
|
+
onChange={(event) => setValue('fixedPriceAmount', event.target.value)}
|
|
558
576
|
placeholder="150"
|
|
559
577
|
className={errorInputClassName(fixedPriceAmountError)}
|
|
560
578
|
aria-invalid={Boolean(fixedPriceAmountError)}
|
|
@@ -578,7 +596,7 @@ export function PricingSection({ values, setValue, errors }: CrudFormGroupCompon
|
|
|
578
596
|
type="text"
|
|
579
597
|
inputMode="decimal"
|
|
580
598
|
value={readNumberInputValue(values.fixedPriceOriginalAmount)}
|
|
581
|
-
onChange={(event) => setValue('fixedPriceOriginalAmount',
|
|
599
|
+
onChange={(event) => setValue('fixedPriceOriginalAmount', event.target.value)}
|
|
582
600
|
placeholder="200"
|
|
583
601
|
className={errorInputClassName(fixedPriceOriginalAmountError)}
|
|
584
602
|
aria-invalid={Boolean(fixedPriceOriginalAmountError)}
|
|
@@ -605,7 +623,7 @@ export function PricingSection({ values, setValue, errors }: CrudFormGroupCompon
|
|
|
605
623
|
type="text"
|
|
606
624
|
inputMode="decimal"
|
|
607
625
|
value={readNumberInputValue(values.customAmountMin)}
|
|
608
|
-
onChange={(event) => setValue('customAmountMin',
|
|
626
|
+
onChange={(event) => setValue('customAmountMin', event.target.value)}
|
|
609
627
|
placeholder="10"
|
|
610
628
|
className={errorInputClassName(customAmountMinError)}
|
|
611
629
|
aria-invalid={Boolean(customAmountMinError)}
|
|
@@ -617,7 +635,7 @@ export function PricingSection({ values, setValue, errors }: CrudFormGroupCompon
|
|
|
617
635
|
type="text"
|
|
618
636
|
inputMode="decimal"
|
|
619
637
|
value={readNumberInputValue(values.customAmountMax)}
|
|
620
|
-
onChange={(event) => setValue('customAmountMax',
|
|
638
|
+
onChange={(event) => setValue('customAmountMax', event.target.value)}
|
|
621
639
|
placeholder="500"
|
|
622
640
|
className={errorInputClassName(customAmountMaxError)}
|
|
623
641
|
aria-invalid={Boolean(customAmountMaxError)}
|
|
@@ -1318,6 +1336,7 @@ function SettingsSection({ values, setValue, errors }: CrudFormGroupComponentPro
|
|
|
1318
1336
|
|
|
1319
1337
|
export function LinkTemplateForm({ mode, recordId }: Props) {
|
|
1320
1338
|
const t = useT()
|
|
1339
|
+
const locale = useLocale()
|
|
1321
1340
|
const searchParams = useSearchParams()
|
|
1322
1341
|
const entityId = mode === 'link' ? CHECKOUT_ENTITY_IDS.link : CHECKOUT_ENTITY_IDS.template
|
|
1323
1342
|
const templateId = React.useMemo(() => {
|
|
@@ -1670,6 +1689,14 @@ export function LinkTemplateForm({ mode, recordId }: Props) {
|
|
|
1670
1689
|
const payload = {
|
|
1671
1690
|
...values,
|
|
1672
1691
|
status: submitIntent === 'publish' ? 'active' : values.status,
|
|
1692
|
+
fixedPriceAmount: toSubmittedAmount(values.fixedPriceAmount, locale),
|
|
1693
|
+
fixedPriceOriginalAmount: toSubmittedAmount(values.fixedPriceOriginalAmount, locale),
|
|
1694
|
+
customAmountMin: toSubmittedAmount(values.customAmountMin, locale),
|
|
1695
|
+
customAmountMax: toSubmittedAmount(values.customAmountMax, locale),
|
|
1696
|
+
priceListItems: normalizePriceListItems(values.priceListItems).map((item) => ({
|
|
1697
|
+
...item,
|
|
1698
|
+
amount: toSubmittedAmount(item.amount, locale) ?? Number.NaN,
|
|
1699
|
+
})),
|
|
1673
1700
|
customFields: collectCustomFieldValues(values),
|
|
1674
1701
|
}
|
|
1675
1702
|
const endpoint = `/api/checkout/${mode === 'link' ? 'links' : 'templates'}${recordId ? `/${encodeURIComponent(recordId)}` : ''}`
|
package/src/modules/checkout/components/__tests__/LinkTemplateForm.localeDecimalSeparator.test.tsx
CHANGED
|
@@ -54,7 +54,7 @@ jest.mock('../LogoUploadField', () => ({
|
|
|
54
54
|
LogoUploadField: () => null,
|
|
55
55
|
}))
|
|
56
56
|
|
|
57
|
-
import { PricingSection, PriceListEditor } from '../LinkTemplateForm'
|
|
57
|
+
import { PricingSection, PriceListEditor, toSubmittedAmount } from '../LinkTemplateForm'
|
|
58
58
|
|
|
59
59
|
function renderPricingSection(initialValues: Record<string, unknown>) {
|
|
60
60
|
const setValue = jest.fn()
|
|
@@ -76,57 +76,87 @@ function renderPricingSection(initialValues: Record<string, unknown>) {
|
|
|
76
76
|
return setValue
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
+
// Fires one `change` event per character, re-reading the input's own DOM value between
|
|
80
|
+
// keystrokes — a single `fireEvent.change(input, { value: 'full string' })` does not exercise
|
|
81
|
+
// the eager re-parse-and-re-serialize path that used to corrupt a value typed character by
|
|
82
|
+
// character (issue #5828: typing "110,70" ended up submitted as "11070").
|
|
83
|
+
function typeSequentially(input: HTMLInputElement, text: string) {
|
|
84
|
+
for (const char of text) {
|
|
85
|
+
fireEvent.change(input, { target: { value: input.value + char } })
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
79
89
|
describe('LinkTemplateForm locale decimal separator (issue #5828)', () => {
|
|
80
|
-
it('
|
|
81
|
-
|
|
82
|
-
const amountInput = screen.getByPlaceholderText('150')
|
|
83
|
-
|
|
84
|
-
|
|
90
|
+
it('keeps a comma-decimal fixed price amount intact while typing it character by character', () => {
|
|
91
|
+
renderPricingSection({ pricingMode: 'fixed' })
|
|
92
|
+
const amountInput = screen.getByPlaceholderText('150') as HTMLInputElement
|
|
93
|
+
typeSequentially(amountInput, '110,70')
|
|
94
|
+
// Before the fix, the field eagerly re-parsed and re-serialized the number on every
|
|
95
|
+
// keystroke, which dropped the in-progress comma and left "11070" once typing finished.
|
|
96
|
+
expect(amountInput.value).toBe('110,70')
|
|
85
97
|
})
|
|
86
98
|
|
|
87
|
-
it('
|
|
88
|
-
|
|
89
|
-
const compareInput = screen.getByPlaceholderText('200')
|
|
90
|
-
|
|
91
|
-
expect(
|
|
99
|
+
it('keeps a comma-decimal compare-at price intact while typing it character by character', () => {
|
|
100
|
+
renderPricingSection({ pricingMode: 'fixed' })
|
|
101
|
+
const compareInput = screen.getByPlaceholderText('200') as HTMLInputElement
|
|
102
|
+
typeSequentially(compareInput, '150,50')
|
|
103
|
+
expect(compareInput.value).toBe('150,50')
|
|
92
104
|
})
|
|
93
105
|
|
|
94
|
-
it('
|
|
95
|
-
|
|
96
|
-
const minInput = screen.getByPlaceholderText('10')
|
|
97
|
-
|
|
98
|
-
expect(
|
|
106
|
+
it('keeps comma-decimal custom-amount min/max intact while typing them character by character', () => {
|
|
107
|
+
renderPricingSection({ pricingMode: 'custom_amount' })
|
|
108
|
+
const minInput = screen.getByPlaceholderText('10') as HTMLInputElement
|
|
109
|
+
typeSequentially(minInput, '10,50')
|
|
110
|
+
expect(minInput.value).toBe('10,50')
|
|
99
111
|
|
|
100
|
-
const maxInput = screen.getByPlaceholderText('500')
|
|
101
|
-
|
|
102
|
-
expect(
|
|
112
|
+
const maxInput = screen.getByPlaceholderText('500') as HTMLInputElement
|
|
113
|
+
typeSequentially(maxInput, '500,25')
|
|
114
|
+
expect(maxInput.value).toBe('500,25')
|
|
103
115
|
})
|
|
104
116
|
|
|
105
|
-
it('still accepts a dot, so the workaround users learned keeps working', () => {
|
|
106
|
-
|
|
107
|
-
const amountInput = screen.getByPlaceholderText('150')
|
|
108
|
-
|
|
109
|
-
expect(
|
|
117
|
+
it('still accepts a dot typed character by character, so the workaround users learned keeps working', () => {
|
|
118
|
+
renderPricingSection({ pricingMode: 'fixed' })
|
|
119
|
+
const amountInput = screen.getByPlaceholderText('150') as HTMLInputElement
|
|
120
|
+
typeSequentially(amountInput, '110.70')
|
|
121
|
+
expect(amountInput.value).toBe('110.70')
|
|
110
122
|
})
|
|
111
123
|
|
|
112
|
-
it('
|
|
113
|
-
const setValue = renderPricingSection({ pricingMode: 'fixed' })
|
|
114
|
-
const amountInput = screen.getByPlaceholderText('150')
|
|
115
|
-
fireEvent.change(amountInput, { target: { value: 'abc' } })
|
|
116
|
-
expect(setValue).toHaveBeenLastCalledWith('fixedPriceAmount', null)
|
|
117
|
-
})
|
|
118
|
-
|
|
119
|
-
it('parses a comma-decimal amount in a price list row', () => {
|
|
124
|
+
it('keeps a comma-decimal amount intact while typing it character by character in a price list row', () => {
|
|
120
125
|
const onChange = jest.fn()
|
|
121
|
-
render(
|
|
126
|
+
const { rerender } = render(
|
|
122
127
|
<PriceListEditor
|
|
123
|
-
value={[{ id: 'item-1', description: 'Item', amount:
|
|
128
|
+
value={[{ id: 'item-1', description: 'Item', amount: '', currencyCode: 'USD' }]}
|
|
124
129
|
onChange={onChange}
|
|
125
130
|
/>,
|
|
126
131
|
)
|
|
127
|
-
const amountInput = screen.getByLabelText(
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
132
|
+
const amountInput = screen.getByLabelText(
|
|
133
|
+
'checkout.linkTemplateForm.priceList.aria.amount',
|
|
134
|
+
) as HTMLInputElement
|
|
135
|
+
for (const char of '25,99') {
|
|
136
|
+
fireEvent.change(amountInput, { target: { value: amountInput.value + char } })
|
|
137
|
+
const lastItems = onChange.mock.calls.at(-1)?.[0]
|
|
138
|
+
rerender(<PriceListEditor value={lastItems} onChange={onChange} />)
|
|
139
|
+
}
|
|
140
|
+
expect(amountInput.value).toBe('25,99')
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
describe('toSubmittedAmount (converts the raw typed text to a number at submit time)', () => {
|
|
144
|
+
it('parses a comma-decimal value', () => {
|
|
145
|
+
expect(toSubmittedAmount('110,70', 'pl-PL')).toBe(110.7)
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
it('still parses a dot-decimal value', () => {
|
|
149
|
+
expect(toSubmittedAmount('110.70', 'pl-PL')).toBe(110.7)
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
it('passes an already-numeric value through unchanged', () => {
|
|
153
|
+
expect(toSubmittedAmount(150, 'pl-PL')).toBe(150)
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
it('returns null for unparseable or blank input, never a silent 0 or NaN', () => {
|
|
157
|
+
expect(toSubmittedAmount('abc', 'pl-PL')).toBeNull()
|
|
158
|
+
expect(toSubmittedAmount('', 'pl-PL')).toBeNull()
|
|
159
|
+
expect(toSubmittedAmount(null, 'pl-PL')).toBeNull()
|
|
160
|
+
})
|
|
131
161
|
})
|
|
132
162
|
})
|