@open-mercato/core 0.5.1-develop.2949.009dcdd2d5 → 0.5.1-develop.2954.610bab2d08
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/helpers/integration/salesUi.js +25 -23
- package/dist/helpers/integration/salesUi.js.map +2 -2
- package/dist/modules/api_docs/frontend/docs/api/Explorer.js +24 -24
- package/dist/modules/api_docs/frontend/docs/api/Explorer.js.map +2 -2
- package/dist/modules/attachments/components/AttachmentPartitionSettings.js +15 -7
- package/dist/modules/attachments/components/AttachmentPartitionSettings.js.map +2 -2
- package/dist/modules/attachments/fields/attachment.js +4 -6
- package/dist/modules/attachments/fields/attachment.js.map +2 -2
- package/dist/modules/auth/api/users/route.js +63 -23
- package/dist/modules/auth/api/users/route.js.map +2 -2
- package/dist/modules/auth/backend/users/create/page.js +26 -26
- package/dist/modules/auth/backend/users/create/page.js.map +2 -2
- package/dist/modules/business_rules/components/ActionRow.js +36 -25
- package/dist/modules/business_rules/components/ActionRow.js.map +2 -2
- package/dist/modules/business_rules/components/ConditionGroup.js +14 -5
- package/dist/modules/business_rules/components/ConditionGroup.js.map +2 -2
- package/dist/modules/business_rules/components/ConditionRow.js +19 -10
- package/dist/modules/business_rules/components/ConditionRow.js.map +2 -2
- package/dist/modules/business_rules/components/RuleSetMembers.js +16 -10
- package/dist/modules/business_rules/components/RuleSetMembers.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js +30 -34
- package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
- package/dist/modules/catalog/backend/catalog/products/create/page.js +220 -223
- package/dist/modules/catalog/backend/catalog/products/create/page.js.map +2 -2
- package/dist/modules/catalog/components/PriceKindSettings.js +20 -19
- package/dist/modules/catalog/components/PriceKindSettings.js.map +2 -2
- package/dist/modules/catalog/components/products/ProductUomSection.js +42 -37
- package/dist/modules/catalog/components/products/ProductUomSection.js.map +2 -2
- package/dist/modules/catalog/components/products/VariantBuilder.js +22 -18
- package/dist/modules/catalog/components/products/VariantBuilder.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js +18 -26
- package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js.map +2 -2
- package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +4 -6
- package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
- package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js +5 -4
- package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js.map +2 -2
- package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js +19 -7
- package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js.map +2 -2
- package/dist/modules/customers/backend/customers/deals/pipeline/page.js +24 -21
- package/dist/modules/customers/backend/customers/deals/pipeline/page.js.map +2 -2
- package/dist/modules/customers/components/AddressEditor.js +24 -7
- package/dist/modules/customers/components/AddressEditor.js.map +2 -2
- package/dist/modules/customers/components/AddressFormatSettings.js +35 -25
- package/dist/modules/customers/components/AddressFormatSettings.js.map +2 -2
- package/dist/modules/customers/components/detail/ActivityForm.js +20 -12
- package/dist/modules/customers/components/detail/ActivityForm.js.map +2 -2
- package/dist/modules/customers/components/detail/AnnualRevenueField.js +2 -2
- package/dist/modules/customers/components/detail/AnnualRevenueField.js.map +2 -2
- package/dist/modules/customers/components/detail/DealForm.js +19 -14
- package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
- package/dist/modules/customers/components/formConfig.js +16 -12
- package/dist/modules/customers/components/formConfig.js.map +2 -2
- package/dist/modules/customers/widgets/dashboard/customer-todos/widget.client.js +3 -2
- package/dist/modules/customers/widgets/dashboard/customer-todos/widget.client.js.map +2 -2
- package/dist/modules/customers/widgets/dashboard/new-customers/widget.client.js +18 -10
- package/dist/modules/customers/widgets/dashboard/new-customers/widget.client.js.map +2 -2
- package/dist/modules/customers/widgets/dashboard/new-deals/widget.client.js +3 -2
- package/dist/modules/customers/widgets/dashboard/new-deals/widget.client.js.map +2 -2
- package/dist/modules/customers/widgets/dashboard/next-interactions/widget.client.js +3 -2
- package/dist/modules/customers/widgets/dashboard/next-interactions/widget.client.js.map +2 -2
- package/dist/modules/dashboards/components/WidgetVisibilityEditor.js +27 -28
- package/dist/modules/dashboards/components/WidgetVisibilityEditor.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/orders-by-status/widget.client.js +14 -6
- package/dist/modules/dashboards/widgets/dashboard/orders-by-status/widget.client.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.js +14 -6
- package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.js +3 -2
- package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.client.js +3 -2
- package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.client.js.map +2 -2
- package/dist/modules/dashboards/widgets/dashboard/top-products/widget.client.js +17 -8
- package/dist/modules/dashboards/widgets/dashboard/top-products/widget.client.js.map +2 -2
- package/dist/modules/data_sync/backend/data-sync/page.js +40 -23
- package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
- package/dist/modules/data_sync/components/IntegrationScheduleTab.js +15 -6
- package/dist/modules/data_sync/components/IntegrationScheduleTab.js.map +2 -2
- package/dist/modules/dictionaries/components/AppearanceSelector.js +4 -4
- package/dist/modules/dictionaries/components/AppearanceSelector.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js +4 -5
- package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js.map +2 -2
- package/dist/modules/dictionaries/components/DictionaryEntrySelect.js +22 -14
- package/dist/modules/dictionaries/components/DictionaryEntrySelect.js.map +2 -2
- package/dist/modules/dictionaries/fields/dictionary.js +18 -13
- package/dist/modules/dictionaries/fields/dictionary.js.map +2 -2
- package/dist/modules/entities/components/EncryptionManager.js +23 -19
- package/dist/modules/entities/components/EncryptionManager.js.map +2 -2
- package/dist/modules/feature_toggles/components/formConfig.js +17 -9
- package/dist/modules/feature_toggles/components/formConfig.js.map +2 -2
- package/dist/modules/feature_toggles/components/overrideFormConfig.js +17 -9
- package/dist/modules/feature_toggles/components/overrideFormConfig.js.map +2 -2
- package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js +15 -8
- package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js.map +2 -2
- package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js +37 -22
- package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/[id]/page.js +22 -17
- package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
- package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js +12 -6
- package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js.map +2 -2
- package/dist/modules/planner/components/AvailabilityRulesEditor.js +19 -12
- package/dist/modules/planner/components/AvailabilityRulesEditor.js.map +2 -2
- package/dist/modules/resources/components/ResourceCrudForm.js +15 -10
- package/dist/modules/resources/components/ResourceCrudForm.js.map +3 -3
- package/dist/modules/sales/backend/sales/documents/[id]/page.js +15 -18
- package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
- package/dist/modules/sales/components/ProviderFieldInput.js +23 -20
- package/dist/modules/sales/components/ProviderFieldInput.js.map +2 -2
- package/dist/modules/sales/components/ShippingMethodsSettings.js +25 -17
- package/dist/modules/sales/components/ShippingMethodsSettings.js.map +3 -3
- package/dist/modules/sales/components/channels/ChannelOfferForm.js +35 -42
- package/dist/modules/sales/components/channels/ChannelOfferForm.js.map +2 -2
- package/dist/modules/sales/components/documents/AddressesSection.js +87 -90
- package/dist/modules/sales/components/documents/AddressesSection.js.map +2 -2
- package/dist/modules/sales/components/documents/AdjustmentDialog.js +17 -6
- package/dist/modules/sales/components/documents/AdjustmentDialog.js.map +3 -3
- package/dist/modules/sales/components/documents/LineItemDialog.js +42 -25
- package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
- package/dist/modules/sales/components/documents/SalesDocumentForm.js +96 -87
- package/dist/modules/sales/components/documents/SalesDocumentForm.js.map +2 -2
- package/dist/modules/sales/widgets/dashboard/new-orders/widget.client.js +20 -11
- package/dist/modules/sales/widgets/dashboard/new-orders/widget.client.js.map +2 -2
- package/dist/modules/sales/widgets/dashboard/new-quotes/widget.client.js +20 -11
- package/dist/modules/sales/widgets/dashboard/new-quotes/widget.client.js.map +2 -2
- package/dist/modules/shipping_carriers/lib/shipment-wizard/components/ConfigureStep.js +36 -22
- package/dist/modules/shipping_carriers/lib/shipment-wizard/components/ConfigureStep.js.map +2 -2
- package/dist/modules/staff/components/TeamMemberForm.js +14 -9
- package/dist/modules/staff/components/TeamMemberForm.js.map +3 -3
- package/dist/modules/workflows/backend/tasks/[id]/page.js +42 -21
- package/dist/modules/workflows/backend/tasks/[id]/page.js.map +2 -2
- package/dist/modules/workflows/components/ActivitiesEditor.js +14 -6
- package/dist/modules/workflows/components/ActivitiesEditor.js.map +3 -3
- package/dist/modules/workflows/components/DefinitionTriggersEditor.js +25 -17
- package/dist/modules/workflows/components/DefinitionTriggersEditor.js.map +3 -3
- package/dist/modules/workflows/components/EdgeEditDialog.js +48 -45
- package/dist/modules/workflows/components/EdgeEditDialog.js.map +2 -2
- package/dist/modules/workflows/components/NodeEditDialog.js +90 -90
- package/dist/modules/workflows/components/NodeEditDialog.js.map +2 -2
- package/dist/modules/workflows/components/StepsEditor.js +14 -6
- package/dist/modules/workflows/components/StepsEditor.js.map +3 -3
- package/dist/modules/workflows/components/TransitionsEditor.js +31 -26
- package/dist/modules/workflows/components/TransitionsEditor.js.map +3 -3
- package/dist/modules/workflows/components/fields/ActivityArrayEditor.js +19 -11
- package/dist/modules/workflows/components/fields/ActivityArrayEditor.js.map +3 -3
- package/dist/modules/workflows/components/fields/BusinessRuleConditionsEditor.js +12 -14
- package/dist/modules/workflows/components/fields/BusinessRuleConditionsEditor.js.map +2 -2
- package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js +24 -16
- package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js.map +3 -3
- package/dist/modules/workflows/components/fields/StartPreConditionsEditor.js +12 -13
- package/dist/modules/workflows/components/fields/StartPreConditionsEditor.js.map +2 -2
- package/dist/modules/workflows/components/mobile/MobileTaskForm.js +12 -8
- package/dist/modules/workflows/components/mobile/MobileTaskForm.js.map +2 -2
- package/dist/modules/workflows/frontend/checkout-demo/page.js +43 -46
- package/dist/modules/workflows/frontend/checkout-demo/page.js.map +2 -2
- package/package.json +3 -3
- package/src/helpers/integration/salesUi.ts +40 -30
- package/src/modules/api_docs/frontend/docs/api/Explorer.tsx +25 -19
- package/src/modules/attachments/components/AttachmentPartitionSettings.tsx +21 -11
- package/src/modules/attachments/fields/attachment.tsx +4 -6
- package/src/modules/auth/api/users/route.ts +75 -25
- package/src/modules/auth/backend/users/create/page.tsx +16 -20
- package/src/modules/business_rules/components/ActionRow.tsx +51 -32
- package/src/modules/business_rules/components/ConditionGroup.tsx +20 -9
- package/src/modules/business_rules/components/ConditionRow.tsx +24 -15
- package/src/modules/business_rules/components/RuleSetMembers.tsx +23 -13
- package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +47 -53
- package/src/modules/catalog/backend/catalog/products/create/page.tsx +84 -87
- package/src/modules/catalog/components/PriceKindSettings.tsx +9 -9
- package/src/modules/catalog/components/products/ProductUomSection.tsx +85 -83
- package/src/modules/catalog/components/products/VariantBuilder.tsx +49 -33
- package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +12 -27
- package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +4 -6
- package/src/modules/customer_accounts/widgets/injection/account-status/widget.client.tsx +5 -4
- package/src/modules/customers/backend/config/customers/pipeline-stages/page.tsx +28 -15
- package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +37 -26
- package/src/modules/customers/components/AddressEditor.tsx +30 -16
- package/src/modules/customers/components/AddressFormatSettings.tsx +25 -19
- package/src/modules/customers/components/detail/ActivityForm.tsx +35 -23
- package/src/modules/customers/components/detail/AnnualRevenueField.tsx +2 -2
- package/src/modules/customers/components/detail/DealForm.tsx +33 -20
- package/src/modules/customers/components/formConfig.tsx +25 -17
- package/src/modules/customers/widgets/dashboard/customer-todos/widget.client.tsx +3 -2
- package/src/modules/customers/widgets/dashboard/new-customers/widget.client.tsx +21 -11
- package/src/modules/customers/widgets/dashboard/new-deals/widget.client.tsx +3 -2
- package/src/modules/customers/widgets/dashboard/next-interactions/widget.client.tsx +3 -2
- package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +17 -22
- package/src/modules/dashboards/widgets/dashboard/orders-by-status/widget.client.tsx +17 -7
- package/src/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.tsx +20 -10
- package/src/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.tsx +3 -2
- package/src/modules/dashboards/widgets/dashboard/top-customers/widget.client.tsx +3 -2
- package/src/modules/dashboards/widgets/dashboard/top-products/widget.client.tsx +20 -9
- package/src/modules/data_sync/backend/data-sync/page.tsx +64 -38
- package/src/modules/data_sync/components/IntegrationScheduleTab.tsx +18 -7
- package/src/modules/dictionaries/components/AppearanceSelector.tsx +4 -4
- package/src/modules/dictionaries/components/DictionaryEntriesEditor.tsx +3 -4
- package/src/modules/dictionaries/components/DictionaryEntrySelect.tsx +27 -21
- package/src/modules/dictionaries/fields/dictionary.tsx +36 -23
- package/src/modules/entities/components/EncryptionManager.tsx +49 -33
- package/src/modules/feature_toggles/components/formConfig.tsx +20 -10
- package/src/modules/feature_toggles/components/overrideFormConfig.tsx +20 -10
- package/src/modules/inbox_ops/backend/inbox-ops/settings/page.tsx +19 -10
- package/src/modules/inbox_ops/components/proposals/EditActionDialog.tsx +49 -26
- package/src/modules/integrations/backend/integrations/[id]/page.tsx +20 -11
- package/src/modules/integrations/backend/integrations/bundle/[id]/page.tsx +19 -9
- package/src/modules/planner/components/AvailabilityRulesEditor.tsx +34 -21
- package/src/modules/resources/components/ResourceCrudForm.tsx +24 -15
- package/src/modules/sales/backend/sales/documents/[id]/page.tsx +12 -15
- package/src/modules/sales/components/ProviderFieldInput.tsx +26 -17
- package/src/modules/sales/components/ShippingMethodsSettings.tsx +28 -20
- package/src/modules/sales/components/channels/ChannelOfferForm.tsx +51 -46
- package/src/modules/sales/components/documents/AddressesSection.tsx +78 -76
- package/src/modules/sales/components/documents/AdjustmentDialog.tsx +27 -15
- package/src/modules/sales/components/documents/LineItemDialog.tsx +69 -51
- package/src/modules/sales/components/documents/SalesDocumentForm.tsx +98 -87
- package/src/modules/sales/widgets/dashboard/new-orders/widget.client.tsx +23 -12
- package/src/modules/sales/widgets/dashboard/new-quotes/widget.client.tsx +23 -12
- package/src/modules/shipping_carriers/lib/shipment-wizard/components/ConfigureStep.tsx +35 -19
- package/src/modules/staff/components/TeamMemberForm.tsx +23 -14
- package/src/modules/workflows/backend/tasks/[id]/page.tsx +51 -23
- package/src/modules/workflows/components/ActivitiesEditor.tsx +20 -10
- package/src/modules/workflows/components/DefinitionTriggersEditor.tsx +28 -18
- package/src/modules/workflows/components/EdgeEditDialog.tsx +51 -40
- package/src/modules/workflows/components/NodeEditDialog.tsx +81 -77
- package/src/modules/workflows/components/StepsEditor.tsx +20 -10
- package/src/modules/workflows/components/TransitionsEditor.tsx +61 -44
- package/src/modules/workflows/components/fields/ActivityArrayEditor.tsx +22 -12
- package/src/modules/workflows/components/fields/BusinessRuleConditionsEditor.tsx +9 -13
- package/src/modules/workflows/components/fields/FormFieldArrayEditor.tsx +27 -17
- package/src/modules/workflows/components/fields/StartPreConditionsEditor.tsx +9 -12
- package/src/modules/workflows/components/mobile/MobileTaskForm.tsx +19 -11
- package/src/modules/workflows/frontend/checkout-demo/page.tsx +71 -60
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/sales/components/channels/ChannelOfferForm.tsx"],
|
|
4
|
-
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { CrudForm, type CrudField, type CrudFormGroup, type CrudFormGroupComponentProps } from '@open-mercato/ui/backend/CrudForm'\nimport { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'\nimport { createCrud, updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { createCrudFormError, type CrudServerFieldErrors } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { readApiResultOrThrow, apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Loader2, Search, Image as ImageIcon, Trash2 } from 'lucide-react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { E } from '#generated/entities.ids.generated'\nimport { buildAttachmentImageUrl, slugifyAttachmentFileName } from '@open-mercato/core/modules/attachments/lib/imageUrls'\nimport { cn } from '@open-mercato/shared/lib/utils'\n\ntype PriceKindSummary = {\n id: string\n code: string | null\n title: string | null\n displayMode: 'including-tax' | 'excluding-tax'\n currencyCode: string | null\n}\n\ntype PriceOverrideDraft = {\n tempId: string\n priceId?: string | null\n priceKindId?: string | null\n priceKindCode?: string | null\n currencyCode?: string | null\n displayMode?: 'including-tax' | 'excluding-tax' | null\n amount?: string\n}\n\nexport type OfferFormValues = {\n channelId: string | null\n productId: string | null\n title: string\n description: string\n defaultMediaId?: string | null\n isActive: boolean\n priceOverrides: PriceOverrideDraft[]\n} & Record<string, unknown>\n\ntype ChannelOfferFormProps = {\n channelId?: string\n offerId?: string\n mode: 'create' | 'edit'\n}\n\ntype OfferResponse = {\n items?: Array<Record<string, unknown>>\n}\n\ntype PriceResponse = {\n items?: Array<Record<string, unknown>>\n}\n\ntype AttachmentsResponse = {\n items?: Array<{ id?: string; fileName?: string; url?: string; thumbnailUrl?: string | null }>\n}\n\ntype ProductSummaryCacheEntry = {\n title: string\n description: string | null\n defaultMediaId: string | null\n defaultMediaUrl: string | null\n sku: string | null\n pricing: PricingSummary | null\n}\n\ntype MediaOption = { id: string; label: string; fileName: string; thumbnailUrl?: string | null }\n\ntype PricingSummary = {\n currencyCode: string | null\n unitPriceNet: string | null\n unitPriceGross: string | null\n displayMode: 'including-tax' | 'excluding-tax' | null\n}\n\ntype ProductVariantPreview = {\n id: string\n name: string\n sku: string | null\n thumbnailUrl: string | null\n thumbnailId: string | null\n thumbnailFileName: string | null\n}\n\ntype ProductSummary = ProductSummaryCacheEntry | null\n\ntype ProductSearchResult = {\n id: string\n title: string\n sku: string | null\n defaultMediaUrl: string | null\n pricing: PricingSummary | null\n existingOfferId: string | null\n existingOfferTitle: string | null\n isCurrentOfferProduct: boolean\n}\n\nconst UUID_REGEX = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/\nconst MAX_LIST_PAGE_SIZE = 100\ntype VariantThumbnailInfo = { attachmentId: string | null; thumbnailUrl: string | null; fileName: string | null }\n\nexport function ChannelOfferForm({ channelId: lockedChannelId, offerId, mode }: ChannelOfferFormProps) {\n const t = useT()\n const router = useRouter()\n const [initialValues, setInitialValues] = React.useState<OfferFormValues | null>(mode === 'create'\n ? {\n channelId: lockedChannelId ?? null,\n productId: null,\n title: '',\n description: '',\n defaultMediaId: null,\n isActive: true,\n priceOverrides: [],\n }\n : null)\n const [loading, setLoading] = React.useState(mode === 'edit')\n const [error, setError] = React.useState<string | null>(null)\n const [priceKinds, setPriceKinds] = React.useState<PriceKindSummary[]>([])\n const [mediaOptions, setMediaOptions] = React.useState<MediaOption[]>([])\n const attachmentCache = React.useRef<Map<string, MediaOption[]>>(new Map())\n const productCache = React.useRef<Map<string, ProductSummaryCacheEntry>>(new Map())\n const [productSummary, setProductSummary] = React.useState<ProductSummary>(null)\n const [variantPreviews, setVariantPreviews] = React.useState<ProductVariantPreview[]>([])\n const variantCache = React.useRef<Map<string, ProductVariantPreview[]>>(new Map())\n const variantMediaCache = React.useRef<Map<string, VariantThumbnailInfo>>(new Map())\n const [selectedChannelId, setSelectedChannelId] = React.useState<string | null>(lockedChannelId ?? null)\n const manualMediaSelections = React.useRef<Set<string>>(new Set())\n const initialPriceIdsRef = React.useRef<Set<string>>(new Set())\n const [currentProductId, setCurrentProductId] = React.useState<string | null>(null)\n React.useEffect(() => {\n if (initialValues) {\n initialPriceIdsRef.current = collectPriceIds(initialValues.priceOverrides)\n } else {\n initialPriceIdsRef.current = new Set()\n }\n }, [initialValues])\n const channelOffersHref = React.useMemo(\n () => buildChannelOffersHref(lockedChannelId),\n [lockedChannelId],\n )\n\n React.useEffect(() => {\n if (lockedChannelId) {\n setSelectedChannelId(lockedChannelId)\n } else if (initialValues?.channelId) {\n setSelectedChannelId(initialValues.channelId)\n }\n }, [initialValues?.channelId, lockedChannelId])\n\n React.useEffect(() => {\n if (typeof initialValues?.productId === 'string') {\n setCurrentProductId(initialValues.productId)\n }\n }, [initialValues?.productId])\n\n React.useEffect(() => {\n if (typeof initialValues?.productId === 'string' && initialValues?.defaultMediaId === null) {\n manualMediaSelections.current.add(initialValues.productId)\n }\n }, [initialValues?.defaultMediaId, initialValues?.productId])\n\n React.useEffect(() => {\n if (mode !== 'edit') return\n const productId = typeof initialValues?.productId === 'string' ? initialValues.productId : null\n if (!productId) return\n const resolvedProductId = productId\n const hydrationChannelId = selectedChannelId\n ?? lockedChannelId\n ?? (typeof initialValues?.channelId === 'string' ? initialValues.channelId : null)\n let cancelled = false\n async function hydrateExistingProduct() {\n try {\n const [summary, attachments, variants] = await Promise.all([\n resolveProductSummaryWithCache({\n productId: resolvedProductId,\n channelId: hydrationChannelId ?? null,\n productCache,\n }),\n resolveProductMediaOptionsWithCache({ productId: resolvedProductId, attachmentCache }),\n resolveVariantPreviewsWithCache({ productId: resolvedProductId, variantCache, variantMediaCache }),\n ])\n if (!cancelled) {\n setProductSummary(summary ?? null)\n const mergedMedia = buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n })\n attachmentCache.current.set(resolvedProductId, mergedMedia)\n setMediaOptions(mergedMedia)\n setVariantPreviews(variants)\n }\n } catch (err) {\n console.error('sales.channels.offer.initialHydrate', err)\n }\n }\n void hydrateExistingProduct()\n return () => {\n cancelled = true\n }\n }, [\n attachmentCache,\n initialValues?.channelId,\n initialValues?.productId,\n lockedChannelId,\n mode,\n productCache,\n selectedChannelId,\n setMediaOptions,\n setProductSummary,\n setVariantPreviews,\n variantCache,\n variantMediaCache,\n ])\n\n React.useEffect(() => {\n async function loadKinds() {\n const mapItems = (items: Array<Record<string, unknown>>): PriceKindSummary[] =>\n items.map((item): PriceKindSummary => {\n const displayMode =\n item.displayMode === 'including-tax' || item.display_mode === 'including-tax'\n ? 'including-tax'\n : 'excluding-tax'\n return {\n id: typeof item.id === 'string' ? item.id : '',\n code: typeof item.code === 'string' ? item.code : null,\n title: typeof item.title === 'string' ? item.title : null,\n currencyCode:\n typeof item.currencyCode === 'string'\n ? item.currencyCode\n : typeof item.currency_code === 'string'\n ? item.currency_code\n : null,\n displayMode,\n }\n })\n const endpoints = [\n `/api/sales/price-kinds?pageSize=${MAX_LIST_PAGE_SIZE}`,\n `/api/catalog/price-kinds?pageSize=${MAX_LIST_PAGE_SIZE}`,\n ]\n try {\n for (const endpoint of endpoints) {\n try {\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n endpoint,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n setPriceKinds(mapItems(items))\n return\n } catch (err) {\n console.error('sales.channels.price-kinds.fetch', { endpoint, err })\n }\n }\n setPriceKinds([])\n } catch (err) {\n console.error('catalog.price-kinds.list', err)\n }\n }\n void loadKinds()\n }, [])\n\n React.useEffect(() => {\n if (mode !== 'edit' || !offerId) return\n const offerKey = offerId\n let cancelled = false\n async function loadOffer() {\n setLoading(true)\n setError(null)\n try {\n const payload = await readApiResultOrThrow<OfferResponse>(\n `/api/catalog/offers?id=${encodeURIComponent(offerKey)}&pageSize=1`,\n undefined,\n { errorMessage: t('sales.channels.offers.errors.loadOffer', 'Failed to load offer.') },\n )\n const offer = Array.isArray(payload.items) ? payload.items[0] : null\n if (!offer) throw new Error('not_found')\n const values = mapOfferToFormValues(offer, lockedChannelId)\n const pricePayload = await readApiResultOrThrow<PriceResponse>(\n `/api/catalog/prices?offerId=${encodeURIComponent(offer.id as string)}&pageSize=${MAX_LIST_PAGE_SIZE}`,\n undefined,\n { fallback: { items: [] } },\n )\n const priceItems = Array.isArray(pricePayload.items) ? pricePayload.items : []\n values.priceOverrides = priceItems.map(mapPriceRow)\n let preloadedMedia: MediaOption[] = []\n let preloadedVariants: ProductVariantPreview[] = []\n let preloadedSummary: ProductSummary | null = null\n const productId = typeof values.productId === 'string' ? values.productId : null\n if (productId) {\n try {\n const hydrationChannelId = selectedChannelId\n ?? lockedChannelId\n ?? (typeof values.channelId === 'string' ? values.channelId : null)\n const [summary, attachments, variants] = await Promise.all([\n resolveProductSummaryWithCache({\n productId,\n channelId: hydrationChannelId ?? null,\n productCache,\n }),\n loadProductMedia(productId),\n resolveVariantPreviewsWithCache({ productId, variantCache, variantMediaCache }),\n ])\n preloadedSummary = summary ?? null\n preloadedVariants = variants\n preloadedMedia = buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n })\n attachmentCache.current.set(productId, preloadedMedia)\n } catch (err) {\n console.error('sales.channels.offer.media.preload', err)\n }\n }\n if (!cancelled) {\n setInitialValues(values)\n setProductSummary(preloadedSummary)\n setVariantPreviews(preloadedVariants)\n setMediaOptions(preloadedMedia)\n }\n } catch (err) {\n console.error('sales.channels.offer.load', err)\n if (!cancelled) setError(t('sales.channels.offers.errors.loadOffer', 'Failed to load offer.'))\n } finally {\n if (!cancelled) setLoading(false)\n }\n }\n void loadOffer()\n return () => { cancelled = true }\n }, [\n attachmentCache,\n lockedChannelId,\n mode,\n offerId,\n productCache,\n selectedChannelId,\n setMediaOptions,\n setProductSummary,\n setVariantPreviews,\n t,\n variantCache,\n variantMediaCache,\n ])\n\n const fields = React.useMemo<CrudField[]>(() => [\n {\n id: 'channelId',\n label: t('sales.channels.offers.form.channel', 'Channel'),\n type: 'custom',\n required: true,\n component: ({ value, setValue }) => (\n <ChannelSelectInput\n value={(value as string | null) ?? lockedChannelId ?? null}\n onChange={(next) => {\n setValue(next ?? null)\n setSelectedChannelId(next ?? null)\n }}\n disabled={!!lockedChannelId}\n showDetailsLink\n />\n ),\n },\n {\n id: 'productId',\n label: t('sales.channels.offers.form.product', 'Product'),\n type: 'custom',\n required: true,\n component: ({ value, setValue }) => (\n <ProductSelectInput\n value={(value as string | null) ?? null}\n onChange={(next) => setValue(next)}\n channelId={selectedChannelId}\n currentOfferId={offerId ?? null}\n />\n ),\n },\n {\n id: 'defaultMediaId',\n label: t('sales.channels.offers.form.defaultMedia', 'Default media'),\n type: 'custom',\n component: ({ value, setValue }) => (\n <DefaultMediaSelect\n value={(value as string | null | undefined) ?? null}\n onChange={(next) => {\n setValue(next)\n if (!currentProductId) return\n if (next === null || next === undefined) {\n manualMediaSelections.current.add(currentProductId)\n } else {\n manualMediaSelections.current.delete(currentProductId)\n }\n }}\n options={mediaOptions}\n productThumbnail={productSummary?.defaultMediaUrl ?? null}\n hasProduct={Boolean(productSummary)}\n productDefaultMediaId={productSummary?.defaultMediaId ?? null}\n />\n ),\n },\n {\n id: 'title',\n label: t('sales.channels.offers.form.title', 'Title'),\n type: 'text',\n required: true,\n },\n {\n id: 'description',\n label: t('sales.channels.offers.form.description', 'Description'),\n type: 'textarea',\n },\n {\n id: 'isActive',\n label: t('sales.channels.offers.form.active', 'Active'),\n type: 'checkbox',\n },\n ], [lockedChannelId, mediaOptions, productSummary, selectedChannelId, t, currentProductId])\n\n const handleOverrideRemove = React.useCallback(async (draft: PriceOverrideDraft) => {\n const priceId = typeof draft?.priceId === 'string' ? draft.priceId : null\n if (!priceId) return true\n if (mode !== 'edit') return true\n try {\n await deleteCrud('catalog/prices', priceId, {\n errorMessage: t('sales.channels.offers.errors.removePrice', 'Failed to remove price override.'),\n })\n initialPriceIdsRef.current.delete(priceId)\n return true\n } catch (err) {\n console.error('sales.channels.pricing.remove', err)\n flash(t('sales.channels.offers.errors.removePrice', 'Failed to remove price override.'), 'error')\n return false\n }\n }, [mode, t])\n\n const groups = React.useMemo<CrudFormGroup[]>(() => [\n { id: 'associations', column: 1, title: t('sales.channels.offers.form.groups.associations', 'Associations'), fields: ['channelId'] },\n {\n id: 'product',\n column: 1,\n title: t('sales.channels.offers.form.productGroup', 'Product'),\n description: t('sales.channels.offers.form.productGroupHelp', 'Search the catalog and pick the product you want to customize for this channel.'),\n fields: ['productId'],\n },\n {\n id: 'productSummary',\n column: 2,\n title: t('sales.channels.offers.form.productSummaryTitle', 'Product summary'),\n component: () => (\n <ProductOverviewCard summary={productSummary} variants={variantPreviews} />\n ),\n },\n {\n id: 'media',\n column: 1,\n title: t('sales.channels.offers.form.mediaGroupTitle', 'Default media override'),\n fields: ['defaultMediaId'],\n },\n { id: 'content', column: 1, title: t('sales.channels.offers.form.groups.content', 'Content'), fields: ['title', 'description', 'isActive'] },\n {\n id: 'pricing',\n column: 1,\n title: t('sales.channels.offers.form.groups.pricing', 'Price overrides'),\n component: ({ values, setValue }) => (\n <PriceOverridesEditor\n values={Array.isArray(values.priceOverrides) ? values.priceOverrides as PriceOverrideDraft[] : []}\n onChange={(next) => setValue('priceOverrides', next)}\n priceKinds={priceKinds}\n basePrice={productSummary?.pricing ?? null}\n onRemoveDraft={handleOverrideRemove}\n />\n ),\n },\n {\n id: 'customFields',\n column: 2,\n title: t('entities.customFields.title', 'Custom attributes'),\n kind: 'customFields',\n },\n {\n id: 'watchers',\n column: 1,\n bare: true,\n component: ({ values, setValue, errors }) => (\n <OfferFormWatchers\n values={values}\n setValue={setValue}\n errors={errors}\n productCache={productCache}\n attachmentCache={attachmentCache}\n setMediaOptions={setMediaOptions}\n setProductSummary={setProductSummary}\n setVariantPreviews={setVariantPreviews}\n variantCache={variantCache}\n variantMediaCache={variantMediaCache}\n channelId={selectedChannelId}\n manualMediaSelections={manualMediaSelections}\n setCurrentProductId={setCurrentProductId}\n />\n ),\n },\n ], [\n attachmentCache,\n handleOverrideRemove,\n manualMediaSelections,\n priceKinds,\n productCache,\n productSummary,\n selectedChannelId,\n setMediaOptions,\n setCurrentProductId,\n t,\n variantPreviews,\n ])\n\n const handleSubmit = React.useCallback(async (values: OfferFormValues) => {\n const channelId = typeof values.channelId === 'string' && values.channelId.length\n ? values.channelId\n : selectedChannelId ?? lockedChannelId\n const productId = typeof values.productId === 'string' ? values.productId : null\n if (!channelId || !productId) {\n throw new Error(t('sales.channels.offers.errors.requiredFields', 'Choose a channel and product.'))\n }\n const resolvedDefaultMediaId = typeof values.defaultMediaId === 'string' && values.defaultMediaId.trim().length\n ? values.defaultMediaId\n : values.defaultMediaId === null\n ? null\n : undefined\n const basePayload: Record<string, unknown> = {\n channelId,\n productId,\n title: values.title?.trim() || undefined,\n description: values.description?.trim() || undefined,\n isActive: values.isActive !== false,\n }\n if (resolvedDefaultMediaId !== undefined) {\n basePayload.defaultMediaId = resolvedDefaultMediaId\n }\n const attachmentLookup = attachmentCache.current.get(productId) ?? []\n const mediaMap = new Map(attachmentLookup.map((entry) => [entry.id, entry.fileName]))\n if (typeof resolvedDefaultMediaId === 'string' && mediaMap.has(resolvedDefaultMediaId)) {\n const fileName = mediaMap.get(resolvedDefaultMediaId) ?? null\n basePayload.defaultMediaUrl = buildAttachmentImageUrl(resolvedDefaultMediaId, {\n slug: slugifyAttachmentFileName(fileName),\n })\n } else if (resolvedDefaultMediaId === null) {\n basePayload.defaultMediaUrl = null\n }\n const customFields = collectCustomFieldValues(values)\n if (Object.keys(customFields).length) basePayload.customFields = customFields\n const overrides = Array.isArray(values.priceOverrides) ? values.priceOverrides as PriceOverrideDraft[] : []\n const priceWithoutKind = overrides.find((entry) => {\n const amount = typeof entry.amount === 'string' ? entry.amount.trim() : entry.amount\n const hasAmount = typeof amount === 'string' ? amount.length > 0 : amount !== undefined && amount !== null\n const hasExistingPrice = typeof entry.priceId === 'string' && entry.priceId.length > 0\n const hasCurrency = typeof entry.currencyCode === 'string' && entry.currencyCode.length > 0\n return !entry.priceKindId && (hasAmount || hasExistingPrice || hasCurrency)\n })\n if (priceWithoutKind) {\n throw createCrudFormError(t('sales.channels.offers.errors.priceKindRequired', 'Select a price kind for each override.'), {})\n }\n const duplicateKind = (() => {\n const seen = new Set<string>()\n for (const entry of overrides) {\n const kindId = typeof entry.priceKindId === 'string' ? entry.priceKindId : null\n if (!kindId) continue\n if (seen.has(kindId)) return kindId\n seen.add(kindId)\n }\n return null\n })()\n if (duplicateKind) {\n throw createCrudFormError(\n t('sales.channels.offers.errors.priceKindDuplicate', 'Each price kind can only be overridden once.'),\n {},\n )\n }\n const submittedPriceIds = collectPriceIds(overrides)\n const deletedIdSet = new Set<string>()\n initialPriceIdsRef.current.forEach((id) => {\n if (!submittedPriceIds.has(id)) deletedIdSet.add(id)\n })\n const deletedIds = Array.from(deletedIdSet)\n let savedId = offerId ?? null\n try {\n if (mode === 'create') {\n const res = await createCrud<{ id?: string; offerId?: string }>('catalog/offers', basePayload, {\n errorMessage: t('sales.channels.offers.errors.save', 'Failed to save offer.'),\n })\n savedId = res?.result?.offerId ?? res?.result?.id ?? null\n } else if (offerId) {\n await updateCrud('catalog/offers', { id: offerId, ...basePayload }, {\n errorMessage: t('sales.channels.offers.errors.save', 'Failed to save offer.'),\n })\n savedId = offerId\n }\n } catch (err) {\n const details = (err as { details?: unknown })?.details\n const rawFieldErrors = (err as { fieldErrors?: unknown })?.fieldErrors\n const fieldErrors = rawFieldErrors && typeof rawFieldErrors === 'object'\n ? (rawFieldErrors as CrudServerFieldErrors)\n : undefined\n const status = (err as { status?: number })?.status\n const message = typeof (err as { message?: unknown }).message === 'string' && (err as { message: string }).message.trim().length\n ? (err as { message: string }).message\n : t(\n 'sales.channels.offers.errors.duplicateProduct',\n 'This product already has an offer in this channel.',\n )\n throw createCrudFormError(\n message,\n fieldErrors,\n { status, details },\n )\n }\n if (savedId) {\n await syncPriceOverrides({\n overrides,\n deletedIds,\n offerId: savedId,\n channelId,\n productId,\n })\n initialPriceIdsRef.current = submittedPriceIds\n }\n flash(t('sales.channels.offers.messages.saved', 'Offer saved.'), 'success')\n router.push(buildChannelOffersHref(channelId))\n }, [attachmentCache, initialPriceIdsRef, lockedChannelId, mode, offerId, router, selectedChannelId, t])\n\n const handleDelete = React.useCallback(async () => {\n if (!offerId) return\n await deleteCrud('catalog/offers', offerId, {\n errorMessage: t('sales.channels.offers.errors.delete', 'Failed to delete offer.'),\n })\n flash(t('sales.channels.offers.messages.deleted', 'Offer deleted.'), 'success')\n const targetChannel = initialValues?.channelId ?? lockedChannelId ?? ''\n router.push(buildChannelOffersHref(targetChannel))\n }, [initialValues?.channelId, lockedChannelId, offerId, router, t])\n\n return (\n <div>\n {error ? (\n <div className=\"mb-4 rounded border border-destructive/40 bg-destructive/10 px-4 py-3 text-sm text-destructive\">\n {error}\n </div>\n ) : null}\n <CrudForm<OfferFormValues>\n title={mode === 'create'\n ? t('sales.channels.offers.form.createTitle', 'Create offer')\n : t('sales.channels.offers.form.editTitle', 'Edit offer')}\n entityId={E.catalog.catalog_offer}\n fields={fields}\n groups={groups}\n initialValues={initialValues ?? undefined}\n isLoading={loading}\n loadingMessage={t('sales.channels.offers.form.loading', 'Loading offer\u2026')}\n submitLabel={mode === 'create'\n ? t('sales.channels.offers.form.createSubmit', 'Create offer')\n : t('sales.channels.offers.form.updateSubmit', 'Save changes')}\n cancelHref={channelOffersHref}\n backHref={channelOffersHref}\n onSubmit={handleSubmit}\n onDelete={mode === 'edit' ? handleDelete : undefined}\n deleteVisible={mode === 'edit'}\n deleteRedirect={channelOffersHref}\n />\n </div>\n )\n}\n\nfunction mapOfferToFormValues(item: Record<string, unknown>, lockedChannelId?: string | null): OfferFormValues {\n const values: OfferFormValues = {\n channelId: typeof item.channelId === 'string'\n ? item.channelId\n : typeof item.channel_id === 'string'\n ? item.channel_id\n : lockedChannelId ?? null,\n productId: typeof item.productId === 'string'\n ? item.productId\n : typeof item.product_id === 'string'\n ? item.product_id\n : null,\n title: typeof item.title === 'string' ? item.title : '',\n description: typeof item.description === 'string' ? item.description : '',\n defaultMediaId: typeof item.defaultMediaId === 'string'\n ? item.defaultMediaId\n : typeof item.default_media_id === 'string'\n ? item.default_media_id\n : null,\n isActive: item.isActive === true || item.is_active === true,\n priceOverrides: [],\n }\n mergeCustomFieldValues(values, item)\n return values\n}\n\nfunction mapPriceRow(row: Record<string, unknown>): PriceOverrideDraft {\n return {\n tempId: String(row.id ?? crypto.randomUUID?.() ?? Math.random()),\n priceId: typeof row.id === 'string' ? row.id : undefined,\n priceKindId: typeof row.priceKindId === 'string'\n ? row.priceKindId\n : typeof row.price_kind_id === 'string'\n ? row.price_kind_id\n : undefined,\n priceKindCode: typeof row.priceKindCode === 'string'\n ? row.priceKindCode\n : typeof row.price_kind_code === 'string'\n ? row.price_kind_code\n : null,\n currencyCode: typeof row.currencyCode === 'string'\n ? row.currencyCode\n : typeof row.currency_code === 'string'\n ? row.currency_code\n : null,\n displayMode: row.displayMode === 'including-tax' || row.display_mode === 'including-tax'\n ? 'including-tax'\n : 'excluding-tax',\n amount: typeof row.unitPriceNet === 'string'\n ? row.unitPriceNet\n : typeof row.unit_price_net === 'string'\n ? row.unit_price_net\n : typeof row.unitPriceGross === 'string'\n ? row.unitPriceGross\n : typeof row.unit_price_gross === 'string'\n ? row.unit_price_gross\n : '',\n }\n}\n\nfunction collectPriceIds(source: PriceOverrideDraft[] | null | undefined): Set<string> {\n if (!Array.isArray(source)) return new Set()\n const ids = source\n .map((entry) => (typeof entry?.priceId === 'string' ? entry.priceId : null))\n .filter((id): id is string => Boolean(id))\n return new Set(ids)\n}\n\nfunction mergeCustomFieldValues(target: Record<string, unknown>, source: Record<string, unknown> | null | undefined) {\n if (!source || typeof source !== 'object') return\n const assign = (key: string | null | undefined, value: unknown) => {\n if (!key) return\n target[`cf_${key}`] = value\n }\n for (const [rawKey, rawValue] of Object.entries(source)) {\n if (rawKey.startsWith('cf_')) {\n if (rawKey.endsWith('__is_multi')) continue\n target[rawKey] = rawValue\n } else if (rawKey.startsWith('cf:')) {\n assign(rawKey.slice(3), rawValue)\n }\n }\n const customValues =\n (source as Record<string, unknown>).customValues ??\n (source as Record<string, unknown>).custom_values\n if (customValues && typeof customValues === 'object' && !Array.isArray(customValues)) {\n for (const [key, value] of Object.entries(customValues as Record<string, unknown>)) {\n assign(key, value)\n }\n }\n const customFields =\n (source as Record<string, unknown>).customFields ??\n (source as Record<string, unknown>).custom_fields\n if (Array.isArray(customFields)) {\n customFields.forEach((entry) => {\n if (!entry || typeof entry !== 'object') return\n const entryRecord = entry as Record<string, unknown>\n const key = typeof entryRecord.key === 'string' ? entryRecord.key : null\n if (!key) return\n assign(key, entryRecord.value)\n })\n } else if (customFields && typeof customFields === 'object') {\n for (const [key, value] of Object.entries(customFields as Record<string, unknown>)) {\n assign(key, value)\n }\n }\n const customEntries =\n (source as Record<string, unknown>).customFieldEntries ??\n (source as Record<string, unknown>).custom_field_entries\n if (Array.isArray(customEntries)) {\n customEntries.forEach((entry) => {\n if (!entry || typeof entry !== 'object') return\n const entryRecord = entry as Record<string, unknown>\n const key = typeof entryRecord.key === 'string' ? entryRecord.key : null\n if (!key) return\n assign(key, entryRecord.value)\n })\n }\n}\n\nfunction buildChannelOffersHref(channelId?: string | null): string {\n return channelId && channelId.length\n ? `/backend/sales/channels/${channelId}/edit?tab=offers`\n : '/backend/sales/channels/offers'\n}\n\nasync function syncPriceOverrides(params: {\n overrides: PriceOverrideDraft[]\n deletedIds: string[]\n offerId: string\n channelId: string\n productId: string\n}) {\n const { overrides, deletedIds, offerId, channelId, productId } = params\n for (const draft of overrides) {\n if (!draft.priceKindId || !draft.amount) continue\n const amount = Number(draft.amount)\n if (Number.isNaN(amount)) continue\n const payload: Record<string, unknown> = {\n offerId,\n productId,\n channelId,\n priceKindId: draft.priceKindId,\n currencyCode: draft.currencyCode ?? undefined,\n }\n if (draft.displayMode === 'including-tax') {\n payload.unitPriceGross = amount\n } else {\n payload.unitPriceNet = amount\n }\n if (draft.priceId) {\n await updateCrud('catalog/prices', { id: draft.priceId, ...payload })\n } else {\n await createCrud('catalog/prices', payload)\n }\n }\n const uniqueDeletedIds = Array.from(new Set(\n deletedIds.filter((id): id is string => typeof id === 'string' && id.length > 0),\n ))\n for (const id of uniqueDeletedIds) {\n if (!id) continue\n try {\n await deleteCrud('catalog/prices', id)\n } catch (err) {\n console.error('catalog.prices.delete', err)\n }\n }\n}\n\nfunction ChannelSelectInput({\n value,\n onChange,\n disabled,\n showDetailsLink,\n}: {\n value: string | null\n onChange: (next: string | null) => void\n disabled?: boolean\n showDetailsLink?: boolean\n}) {\n const t = useT()\n const [options, setOptions] = React.useState<Array<{ id: string; name: string; code: string | null }>>([])\n const selectedOption = React.useMemo(\n () => (value ? options.find((opt) => opt.id === value) ?? null : null),\n [options, value],\n )\n React.useEffect(() => {\n async function load() {\n try {\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/channels?pageSize=${MAX_LIST_PAGE_SIZE}`,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n setOptions(items.map((item) => ({\n id: typeof item.id === 'string' ? item.id : '',\n name: typeof item.name === 'string' ? item.name : '',\n code: typeof item.code === 'string' ? item.code : null,\n })))\n } catch (err) {\n console.error('sales.channels.options', err)\n }\n }\n void load()\n }, [])\n React.useEffect(() => {\n const channelIdToLoad = typeof value === 'string' ? value : null\n if (!channelIdToLoad || selectedOption) return\n const resolvedChannelId = channelIdToLoad\n let cancelled = false\n async function loadSingle() {\n try {\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/channels?id=${encodeURIComponent(resolvedChannelId)}&pageSize=1`,\n undefined,\n { fallback: { items: [] } },\n )\n const item = Array.isArray(payload.items) ? payload.items[0] : null\n if (!item || cancelled) return\n const entry = {\n id: typeof item.id === 'string' ? item.id : resolvedChannelId,\n name: typeof item.name === 'string' ? item.name : resolvedChannelId,\n code: typeof item.code === 'string' ? item.code : null,\n }\n setOptions((prev) => {\n if (prev.some((opt) => opt.id === entry.id)) return prev\n return [...prev, entry]\n })\n } catch (err) {\n console.error('sales.channels.lookup', err)\n }\n }\n void loadSingle()\n return () => { cancelled = true }\n }, [selectedOption, value])\n\n if (disabled && value) {\n const label = selectedOption?.name ?? value\n const detail = selectedOption?.code ?? null\n return (\n <div className=\"flex items-center justify-between gap-3 rounded border bg-muted px-3 py-2 text-sm\">\n <div className=\"min-w-0\">\n <div className=\"font-medium truncate\">{label}</div>\n {detail ? (\n <div className=\"text-xs text-muted-foreground truncate\">{detail}</div>\n ) : null}\n </div>\n {showDetailsLink ? (\n <Link href={`/backend/sales/channels/${value}/edit`} className=\"text-xs font-medium text-primary hover:underline\">\n {t('sales.channels.offers.form.channelDetails', 'Details')}\n </Link>\n ) : null}\n </div>\n )\n }\n return (\n <select\n className=\"w-full rounded border px-2 py-2 text-sm\"\n value={value ?? ''}\n onChange={(event) => onChange(event.target.value || null)}\n >\n <option value=\"\">{t('sales.channels.offers.form.channelPlaceholder', 'Select channel')}</option>\n {options.map((opt) => (\n <option key={opt.id} value={opt.id}>\n {opt.code ? `${opt.name} (${opt.code})` : opt.name}\n </option>\n ))}\n </select>\n )\n}\n\nfunction ProductSelectInput({\n value,\n onChange,\n channelId,\n currentOfferId,\n}: {\n value: string | null\n onChange: (next: string | null) => void\n channelId: string | null\n currentOfferId?: string | null\n}) {\n const t = useT()\n const [query, setQuery] = React.useState('')\n const [results, setResults] = React.useState<ProductSearchResult[]>([])\n const [isLoading, setLoading] = React.useState(false)\n const [hasTyped, setHasTyped] = React.useState(false)\n\n const trimmed = query.trim()\n const shouldSearch = trimmed.length >= 2 || UUID_REGEX.test(trimmed)\n\n React.useEffect(() => {\n if (!shouldSearch) {\n setResults([])\n return\n }\n let cancelled = false\n const controller = new AbortController()\n const timeout = setTimeout(async () => {\n setLoading(true)\n try {\n const params = new URLSearchParams({ pageSize: '10' })\n if (UUID_REGEX.test(trimmed)) {\n params.set('id', trimmed)\n } else if (trimmed.length) {\n params.set('search', trimmed)\n }\n if (channelId) params.set('channelId', channelId)\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/catalog/products?${params.toString()}`,\n { signal: controller.signal },\n { fallback: { items: [] } },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n if (!cancelled) {\n const mapped = items.map((item) => mapProductSearchResult(item, channelId, currentOfferId))\n mapped.sort((a, b) => {\n const aBlocked = Boolean(a.existingOfferId && !a.isCurrentOfferProduct)\n const bBlocked = Boolean(b.existingOfferId && !b.isCurrentOfferProduct)\n return Number(aBlocked) - Number(bBlocked)\n })\n setResults(mapped)\n }\n } catch (err) {\n if ((err as Error).name === 'AbortError') return\n console.error('catalog.products.lookup', err)\n } finally {\n if (!cancelled) setLoading(false)\n }\n }, 250)\n return () => {\n cancelled = true\n clearTimeout(timeout)\n controller.abort()\n }\n }, [channelId, currentOfferId, shouldSearch, trimmed])\n\n const handleKeyDown = React.useCallback((event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.key === 'Enter' && UUID_REGEX.test(trimmed)) {\n event.preventDefault()\n onChange(trimmed)\n }\n }, [onChange, trimmed])\n\n const selectedHint = value\n ? t('sales.channels.offers.form.productSelectedHint', 'Selected product ID: {{id}}', { id: value })\n : null\n\n return (\n <div className=\"space-y-3\">\n <div className=\"relative\">\n <Search className=\"pointer-events-none absolute left-2 top-2.5 h-4 w-4 text-muted-foreground\" />\n <input\n className=\"w-full rounded border pl-8 pr-2 py-2 text-sm\"\n value={query}\n onChange={(event) => {\n setQuery(event.target.value)\n setHasTyped(true)\n }}\n onKeyDown={handleKeyDown}\n placeholder={t('sales.channels.offers.form.productSearchPlaceholder', 'Search by title, SKU, or ID\u2026')}\n />\n </div>\n {selectedHint ? (\n <div className=\"rounded border bg-muted px-3 py-2 text-xs text-muted-foreground\">\n {selectedHint}\n </div>\n ) : null}\n {value ? (\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => onChange(null)}>\n {t('sales.channels.offers.form.productClear', 'Clear selection')}\n </Button>\n ) : null}\n {shouldSearch ? (\n <div className=\"space-y-2\">\n {isLoading ? (\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n {t('sales.channels.offers.form.productSearchLoading', 'Searching products\u2026')}\n </div>\n ) : null}\n {!isLoading && !results.length ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSearchEmpty', 'No products match your search.')}\n </p>\n ) : null}\n <div className=\"space-y-2 max-h-80 overflow-y-auto\">\n {results.map((product) => {\n const isSelected = value === product.id\n const hasConflict = Boolean(product.existingOfferId && !product.isCurrentOfferProduct)\n return (\n <div\n key={product.id}\n className={cn(\n 'flex gap-3 rounded border bg-card p-3 transition-colors',\n isSelected ? 'border-primary/70 bg-primary/5' : 'hover:border-primary/50',\n )}\n >\n <div className=\"h-12 w-12 overflow-hidden rounded border bg-muted\">\n {product.defaultMediaUrl ? (\n <img src={product.defaultMediaUrl} alt={product.title} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-5 w-5\" />\n </div>\n )}\n </div>\n <div className=\"flex flex-1 flex-col gap-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm font-medium\">{product.title || t('sales.channels.offers.form.productUntitled', 'Untitled product')}</div>\n {product.sku ? (\n <div className=\"text-xs text-muted-foreground\">SKU \u00B7 {product.sku}</div>\n ) : null}\n </div>\n <div className=\"text-xs font-medium text-muted-foreground\">\n {product.pricing ? formatPriceDisplay(product.pricing) : t('sales.channels.offers.form.productPriceMissing', 'No price')}\n </div>\n </div>\n {hasConflict ? (\n <div className=\"flex items-center justify-between gap-2 text-xs text-status-warning-text\">\n <span className=\"truncate\">\n {t('sales.channels.offers.form.productHasOffer', 'Already has an offer for this channel.')}\n </span>\n {channelId && product.existingOfferId ? (\n <Link\n href={`/backend/sales/channels/${encodeURIComponent(\n String(channelId)\n )}/offers/${encodeURIComponent(String(product.existingOfferId))}/edit`}\n className=\"shrink-0 font-medium text-primary hover:underline\"\n >\n {t('sales.channels.offers.form.productHasOfferLink', 'View offer')}\n </Link>\n ) : null}\n </div>\n ) : null}\n <div className=\"flex justify-end\">\n <Button\n type=\"button\"\n variant={isSelected ? 'secondary' : 'outline'}\n size=\"sm\"\n onClick={() => onChange(product.id)}\n disabled={hasConflict && !isSelected}\n >\n {hasConflict && !isSelected\n ? t('sales.channels.offers.form.productUnavailable', 'Unavailable')\n : isSelected\n ? t('sales.channels.offers.form.productSelected', 'Selected')\n : t('sales.channels.offers.form.productSelect', 'Select')}\n </Button>\n </div>\n </div>\n </div>\n )\n })}\n </div>\n </div>\n ) : hasTyped ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSearchHint', 'Type at least 2 characters or paste a product ID.')}\n </p>\n ) : (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSearchIntro', 'Search by name or paste the product id to find catalog items.')}\n </p>\n )}\n </div>\n )\n}\n\nfunction DefaultMediaSelect({\n value,\n options,\n onChange,\n productThumbnail,\n hasProduct,\n productDefaultMediaId,\n}: {\n value: string | null\n options: MediaOption[]\n onChange: (next: string | null) => void\n productThumbnail: string | null\n hasProduct: boolean\n productDefaultMediaId?: string | null\n}) {\n const t = useT()\n const filteredOptions = React.useMemo(() => {\n if (!productDefaultMediaId) return options\n return options.filter((opt) => opt.id !== productDefaultMediaId)\n }, [options, productDefaultMediaId])\n const hasAttachmentOptions = filteredOptions.length > 0\n const showPlaceholder = !hasAttachmentOptions && !productThumbnail && !hasProduct\n if (showPlaceholder) {\n return (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.mediaSelectProduct', 'Select a product to load its media.')}\n </p>\n )\n }\n const tiles = [\n {\n id: 'inherit',\n label: t('sales.channels.offers.form.mediaInherit', 'Use product default'),\n thumbnail: productThumbnail,\n selected: value == null,\n onClick: () => onChange(null),\n },\n ...filteredOptions.map((opt) => ({\n id: opt.id,\n label: opt.label,\n thumbnail: opt.thumbnailUrl ?? null,\n selected: value === opt.id,\n onClick: () => onChange(opt.id),\n })),\n ]\n return (\n <div className=\"space-y-3\">\n <div className=\"text-xs text-muted-foreground\">\n <p>\n {t('sales.channels.offers.form.mediaHelp', 'Choose the thumbnail that should represent this offer in the channel.')}\n </p>\n {!hasAttachmentOptions && hasProduct ? (\n <p className=\"mt-1\">\n {t('sales.channels.offers.form.mediaEmpty', 'This product has no uploaded media yet; the product default will be used.')}\n </p>\n ) : null}\n </div>\n <div className=\"grid gap-3 sm:grid-cols-3\">\n {tiles.map((tile) => (\n <button\n key={tile.id}\n type=\"button\"\n className={cn(\n 'flex flex-col rounded border text-left transition-colors',\n tile.selected ? 'border-primary shadow-sm' : 'hover:border-primary/60',\n )}\n onClick={tile.onClick}\n >\n <div className=\"relative aspect-square overflow-hidden rounded-t bg-muted\">\n {tile.thumbnail ? (\n <img src={tile.thumbnail} alt={tile.label} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-6 w-6\" />\n </div>\n )}\n {tile.selected ? (\n <div className=\"absolute right-2 top-2 rounded-full bg-primary/90 px-2 py-0.5 text-xs font-semibold text-primary-foreground\">\n {t('sales.channels.offers.form.mediaSelected', 'Active')}\n </div>\n ) : null}\n </div>\n <div className=\"p-2\">\n <div className=\"line-clamp-2 text-xs font-medium\">{tile.label}</div>\n </div>\n </button>\n ))}\n </div>\n </div>\n )\n}\n\nfunction OfferFormWatchers({\n values,\n setValue,\n productCache,\n attachmentCache,\n setMediaOptions,\n setProductSummary,\n setVariantPreviews,\n variantCache,\n variantMediaCache,\n channelId,\n manualMediaSelections,\n setCurrentProductId,\n errors,\n}: CrudFormGroupComponentProps & {\n productCache: React.MutableRefObject<Map<string, ProductSummaryCacheEntry>>\n attachmentCache: React.MutableRefObject<Map<string, MediaOption[]>>\n setMediaOptions: React.Dispatch<React.SetStateAction<MediaOption[]>>\n setProductSummary: React.Dispatch<React.SetStateAction<ProductSummary>>\n setVariantPreviews: React.Dispatch<React.SetStateAction<ProductVariantPreview[]>>\n variantCache: React.MutableRefObject<Map<string, ProductVariantPreview[]>>\n variantMediaCache: React.MutableRefObject<Map<string, VariantThumbnailInfo>>\n channelId: string | null\n manualMediaSelections: React.MutableRefObject<Set<string>>\n setCurrentProductId: React.Dispatch<React.SetStateAction<string | null>>\n}) {\n const previousProductIdRef = React.useRef<string | null>(null)\n const initializedProductRef = React.useRef(false)\n React.useEffect(() => {\n const productId = typeof values.productId === 'string' ? values.productId : null\n setCurrentProductId(productId)\n if (!productId) {\n setMediaOptions([])\n setProductSummary(null)\n setVariantPreviews([])\n previousProductIdRef.current = null\n return\n }\n const resolvedProductId = productId as string\n const resolvedChannelId = channelId ?? null\n if (!initializedProductRef.current) {\n previousProductIdRef.current = resolvedProductId\n initializedProductRef.current = true\n } else if (previousProductIdRef.current !== resolvedProductId) {\n previousProductIdRef.current = resolvedProductId\n setValue('defaultMediaId', undefined)\n }\n let cancelled = false\n async function load() {\n try {\n const summary = await resolveProductSummaryWithCache({\n productId: resolvedProductId,\n channelId: resolvedChannelId,\n productCache,\n })\n if (!cancelled) {\n setProductSummary(summary ?? null)\n if (summary) {\n const hasTitle = typeof values.title === 'string' && values.title.trim().length > 0\n if (!hasTitle && summary.title) {\n setValue('title', summary.title)\n }\n const hasDescription =\n typeof values.description === 'string' && values.description.trim().length > 0\n if (!hasDescription && summary.description) {\n setValue('description', summary.description)\n }\n if (\n !values.defaultMediaId &&\n summary.defaultMediaId &&\n !manualMediaSelections.current.has(resolvedProductId)\n ) {\n setValue('defaultMediaId', summary.defaultMediaId)\n }\n }\n }\n const attachments = await resolveProductMediaOptionsWithCache({\n productId: resolvedProductId,\n attachmentCache,\n })\n if (!cancelled) {\n const variants = await resolveVariantPreviewsWithCache({\n productId: resolvedProductId,\n variantCache,\n variantMediaCache,\n })\n const mergedMedia = buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n })\n attachmentCache.current.set(resolvedProductId, mergedMedia)\n setMediaOptions(mergedMedia)\n setVariantPreviews(variants)\n }\n } catch (err) {\n console.error('sales.channels.offer.watchers', err)\n }\n }\n void load()\n return () => { cancelled = true }\n }, [\n attachmentCache,\n channelId,\n manualMediaSelections,\n productCache,\n setMediaOptions,\n setProductSummary,\n setValue,\n setVariantPreviews,\n values.defaultMediaId,\n values.description,\n values.productId,\n values.title,\n variantCache,\n variantMediaCache,\n setCurrentProductId,\n ])\n return null\n}\n\nasync function resolveProductSummaryWithCache({\n productId,\n channelId,\n productCache,\n}: {\n productId: string\n channelId: string | null\n productCache: React.MutableRefObject<Map<string, ProductSummaryCacheEntry>>\n}): Promise<ProductSummaryCacheEntry | null> {\n if (!productId) return null\n const cacheKey = channelId ? `${productId}:${channelId}` : productId\n let summary: ProductSummaryCacheEntry | null | undefined = productCache.current.get(cacheKey)\n if (summary) return summary\n const params = new URLSearchParams({ id: productId, pageSize: '1' })\n if (channelId) params.set('channelId', channelId)\n const payload = await readApiResultOrThrow<OfferResponse>(\n `/api/catalog/products?${params.toString()}`,\n undefined,\n { fallback: { items: [] } },\n )\n const product = Array.isArray(payload.items) ? payload.items[0] : null\n summary = product ? mapProductSummary(product) : null\n if (summary) {\n productCache.current.set(cacheKey, summary)\n }\n return summary ?? null\n}\n\nasync function resolveProductMediaOptionsWithCache({\n productId,\n attachmentCache,\n}: {\n productId: string\n attachmentCache: React.MutableRefObject<Map<string, MediaOption[]>>\n}): Promise<MediaOption[]> {\n if (!productId) return []\n const cached = attachmentCache.current.get(productId) ?? []\n if (cached.length) {\n const deduped = dedupeMediaOptions(cached)\n attachmentCache.current.set(productId, deduped)\n return deduped\n }\n const attachments = dedupeMediaOptions(await loadProductMedia(productId))\n attachmentCache.current.set(productId, attachments)\n return attachments\n}\n\nasync function resolveVariantPreviewsWithCache({\n productId,\n variantCache,\n variantMediaCache,\n}: {\n productId: string\n variantCache: React.MutableRefObject<Map<string, ProductVariantPreview[]>>\n variantMediaCache: React.MutableRefObject<Map<string, VariantThumbnailInfo>>\n}): Promise<ProductVariantPreview[]> {\n if (!productId) return []\n const cached = variantCache.current.get(productId)\n if (cached) return cached\n const variantPayload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/catalog/variants?productId=${encodeURIComponent(productId)}&pageSize=${MAX_LIST_PAGE_SIZE}`,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(variantPayload.items) ? variantPayload.items : []\n const variants = await Promise.all(\n items.map(async (item) => {\n const preview = mapVariantPreview(item)\n const media = await resolveVariantThumbnail(preview.id, variantMediaCache)\n return {\n ...preview,\n thumbnailId: media?.attachmentId ?? preview.thumbnailId,\n thumbnailUrl: media?.thumbnailUrl ?? preview.thumbnailUrl,\n thumbnailFileName: media?.fileName ?? preview.thumbnailFileName,\n }\n }),\n )\n variantCache.current.set(productId, variants)\n return variants\n}\n\nfunction mapProductSummary(item: Record<string, unknown>): ProductSummaryCacheEntry {\n const pricingSource = item.pricing && typeof item.pricing === 'object' ? item.pricing as Record<string, unknown> : null\n return {\n title: typeof item.title === 'string' ? item.title : '',\n description: typeof item.description === 'string' ? item.description : null,\n defaultMediaId: typeof item.defaultMediaId === 'string'\n ? item.defaultMediaId\n : typeof item.default_media_id === 'string'\n ? item.default_media_id\n : null,\n defaultMediaUrl: typeof item.defaultMediaUrl === 'string'\n ? item.defaultMediaUrl\n : typeof item.default_media_url === 'string'\n ? item.default_media_url\n : null,\n sku: typeof item.sku === 'string' ? item.sku : null,\n pricing: normalizePricing(pricingSource),\n }\n}\n\nfunction normalizePricing(source: Record<string, unknown> | null): PricingSummary | null {\n if (!source) return null\n const currencyCode = typeof source.currencyCode === 'string'\n ? source.currencyCode\n : typeof source.currency_code === 'string'\n ? source.currency_code\n : null\n const unitPriceNet = typeof source.unitPriceNet === 'string'\n ? source.unitPriceNet\n : typeof source.unit_price_net === 'string'\n ? source.unit_price_net\n : null\n const unitPriceGross = typeof source.unitPriceGross === 'string'\n ? source.unitPriceGross\n : typeof source.unit_price_gross === 'string'\n ? source.unit_price_gross\n : null\n const displayMode = source.displayMode === 'including-tax' || source.display_mode === 'including-tax'\n ? 'including-tax'\n : source.displayMode === 'excluding-tax' || source.display_mode === 'excluding-tax'\n ? 'excluding-tax'\n : null\n return { currencyCode, unitPriceNet, unitPriceGross, displayMode }\n}\n\nasync function loadProductMedia(productId: string): Promise<MediaOption[]> {\n if (!productId) return []\n const normalize = (items: Array<{ id?: string; fileName?: string; thumbnailUrl?: string | null }>) => (\n items\n .filter((item): item is { id: string; fileName: string; thumbnailUrl?: string | null } => (\n typeof item.id === 'string' && typeof item.fileName === 'string'\n ))\n .map((item) => ({\n id: item.id,\n label: item.fileName,\n fileName: item.fileName,\n thumbnailUrl: typeof item.thumbnailUrl === 'string'\n ? item.thumbnailUrl\n : buildAttachmentImageUrl(item.id, {\n width: 360,\n height: 360,\n slug: slugifyAttachmentFileName(item.fileName),\n }),\n }))\n )\n try {\n const primary = await apiCall<AttachmentsResponse>(\n `/api/catalog/product-media?productId=${encodeURIComponent(productId)}`,\n undefined,\n { fallback: { items: [] } },\n )\n if (primary.ok && primary.result?.items) {\n return normalize(primary.result.items)\n }\n } catch (err) {\n console.error('catalog.product-media.lookup', err)\n }\n try {\n const fallback = await apiCall<AttachmentsResponse>(\n `/api/attachments?entityId=${encodeURIComponent(E.catalog.catalog_product)}&recordId=${encodeURIComponent(productId)}`,\n undefined,\n { fallback: { items: [] } },\n )\n if (fallback.ok && fallback.result?.items) {\n return normalize(fallback.result.items)\n }\n } catch (err) {\n console.error('attachments.lookup', err)\n }\n return []\n}\n\nfunction buildVariantMediaOptions(variants: ProductVariantPreview[]): MediaOption[] {\n return variants\n .map((variant): MediaOption | null => {\n if (!variant.thumbnailId || !variant.thumbnailUrl) return null\n const label = variant.name || variant.sku || 'Variant'\n const fileName = variant.thumbnailFileName ?? `${variant.thumbnailId}.jpg`\n return {\n id: variant.thumbnailId,\n label,\n fileName,\n thumbnailUrl: variant.thumbnailUrl,\n }\n })\n .filter((entry): entry is MediaOption => Boolean(entry))\n}\n\nfunction buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n}: {\n attachments?: MediaOption[] | null\n variants?: ProductVariantPreview[] | null\n summary?: ProductSummary | null\n}): MediaOption[] {\n const merged = dedupeMediaOptions([\n ...(attachments ?? []),\n ...buildVariantMediaOptions(variants ?? []),\n ])\n const defaultId = summary?.defaultMediaId ?? null\n const defaultUrl = summary?.defaultMediaUrl ?? null\n if (defaultId && defaultUrl && !merged.some((entry) => entry.id === defaultId)) {\n const fileName = inferFileNameFromUrl(defaultUrl, defaultId)\n merged.unshift({\n id: defaultId,\n label: fileName,\n fileName,\n thumbnailUrl: defaultUrl,\n })\n }\n return merged\n}\n\nfunction dedupeMediaOptions(entries: MediaOption[] | null | undefined): MediaOption[] {\n if (!Array.isArray(entries)) return []\n const seen = new Set<string>()\n const result: MediaOption[] = []\n for (const entry of entries) {\n if (!entry || typeof entry.id !== 'string') continue\n if (seen.has(entry.id)) continue\n seen.add(entry.id)\n result.push(entry)\n }\n return result\n}\n\nfunction inferFileNameFromUrl(url: string | null, fallbackId: string): string {\n if (typeof url === 'string' && url.length) {\n const cleaned = url.split(/[?#]/)[0]\n const last = cleaned.split('/').pop()\n if (last && last.trim().length) return last\n }\n return `${fallbackId}.jpg`\n}\n\nfunction mapVariantPreview(item: Record<string, unknown>): ProductVariantPreview {\n return {\n id: typeof item.id === 'string' ? item.id : '',\n name: typeof item.name === 'string'\n ? item.name\n : typeof item.sku === 'string'\n ? item.sku\n : 'Variant',\n sku: typeof item.sku === 'string' ? item.sku : null,\n thumbnailUrl: typeof item.defaultMediaUrl === 'string'\n ? item.defaultMediaUrl\n : typeof item.default_media_url === 'string'\n ? item.default_media_url\n : null,\n thumbnailId: null,\n thumbnailFileName: null,\n }\n}\n\nasync function resolveVariantThumbnail(\n variantId: string,\n cache: React.MutableRefObject<Map<string, VariantThumbnailInfo>>,\n): Promise<VariantThumbnailInfo | null> {\n if (!variantId) return null\n if (cache.current.has(variantId)) {\n return cache.current.get(variantId) ?? null\n }\n try {\n const payload = await apiCall<AttachmentsResponse>(\n `/api/attachments?entityId=${encodeURIComponent(E.catalog.catalog_product_variant)}&recordId=${encodeURIComponent(variantId)}`,\n )\n const items = payload.ok && payload.result?.items ? payload.result.items : []\n const first = items.find((item) => typeof item.id === 'string')\n if (first?.id) {\n const thumbnailUrl = typeof first.thumbnailUrl === 'string'\n ? first.thumbnailUrl\n : buildAttachmentImageUrl(first.id, {\n width: 360,\n height: 360,\n slug: slugifyAttachmentFileName(first.fileName ?? first.id),\n })\n const info: VariantThumbnailInfo = {\n attachmentId: first.id,\n thumbnailUrl: thumbnailUrl ?? null,\n fileName: typeof first.fileName === 'string' ? first.fileName : null,\n }\n cache.current.set(variantId, info)\n return info\n }\n } catch (err) {\n console.error('sales.channels.offer.variantMedia', err)\n }\n const empty: VariantThumbnailInfo = { attachmentId: null, thumbnailUrl: null, fileName: null }\n cache.current.set(variantId, empty)\n return empty\n}\n\nfunction mapProductSearchResult(\n item: Record<string, unknown>,\n channelId?: string | null,\n currentOfferId?: string | null,\n): ProductSearchResult {\n const offers = Array.isArray((item as { offers?: unknown }).offers)\n ? (item as { offers: Array<Record<string, unknown>> }).offers\n : []\n const channelOffer = offers.find((entry) => {\n if (!entry || typeof entry !== 'object') return false\n const offerChannelId = typeof entry.channelId === 'string'\n ? entry.channelId\n : typeof (entry as Record<string, unknown>).channel_id === 'string'\n ? (entry as Record<string, unknown>).channel_id\n : null\n return channelId ? offerChannelId === channelId : false\n }) ?? null\n const existingOfferId = channelOffer && typeof channelOffer.id === 'string' ? channelOffer.id : null\n return {\n id: typeof item.id === 'string' ? item.id : '',\n title: typeof item.title === 'string' ? item.title : '',\n sku: typeof item.sku === 'string' ? item.sku : null,\n defaultMediaUrl: typeof item.defaultMediaUrl === 'string'\n ? item.defaultMediaUrl\n : typeof item.default_media_url === 'string'\n ? item.default_media_url\n : null,\n pricing: item.pricing && typeof item.pricing === 'object'\n ? normalizePricing(item.pricing as Record<string, unknown>)\n : null,\n existingOfferId,\n existingOfferTitle:\n channelOffer && typeof channelOffer.title === 'string' ? channelOffer.title : null,\n isCurrentOfferProduct: Boolean(existingOfferId && currentOfferId && existingOfferId === currentOfferId),\n }\n}\n\nfunction formatPriceDisplay(pricing: PricingSummary | null): string {\n if (!pricing) return '\u2014'\n const amount = pricing.displayMode === 'including-tax'\n ? pricing.unitPriceGross ?? pricing.unitPriceNet\n : pricing.unitPriceNet ?? pricing.unitPriceGross\n if (!amount) return pricing.currencyCode ?? '\u2014'\n return `${pricing.currencyCode ?? ''} ${amount}`\n}\n\nfunction PriceOverridesEditor({\n values,\n onChange,\n priceKinds,\n basePrice,\n onRemoveDraft,\n}: {\n values: PriceOverrideDraft[]\n onChange: (next: PriceOverrideDraft[]) => void\n priceKinds: PriceKindSummary[]\n basePrice: PricingSummary | null\n onRemoveDraft?: (draft: PriceOverrideDraft) => Promise<boolean> | boolean\n}) {\n const t = useT()\n const baseAmount = React.useMemo(() => {\n if (!basePrice) return ''\n const net = basePrice.unitPriceNet ?? null\n const gross = basePrice.unitPriceGross ?? null\n if (basePrice.displayMode === 'including-tax') {\n return gross ?? net ?? ''\n }\n if (basePrice.displayMode === 'excluding-tax') {\n return net ?? gross ?? ''\n }\n return net ?? gross ?? ''\n }, [basePrice])\n const baseDefaults = React.useMemo(() => ({\n amount: baseAmount,\n currencyCode: basePrice?.currencyCode ?? null,\n displayMode: basePrice?.displayMode ?? null,\n }), [baseAmount, basePrice?.currencyCode, basePrice?.displayMode])\n const usedKindIdSet = React.useMemo(() => {\n const next = new Set<string>()\n values.forEach((row) => {\n if (typeof row.priceKindId === 'string' && row.priceKindId.length) {\n next.add(row.priceKindId)\n }\n })\n return next\n }, [values])\n const availableKindCount = priceKinds.reduce(\n (count, kind) => (usedKindIdSet.has(kind.id) ? count : count + 1),\n 0,\n )\n const canAddRow = availableKindCount > 0\n const addRow = React.useCallback(() => {\n const usedIds = new Set<string>()\n values.forEach((row) => {\n if (typeof row.priceKindId === 'string' && row.priceKindId.length) {\n usedIds.add(row.priceKindId)\n }\n })\n const nextKind = priceKinds.find((kind) => !usedIds.has(kind.id))\n if (!nextKind && priceKinds.length) {\n return\n }\n onChange([\n ...values,\n {\n tempId: crypto.randomUUID?.() ?? Math.random().toString(36).slice(2),\n amount: baseDefaults.amount,\n currencyCode: nextKind?.currencyCode ?? baseDefaults.currencyCode,\n displayMode: nextKind?.displayMode ?? baseDefaults.displayMode,\n priceKindId: nextKind?.id ?? null,\n priceKindCode: nextKind?.code ?? nextKind?.title ?? null,\n },\n ])\n }, [baseDefaults, onChange, priceKinds, values])\n\n const updateRow = React.useCallback((tempId: string, patch: Partial<PriceOverrideDraft>) => {\n onChange(values.map((row) => (row.tempId === tempId ? { ...row, ...patch } : row)))\n }, [onChange, values])\n\n const removeRow = React.useCallback(async (row: PriceOverrideDraft) => {\n const allowRemoval = await onRemoveDraft?.(row)\n if (allowRemoval === false) return\n onChange(values.filter((entry) => entry.tempId !== row.tempId))\n }, [onChange, onRemoveDraft, values])\n\n return (\n <div className=\"space-y-4\">\n <div className=\"rounded border bg-muted/50 px-3 py-2\">\n <div className=\"text-xs uppercase text-muted-foreground\">\n {t('sales.channels.offers.pricing.basePriceLabel', 'Original product price')}\n </div>\n <div className=\"text-base font-semibold\">\n {basePrice ? formatPriceDisplay(basePrice) : t('sales.channels.offers.pricing.basePriceMissing', 'No price found')}\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.pricing.basePriceHelp', 'Shown to shoppers when no override is configured.')}\n </div>\n </div>\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-muted-foreground\">\n {t('sales.channels.offers.pricing.help', 'Provide overrides for price kinds when this offer is active.')}\n </p>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={addRow} disabled={!canAddRow}>\n {t('sales.channels.offers.pricing.add', 'Add price')}\n </Button>\n </div>\n {!canAddRow ? (\n <p className=\"text-xs text-muted-foreground\">\n {priceKinds.length\n ? t('sales.channels.offers.pricing.allKindsUsed', 'Each price kind already has an override.')\n : t('sales.channels.offers.pricing.noKindsAvailable', 'Define a price kind before adding overrides.')}\n </p>\n ) : null}\n </div>\n <div className=\"flex items-center justify-between\">\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.pricing.overrideHint', 'Overrides take precedence over the original product price.')}\n </p>\n </div>\n {values.length ? (\n <div className=\"space-y-2\">\n {values.map((row) => (\n <div key={row.tempId} className=\"grid gap-2 rounded border p-3 md:grid-cols-3\">\n <select\n className=\"rounded border px-2 py-2 text-sm\"\n value={row.priceKindId ?? ''}\n onChange={(event) => {\n const next = priceKinds.find((kind) => kind.id === event.target.value)\n updateRow(row.tempId, {\n priceKindId: next?.id ?? null,\n priceKindCode: next?.code ?? next?.title ?? null,\n currencyCode: next?.currencyCode ?? null,\n displayMode: next?.displayMode ?? null,\n })\n }}\n >\n <option value=\"\">{t('sales.channels.offers.pricing.selectKind', 'Select price kind')}</option>\n {priceKinds.map((kind) => (\n <option\n key={kind.id}\n value={kind.id}\n disabled={usedKindIdSet.has(kind.id) && row.priceKindId !== kind.id}\n >\n {kind.title ?? kind.code ?? kind.id}\n </option>\n ))}\n </select>\n <div className=\"relative\">\n {(row.currencyCode ?? basePrice?.currencyCode) ? (\n <span className=\"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-xs font-semibold text-muted-foreground\">\n {row.currencyCode ?? basePrice?.currencyCode}\n </span>\n ) : null}\n <input\n className={cn(\n 'w-full rounded border py-2 text-sm',\n row.currencyCode || basePrice?.currencyCode ? 'pl-16 pr-2' : 'px-2',\n )}\n type=\"number\"\n placeholder={t('sales.channels.offers.pricing.amount', 'Amount')}\n value={row.amount ?? ''}\n onChange={(event) => updateRow(row.tempId, { amount: event.target.value })}\n />\n </div>\n <div className=\"flex flex-col justify-between gap-2 text-xs text-muted-foreground sm:flex-row sm:items-center\">\n <span>\n {row.displayMode === 'including-tax'\n ? t('sales.channels.offers.pricing.includingTax', 'Including tax')\n : t('sales.channels.offers.pricing.excludingTax', 'Excluding tax')}\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"gap-1 px-2 font-normal text-destructive hover:text-destructive focus-visible:text-destructive\"\n onClick={() => { void removeRow(row) }}\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n {t('sales.channels.offers.pricing.remove', 'Remove')}\n </Button>\n </div>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.pricing.empty', 'No overrides yet.')}\n {basePrice ? (\n <>\n {' '}\n {t(\n 'sales.channels.offers.pricing.emptyFallback',\n 'Using {price} from the product until you add overrides.',\n { price: formatPriceDisplay(basePrice) },\n )}\n </>\n ) : null}\n </p>\n )}\n </div>\n )\n}\n\nfunction ProductOverviewCard({ summary, variants }: { summary: ProductSummary; variants: ProductVariantPreview[] }) {\n const t = useT()\n if (!summary) {\n return (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSummaryPlaceholder', 'Select a product to preview its media, price, and variants.')}\n </p>\n )\n }\n return (\n <div className=\"space-y-4\">\n <div className=\"flex gap-3\">\n <div className=\"h-16 w-16 overflow-hidden rounded border bg-muted\">\n {summary.defaultMediaUrl ? (\n <img src={summary.defaultMediaUrl} alt={summary.title} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-5 w-5\" />\n </div>\n )}\n </div>\n <div className=\"flex-1\">\n <div className=\"text-sm font-semibold\">{summary.title || t('sales.channels.offers.form.productUntitled', 'Untitled product')}</div>\n {summary.sku ? (\n <div className=\"text-xs text-muted-foreground\">SKU \u00B7 {summary.sku}</div>\n ) : null}\n <div className=\"text-sm\">\n <span className=\"text-muted-foreground\">{t('sales.channels.offers.form.productPriceLabel', 'Base price')}:</span>{' '}\n <span className=\"font-semibold\">{formatPriceDisplay(summary.pricing)}</span>\n </div>\n </div>\n </div>\n {summary.description ? (\n <p className=\"text-sm text-muted-foreground\">{summary.description}</p>\n ) : null}\n <ProductVariantsList variants={variants} />\n </div>\n )\n}\n\nfunction ProductVariantsList({ variants }: { variants: ProductVariantPreview[] }) {\n const t = useT()\n if (!variants.length) {\n return (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.variantsEmpty', 'No variants available for this product.')}\n </p>\n )\n }\n return (\n <div className=\"space-y-2\">\n <div className=\"text-sm font-medium\">{t('sales.channels.offers.form.variantsTitle', 'Variants')}</div>\n <div className=\"space-y-2 max-h-64 overflow-y-auto pr-1\">\n {variants.map((variant) => (\n <div key={variant.id} className=\"flex gap-3 rounded border bg-card p-2\">\n <div className=\"h-10 w-10 overflow-hidden rounded border bg-muted\">\n {variant.thumbnailUrl ? (\n <img src={variant.thumbnailUrl} alt={variant.name} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-4 w-4\" />\n </div>\n )}\n </div>\n <div className=\"min-w-0\">\n <div className=\"text-xs font-medium\">{variant.name}</div>\n {variant.sku ? (\n <div className=\"text-overline text-muted-foreground\">SKU \u00B7 {variant.sku}</div>\n ) : null}\n </div>\n </div>\n ))}\n </div>\n </div>\n )\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { CrudForm, type CrudField, type CrudFormGroup, type CrudFormGroupComponentProps } from '@open-mercato/ui/backend/CrudForm'\nimport { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'\nimport { createCrud, updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { createCrudFormError, type CrudServerFieldErrors } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { readApiResultOrThrow, apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { Loader2, Search, Image as ImageIcon, Trash2 } from 'lucide-react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { E } from '#generated/entities.ids.generated'\nimport { buildAttachmentImageUrl, slugifyAttachmentFileName } from '@open-mercato/core/modules/attachments/lib/imageUrls'\nimport { cn } from '@open-mercato/shared/lib/utils'\n\ntype PriceKindSummary = {\n id: string\n code: string | null\n title: string | null\n displayMode: 'including-tax' | 'excluding-tax'\n currencyCode: string | null\n}\n\ntype PriceOverrideDraft = {\n tempId: string\n priceId?: string | null\n priceKindId?: string | null\n priceKindCode?: string | null\n currencyCode?: string | null\n displayMode?: 'including-tax' | 'excluding-tax' | null\n amount?: string\n}\n\nexport type OfferFormValues = {\n channelId: string | null\n productId: string | null\n title: string\n description: string\n defaultMediaId?: string | null\n isActive: boolean\n priceOverrides: PriceOverrideDraft[]\n} & Record<string, unknown>\n\ntype ChannelOfferFormProps = {\n channelId?: string\n offerId?: string\n mode: 'create' | 'edit'\n}\n\ntype OfferResponse = {\n items?: Array<Record<string, unknown>>\n}\n\ntype PriceResponse = {\n items?: Array<Record<string, unknown>>\n}\n\ntype AttachmentsResponse = {\n items?: Array<{ id?: string; fileName?: string; url?: string; thumbnailUrl?: string | null }>\n}\n\ntype ProductSummaryCacheEntry = {\n title: string\n description: string | null\n defaultMediaId: string | null\n defaultMediaUrl: string | null\n sku: string | null\n pricing: PricingSummary | null\n}\n\ntype MediaOption = { id: string; label: string; fileName: string; thumbnailUrl?: string | null }\n\ntype PricingSummary = {\n currencyCode: string | null\n unitPriceNet: string | null\n unitPriceGross: string | null\n displayMode: 'including-tax' | 'excluding-tax' | null\n}\n\ntype ProductVariantPreview = {\n id: string\n name: string\n sku: string | null\n thumbnailUrl: string | null\n thumbnailId: string | null\n thumbnailFileName: string | null\n}\n\ntype ProductSummary = ProductSummaryCacheEntry | null\n\ntype ProductSearchResult = {\n id: string\n title: string\n sku: string | null\n defaultMediaUrl: string | null\n pricing: PricingSummary | null\n existingOfferId: string | null\n existingOfferTitle: string | null\n isCurrentOfferProduct: boolean\n}\n\nconst UUID_REGEX = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/\nconst MAX_LIST_PAGE_SIZE = 100\ntype VariantThumbnailInfo = { attachmentId: string | null; thumbnailUrl: string | null; fileName: string | null }\n\nexport function ChannelOfferForm({ channelId: lockedChannelId, offerId, mode }: ChannelOfferFormProps) {\n const t = useT()\n const router = useRouter()\n const [initialValues, setInitialValues] = React.useState<OfferFormValues | null>(mode === 'create'\n ? {\n channelId: lockedChannelId ?? null,\n productId: null,\n title: '',\n description: '',\n defaultMediaId: null,\n isActive: true,\n priceOverrides: [],\n }\n : null)\n const [loading, setLoading] = React.useState(mode === 'edit')\n const [error, setError] = React.useState<string | null>(null)\n const [priceKinds, setPriceKinds] = React.useState<PriceKindSummary[]>([])\n const [mediaOptions, setMediaOptions] = React.useState<MediaOption[]>([])\n const attachmentCache = React.useRef<Map<string, MediaOption[]>>(new Map())\n const productCache = React.useRef<Map<string, ProductSummaryCacheEntry>>(new Map())\n const [productSummary, setProductSummary] = React.useState<ProductSummary>(null)\n const [variantPreviews, setVariantPreviews] = React.useState<ProductVariantPreview[]>([])\n const variantCache = React.useRef<Map<string, ProductVariantPreview[]>>(new Map())\n const variantMediaCache = React.useRef<Map<string, VariantThumbnailInfo>>(new Map())\n const [selectedChannelId, setSelectedChannelId] = React.useState<string | null>(lockedChannelId ?? null)\n const manualMediaSelections = React.useRef<Set<string>>(new Set())\n const initialPriceIdsRef = React.useRef<Set<string>>(new Set())\n const [currentProductId, setCurrentProductId] = React.useState<string | null>(null)\n React.useEffect(() => {\n if (initialValues) {\n initialPriceIdsRef.current = collectPriceIds(initialValues.priceOverrides)\n } else {\n initialPriceIdsRef.current = new Set()\n }\n }, [initialValues])\n const channelOffersHref = React.useMemo(\n () => buildChannelOffersHref(lockedChannelId),\n [lockedChannelId],\n )\n\n React.useEffect(() => {\n if (lockedChannelId) {\n setSelectedChannelId(lockedChannelId)\n } else if (initialValues?.channelId) {\n setSelectedChannelId(initialValues.channelId)\n }\n }, [initialValues?.channelId, lockedChannelId])\n\n React.useEffect(() => {\n if (typeof initialValues?.productId === 'string') {\n setCurrentProductId(initialValues.productId)\n }\n }, [initialValues?.productId])\n\n React.useEffect(() => {\n if (typeof initialValues?.productId === 'string' && initialValues?.defaultMediaId === null) {\n manualMediaSelections.current.add(initialValues.productId)\n }\n }, [initialValues?.defaultMediaId, initialValues?.productId])\n\n React.useEffect(() => {\n if (mode !== 'edit') return\n const productId = typeof initialValues?.productId === 'string' ? initialValues.productId : null\n if (!productId) return\n const resolvedProductId = productId\n const hydrationChannelId = selectedChannelId\n ?? lockedChannelId\n ?? (typeof initialValues?.channelId === 'string' ? initialValues.channelId : null)\n let cancelled = false\n async function hydrateExistingProduct() {\n try {\n const [summary, attachments, variants] = await Promise.all([\n resolveProductSummaryWithCache({\n productId: resolvedProductId,\n channelId: hydrationChannelId ?? null,\n productCache,\n }),\n resolveProductMediaOptionsWithCache({ productId: resolvedProductId, attachmentCache }),\n resolveVariantPreviewsWithCache({ productId: resolvedProductId, variantCache, variantMediaCache }),\n ])\n if (!cancelled) {\n setProductSummary(summary ?? null)\n const mergedMedia = buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n })\n attachmentCache.current.set(resolvedProductId, mergedMedia)\n setMediaOptions(mergedMedia)\n setVariantPreviews(variants)\n }\n } catch (err) {\n console.error('sales.channels.offer.initialHydrate', err)\n }\n }\n void hydrateExistingProduct()\n return () => {\n cancelled = true\n }\n }, [\n attachmentCache,\n initialValues?.channelId,\n initialValues?.productId,\n lockedChannelId,\n mode,\n productCache,\n selectedChannelId,\n setMediaOptions,\n setProductSummary,\n setVariantPreviews,\n variantCache,\n variantMediaCache,\n ])\n\n React.useEffect(() => {\n async function loadKinds() {\n const mapItems = (items: Array<Record<string, unknown>>): PriceKindSummary[] =>\n items.map((item): PriceKindSummary => {\n const displayMode =\n item.displayMode === 'including-tax' || item.display_mode === 'including-tax'\n ? 'including-tax'\n : 'excluding-tax'\n return {\n id: typeof item.id === 'string' ? item.id : '',\n code: typeof item.code === 'string' ? item.code : null,\n title: typeof item.title === 'string' ? item.title : null,\n currencyCode:\n typeof item.currencyCode === 'string'\n ? item.currencyCode\n : typeof item.currency_code === 'string'\n ? item.currency_code\n : null,\n displayMode,\n }\n })\n const endpoints = [\n `/api/sales/price-kinds?pageSize=${MAX_LIST_PAGE_SIZE}`,\n `/api/catalog/price-kinds?pageSize=${MAX_LIST_PAGE_SIZE}`,\n ]\n try {\n for (const endpoint of endpoints) {\n try {\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n endpoint,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n setPriceKinds(mapItems(items))\n return\n } catch (err) {\n console.error('sales.channels.price-kinds.fetch', { endpoint, err })\n }\n }\n setPriceKinds([])\n } catch (err) {\n console.error('catalog.price-kinds.list', err)\n }\n }\n void loadKinds()\n }, [])\n\n React.useEffect(() => {\n if (mode !== 'edit' || !offerId) return\n const offerKey = offerId\n let cancelled = false\n async function loadOffer() {\n setLoading(true)\n setError(null)\n try {\n const payload = await readApiResultOrThrow<OfferResponse>(\n `/api/catalog/offers?id=${encodeURIComponent(offerKey)}&pageSize=1`,\n undefined,\n { errorMessage: t('sales.channels.offers.errors.loadOffer', 'Failed to load offer.') },\n )\n const offer = Array.isArray(payload.items) ? payload.items[0] : null\n if (!offer) throw new Error('not_found')\n const values = mapOfferToFormValues(offer, lockedChannelId)\n const pricePayload = await readApiResultOrThrow<PriceResponse>(\n `/api/catalog/prices?offerId=${encodeURIComponent(offer.id as string)}&pageSize=${MAX_LIST_PAGE_SIZE}`,\n undefined,\n { fallback: { items: [] } },\n )\n const priceItems = Array.isArray(pricePayload.items) ? pricePayload.items : []\n values.priceOverrides = priceItems.map(mapPriceRow)\n let preloadedMedia: MediaOption[] = []\n let preloadedVariants: ProductVariantPreview[] = []\n let preloadedSummary: ProductSummary | null = null\n const productId = typeof values.productId === 'string' ? values.productId : null\n if (productId) {\n try {\n const hydrationChannelId = selectedChannelId\n ?? lockedChannelId\n ?? (typeof values.channelId === 'string' ? values.channelId : null)\n const [summary, attachments, variants] = await Promise.all([\n resolveProductSummaryWithCache({\n productId,\n channelId: hydrationChannelId ?? null,\n productCache,\n }),\n loadProductMedia(productId),\n resolveVariantPreviewsWithCache({ productId, variantCache, variantMediaCache }),\n ])\n preloadedSummary = summary ?? null\n preloadedVariants = variants\n preloadedMedia = buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n })\n attachmentCache.current.set(productId, preloadedMedia)\n } catch (err) {\n console.error('sales.channels.offer.media.preload', err)\n }\n }\n if (!cancelled) {\n setInitialValues(values)\n setProductSummary(preloadedSummary)\n setVariantPreviews(preloadedVariants)\n setMediaOptions(preloadedMedia)\n }\n } catch (err) {\n console.error('sales.channels.offer.load', err)\n if (!cancelled) setError(t('sales.channels.offers.errors.loadOffer', 'Failed to load offer.'))\n } finally {\n if (!cancelled) setLoading(false)\n }\n }\n void loadOffer()\n return () => { cancelled = true }\n }, [\n attachmentCache,\n lockedChannelId,\n mode,\n offerId,\n productCache,\n selectedChannelId,\n setMediaOptions,\n setProductSummary,\n setVariantPreviews,\n t,\n variantCache,\n variantMediaCache,\n ])\n\n const fields = React.useMemo<CrudField[]>(() => [\n {\n id: 'channelId',\n label: t('sales.channels.offers.form.channel', 'Channel'),\n type: 'custom',\n required: true,\n component: ({ value, setValue }) => (\n <ChannelSelectInput\n value={(value as string | null) ?? lockedChannelId ?? null}\n onChange={(next) => {\n setValue(next ?? null)\n setSelectedChannelId(next ?? null)\n }}\n disabled={!!lockedChannelId}\n showDetailsLink\n />\n ),\n },\n {\n id: 'productId',\n label: t('sales.channels.offers.form.product', 'Product'),\n type: 'custom',\n required: true,\n component: ({ value, setValue }) => (\n <ProductSelectInput\n value={(value as string | null) ?? null}\n onChange={(next) => setValue(next)}\n channelId={selectedChannelId}\n currentOfferId={offerId ?? null}\n />\n ),\n },\n {\n id: 'defaultMediaId',\n label: t('sales.channels.offers.form.defaultMedia', 'Default media'),\n type: 'custom',\n component: ({ value, setValue }) => (\n <DefaultMediaSelect\n value={(value as string | null | undefined) ?? null}\n onChange={(next) => {\n setValue(next)\n if (!currentProductId) return\n if (next === null || next === undefined) {\n manualMediaSelections.current.add(currentProductId)\n } else {\n manualMediaSelections.current.delete(currentProductId)\n }\n }}\n options={mediaOptions}\n productThumbnail={productSummary?.defaultMediaUrl ?? null}\n hasProduct={Boolean(productSummary)}\n productDefaultMediaId={productSummary?.defaultMediaId ?? null}\n />\n ),\n },\n {\n id: 'title',\n label: t('sales.channels.offers.form.title', 'Title'),\n type: 'text',\n required: true,\n },\n {\n id: 'description',\n label: t('sales.channels.offers.form.description', 'Description'),\n type: 'textarea',\n },\n {\n id: 'isActive',\n label: t('sales.channels.offers.form.active', 'Active'),\n type: 'checkbox',\n },\n ], [lockedChannelId, mediaOptions, productSummary, selectedChannelId, t, currentProductId])\n\n const handleOverrideRemove = React.useCallback(async (draft: PriceOverrideDraft) => {\n const priceId = typeof draft?.priceId === 'string' ? draft.priceId : null\n if (!priceId) return true\n if (mode !== 'edit') return true\n try {\n await deleteCrud('catalog/prices', priceId, {\n errorMessage: t('sales.channels.offers.errors.removePrice', 'Failed to remove price override.'),\n })\n initialPriceIdsRef.current.delete(priceId)\n return true\n } catch (err) {\n console.error('sales.channels.pricing.remove', err)\n flash(t('sales.channels.offers.errors.removePrice', 'Failed to remove price override.'), 'error')\n return false\n }\n }, [mode, t])\n\n const groups = React.useMemo<CrudFormGroup[]>(() => [\n { id: 'associations', column: 1, title: t('sales.channels.offers.form.groups.associations', 'Associations'), fields: ['channelId'] },\n {\n id: 'product',\n column: 1,\n title: t('sales.channels.offers.form.productGroup', 'Product'),\n description: t('sales.channels.offers.form.productGroupHelp', 'Search the catalog and pick the product you want to customize for this channel.'),\n fields: ['productId'],\n },\n {\n id: 'productSummary',\n column: 2,\n title: t('sales.channels.offers.form.productSummaryTitle', 'Product summary'),\n component: () => (\n <ProductOverviewCard summary={productSummary} variants={variantPreviews} />\n ),\n },\n {\n id: 'media',\n column: 1,\n title: t('sales.channels.offers.form.mediaGroupTitle', 'Default media override'),\n fields: ['defaultMediaId'],\n },\n { id: 'content', column: 1, title: t('sales.channels.offers.form.groups.content', 'Content'), fields: ['title', 'description', 'isActive'] },\n {\n id: 'pricing',\n column: 1,\n title: t('sales.channels.offers.form.groups.pricing', 'Price overrides'),\n component: ({ values, setValue }) => (\n <PriceOverridesEditor\n values={Array.isArray(values.priceOverrides) ? values.priceOverrides as PriceOverrideDraft[] : []}\n onChange={(next) => setValue('priceOverrides', next)}\n priceKinds={priceKinds}\n basePrice={productSummary?.pricing ?? null}\n onRemoveDraft={handleOverrideRemove}\n />\n ),\n },\n {\n id: 'customFields',\n column: 2,\n title: t('entities.customFields.title', 'Custom attributes'),\n kind: 'customFields',\n },\n {\n id: 'watchers',\n column: 1,\n bare: true,\n component: ({ values, setValue, errors }) => (\n <OfferFormWatchers\n values={values}\n setValue={setValue}\n errors={errors}\n productCache={productCache}\n attachmentCache={attachmentCache}\n setMediaOptions={setMediaOptions}\n setProductSummary={setProductSummary}\n setVariantPreviews={setVariantPreviews}\n variantCache={variantCache}\n variantMediaCache={variantMediaCache}\n channelId={selectedChannelId}\n manualMediaSelections={manualMediaSelections}\n setCurrentProductId={setCurrentProductId}\n />\n ),\n },\n ], [\n attachmentCache,\n handleOverrideRemove,\n manualMediaSelections,\n priceKinds,\n productCache,\n productSummary,\n selectedChannelId,\n setMediaOptions,\n setCurrentProductId,\n t,\n variantPreviews,\n ])\n\n const handleSubmit = React.useCallback(async (values: OfferFormValues) => {\n const channelId = typeof values.channelId === 'string' && values.channelId.length\n ? values.channelId\n : selectedChannelId ?? lockedChannelId\n const productId = typeof values.productId === 'string' ? values.productId : null\n if (!channelId || !productId) {\n throw new Error(t('sales.channels.offers.errors.requiredFields', 'Choose a channel and product.'))\n }\n const resolvedDefaultMediaId = typeof values.defaultMediaId === 'string' && values.defaultMediaId.trim().length\n ? values.defaultMediaId\n : values.defaultMediaId === null\n ? null\n : undefined\n const basePayload: Record<string, unknown> = {\n channelId,\n productId,\n title: values.title?.trim() || undefined,\n description: values.description?.trim() || undefined,\n isActive: values.isActive !== false,\n }\n if (resolvedDefaultMediaId !== undefined) {\n basePayload.defaultMediaId = resolvedDefaultMediaId\n }\n const attachmentLookup = attachmentCache.current.get(productId) ?? []\n const mediaMap = new Map(attachmentLookup.map((entry) => [entry.id, entry.fileName]))\n if (typeof resolvedDefaultMediaId === 'string' && mediaMap.has(resolvedDefaultMediaId)) {\n const fileName = mediaMap.get(resolvedDefaultMediaId) ?? null\n basePayload.defaultMediaUrl = buildAttachmentImageUrl(resolvedDefaultMediaId, {\n slug: slugifyAttachmentFileName(fileName),\n })\n } else if (resolvedDefaultMediaId === null) {\n basePayload.defaultMediaUrl = null\n }\n const customFields = collectCustomFieldValues(values)\n if (Object.keys(customFields).length) basePayload.customFields = customFields\n const overrides = Array.isArray(values.priceOverrides) ? values.priceOverrides as PriceOverrideDraft[] : []\n const priceWithoutKind = overrides.find((entry) => {\n const amount = typeof entry.amount === 'string' ? entry.amount.trim() : entry.amount\n const hasAmount = typeof amount === 'string' ? amount.length > 0 : amount !== undefined && amount !== null\n const hasExistingPrice = typeof entry.priceId === 'string' && entry.priceId.length > 0\n const hasCurrency = typeof entry.currencyCode === 'string' && entry.currencyCode.length > 0\n return !entry.priceKindId && (hasAmount || hasExistingPrice || hasCurrency)\n })\n if (priceWithoutKind) {\n throw createCrudFormError(t('sales.channels.offers.errors.priceKindRequired', 'Select a price kind for each override.'), {})\n }\n const duplicateKind = (() => {\n const seen = new Set<string>()\n for (const entry of overrides) {\n const kindId = typeof entry.priceKindId === 'string' ? entry.priceKindId : null\n if (!kindId) continue\n if (seen.has(kindId)) return kindId\n seen.add(kindId)\n }\n return null\n })()\n if (duplicateKind) {\n throw createCrudFormError(\n t('sales.channels.offers.errors.priceKindDuplicate', 'Each price kind can only be overridden once.'),\n {},\n )\n }\n const submittedPriceIds = collectPriceIds(overrides)\n const deletedIdSet = new Set<string>()\n initialPriceIdsRef.current.forEach((id) => {\n if (!submittedPriceIds.has(id)) deletedIdSet.add(id)\n })\n const deletedIds = Array.from(deletedIdSet)\n let savedId = offerId ?? null\n try {\n if (mode === 'create') {\n const res = await createCrud<{ id?: string; offerId?: string }>('catalog/offers', basePayload, {\n errorMessage: t('sales.channels.offers.errors.save', 'Failed to save offer.'),\n })\n savedId = res?.result?.offerId ?? res?.result?.id ?? null\n } else if (offerId) {\n await updateCrud('catalog/offers', { id: offerId, ...basePayload }, {\n errorMessage: t('sales.channels.offers.errors.save', 'Failed to save offer.'),\n })\n savedId = offerId\n }\n } catch (err) {\n const details = (err as { details?: unknown })?.details\n const rawFieldErrors = (err as { fieldErrors?: unknown })?.fieldErrors\n const fieldErrors = rawFieldErrors && typeof rawFieldErrors === 'object'\n ? (rawFieldErrors as CrudServerFieldErrors)\n : undefined\n const status = (err as { status?: number })?.status\n const message = typeof (err as { message?: unknown }).message === 'string' && (err as { message: string }).message.trim().length\n ? (err as { message: string }).message\n : t(\n 'sales.channels.offers.errors.duplicateProduct',\n 'This product already has an offer in this channel.',\n )\n throw createCrudFormError(\n message,\n fieldErrors,\n { status, details },\n )\n }\n if (savedId) {\n await syncPriceOverrides({\n overrides,\n deletedIds,\n offerId: savedId,\n channelId,\n productId,\n })\n initialPriceIdsRef.current = submittedPriceIds\n }\n flash(t('sales.channels.offers.messages.saved', 'Offer saved.'), 'success')\n router.push(buildChannelOffersHref(channelId))\n }, [attachmentCache, initialPriceIdsRef, lockedChannelId, mode, offerId, router, selectedChannelId, t])\n\n const handleDelete = React.useCallback(async () => {\n if (!offerId) return\n await deleteCrud('catalog/offers', offerId, {\n errorMessage: t('sales.channels.offers.errors.delete', 'Failed to delete offer.'),\n })\n flash(t('sales.channels.offers.messages.deleted', 'Offer deleted.'), 'success')\n const targetChannel = initialValues?.channelId ?? lockedChannelId ?? ''\n router.push(buildChannelOffersHref(targetChannel))\n }, [initialValues?.channelId, lockedChannelId, offerId, router, t])\n\n return (\n <div>\n {error ? (\n <div className=\"mb-4 rounded border border-destructive/40 bg-destructive/10 px-4 py-3 text-sm text-destructive\">\n {error}\n </div>\n ) : null}\n <CrudForm<OfferFormValues>\n title={mode === 'create'\n ? t('sales.channels.offers.form.createTitle', 'Create offer')\n : t('sales.channels.offers.form.editTitle', 'Edit offer')}\n entityId={E.catalog.catalog_offer}\n fields={fields}\n groups={groups}\n initialValues={initialValues ?? undefined}\n isLoading={loading}\n loadingMessage={t('sales.channels.offers.form.loading', 'Loading offer\u2026')}\n submitLabel={mode === 'create'\n ? t('sales.channels.offers.form.createSubmit', 'Create offer')\n : t('sales.channels.offers.form.updateSubmit', 'Save changes')}\n cancelHref={channelOffersHref}\n backHref={channelOffersHref}\n onSubmit={handleSubmit}\n onDelete={mode === 'edit' ? handleDelete : undefined}\n deleteVisible={mode === 'edit'}\n deleteRedirect={channelOffersHref}\n />\n </div>\n )\n}\n\nfunction mapOfferToFormValues(item: Record<string, unknown>, lockedChannelId?: string | null): OfferFormValues {\n const values: OfferFormValues = {\n channelId: typeof item.channelId === 'string'\n ? item.channelId\n : typeof item.channel_id === 'string'\n ? item.channel_id\n : lockedChannelId ?? null,\n productId: typeof item.productId === 'string'\n ? item.productId\n : typeof item.product_id === 'string'\n ? item.product_id\n : null,\n title: typeof item.title === 'string' ? item.title : '',\n description: typeof item.description === 'string' ? item.description : '',\n defaultMediaId: typeof item.defaultMediaId === 'string'\n ? item.defaultMediaId\n : typeof item.default_media_id === 'string'\n ? item.default_media_id\n : null,\n isActive: item.isActive === true || item.is_active === true,\n priceOverrides: [],\n }\n mergeCustomFieldValues(values, item)\n return values\n}\n\nfunction mapPriceRow(row: Record<string, unknown>): PriceOverrideDraft {\n return {\n tempId: String(row.id ?? crypto.randomUUID?.() ?? Math.random()),\n priceId: typeof row.id === 'string' ? row.id : undefined,\n priceKindId: typeof row.priceKindId === 'string'\n ? row.priceKindId\n : typeof row.price_kind_id === 'string'\n ? row.price_kind_id\n : undefined,\n priceKindCode: typeof row.priceKindCode === 'string'\n ? row.priceKindCode\n : typeof row.price_kind_code === 'string'\n ? row.price_kind_code\n : null,\n currencyCode: typeof row.currencyCode === 'string'\n ? row.currencyCode\n : typeof row.currency_code === 'string'\n ? row.currency_code\n : null,\n displayMode: row.displayMode === 'including-tax' || row.display_mode === 'including-tax'\n ? 'including-tax'\n : 'excluding-tax',\n amount: typeof row.unitPriceNet === 'string'\n ? row.unitPriceNet\n : typeof row.unit_price_net === 'string'\n ? row.unit_price_net\n : typeof row.unitPriceGross === 'string'\n ? row.unitPriceGross\n : typeof row.unit_price_gross === 'string'\n ? row.unit_price_gross\n : '',\n }\n}\n\nfunction collectPriceIds(source: PriceOverrideDraft[] | null | undefined): Set<string> {\n if (!Array.isArray(source)) return new Set()\n const ids = source\n .map((entry) => (typeof entry?.priceId === 'string' ? entry.priceId : null))\n .filter((id): id is string => Boolean(id))\n return new Set(ids)\n}\n\nfunction mergeCustomFieldValues(target: Record<string, unknown>, source: Record<string, unknown> | null | undefined) {\n if (!source || typeof source !== 'object') return\n const assign = (key: string | null | undefined, value: unknown) => {\n if (!key) return\n target[`cf_${key}`] = value\n }\n for (const [rawKey, rawValue] of Object.entries(source)) {\n if (rawKey.startsWith('cf_')) {\n if (rawKey.endsWith('__is_multi')) continue\n target[rawKey] = rawValue\n } else if (rawKey.startsWith('cf:')) {\n assign(rawKey.slice(3), rawValue)\n }\n }\n const customValues =\n (source as Record<string, unknown>).customValues ??\n (source as Record<string, unknown>).custom_values\n if (customValues && typeof customValues === 'object' && !Array.isArray(customValues)) {\n for (const [key, value] of Object.entries(customValues as Record<string, unknown>)) {\n assign(key, value)\n }\n }\n const customFields =\n (source as Record<string, unknown>).customFields ??\n (source as Record<string, unknown>).custom_fields\n if (Array.isArray(customFields)) {\n customFields.forEach((entry) => {\n if (!entry || typeof entry !== 'object') return\n const entryRecord = entry as Record<string, unknown>\n const key = typeof entryRecord.key === 'string' ? entryRecord.key : null\n if (!key) return\n assign(key, entryRecord.value)\n })\n } else if (customFields && typeof customFields === 'object') {\n for (const [key, value] of Object.entries(customFields as Record<string, unknown>)) {\n assign(key, value)\n }\n }\n const customEntries =\n (source as Record<string, unknown>).customFieldEntries ??\n (source as Record<string, unknown>).custom_field_entries\n if (Array.isArray(customEntries)) {\n customEntries.forEach((entry) => {\n if (!entry || typeof entry !== 'object') return\n const entryRecord = entry as Record<string, unknown>\n const key = typeof entryRecord.key === 'string' ? entryRecord.key : null\n if (!key) return\n assign(key, entryRecord.value)\n })\n }\n}\n\nfunction buildChannelOffersHref(channelId?: string | null): string {\n return channelId && channelId.length\n ? `/backend/sales/channels/${channelId}/edit?tab=offers`\n : '/backend/sales/channels/offers'\n}\n\nasync function syncPriceOverrides(params: {\n overrides: PriceOverrideDraft[]\n deletedIds: string[]\n offerId: string\n channelId: string\n productId: string\n}) {\n const { overrides, deletedIds, offerId, channelId, productId } = params\n for (const draft of overrides) {\n if (!draft.priceKindId || !draft.amount) continue\n const amount = Number(draft.amount)\n if (Number.isNaN(amount)) continue\n const payload: Record<string, unknown> = {\n offerId,\n productId,\n channelId,\n priceKindId: draft.priceKindId,\n currencyCode: draft.currencyCode ?? undefined,\n }\n if (draft.displayMode === 'including-tax') {\n payload.unitPriceGross = amount\n } else {\n payload.unitPriceNet = amount\n }\n if (draft.priceId) {\n await updateCrud('catalog/prices', { id: draft.priceId, ...payload })\n } else {\n await createCrud('catalog/prices', payload)\n }\n }\n const uniqueDeletedIds = Array.from(new Set(\n deletedIds.filter((id): id is string => typeof id === 'string' && id.length > 0),\n ))\n for (const id of uniqueDeletedIds) {\n if (!id) continue\n try {\n await deleteCrud('catalog/prices', id)\n } catch (err) {\n console.error('catalog.prices.delete', err)\n }\n }\n}\n\nfunction ChannelSelectInput({\n value,\n onChange,\n disabled,\n showDetailsLink,\n}: {\n value: string | null\n onChange: (next: string | null) => void\n disabled?: boolean\n showDetailsLink?: boolean\n}) {\n const t = useT()\n const [options, setOptions] = React.useState<Array<{ id: string; name: string; code: string | null }>>([])\n const selectedOption = React.useMemo(\n () => (value ? options.find((opt) => opt.id === value) ?? null : null),\n [options, value],\n )\n React.useEffect(() => {\n async function load() {\n try {\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/channels?pageSize=${MAX_LIST_PAGE_SIZE}`,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n setOptions(items.map((item) => ({\n id: typeof item.id === 'string' ? item.id : '',\n name: typeof item.name === 'string' ? item.name : '',\n code: typeof item.code === 'string' ? item.code : null,\n })))\n } catch (err) {\n console.error('sales.channels.options', err)\n }\n }\n void load()\n }, [])\n React.useEffect(() => {\n const channelIdToLoad = typeof value === 'string' ? value : null\n if (!channelIdToLoad || selectedOption) return\n const resolvedChannelId = channelIdToLoad\n let cancelled = false\n async function loadSingle() {\n try {\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/channels?id=${encodeURIComponent(resolvedChannelId)}&pageSize=1`,\n undefined,\n { fallback: { items: [] } },\n )\n const item = Array.isArray(payload.items) ? payload.items[0] : null\n if (!item || cancelled) return\n const entry = {\n id: typeof item.id === 'string' ? item.id : resolvedChannelId,\n name: typeof item.name === 'string' ? item.name : resolvedChannelId,\n code: typeof item.code === 'string' ? item.code : null,\n }\n setOptions((prev) => {\n if (prev.some((opt) => opt.id === entry.id)) return prev\n return [...prev, entry]\n })\n } catch (err) {\n console.error('sales.channels.lookup', err)\n }\n }\n void loadSingle()\n return () => { cancelled = true }\n }, [selectedOption, value])\n\n if (disabled && value) {\n const label = selectedOption?.name ?? value\n const detail = selectedOption?.code ?? null\n return (\n <div className=\"flex items-center justify-between gap-3 rounded border bg-muted px-3 py-2 text-sm\">\n <div className=\"min-w-0\">\n <div className=\"font-medium truncate\">{label}</div>\n {detail ? (\n <div className=\"text-xs text-muted-foreground truncate\">{detail}</div>\n ) : null}\n </div>\n {showDetailsLink ? (\n <Link href={`/backend/sales/channels/${value}/edit`} className=\"text-xs font-medium text-primary hover:underline\">\n {t('sales.channels.offers.form.channelDetails', 'Details')}\n </Link>\n ) : null}\n </div>\n )\n }\n return (\n <Select value={value || undefined} onValueChange={(next) => onChange(next || null)}>\n <SelectTrigger>\n <SelectValue placeholder={t('sales.channels.offers.form.channelPlaceholder', 'Select channel')} />\n </SelectTrigger>\n <SelectContent>\n {options.map((opt) => (\n <SelectItem key={opt.id} value={opt.id}>\n {opt.code ? `${opt.name} (${opt.code})` : opt.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )\n}\n\nfunction ProductSelectInput({\n value,\n onChange,\n channelId,\n currentOfferId,\n}: {\n value: string | null\n onChange: (next: string | null) => void\n channelId: string | null\n currentOfferId?: string | null\n}) {\n const t = useT()\n const [query, setQuery] = React.useState('')\n const [results, setResults] = React.useState<ProductSearchResult[]>([])\n const [isLoading, setLoading] = React.useState(false)\n const [hasTyped, setHasTyped] = React.useState(false)\n\n const trimmed = query.trim()\n const shouldSearch = trimmed.length >= 2 || UUID_REGEX.test(trimmed)\n\n React.useEffect(() => {\n if (!shouldSearch) {\n setResults([])\n return\n }\n let cancelled = false\n const controller = new AbortController()\n const timeout = setTimeout(async () => {\n setLoading(true)\n try {\n const params = new URLSearchParams({ pageSize: '10' })\n if (UUID_REGEX.test(trimmed)) {\n params.set('id', trimmed)\n } else if (trimmed.length) {\n params.set('search', trimmed)\n }\n if (channelId) params.set('channelId', channelId)\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/catalog/products?${params.toString()}`,\n { signal: controller.signal },\n { fallback: { items: [] } },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n if (!cancelled) {\n const mapped = items.map((item) => mapProductSearchResult(item, channelId, currentOfferId))\n mapped.sort((a, b) => {\n const aBlocked = Boolean(a.existingOfferId && !a.isCurrentOfferProduct)\n const bBlocked = Boolean(b.existingOfferId && !b.isCurrentOfferProduct)\n return Number(aBlocked) - Number(bBlocked)\n })\n setResults(mapped)\n }\n } catch (err) {\n if ((err as Error).name === 'AbortError') return\n console.error('catalog.products.lookup', err)\n } finally {\n if (!cancelled) setLoading(false)\n }\n }, 250)\n return () => {\n cancelled = true\n clearTimeout(timeout)\n controller.abort()\n }\n }, [channelId, currentOfferId, shouldSearch, trimmed])\n\n const handleKeyDown = React.useCallback((event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.key === 'Enter' && UUID_REGEX.test(trimmed)) {\n event.preventDefault()\n onChange(trimmed)\n }\n }, [onChange, trimmed])\n\n const selectedHint = value\n ? t('sales.channels.offers.form.productSelectedHint', 'Selected product ID: {{id}}', { id: value })\n : null\n\n return (\n <div className=\"space-y-3\">\n <Input\n leftIcon={<Search />}\n value={query}\n onChange={(event) => {\n setQuery(event.target.value)\n setHasTyped(true)\n }}\n onKeyDown={handleKeyDown}\n placeholder={t('sales.channels.offers.form.productSearchPlaceholder', 'Search by title, SKU, or ID\u2026')}\n />\n {selectedHint ? (\n <div className=\"rounded border bg-muted px-3 py-2 text-xs text-muted-foreground\">\n {selectedHint}\n </div>\n ) : null}\n {value ? (\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => onChange(null)}>\n {t('sales.channels.offers.form.productClear', 'Clear selection')}\n </Button>\n ) : null}\n {shouldSearch ? (\n <div className=\"space-y-2\">\n {isLoading ? (\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n {t('sales.channels.offers.form.productSearchLoading', 'Searching products\u2026')}\n </div>\n ) : null}\n {!isLoading && !results.length ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSearchEmpty', 'No products match your search.')}\n </p>\n ) : null}\n <div className=\"space-y-2 max-h-80 overflow-y-auto\">\n {results.map((product) => {\n const isSelected = value === product.id\n const hasConflict = Boolean(product.existingOfferId && !product.isCurrentOfferProduct)\n return (\n <div\n key={product.id}\n className={cn(\n 'flex gap-3 rounded border bg-card p-3 transition-colors',\n isSelected ? 'border-primary/70 bg-primary/5' : 'hover:border-primary/50',\n )}\n >\n <div className=\"h-12 w-12 overflow-hidden rounded border bg-muted\">\n {product.defaultMediaUrl ? (\n <img src={product.defaultMediaUrl} alt={product.title} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-5 w-5\" />\n </div>\n )}\n </div>\n <div className=\"flex flex-1 flex-col gap-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm font-medium\">{product.title || t('sales.channels.offers.form.productUntitled', 'Untitled product')}</div>\n {product.sku ? (\n <div className=\"text-xs text-muted-foreground\">SKU \u00B7 {product.sku}</div>\n ) : null}\n </div>\n <div className=\"text-xs font-medium text-muted-foreground\">\n {product.pricing ? formatPriceDisplay(product.pricing) : t('sales.channels.offers.form.productPriceMissing', 'No price')}\n </div>\n </div>\n {hasConflict ? (\n <div className=\"flex items-center justify-between gap-2 text-xs text-status-warning-text\">\n <span className=\"truncate\">\n {t('sales.channels.offers.form.productHasOffer', 'Already has an offer for this channel.')}\n </span>\n {channelId && product.existingOfferId ? (\n <Link\n href={`/backend/sales/channels/${encodeURIComponent(\n String(channelId)\n )}/offers/${encodeURIComponent(String(product.existingOfferId))}/edit`}\n className=\"shrink-0 font-medium text-primary hover:underline\"\n >\n {t('sales.channels.offers.form.productHasOfferLink', 'View offer')}\n </Link>\n ) : null}\n </div>\n ) : null}\n <div className=\"flex justify-end\">\n <Button\n type=\"button\"\n variant={isSelected ? 'secondary' : 'outline'}\n size=\"sm\"\n onClick={() => onChange(product.id)}\n disabled={hasConflict && !isSelected}\n >\n {hasConflict && !isSelected\n ? t('sales.channels.offers.form.productUnavailable', 'Unavailable')\n : isSelected\n ? t('sales.channels.offers.form.productSelected', 'Selected')\n : t('sales.channels.offers.form.productSelect', 'Select')}\n </Button>\n </div>\n </div>\n </div>\n )\n })}\n </div>\n </div>\n ) : hasTyped ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSearchHint', 'Type at least 2 characters or paste a product ID.')}\n </p>\n ) : (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSearchIntro', 'Search by name or paste the product id to find catalog items.')}\n </p>\n )}\n </div>\n )\n}\n\nfunction DefaultMediaSelect({\n value,\n options,\n onChange,\n productThumbnail,\n hasProduct,\n productDefaultMediaId,\n}: {\n value: string | null\n options: MediaOption[]\n onChange: (next: string | null) => void\n productThumbnail: string | null\n hasProduct: boolean\n productDefaultMediaId?: string | null\n}) {\n const t = useT()\n const filteredOptions = React.useMemo(() => {\n if (!productDefaultMediaId) return options\n return options.filter((opt) => opt.id !== productDefaultMediaId)\n }, [options, productDefaultMediaId])\n const hasAttachmentOptions = filteredOptions.length > 0\n const showPlaceholder = !hasAttachmentOptions && !productThumbnail && !hasProduct\n if (showPlaceholder) {\n return (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.mediaSelectProduct', 'Select a product to load its media.')}\n </p>\n )\n }\n const tiles = [\n {\n id: 'inherit',\n label: t('sales.channels.offers.form.mediaInherit', 'Use product default'),\n thumbnail: productThumbnail,\n selected: value == null,\n onClick: () => onChange(null),\n },\n ...filteredOptions.map((opt) => ({\n id: opt.id,\n label: opt.label,\n thumbnail: opt.thumbnailUrl ?? null,\n selected: value === opt.id,\n onClick: () => onChange(opt.id),\n })),\n ]\n return (\n <div className=\"space-y-3\">\n <div className=\"text-xs text-muted-foreground\">\n <p>\n {t('sales.channels.offers.form.mediaHelp', 'Choose the thumbnail that should represent this offer in the channel.')}\n </p>\n {!hasAttachmentOptions && hasProduct ? (\n <p className=\"mt-1\">\n {t('sales.channels.offers.form.mediaEmpty', 'This product has no uploaded media yet; the product default will be used.')}\n </p>\n ) : null}\n </div>\n <div className=\"grid gap-3 sm:grid-cols-3\">\n {tiles.map((tile) => (\n <button\n key={tile.id}\n type=\"button\"\n className={cn(\n 'flex flex-col rounded border text-left transition-colors',\n tile.selected ? 'border-primary shadow-sm' : 'hover:border-primary/60',\n )}\n onClick={tile.onClick}\n >\n <div className=\"relative aspect-square overflow-hidden rounded-t bg-muted\">\n {tile.thumbnail ? (\n <img src={tile.thumbnail} alt={tile.label} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-6 w-6\" />\n </div>\n )}\n {tile.selected ? (\n <div className=\"absolute right-2 top-2 rounded-full bg-primary/90 px-2 py-0.5 text-xs font-semibold text-primary-foreground\">\n {t('sales.channels.offers.form.mediaSelected', 'Active')}\n </div>\n ) : null}\n </div>\n <div className=\"p-2\">\n <div className=\"line-clamp-2 text-xs font-medium\">{tile.label}</div>\n </div>\n </button>\n ))}\n </div>\n </div>\n )\n}\n\nfunction OfferFormWatchers({\n values,\n setValue,\n productCache,\n attachmentCache,\n setMediaOptions,\n setProductSummary,\n setVariantPreviews,\n variantCache,\n variantMediaCache,\n channelId,\n manualMediaSelections,\n setCurrentProductId,\n errors,\n}: CrudFormGroupComponentProps & {\n productCache: React.MutableRefObject<Map<string, ProductSummaryCacheEntry>>\n attachmentCache: React.MutableRefObject<Map<string, MediaOption[]>>\n setMediaOptions: React.Dispatch<React.SetStateAction<MediaOption[]>>\n setProductSummary: React.Dispatch<React.SetStateAction<ProductSummary>>\n setVariantPreviews: React.Dispatch<React.SetStateAction<ProductVariantPreview[]>>\n variantCache: React.MutableRefObject<Map<string, ProductVariantPreview[]>>\n variantMediaCache: React.MutableRefObject<Map<string, VariantThumbnailInfo>>\n channelId: string | null\n manualMediaSelections: React.MutableRefObject<Set<string>>\n setCurrentProductId: React.Dispatch<React.SetStateAction<string | null>>\n}) {\n const previousProductIdRef = React.useRef<string | null>(null)\n const initializedProductRef = React.useRef(false)\n React.useEffect(() => {\n const productId = typeof values.productId === 'string' ? values.productId : null\n setCurrentProductId(productId)\n if (!productId) {\n setMediaOptions([])\n setProductSummary(null)\n setVariantPreviews([])\n previousProductIdRef.current = null\n return\n }\n const resolvedProductId = productId as string\n const resolvedChannelId = channelId ?? null\n if (!initializedProductRef.current) {\n previousProductIdRef.current = resolvedProductId\n initializedProductRef.current = true\n } else if (previousProductIdRef.current !== resolvedProductId) {\n previousProductIdRef.current = resolvedProductId\n setValue('defaultMediaId', undefined)\n }\n let cancelled = false\n async function load() {\n try {\n const summary = await resolveProductSummaryWithCache({\n productId: resolvedProductId,\n channelId: resolvedChannelId,\n productCache,\n })\n if (!cancelled) {\n setProductSummary(summary ?? null)\n if (summary) {\n const hasTitle = typeof values.title === 'string' && values.title.trim().length > 0\n if (!hasTitle && summary.title) {\n setValue('title', summary.title)\n }\n const hasDescription =\n typeof values.description === 'string' && values.description.trim().length > 0\n if (!hasDescription && summary.description) {\n setValue('description', summary.description)\n }\n if (\n !values.defaultMediaId &&\n summary.defaultMediaId &&\n !manualMediaSelections.current.has(resolvedProductId)\n ) {\n setValue('defaultMediaId', summary.defaultMediaId)\n }\n }\n }\n const attachments = await resolveProductMediaOptionsWithCache({\n productId: resolvedProductId,\n attachmentCache,\n })\n if (!cancelled) {\n const variants = await resolveVariantPreviewsWithCache({\n productId: resolvedProductId,\n variantCache,\n variantMediaCache,\n })\n const mergedMedia = buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n })\n attachmentCache.current.set(resolvedProductId, mergedMedia)\n setMediaOptions(mergedMedia)\n setVariantPreviews(variants)\n }\n } catch (err) {\n console.error('sales.channels.offer.watchers', err)\n }\n }\n void load()\n return () => { cancelled = true }\n }, [\n attachmentCache,\n channelId,\n manualMediaSelections,\n productCache,\n setMediaOptions,\n setProductSummary,\n setValue,\n setVariantPreviews,\n values.defaultMediaId,\n values.description,\n values.productId,\n values.title,\n variantCache,\n variantMediaCache,\n setCurrentProductId,\n ])\n return null\n}\n\nasync function resolveProductSummaryWithCache({\n productId,\n channelId,\n productCache,\n}: {\n productId: string\n channelId: string | null\n productCache: React.MutableRefObject<Map<string, ProductSummaryCacheEntry>>\n}): Promise<ProductSummaryCacheEntry | null> {\n if (!productId) return null\n const cacheKey = channelId ? `${productId}:${channelId}` : productId\n let summary: ProductSummaryCacheEntry | null | undefined = productCache.current.get(cacheKey)\n if (summary) return summary\n const params = new URLSearchParams({ id: productId, pageSize: '1' })\n if (channelId) params.set('channelId', channelId)\n const payload = await readApiResultOrThrow<OfferResponse>(\n `/api/catalog/products?${params.toString()}`,\n undefined,\n { fallback: { items: [] } },\n )\n const product = Array.isArray(payload.items) ? payload.items[0] : null\n summary = product ? mapProductSummary(product) : null\n if (summary) {\n productCache.current.set(cacheKey, summary)\n }\n return summary ?? null\n}\n\nasync function resolveProductMediaOptionsWithCache({\n productId,\n attachmentCache,\n}: {\n productId: string\n attachmentCache: React.MutableRefObject<Map<string, MediaOption[]>>\n}): Promise<MediaOption[]> {\n if (!productId) return []\n const cached = attachmentCache.current.get(productId) ?? []\n if (cached.length) {\n const deduped = dedupeMediaOptions(cached)\n attachmentCache.current.set(productId, deduped)\n return deduped\n }\n const attachments = dedupeMediaOptions(await loadProductMedia(productId))\n attachmentCache.current.set(productId, attachments)\n return attachments\n}\n\nasync function resolveVariantPreviewsWithCache({\n productId,\n variantCache,\n variantMediaCache,\n}: {\n productId: string\n variantCache: React.MutableRefObject<Map<string, ProductVariantPreview[]>>\n variantMediaCache: React.MutableRefObject<Map<string, VariantThumbnailInfo>>\n}): Promise<ProductVariantPreview[]> {\n if (!productId) return []\n const cached = variantCache.current.get(productId)\n if (cached) return cached\n const variantPayload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/catalog/variants?productId=${encodeURIComponent(productId)}&pageSize=${MAX_LIST_PAGE_SIZE}`,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(variantPayload.items) ? variantPayload.items : []\n const variants = await Promise.all(\n items.map(async (item) => {\n const preview = mapVariantPreview(item)\n const media = await resolveVariantThumbnail(preview.id, variantMediaCache)\n return {\n ...preview,\n thumbnailId: media?.attachmentId ?? preview.thumbnailId,\n thumbnailUrl: media?.thumbnailUrl ?? preview.thumbnailUrl,\n thumbnailFileName: media?.fileName ?? preview.thumbnailFileName,\n }\n }),\n )\n variantCache.current.set(productId, variants)\n return variants\n}\n\nfunction mapProductSummary(item: Record<string, unknown>): ProductSummaryCacheEntry {\n const pricingSource = item.pricing && typeof item.pricing === 'object' ? item.pricing as Record<string, unknown> : null\n return {\n title: typeof item.title === 'string' ? item.title : '',\n description: typeof item.description === 'string' ? item.description : null,\n defaultMediaId: typeof item.defaultMediaId === 'string'\n ? item.defaultMediaId\n : typeof item.default_media_id === 'string'\n ? item.default_media_id\n : null,\n defaultMediaUrl: typeof item.defaultMediaUrl === 'string'\n ? item.defaultMediaUrl\n : typeof item.default_media_url === 'string'\n ? item.default_media_url\n : null,\n sku: typeof item.sku === 'string' ? item.sku : null,\n pricing: normalizePricing(pricingSource),\n }\n}\n\nfunction normalizePricing(source: Record<string, unknown> | null): PricingSummary | null {\n if (!source) return null\n const currencyCode = typeof source.currencyCode === 'string'\n ? source.currencyCode\n : typeof source.currency_code === 'string'\n ? source.currency_code\n : null\n const unitPriceNet = typeof source.unitPriceNet === 'string'\n ? source.unitPriceNet\n : typeof source.unit_price_net === 'string'\n ? source.unit_price_net\n : null\n const unitPriceGross = typeof source.unitPriceGross === 'string'\n ? source.unitPriceGross\n : typeof source.unit_price_gross === 'string'\n ? source.unit_price_gross\n : null\n const displayMode = source.displayMode === 'including-tax' || source.display_mode === 'including-tax'\n ? 'including-tax'\n : source.displayMode === 'excluding-tax' || source.display_mode === 'excluding-tax'\n ? 'excluding-tax'\n : null\n return { currencyCode, unitPriceNet, unitPriceGross, displayMode }\n}\n\nasync function loadProductMedia(productId: string): Promise<MediaOption[]> {\n if (!productId) return []\n const normalize = (items: Array<{ id?: string; fileName?: string; thumbnailUrl?: string | null }>) => (\n items\n .filter((item): item is { id: string; fileName: string; thumbnailUrl?: string | null } => (\n typeof item.id === 'string' && typeof item.fileName === 'string'\n ))\n .map((item) => ({\n id: item.id,\n label: item.fileName,\n fileName: item.fileName,\n thumbnailUrl: typeof item.thumbnailUrl === 'string'\n ? item.thumbnailUrl\n : buildAttachmentImageUrl(item.id, {\n width: 360,\n height: 360,\n slug: slugifyAttachmentFileName(item.fileName),\n }),\n }))\n )\n try {\n const primary = await apiCall<AttachmentsResponse>(\n `/api/catalog/product-media?productId=${encodeURIComponent(productId)}`,\n undefined,\n { fallback: { items: [] } },\n )\n if (primary.ok && primary.result?.items) {\n return normalize(primary.result.items)\n }\n } catch (err) {\n console.error('catalog.product-media.lookup', err)\n }\n try {\n const fallback = await apiCall<AttachmentsResponse>(\n `/api/attachments?entityId=${encodeURIComponent(E.catalog.catalog_product)}&recordId=${encodeURIComponent(productId)}`,\n undefined,\n { fallback: { items: [] } },\n )\n if (fallback.ok && fallback.result?.items) {\n return normalize(fallback.result.items)\n }\n } catch (err) {\n console.error('attachments.lookup', err)\n }\n return []\n}\n\nfunction buildVariantMediaOptions(variants: ProductVariantPreview[]): MediaOption[] {\n return variants\n .map((variant): MediaOption | null => {\n if (!variant.thumbnailId || !variant.thumbnailUrl) return null\n const label = variant.name || variant.sku || 'Variant'\n const fileName = variant.thumbnailFileName ?? `${variant.thumbnailId}.jpg`\n return {\n id: variant.thumbnailId,\n label,\n fileName,\n thumbnailUrl: variant.thumbnailUrl,\n }\n })\n .filter((entry): entry is MediaOption => Boolean(entry))\n}\n\nfunction buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n}: {\n attachments?: MediaOption[] | null\n variants?: ProductVariantPreview[] | null\n summary?: ProductSummary | null\n}): MediaOption[] {\n const merged = dedupeMediaOptions([\n ...(attachments ?? []),\n ...buildVariantMediaOptions(variants ?? []),\n ])\n const defaultId = summary?.defaultMediaId ?? null\n const defaultUrl = summary?.defaultMediaUrl ?? null\n if (defaultId && defaultUrl && !merged.some((entry) => entry.id === defaultId)) {\n const fileName = inferFileNameFromUrl(defaultUrl, defaultId)\n merged.unshift({\n id: defaultId,\n label: fileName,\n fileName,\n thumbnailUrl: defaultUrl,\n })\n }\n return merged\n}\n\nfunction dedupeMediaOptions(entries: MediaOption[] | null | undefined): MediaOption[] {\n if (!Array.isArray(entries)) return []\n const seen = new Set<string>()\n const result: MediaOption[] = []\n for (const entry of entries) {\n if (!entry || typeof entry.id !== 'string') continue\n if (seen.has(entry.id)) continue\n seen.add(entry.id)\n result.push(entry)\n }\n return result\n}\n\nfunction inferFileNameFromUrl(url: string | null, fallbackId: string): string {\n if (typeof url === 'string' && url.length) {\n const cleaned = url.split(/[?#]/)[0]\n const last = cleaned.split('/').pop()\n if (last && last.trim().length) return last\n }\n return `${fallbackId}.jpg`\n}\n\nfunction mapVariantPreview(item: Record<string, unknown>): ProductVariantPreview {\n return {\n id: typeof item.id === 'string' ? item.id : '',\n name: typeof item.name === 'string'\n ? item.name\n : typeof item.sku === 'string'\n ? item.sku\n : 'Variant',\n sku: typeof item.sku === 'string' ? item.sku : null,\n thumbnailUrl: typeof item.defaultMediaUrl === 'string'\n ? item.defaultMediaUrl\n : typeof item.default_media_url === 'string'\n ? item.default_media_url\n : null,\n thumbnailId: null,\n thumbnailFileName: null,\n }\n}\n\nasync function resolveVariantThumbnail(\n variantId: string,\n cache: React.MutableRefObject<Map<string, VariantThumbnailInfo>>,\n): Promise<VariantThumbnailInfo | null> {\n if (!variantId) return null\n if (cache.current.has(variantId)) {\n return cache.current.get(variantId) ?? null\n }\n try {\n const payload = await apiCall<AttachmentsResponse>(\n `/api/attachments?entityId=${encodeURIComponent(E.catalog.catalog_product_variant)}&recordId=${encodeURIComponent(variantId)}`,\n )\n const items = payload.ok && payload.result?.items ? payload.result.items : []\n const first = items.find((item) => typeof item.id === 'string')\n if (first?.id) {\n const thumbnailUrl = typeof first.thumbnailUrl === 'string'\n ? first.thumbnailUrl\n : buildAttachmentImageUrl(first.id, {\n width: 360,\n height: 360,\n slug: slugifyAttachmentFileName(first.fileName ?? first.id),\n })\n const info: VariantThumbnailInfo = {\n attachmentId: first.id,\n thumbnailUrl: thumbnailUrl ?? null,\n fileName: typeof first.fileName === 'string' ? first.fileName : null,\n }\n cache.current.set(variantId, info)\n return info\n }\n } catch (err) {\n console.error('sales.channels.offer.variantMedia', err)\n }\n const empty: VariantThumbnailInfo = { attachmentId: null, thumbnailUrl: null, fileName: null }\n cache.current.set(variantId, empty)\n return empty\n}\n\nfunction mapProductSearchResult(\n item: Record<string, unknown>,\n channelId?: string | null,\n currentOfferId?: string | null,\n): ProductSearchResult {\n const offers = Array.isArray((item as { offers?: unknown }).offers)\n ? (item as { offers: Array<Record<string, unknown>> }).offers\n : []\n const channelOffer = offers.find((entry) => {\n if (!entry || typeof entry !== 'object') return false\n const offerChannelId = typeof entry.channelId === 'string'\n ? entry.channelId\n : typeof (entry as Record<string, unknown>).channel_id === 'string'\n ? (entry as Record<string, unknown>).channel_id\n : null\n return channelId ? offerChannelId === channelId : false\n }) ?? null\n const existingOfferId = channelOffer && typeof channelOffer.id === 'string' ? channelOffer.id : null\n return {\n id: typeof item.id === 'string' ? item.id : '',\n title: typeof item.title === 'string' ? item.title : '',\n sku: typeof item.sku === 'string' ? item.sku : null,\n defaultMediaUrl: typeof item.defaultMediaUrl === 'string'\n ? item.defaultMediaUrl\n : typeof item.default_media_url === 'string'\n ? item.default_media_url\n : null,\n pricing: item.pricing && typeof item.pricing === 'object'\n ? normalizePricing(item.pricing as Record<string, unknown>)\n : null,\n existingOfferId,\n existingOfferTitle:\n channelOffer && typeof channelOffer.title === 'string' ? channelOffer.title : null,\n isCurrentOfferProduct: Boolean(existingOfferId && currentOfferId && existingOfferId === currentOfferId),\n }\n}\n\nfunction formatPriceDisplay(pricing: PricingSummary | null): string {\n if (!pricing) return '\u2014'\n const amount = pricing.displayMode === 'including-tax'\n ? pricing.unitPriceGross ?? pricing.unitPriceNet\n : pricing.unitPriceNet ?? pricing.unitPriceGross\n if (!amount) return pricing.currencyCode ?? '\u2014'\n return `${pricing.currencyCode ?? ''} ${amount}`\n}\n\nfunction PriceOverridesEditor({\n values,\n onChange,\n priceKinds,\n basePrice,\n onRemoveDraft,\n}: {\n values: PriceOverrideDraft[]\n onChange: (next: PriceOverrideDraft[]) => void\n priceKinds: PriceKindSummary[]\n basePrice: PricingSummary | null\n onRemoveDraft?: (draft: PriceOverrideDraft) => Promise<boolean> | boolean\n}) {\n const t = useT()\n const baseAmount = React.useMemo(() => {\n if (!basePrice) return ''\n const net = basePrice.unitPriceNet ?? null\n const gross = basePrice.unitPriceGross ?? null\n if (basePrice.displayMode === 'including-tax') {\n return gross ?? net ?? ''\n }\n if (basePrice.displayMode === 'excluding-tax') {\n return net ?? gross ?? ''\n }\n return net ?? gross ?? ''\n }, [basePrice])\n const baseDefaults = React.useMemo(() => ({\n amount: baseAmount,\n currencyCode: basePrice?.currencyCode ?? null,\n displayMode: basePrice?.displayMode ?? null,\n }), [baseAmount, basePrice?.currencyCode, basePrice?.displayMode])\n const usedKindIdSet = React.useMemo(() => {\n const next = new Set<string>()\n values.forEach((row) => {\n if (typeof row.priceKindId === 'string' && row.priceKindId.length) {\n next.add(row.priceKindId)\n }\n })\n return next\n }, [values])\n const availableKindCount = priceKinds.reduce(\n (count, kind) => (usedKindIdSet.has(kind.id) ? count : count + 1),\n 0,\n )\n const canAddRow = availableKindCount > 0\n const addRow = React.useCallback(() => {\n const usedIds = new Set<string>()\n values.forEach((row) => {\n if (typeof row.priceKindId === 'string' && row.priceKindId.length) {\n usedIds.add(row.priceKindId)\n }\n })\n const nextKind = priceKinds.find((kind) => !usedIds.has(kind.id))\n if (!nextKind && priceKinds.length) {\n return\n }\n onChange([\n ...values,\n {\n tempId: crypto.randomUUID?.() ?? Math.random().toString(36).slice(2),\n amount: baseDefaults.amount,\n currencyCode: nextKind?.currencyCode ?? baseDefaults.currencyCode,\n displayMode: nextKind?.displayMode ?? baseDefaults.displayMode,\n priceKindId: nextKind?.id ?? null,\n priceKindCode: nextKind?.code ?? nextKind?.title ?? null,\n },\n ])\n }, [baseDefaults, onChange, priceKinds, values])\n\n const updateRow = React.useCallback((tempId: string, patch: Partial<PriceOverrideDraft>) => {\n onChange(values.map((row) => (row.tempId === tempId ? { ...row, ...patch } : row)))\n }, [onChange, values])\n\n const removeRow = React.useCallback(async (row: PriceOverrideDraft) => {\n const allowRemoval = await onRemoveDraft?.(row)\n if (allowRemoval === false) return\n onChange(values.filter((entry) => entry.tempId !== row.tempId))\n }, [onChange, onRemoveDraft, values])\n\n return (\n <div className=\"space-y-4\">\n <div className=\"rounded border bg-muted/50 px-3 py-2\">\n <div className=\"text-xs uppercase text-muted-foreground\">\n {t('sales.channels.offers.pricing.basePriceLabel', 'Original product price')}\n </div>\n <div className=\"text-base font-semibold\">\n {basePrice ? formatPriceDisplay(basePrice) : t('sales.channels.offers.pricing.basePriceMissing', 'No price found')}\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.pricing.basePriceHelp', 'Shown to shoppers when no override is configured.')}\n </div>\n </div>\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-muted-foreground\">\n {t('sales.channels.offers.pricing.help', 'Provide overrides for price kinds when this offer is active.')}\n </p>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={addRow} disabled={!canAddRow}>\n {t('sales.channels.offers.pricing.add', 'Add price')}\n </Button>\n </div>\n {!canAddRow ? (\n <p className=\"text-xs text-muted-foreground\">\n {priceKinds.length\n ? t('sales.channels.offers.pricing.allKindsUsed', 'Each price kind already has an override.')\n : t('sales.channels.offers.pricing.noKindsAvailable', 'Define a price kind before adding overrides.')}\n </p>\n ) : null}\n </div>\n <div className=\"flex items-center justify-between\">\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.pricing.overrideHint', 'Overrides take precedence over the original product price.')}\n </p>\n </div>\n {values.length ? (\n <div className=\"space-y-2\">\n {values.map((row) => (\n <div key={row.tempId} className=\"grid gap-2 rounded border p-3 md:grid-cols-3\">\n <Select\n value={row.priceKindId || undefined}\n onValueChange={(value) => {\n const next = priceKinds.find((kind) => kind.id === value)\n updateRow(row.tempId, {\n priceKindId: next?.id ?? null,\n priceKindCode: next?.code ?? next?.title ?? null,\n currencyCode: next?.currencyCode ?? null,\n displayMode: next?.displayMode ?? null,\n })\n }}\n >\n <SelectTrigger>\n <SelectValue placeholder={t('sales.channels.offers.pricing.selectKind', 'Select price kind')} />\n </SelectTrigger>\n <SelectContent>\n {priceKinds.map((kind) => (\n <SelectItem\n key={kind.id}\n value={kind.id}\n disabled={usedKindIdSet.has(kind.id) && row.priceKindId !== kind.id}\n >\n {kind.title ?? kind.code ?? kind.id}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <div className=\"relative\">\n {(row.currencyCode ?? basePrice?.currencyCode) ? (\n <span className=\"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-xs font-semibold text-muted-foreground\">\n {row.currencyCode ?? basePrice?.currencyCode}\n </span>\n ) : null}\n <Input\n inputClassName={cn(row.currencyCode || basePrice?.currencyCode ? 'pl-13' : '')}\n type=\"number\"\n placeholder={t('sales.channels.offers.pricing.amount', 'Amount')}\n value={row.amount ?? ''}\n onChange={(event) => updateRow(row.tempId, { amount: event.target.value })}\n />\n </div>\n <div className=\"flex flex-col justify-between gap-2 text-xs text-muted-foreground sm:flex-row sm:items-center\">\n <span>\n {row.displayMode === 'including-tax'\n ? t('sales.channels.offers.pricing.includingTax', 'Including tax')\n : t('sales.channels.offers.pricing.excludingTax', 'Excluding tax')}\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"gap-1 px-2 font-normal text-destructive hover:text-destructive focus-visible:text-destructive\"\n onClick={() => { void removeRow(row) }}\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n {t('sales.channels.offers.pricing.remove', 'Remove')}\n </Button>\n </div>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.pricing.empty', 'No overrides yet.')}\n {basePrice ? (\n <>\n {' '}\n {t(\n 'sales.channels.offers.pricing.emptyFallback',\n 'Using {price} from the product until you add overrides.',\n { price: formatPriceDisplay(basePrice) },\n )}\n </>\n ) : null}\n </p>\n )}\n </div>\n )\n}\n\nfunction ProductOverviewCard({ summary, variants }: { summary: ProductSummary; variants: ProductVariantPreview[] }) {\n const t = useT()\n if (!summary) {\n return (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSummaryPlaceholder', 'Select a product to preview its media, price, and variants.')}\n </p>\n )\n }\n return (\n <div className=\"space-y-4\">\n <div className=\"flex gap-3\">\n <div className=\"h-16 w-16 overflow-hidden rounded border bg-muted\">\n {summary.defaultMediaUrl ? (\n <img src={summary.defaultMediaUrl} alt={summary.title} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-5 w-5\" />\n </div>\n )}\n </div>\n <div className=\"flex-1\">\n <div className=\"text-sm font-semibold\">{summary.title || t('sales.channels.offers.form.productUntitled', 'Untitled product')}</div>\n {summary.sku ? (\n <div className=\"text-xs text-muted-foreground\">SKU \u00B7 {summary.sku}</div>\n ) : null}\n <div className=\"text-sm\">\n <span className=\"text-muted-foreground\">{t('sales.channels.offers.form.productPriceLabel', 'Base price')}:</span>{' '}\n <span className=\"font-semibold\">{formatPriceDisplay(summary.pricing)}</span>\n </div>\n </div>\n </div>\n {summary.description ? (\n <p className=\"text-sm text-muted-foreground\">{summary.description}</p>\n ) : null}\n <ProductVariantsList variants={variants} />\n </div>\n )\n}\n\nfunction ProductVariantsList({ variants }: { variants: ProductVariantPreview[] }) {\n const t = useT()\n if (!variants.length) {\n return (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.variantsEmpty', 'No variants available for this product.')}\n </p>\n )\n }\n return (\n <div className=\"space-y-2\">\n <div className=\"text-sm font-medium\">{t('sales.channels.offers.form.variantsTitle', 'Variants')}</div>\n <div className=\"space-y-2 max-h-64 overflow-y-auto pr-1\">\n {variants.map((variant) => (\n <div key={variant.id} className=\"flex gap-3 rounded border bg-card p-2\">\n <div className=\"h-10 w-10 overflow-hidden rounded border bg-muted\">\n {variant.thumbnailUrl ? (\n <img src={variant.thumbnailUrl} alt={variant.name} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-4 w-4\" />\n </div>\n )}\n </div>\n <div className=\"min-w-0\">\n <div className=\"text-xs font-medium\">{variant.name}</div>\n {variant.sku ? (\n <div className=\"text-overline text-muted-foreground\">SKU \u00B7 {variant.sku}</div>\n ) : null}\n </div>\n </div>\n ))}\n </div>\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|