@open-mercato/core 0.6.6-develop.6339.1.193c6c7c71 → 0.6.6-develop.6343.1.8120f84f30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (25) hide show
  1. package/dist/modules/catalog/components/products/ProductComplianceSection.js +1 -1
  2. package/dist/modules/catalog/components/products/ProductComplianceSection.js.map +2 -2
  3. package/dist/modules/catalog/data/validators.js +1 -1
  4. package/dist/modules/catalog/data/validators.js.map +2 -2
  5. package/dist/modules/communication_channels/backend/communication_channels/channels/[id]/page.js +1 -1
  6. package/dist/modules/communication_channels/backend/communication_channels/channels/[id]/page.js.map +2 -2
  7. package/dist/modules/communication_channels/lib/route-mutation-guard.js +19 -29
  8. package/dist/modules/communication_channels/lib/route-mutation-guard.js.map +2 -2
  9. package/dist/modules/customers/backend/customers/deals/pipeline/page.js +4 -4
  10. package/dist/modules/customers/backend/customers/deals/pipeline/page.js.map +2 -2
  11. package/dist/modules/customers/components/calendar/CalendarScreen.js +1 -1
  12. package/dist/modules/customers/components/calendar/CalendarScreen.js.map +2 -2
  13. package/dist/modules/notifications/lib/routeHelpers.js +18 -25
  14. package/dist/modules/notifications/lib/routeHelpers.js.map +2 -2
  15. package/dist/modules/payment_gateways/backend/payment-gateways/page.js +1 -1
  16. package/dist/modules/payment_gateways/backend/payment-gateways/page.js.map +2 -2
  17. package/package.json +7 -7
  18. package/src/modules/catalog/components/products/ProductComplianceSection.tsx +1 -1
  19. package/src/modules/catalog/data/validators.ts +1 -1
  20. package/src/modules/communication_channels/backend/communication_channels/channels/[id]/page.tsx +1 -1
  21. package/src/modules/communication_channels/lib/route-mutation-guard.ts +32 -32
  22. package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +4 -4
  23. package/src/modules/customers/components/calendar/CalendarScreen.tsx +1 -1
  24. package/src/modules/notifications/lib/routeHelpers.ts +18 -26
  25. package/src/modules/payment_gateways/backend/payment-gateways/page.tsx +1 -1
@@ -40,7 +40,7 @@ function ProductComplianceSection({
40
40
  const toggleGtuCode = React.useCallback(
41
41
  (code, checked) => {
42
42
  const current = Array.isArray(values.gtuCodes) ? values.gtuCodes : [];
43
- const next = checked ? Array.from(/* @__PURE__ */ new Set([...current, code])).sort() : current.filter((entry) => entry !== code);
43
+ const next = checked ? Array.from(/* @__PURE__ */ new Set([...current, code])).sort((a, b) => a < b ? -1 : a > b ? 1 : 0) : current.filter((entry) => entry !== code);
44
44
  setValue("gtuCodes", next);
45
45
  },
46
46
  [setValue, values.gtuCodes]
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/catalog/components/products/ProductComplianceSection.tsx"],
4
- "sourcesContent": ["\"use client\";\n\nimport * as React from \"react\";\nimport { useT } from \"@open-mercato/shared/lib/i18n/context\";\nimport { Checkbox } from \"@open-mercato/ui/primitives/checkbox\";\nimport { Input } from \"@open-mercato/ui/primitives/input\";\nimport { Label } from \"@open-mercato/ui/primitives/label\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@open-mercato/ui/primitives/select\";\nimport { Textarea } from \"@open-mercato/ui/primitives/textarea\";\nimport {\n CATALOG_EXCISE_CATEGORIES,\n CATALOG_GTU_CODES,\n CATALOG_HAZMAT_PACKING_GROUPS,\n} from \"../../data/types\";\nimport type { ProductFormValues } from \"./productForm\";\n\nconst NONE_OPTION = \"none\";\n\ntype ProductComplianceSectionProps = {\n values: ProductFormValues;\n errors: Record<string, string>;\n setValue: (id: string, value: unknown) => void;\n embedded?: boolean;\n};\n\nfunction fieldErrorId(inputId: string) {\n return `${inputId}-error`;\n}\n\nfunction describedByError(\n inputId: string,\n message?: string,\n): { \"aria-invalid\"?: true; \"aria-describedby\"?: string } {\n return message\n ? { \"aria-invalid\": true, \"aria-describedby\": fieldErrorId(inputId) }\n : {};\n}\n\nfunction FieldError({ id, message }: { id: string; message?: string }) {\n if (!message) return null;\n return (\n <p id={id} className=\"text-xs text-destructive\">\n {message}\n </p>\n );\n}\n\nexport function ProductComplianceSection({\n values,\n errors,\n setValue,\n embedded = false,\n}: ProductComplianceSectionProps) {\n const t = useT();\n const gtuCodes = Array.isArray(values.gtuCodes) ? values.gtuCodes : [];\n\n const toggleGtuCode = React.useCallback(\n (code: string, checked: boolean) => {\n const current = Array.isArray(values.gtuCodes) ? values.gtuCodes : [];\n const next = checked\n ? Array.from(new Set([...current, code])).sort()\n : current.filter((entry) => entry !== code);\n setValue(\"gtuCodes\", next);\n },\n [setValue, values.gtuCodes],\n );\n\n return (\n <div\n className={\n embedded ? \"space-y-6\" : \"space-y-6 rounded-lg border bg-card p-4\"\n }\n >\n <div className=\"space-y-4\">\n <div className=\"space-y-1\">\n <h3 className=\"text-sm font-semibold\">\n {t(\"catalog.products.compliance.codes.title\", \"Compliance codes (PL/EU)\")}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.compliance.codes.description\",\n \"Classification codes used by KSeF/JPK invoices, customs declarations, and marketplace feeds.\",\n )}\n </p>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-country\">\n {t(\"catalog.products.compliance.fields.countryOfOrigin\", \"Country of origin (ISO code)\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-country\"\n value={values.countryOfOriginCode ?? \"\"}\n maxLength={2}\n placeholder={t(\"catalog.products.compliance.placeholders.countryOfOrigin\", \"PL\")}\n onChange={(event) =>\n setValue(\"countryOfOriginCode\", event.target.value.toUpperCase())\n }\n {...describedByError(\"catalog-product-compliance-country\", errors.countryOfOriginCode)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-country\")}\n message={errors.countryOfOriginCode}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-tax-classification\">\n {t(\"catalog.products.compliance.fields.taxClassification\", \"Tax classification code\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-tax-classification\"\n value={values.taxClassificationCode ?? \"\"}\n onChange={(event) => setValue(\"taxClassificationCode\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-tax-classification\", errors.taxClassificationCode)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-tax-classification\")}\n message={errors.taxClassificationCode}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-pkwiu\">\n {t(\"catalog.products.compliance.fields.pkwiu\", \"PKWiU code\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-pkwiu\"\n value={values.pkwiuCode ?? \"\"}\n onChange={(event) => setValue(\"pkwiuCode\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-pkwiu\", errors.pkwiuCode)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-pkwiu\")}\n message={errors.pkwiuCode}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-cn\">\n {t(\"catalog.products.compliance.fields.cn\", \"CN code (Combined Nomenclature)\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-cn\"\n value={values.cnCode ?? \"\"}\n onChange={(event) => setValue(\"cnCode\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-cn\", errors.cnCode)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-cn\")}\n message={errors.cnCode}\n />\n </div>\n <div className=\"space-y-2 md:col-span-2\">\n <Label htmlFor=\"catalog-product-compliance-hs\">\n {t(\"catalog.products.compliance.fields.hs\", \"HS code (customs tariff)\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-hs\"\n value={values.hsCode ?? \"\"}\n onChange={(event) => setValue(\"hsCode\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-hs\", errors.hsCode)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-hs\")}\n message={errors.hsCode}\n />\n </div>\n </div>\n <div className=\"space-y-2\">\n <Label id=\"catalog-product-compliance-gtu-label\">\n {t(\"catalog.products.compliance.fields.gtuCodes\", \"GTU codes (JPK_V7)\")}\n </Label>\n <div\n role=\"group\"\n aria-labelledby=\"catalog-product-compliance-gtu-label\"\n className=\"grid gap-2 sm:grid-cols-3 md:grid-cols-4\"\n {...describedByError(\"catalog-product-compliance-gtu\", errors.gtuCodes)}\n >\n {CATALOG_GTU_CODES.map((code) => (\n <label\n key={code}\n className=\"flex items-center gap-2 text-sm\"\n htmlFor={`catalog-product-compliance-gtu-${code}`}\n >\n <Checkbox\n id={`catalog-product-compliance-gtu-${code}`}\n checked={gtuCodes.includes(code)}\n onCheckedChange={(checked) => toggleGtuCode(code, checked === true)}\n />\n {code.replace(\"_\", \" \")}\n </label>\n ))}\n </div>\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-gtu\")}\n message={errors.gtuCodes}\n />\n </div>\n </div>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-1\">\n <h3 className=\"text-sm font-semibold\">\n {t(\"catalog.products.compliance.safety.title\", \"Restrictions & safety\")}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.compliance.safety.description\",\n \"Age, excise, and dangerous-goods attributes enforced by storefront, POS, and carriers.\",\n )}\n </p>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-age-min\">\n {t(\"catalog.products.compliance.fields.ageMin\", \"Minimum buyer age\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-age-min\"\n type=\"number\"\n min={0}\n max={120}\n value={values.ageMin ?? \"\"}\n onChange={(event) => setValue(\"ageMin\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-age-min\", errors.ageMin)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-age-min\")}\n message={errors.ageMin}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-excise-category\">\n {t(\"catalog.products.compliance.fields.exciseCategory\", \"Excise category\")}\n </Label>\n <Select\n value={values.exciseCategory ?? NONE_OPTION}\n onValueChange={(value) =>\n setValue(\"exciseCategory\", value === NONE_OPTION ? null : value)\n }\n >\n <SelectTrigger\n id=\"catalog-product-compliance-excise-category\"\n {...describedByError(\"catalog-product-compliance-excise-category\", errors.exciseCategory)}\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NONE_OPTION}>\n {t(\"catalog.products.compliance.options.none\", \"None\")}\n </SelectItem>\n {CATALOG_EXCISE_CATEGORIES.map((category) => (\n <SelectItem key={category} value={category}>\n {t(`catalog.products.compliance.exciseCategories.${category}`, category)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-excise-category\")}\n message={errors.exciseCategory}\n />\n </div>\n </div>\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <label\n className=\"flex items-center gap-2 text-sm\"\n htmlFor=\"catalog-product-compliance-excise\"\n >\n <Checkbox\n id=\"catalog-product-compliance-excise\"\n checked={values.isExciseGood === true}\n onCheckedChange={(checked) => setValue(\"isExciseGood\", checked === true)}\n />\n {t(\"catalog.products.compliance.fields.isExciseGood\", \"Excise good\")}\n </label>\n <label\n className=\"flex items-center gap-2 text-sm\"\n htmlFor=\"catalog-product-compliance-prescription\"\n >\n <Checkbox\n id=\"catalog-product-compliance-prescription\"\n checked={values.requiresPrescription === true}\n onCheckedChange={(checked) => setValue(\"requiresPrescription\", checked === true)}\n />\n {t(\"catalog.products.compliance.fields.requiresPrescription\", \"Requires prescription\")}\n </label>\n <label\n className=\"flex items-center gap-2 text-sm\"\n htmlFor=\"catalog-product-compliance-lithium\"\n >\n <Checkbox\n id=\"catalog-product-compliance-lithium\"\n checked={values.containsLithiumBattery === true}\n onCheckedChange={(checked) => setValue(\"containsLithiumBattery\", checked === true)}\n />\n {t(\"catalog.products.compliance.fields.containsLithiumBattery\", \"Contains lithium battery\")}\n </label>\n </div>\n <div className=\"grid gap-4 md:grid-cols-3\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-hazmat-class\">\n {t(\"catalog.products.compliance.fields.hazmatClass\", \"Hazmat class (ADR)\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-hazmat-class\"\n value={values.hazmatClass ?? \"\"}\n onChange={(event) => setValue(\"hazmatClass\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-hazmat-class\", errors.hazmatClass)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-hazmat-class\")}\n message={errors.hazmatClass}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-un-number\">\n {t(\"catalog.products.compliance.fields.unNumber\", \"UN number\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-un-number\"\n placeholder={t(\"catalog.products.compliance.placeholders.unNumber\", \"UN1234\")}\n value={values.unNumber ?? \"\"}\n onChange={(event) => setValue(\"unNumber\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-un-number\", errors.unNumber)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-un-number\")}\n message={errors.unNumber}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-packing-group\">\n {t(\"catalog.products.compliance.fields.hazmatPackingGroup\", \"Packing group\")}\n </Label>\n <Select\n value={values.hazmatPackingGroup ?? NONE_OPTION}\n onValueChange={(value) =>\n setValue(\"hazmatPackingGroup\", value === NONE_OPTION ? null : value)\n }\n >\n <SelectTrigger\n id=\"catalog-product-compliance-packing-group\"\n {...describedByError(\"catalog-product-compliance-packing-group\", errors.hazmatPackingGroup)}\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NONE_OPTION}>\n {t(\"catalog.products.compliance.options.none\", \"None\")}\n </SelectItem>\n {CATALOG_HAZMAT_PACKING_GROUPS.map((group) => (\n <SelectItem key={group} value={group}>\n {group}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-packing-group\")}\n message={errors.hazmatPackingGroup}\n />\n </div>\n </div>\n </div>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-1\">\n <h3 className=\"text-sm font-semibold\">\n {t(\"catalog.products.compliance.logistics.title\", \"Availability & lifecycle\")}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.compliance.logistics.description\",\n \"Launch, end-of-life, and selling windows plus shipping requirements.\",\n )}\n </p>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-launch-at\">\n {t(\"catalog.products.compliance.fields.launchAt\", \"Launch date\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-launch-at\"\n type=\"date\"\n value={values.launchAt ?? \"\"}\n onChange={(event) => setValue(\"launchAt\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-launch-at\", errors.launchAt)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-launch-at\")}\n message={errors.launchAt}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-eol-at\">\n {t(\"catalog.products.compliance.fields.endOfLifeAt\", \"End of life\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-eol-at\"\n type=\"date\"\n value={values.endOfLifeAt ?? \"\"}\n onChange={(event) => setValue(\"endOfLifeAt\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-eol-at\", errors.endOfLifeAt)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-eol-at\")}\n message={errors.endOfLifeAt}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-available-from\">\n {t(\"catalog.products.compliance.fields.availableFrom\", \"Available from\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-available-from\"\n type=\"date\"\n value={values.availableFrom ?? \"\"}\n onChange={(event) => setValue(\"availableFrom\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-available-from\", errors.availableFrom)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-available-from\")}\n message={errors.availableFrom}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-available-until\">\n {t(\"catalog.products.compliance.fields.availableUntil\", \"Available until\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-available-until\"\n type=\"date\"\n value={values.availableUntil ?? \"\"}\n onChange={(event) => setValue(\"availableUntil\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-available-until\", errors.availableUntil)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-available-until\")}\n message={errors.availableUntil}\n />\n </div>\n </div>\n <label\n className=\"flex items-center gap-2 text-sm\"\n htmlFor=\"catalog-product-compliance-requires-shipping\"\n >\n <Checkbox\n id=\"catalog-product-compliance-requires-shipping\"\n checked={values.requiresShipping !== false}\n onCheckedChange={(checked) => setValue(\"requiresShipping\", checked === true)}\n />\n {t(\"catalog.products.compliance.fields.requiresShipping\", \"Requires shipping\")}\n </label>\n </div>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-1\">\n <h3 className=\"text-sm font-semibold\">\n {t(\"catalog.products.compliance.commercial.title\", \"Commercial terms\")}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.compliance.commercial.description\",\n \"Order quantity constraints and quote-only selling for B2B.\",\n )}\n </p>\n </div>\n <div className=\"grid gap-4 md:grid-cols-3\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-min-qty\">\n {t(\"catalog.products.compliance.fields.minOrderQty\", \"Minimum order quantity\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-min-qty\"\n type=\"number\"\n min={1}\n value={values.minOrderQty ?? \"\"}\n onChange={(event) => setValue(\"minOrderQty\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-min-qty\", errors.minOrderQty)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-min-qty\")}\n message={errors.minOrderQty}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-max-qty\">\n {t(\"catalog.products.compliance.fields.maxOrderQty\", \"Maximum order quantity\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-max-qty\"\n type=\"number\"\n min={1}\n value={values.maxOrderQty ?? \"\"}\n onChange={(event) => setValue(\"maxOrderQty\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-max-qty\", errors.maxOrderQty)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-max-qty\")}\n message={errors.maxOrderQty}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-qty-increment\">\n {t(\"catalog.products.compliance.fields.orderQtyIncrement\", \"Quantity increment\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-qty-increment\"\n type=\"number\"\n min={1}\n value={values.orderQtyIncrement ?? \"\"}\n onChange={(event) => setValue(\"orderQtyIncrement\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-qty-increment\", errors.orderQtyIncrement)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-qty-increment\")}\n message={errors.orderQtyIncrement}\n />\n </div>\n </div>\n <label\n className=\"flex items-center gap-2 text-sm\"\n htmlFor=\"catalog-product-compliance-quote-only\"\n >\n <Checkbox\n id=\"catalog-product-compliance-quote-only\"\n checked={values.isQuoteOnly === true}\n onCheckedChange={(checked) => setValue(\"isQuoteOnly\", checked === true)}\n />\n {t(\"catalog.products.compliance.fields.isQuoteOnly\", \"Quote only (price on request)\")}\n </label>\n </div>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-1\">\n <h3 className=\"text-sm font-semibold\">\n {t(\"catalog.products.compliance.seo.title\", \"SEO\")}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.compliance.seo.description\",\n \"Storefront metadata. Title and description are translatable per locale.\",\n )}\n </p>\n </div>\n <div className=\"grid gap-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-seo-title\">\n {t(\"catalog.products.compliance.fields.seoTitle\", \"SEO title\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-seo-title\"\n maxLength={255}\n value={values.seoTitle ?? \"\"}\n onChange={(event) => setValue(\"seoTitle\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-seo-title\", errors.seoTitle)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-seo-title\")}\n message={errors.seoTitle}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-seo-description\">\n {t(\"catalog.products.compliance.fields.seoDescription\", \"SEO description\")}\n </Label>\n <Textarea\n id=\"catalog-product-compliance-seo-description\"\n rows={3}\n maxLength={1000}\n value={values.seoDescription ?? \"\"}\n onChange={(event) => setValue(\"seoDescription\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-seo-description\", errors.seoDescription)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-seo-description\")}\n message={errors.seoDescription}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-canonical-url\">\n {t(\"catalog.products.compliance.fields.canonicalUrl\", \"Canonical URL\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-canonical-url\"\n type=\"url\"\n maxLength={500}\n placeholder=\"https://\"\n value={values.canonicalUrl ?? \"\"}\n onChange={(event) => setValue(\"canonicalUrl\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-canonical-url\", errors.canonicalUrl)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-canonical-url\")}\n message={errors.canonicalUrl}\n />\n </div>\n </div>\n </div>\n </div>\n );\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\";\n\nimport * as React from \"react\";\nimport { useT } from \"@open-mercato/shared/lib/i18n/context\";\nimport { Checkbox } from \"@open-mercato/ui/primitives/checkbox\";\nimport { Input } from \"@open-mercato/ui/primitives/input\";\nimport { Label } from \"@open-mercato/ui/primitives/label\";\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"@open-mercato/ui/primitives/select\";\nimport { Textarea } from \"@open-mercato/ui/primitives/textarea\";\nimport {\n CATALOG_EXCISE_CATEGORIES,\n CATALOG_GTU_CODES,\n CATALOG_HAZMAT_PACKING_GROUPS,\n} from \"../../data/types\";\nimport type { ProductFormValues } from \"./productForm\";\n\nconst NONE_OPTION = \"none\";\n\ntype ProductComplianceSectionProps = {\n values: ProductFormValues;\n errors: Record<string, string>;\n setValue: (id: string, value: unknown) => void;\n embedded?: boolean;\n};\n\nfunction fieldErrorId(inputId: string) {\n return `${inputId}-error`;\n}\n\nfunction describedByError(\n inputId: string,\n message?: string,\n): { \"aria-invalid\"?: true; \"aria-describedby\"?: string } {\n return message\n ? { \"aria-invalid\": true, \"aria-describedby\": fieldErrorId(inputId) }\n : {};\n}\n\nfunction FieldError({ id, message }: { id: string; message?: string }) {\n if (!message) return null;\n return (\n <p id={id} className=\"text-xs text-destructive\">\n {message}\n </p>\n );\n}\n\nexport function ProductComplianceSection({\n values,\n errors,\n setValue,\n embedded = false,\n}: ProductComplianceSectionProps) {\n const t = useT();\n const gtuCodes = Array.isArray(values.gtuCodes) ? values.gtuCodes : [];\n\n const toggleGtuCode = React.useCallback(\n (code: string, checked: boolean) => {\n const current = Array.isArray(values.gtuCodes) ? values.gtuCodes : [];\n const next = checked\n ? Array.from(new Set([...current, code])).sort((a, b) => (a < b ? -1 : a > b ? 1 : 0))\n : current.filter((entry) => entry !== code);\n setValue(\"gtuCodes\", next);\n },\n [setValue, values.gtuCodes],\n );\n\n return (\n <div\n className={\n embedded ? \"space-y-6\" : \"space-y-6 rounded-lg border bg-card p-4\"\n }\n >\n <div className=\"space-y-4\">\n <div className=\"space-y-1\">\n <h3 className=\"text-sm font-semibold\">\n {t(\"catalog.products.compliance.codes.title\", \"Compliance codes (PL/EU)\")}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.compliance.codes.description\",\n \"Classification codes used by KSeF/JPK invoices, customs declarations, and marketplace feeds.\",\n )}\n </p>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-country\">\n {t(\"catalog.products.compliance.fields.countryOfOrigin\", \"Country of origin (ISO code)\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-country\"\n value={values.countryOfOriginCode ?? \"\"}\n maxLength={2}\n placeholder={t(\"catalog.products.compliance.placeholders.countryOfOrigin\", \"PL\")}\n onChange={(event) =>\n setValue(\"countryOfOriginCode\", event.target.value.toUpperCase())\n }\n {...describedByError(\"catalog-product-compliance-country\", errors.countryOfOriginCode)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-country\")}\n message={errors.countryOfOriginCode}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-tax-classification\">\n {t(\"catalog.products.compliance.fields.taxClassification\", \"Tax classification code\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-tax-classification\"\n value={values.taxClassificationCode ?? \"\"}\n onChange={(event) => setValue(\"taxClassificationCode\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-tax-classification\", errors.taxClassificationCode)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-tax-classification\")}\n message={errors.taxClassificationCode}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-pkwiu\">\n {t(\"catalog.products.compliance.fields.pkwiu\", \"PKWiU code\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-pkwiu\"\n value={values.pkwiuCode ?? \"\"}\n onChange={(event) => setValue(\"pkwiuCode\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-pkwiu\", errors.pkwiuCode)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-pkwiu\")}\n message={errors.pkwiuCode}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-cn\">\n {t(\"catalog.products.compliance.fields.cn\", \"CN code (Combined Nomenclature)\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-cn\"\n value={values.cnCode ?? \"\"}\n onChange={(event) => setValue(\"cnCode\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-cn\", errors.cnCode)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-cn\")}\n message={errors.cnCode}\n />\n </div>\n <div className=\"space-y-2 md:col-span-2\">\n <Label htmlFor=\"catalog-product-compliance-hs\">\n {t(\"catalog.products.compliance.fields.hs\", \"HS code (customs tariff)\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-hs\"\n value={values.hsCode ?? \"\"}\n onChange={(event) => setValue(\"hsCode\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-hs\", errors.hsCode)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-hs\")}\n message={errors.hsCode}\n />\n </div>\n </div>\n <div className=\"space-y-2\">\n <Label id=\"catalog-product-compliance-gtu-label\">\n {t(\"catalog.products.compliance.fields.gtuCodes\", \"GTU codes (JPK_V7)\")}\n </Label>\n <div\n role=\"group\"\n aria-labelledby=\"catalog-product-compliance-gtu-label\"\n className=\"grid gap-2 sm:grid-cols-3 md:grid-cols-4\"\n {...describedByError(\"catalog-product-compliance-gtu\", errors.gtuCodes)}\n >\n {CATALOG_GTU_CODES.map((code) => (\n <label\n key={code}\n className=\"flex items-center gap-2 text-sm\"\n htmlFor={`catalog-product-compliance-gtu-${code}`}\n >\n <Checkbox\n id={`catalog-product-compliance-gtu-${code}`}\n checked={gtuCodes.includes(code)}\n onCheckedChange={(checked) => toggleGtuCode(code, checked === true)}\n />\n {code.replace(\"_\", \" \")}\n </label>\n ))}\n </div>\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-gtu\")}\n message={errors.gtuCodes}\n />\n </div>\n </div>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-1\">\n <h3 className=\"text-sm font-semibold\">\n {t(\"catalog.products.compliance.safety.title\", \"Restrictions & safety\")}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.compliance.safety.description\",\n \"Age, excise, and dangerous-goods attributes enforced by storefront, POS, and carriers.\",\n )}\n </p>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-age-min\">\n {t(\"catalog.products.compliance.fields.ageMin\", \"Minimum buyer age\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-age-min\"\n type=\"number\"\n min={0}\n max={120}\n value={values.ageMin ?? \"\"}\n onChange={(event) => setValue(\"ageMin\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-age-min\", errors.ageMin)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-age-min\")}\n message={errors.ageMin}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-excise-category\">\n {t(\"catalog.products.compliance.fields.exciseCategory\", \"Excise category\")}\n </Label>\n <Select\n value={values.exciseCategory ?? NONE_OPTION}\n onValueChange={(value) =>\n setValue(\"exciseCategory\", value === NONE_OPTION ? null : value)\n }\n >\n <SelectTrigger\n id=\"catalog-product-compliance-excise-category\"\n {...describedByError(\"catalog-product-compliance-excise-category\", errors.exciseCategory)}\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NONE_OPTION}>\n {t(\"catalog.products.compliance.options.none\", \"None\")}\n </SelectItem>\n {CATALOG_EXCISE_CATEGORIES.map((category) => (\n <SelectItem key={category} value={category}>\n {t(`catalog.products.compliance.exciseCategories.${category}`, category)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-excise-category\")}\n message={errors.exciseCategory}\n />\n </div>\n </div>\n <div className=\"grid gap-2 sm:grid-cols-2\">\n <label\n className=\"flex items-center gap-2 text-sm\"\n htmlFor=\"catalog-product-compliance-excise\"\n >\n <Checkbox\n id=\"catalog-product-compliance-excise\"\n checked={values.isExciseGood === true}\n onCheckedChange={(checked) => setValue(\"isExciseGood\", checked === true)}\n />\n {t(\"catalog.products.compliance.fields.isExciseGood\", \"Excise good\")}\n </label>\n <label\n className=\"flex items-center gap-2 text-sm\"\n htmlFor=\"catalog-product-compliance-prescription\"\n >\n <Checkbox\n id=\"catalog-product-compliance-prescription\"\n checked={values.requiresPrescription === true}\n onCheckedChange={(checked) => setValue(\"requiresPrescription\", checked === true)}\n />\n {t(\"catalog.products.compliance.fields.requiresPrescription\", \"Requires prescription\")}\n </label>\n <label\n className=\"flex items-center gap-2 text-sm\"\n htmlFor=\"catalog-product-compliance-lithium\"\n >\n <Checkbox\n id=\"catalog-product-compliance-lithium\"\n checked={values.containsLithiumBattery === true}\n onCheckedChange={(checked) => setValue(\"containsLithiumBattery\", checked === true)}\n />\n {t(\"catalog.products.compliance.fields.containsLithiumBattery\", \"Contains lithium battery\")}\n </label>\n </div>\n <div className=\"grid gap-4 md:grid-cols-3\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-hazmat-class\">\n {t(\"catalog.products.compliance.fields.hazmatClass\", \"Hazmat class (ADR)\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-hazmat-class\"\n value={values.hazmatClass ?? \"\"}\n onChange={(event) => setValue(\"hazmatClass\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-hazmat-class\", errors.hazmatClass)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-hazmat-class\")}\n message={errors.hazmatClass}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-un-number\">\n {t(\"catalog.products.compliance.fields.unNumber\", \"UN number\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-un-number\"\n placeholder={t(\"catalog.products.compliance.placeholders.unNumber\", \"UN1234\")}\n value={values.unNumber ?? \"\"}\n onChange={(event) => setValue(\"unNumber\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-un-number\", errors.unNumber)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-un-number\")}\n message={errors.unNumber}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-packing-group\">\n {t(\"catalog.products.compliance.fields.hazmatPackingGroup\", \"Packing group\")}\n </Label>\n <Select\n value={values.hazmatPackingGroup ?? NONE_OPTION}\n onValueChange={(value) =>\n setValue(\"hazmatPackingGroup\", value === NONE_OPTION ? null : value)\n }\n >\n <SelectTrigger\n id=\"catalog-product-compliance-packing-group\"\n {...describedByError(\"catalog-product-compliance-packing-group\", errors.hazmatPackingGroup)}\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NONE_OPTION}>\n {t(\"catalog.products.compliance.options.none\", \"None\")}\n </SelectItem>\n {CATALOG_HAZMAT_PACKING_GROUPS.map((group) => (\n <SelectItem key={group} value={group}>\n {group}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-packing-group\")}\n message={errors.hazmatPackingGroup}\n />\n </div>\n </div>\n </div>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-1\">\n <h3 className=\"text-sm font-semibold\">\n {t(\"catalog.products.compliance.logistics.title\", \"Availability & lifecycle\")}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.compliance.logistics.description\",\n \"Launch, end-of-life, and selling windows plus shipping requirements.\",\n )}\n </p>\n </div>\n <div className=\"grid gap-4 md:grid-cols-2\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-launch-at\">\n {t(\"catalog.products.compliance.fields.launchAt\", \"Launch date\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-launch-at\"\n type=\"date\"\n value={values.launchAt ?? \"\"}\n onChange={(event) => setValue(\"launchAt\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-launch-at\", errors.launchAt)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-launch-at\")}\n message={errors.launchAt}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-eol-at\">\n {t(\"catalog.products.compliance.fields.endOfLifeAt\", \"End of life\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-eol-at\"\n type=\"date\"\n value={values.endOfLifeAt ?? \"\"}\n onChange={(event) => setValue(\"endOfLifeAt\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-eol-at\", errors.endOfLifeAt)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-eol-at\")}\n message={errors.endOfLifeAt}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-available-from\">\n {t(\"catalog.products.compliance.fields.availableFrom\", \"Available from\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-available-from\"\n type=\"date\"\n value={values.availableFrom ?? \"\"}\n onChange={(event) => setValue(\"availableFrom\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-available-from\", errors.availableFrom)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-available-from\")}\n message={errors.availableFrom}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-available-until\">\n {t(\"catalog.products.compliance.fields.availableUntil\", \"Available until\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-available-until\"\n type=\"date\"\n value={values.availableUntil ?? \"\"}\n onChange={(event) => setValue(\"availableUntil\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-available-until\", errors.availableUntil)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-available-until\")}\n message={errors.availableUntil}\n />\n </div>\n </div>\n <label\n className=\"flex items-center gap-2 text-sm\"\n htmlFor=\"catalog-product-compliance-requires-shipping\"\n >\n <Checkbox\n id=\"catalog-product-compliance-requires-shipping\"\n checked={values.requiresShipping !== false}\n onCheckedChange={(checked) => setValue(\"requiresShipping\", checked === true)}\n />\n {t(\"catalog.products.compliance.fields.requiresShipping\", \"Requires shipping\")}\n </label>\n </div>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-1\">\n <h3 className=\"text-sm font-semibold\">\n {t(\"catalog.products.compliance.commercial.title\", \"Commercial terms\")}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.compliance.commercial.description\",\n \"Order quantity constraints and quote-only selling for B2B.\",\n )}\n </p>\n </div>\n <div className=\"grid gap-4 md:grid-cols-3\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-min-qty\">\n {t(\"catalog.products.compliance.fields.minOrderQty\", \"Minimum order quantity\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-min-qty\"\n type=\"number\"\n min={1}\n value={values.minOrderQty ?? \"\"}\n onChange={(event) => setValue(\"minOrderQty\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-min-qty\", errors.minOrderQty)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-min-qty\")}\n message={errors.minOrderQty}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-max-qty\">\n {t(\"catalog.products.compliance.fields.maxOrderQty\", \"Maximum order quantity\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-max-qty\"\n type=\"number\"\n min={1}\n value={values.maxOrderQty ?? \"\"}\n onChange={(event) => setValue(\"maxOrderQty\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-max-qty\", errors.maxOrderQty)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-max-qty\")}\n message={errors.maxOrderQty}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-qty-increment\">\n {t(\"catalog.products.compliance.fields.orderQtyIncrement\", \"Quantity increment\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-qty-increment\"\n type=\"number\"\n min={1}\n value={values.orderQtyIncrement ?? \"\"}\n onChange={(event) => setValue(\"orderQtyIncrement\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-qty-increment\", errors.orderQtyIncrement)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-qty-increment\")}\n message={errors.orderQtyIncrement}\n />\n </div>\n </div>\n <label\n className=\"flex items-center gap-2 text-sm\"\n htmlFor=\"catalog-product-compliance-quote-only\"\n >\n <Checkbox\n id=\"catalog-product-compliance-quote-only\"\n checked={values.isQuoteOnly === true}\n onCheckedChange={(checked) => setValue(\"isQuoteOnly\", checked === true)}\n />\n {t(\"catalog.products.compliance.fields.isQuoteOnly\", \"Quote only (price on request)\")}\n </label>\n </div>\n\n <div className=\"space-y-4\">\n <div className=\"space-y-1\">\n <h3 className=\"text-sm font-semibold\">\n {t(\"catalog.products.compliance.seo.title\", \"SEO\")}\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n \"catalog.products.compliance.seo.description\",\n \"Storefront metadata. Title and description are translatable per locale.\",\n )}\n </p>\n </div>\n <div className=\"grid gap-4\">\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-seo-title\">\n {t(\"catalog.products.compliance.fields.seoTitle\", \"SEO title\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-seo-title\"\n maxLength={255}\n value={values.seoTitle ?? \"\"}\n onChange={(event) => setValue(\"seoTitle\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-seo-title\", errors.seoTitle)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-seo-title\")}\n message={errors.seoTitle}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-seo-description\">\n {t(\"catalog.products.compliance.fields.seoDescription\", \"SEO description\")}\n </Label>\n <Textarea\n id=\"catalog-product-compliance-seo-description\"\n rows={3}\n maxLength={1000}\n value={values.seoDescription ?? \"\"}\n onChange={(event) => setValue(\"seoDescription\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-seo-description\", errors.seoDescription)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-seo-description\")}\n message={errors.seoDescription}\n />\n </div>\n <div className=\"space-y-2\">\n <Label htmlFor=\"catalog-product-compliance-canonical-url\">\n {t(\"catalog.products.compliance.fields.canonicalUrl\", \"Canonical URL\")}\n </Label>\n <Input\n id=\"catalog-product-compliance-canonical-url\"\n type=\"url\"\n maxLength={500}\n placeholder=\"https://\"\n value={values.canonicalUrl ?? \"\"}\n onChange={(event) => setValue(\"canonicalUrl\", event.target.value)}\n {...describedByError(\"catalog-product-compliance-canonical-url\", errors.canonicalUrl)}\n />\n <FieldError\n id={fieldErrorId(\"catalog-product-compliance-canonical-url\")}\n message={errors.canonicalUrl}\n />\n </div>\n </div>\n </div>\n </div>\n );\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -160,7 +160,7 @@ const productBaseSchema = scoped.extend({
160
160
  cnCode: z.string().trim().min(1).max(32).nullable().optional(),
161
161
  hsCode: z.string().trim().min(1).max(32).nullable().optional(),
162
162
  taxClassificationCode: z.string().trim().min(1).max(64).nullable().optional(),
163
- gtuCodes: z.array(z.enum(CATALOG_GTU_CODES)).max(13).transform((codes) => Array.from(new Set(codes)).sort()).nullable().optional(),
163
+ gtuCodes: z.array(z.enum(CATALOG_GTU_CODES)).max(13).transform((codes) => Array.from(new Set(codes)).sort((a, b) => a < b ? -1 : a > b ? 1 : 0)).nullable().optional(),
164
164
  ageMin: z.coerce.number().int().min(0).max(120).nullable().optional(),
165
165
  isExciseGood: z.boolean().optional(),
166
166
  exciseCategory: z.enum(CATALOG_EXCISE_CATEGORIES).nullable().optional(),
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/catalog/data/validators.ts"],
4
- "sourcesContent": ["import { z } from 'zod'\nimport {\n CATALOG_EXCISE_CATEGORIES,\n CATALOG_GTIN_TYPES,\n CATALOG_GTU_CODES,\n CATALOG_HAZMAT_PACKING_GROUPS,\n CATALOG_PRICE_DISPLAY_MODES,\n CATALOG_PRODUCT_TYPES,\n} from './types'\nimport { isValidGtin, normalizeGtinValue } from '../lib/gtin'\nimport { REFERENCE_UNIT_CODES } from '../lib/unitCodes'\nimport {\n getCatalogPriceAmountValidationMessage,\n validateCatalogPriceAmountInput,\n} from '../lib/priceValidation'\n\nconst uuid = () => z.string().uuid()\n\nconst scoped = z.object({\n organizationId: uuid(),\n tenantId: uuid(),\n})\n\nconst tenantScoped = z.object({\n tenantId: uuid(),\n})\n\nconst currencyCodeSchema = z\n .string()\n .trim()\n .regex(/^[A-Z]{3}$/, 'currency code must be a three-letter ISO code')\n\nconst metadataSchema = z.record(z.string(), z.unknown()).optional()\n\nconst slugSchema = z\n .string()\n .trim()\n .toLowerCase()\n .regex(/^[a-z0-9\\-_]+$/, 'code must contain lowercase letters, digits, hyphen, or underscore')\n .max(150)\n\nconst handleSchema = z\n .string()\n .trim()\n .toLowerCase()\n .regex(/^[a-z0-9\\-_]+$/, 'handle must contain lowercase letters, digits, hyphen, or underscore')\n .max(150)\n\nconst skuSchema = z\n .string()\n .trim()\n .regex(/^[A-Za-z0-9\\-_\\.]+$/, 'SKU may include letters, numbers, hyphen, underscore, or period')\n .max(191)\n\nconst variantOptionValuesSchema = z\n .record(\n z\n .string()\n .trim()\n .min(1)\n .max(191),\n z.string().trim().max(255)\n )\n .optional()\n\nconst optionChoiceSchema = z.object({\n code: slugSchema,\n label: z.string().trim().max(255).optional(),\n})\n\nconst optionDefinitionSchema = z.object({\n code: slugSchema,\n label: z.string().trim().min(1).max(255),\n description: z.string().trim().max(2000).optional(),\n inputType: z.enum(['select', 'text', 'textarea', 'number']),\n isRequired: z.boolean().optional(),\n isMultiple: z.boolean().optional(),\n choices: z.array(optionChoiceSchema).max(200).optional(),\n})\n\nconst optionSchema = z.object({\n version: z.number().int().min(1).optional(),\n name: z.string().trim().max(255).optional(),\n description: z.string().trim().max(4000).optional(),\n options: z.array(optionDefinitionSchema).max(64),\n})\n\nconst tagLabelSchema = z.string().trim().min(1).max(100)\n\nconst offerBaseSchema = z.object({\n channelId: uuid(),\n title: z.string().trim().min(1).max(255),\n description: z.string().trim().max(4000).optional(),\n defaultMediaId: uuid().optional().nullable(),\n defaultMediaUrl: z.string().trim().max(500).optional().nullable(),\n metadata: metadataSchema,\n isActive: z.boolean().optional(),\n})\n\nconst offerInputSchema = offerBaseSchema.extend({\n id: uuid().optional(),\n})\n\nexport const offerCreateSchema = scoped.merge(\n offerBaseSchema.extend({\n productId: uuid(),\n })\n)\n\nexport const offerUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(\n offerBaseSchema\n .extend({\n productId: uuid().optional(),\n })\n .partial()\n )\n\nconst productTypeSchema = z.enum(CATALOG_PRODUCT_TYPES)\nconst uomRoundingModeSchema = z.enum(['half_up', 'down', 'up'])\nconst unitPriceReferenceUnitSchema = z.enum(REFERENCE_UNIT_CODES)\nconst unitPriceConfigSchema = z.object({\n enabled: z.boolean().optional(),\n referenceUnit: unitPriceReferenceUnitSchema.nullable().optional(),\n baseQuantity: z.coerce.number().positive().optional(),\n})\n\nconst catalogPriceAmountSchema = z\n .custom<number>((value) => validateCatalogPriceAmountInput(value).ok, {\n message: getCatalogPriceAmountValidationMessage(),\n })\n .transform((value) => {\n const result = validateCatalogPriceAmountInput(value)\n if (!result.ok) {\n throw new Error('catalogPriceAmountSchema transform reached invalid state')\n }\n return result.numeric\n })\n\nfunction productUomCrossFieldRefinement(\n input: {\n defaultUnit?: string | null\n defaultSalesUnit?: string | null\n unitPriceEnabled?: boolean\n unitPriceReferenceUnit?: string | null\n unitPriceBaseQuantity?: number\n unitPrice?: { enabled?: boolean; referenceUnit?: string | null; baseQuantity?: number }\n },\n ctx: z.RefinementCtx,\n) {\n const defaultUnit = typeof input.defaultUnit === 'string' ? input.defaultUnit.trim() : ''\n const defaultSalesUnit =\n typeof input.defaultSalesUnit === 'string' ? input.defaultSalesUnit.trim() : ''\n if (defaultSalesUnit && !defaultUnit) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['defaultSalesUnit'],\n message: 'catalog.products.validation.baseUnitRequired',\n })\n }\n const unitPriceEnabled = input.unitPrice?.enabled ?? input.unitPriceEnabled ?? false\n if (!unitPriceEnabled) return\n const referenceUnit =\n input.unitPrice?.referenceUnit ?? input.unitPriceReferenceUnit ?? null\n const baseQuantity =\n input.unitPrice?.baseQuantity ?? input.unitPriceBaseQuantity ?? null\n if (!referenceUnit) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['unitPrice'],\n message: 'catalog.products.validation.referenceUnitRequired',\n })\n }\n if (baseQuantity === null || baseQuantity === undefined || Number(baseQuantity) <= 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['unitPrice'],\n message: 'catalog.products.unitPrice.errors.baseQuantity',\n })\n }\n}\n\n// Base schema without refinements (used for .partial() in update schema)\nconst productBaseSchema = scoped.extend({\n title: z.string().trim().min(1).max(255),\n subtitle: z.string().trim().max(255).optional(),\n description: z.string().trim().max(4000).optional(),\n sku: skuSchema.nullable().optional(),\n handle: handleSchema.optional(),\n taxRateId: uuid().nullable().optional(),\n taxRate: z.coerce.number().min(0).max(100).optional().nullable(),\n productType: productTypeSchema.default('simple'),\n statusEntryId: uuid().optional(),\n primaryCurrencyCode: currencyCodeSchema.optional(),\n defaultUnit: z.string().trim().max(50).optional().nullable(),\n defaultSalesUnit: z.string().trim().max(50).optional().nullable(),\n defaultSalesUnitQuantity: z.coerce.number().positive().optional(),\n uomRoundingScale: z.coerce.number().int().min(0).max(6).optional(),\n uomRoundingMode: uomRoundingModeSchema.optional(),\n unitPriceEnabled: z.boolean().optional(),\n unitPriceReferenceUnit: unitPriceReferenceUnitSchema.nullable().optional(),\n unitPriceBaseQuantity: z.coerce.number().positive().optional(),\n unitPrice: unitPriceConfigSchema.optional(),\n defaultMediaId: uuid().optional().nullable(),\n defaultMediaUrl: z.string().trim().max(500).optional().nullable(),\n weightValue: z.coerce.number().min(0).optional().nullable(),\n weightUnit: z.string().trim().max(25).optional().nullable(),\n dimensions: z\n .object({\n width: z.coerce.number().min(0).optional(),\n height: z.coerce.number().min(0).optional(),\n depth: z.coerce.number().min(0).optional(),\n unit: z.string().trim().max(25).optional(),\n })\n .optional()\n .nullable(),\n optionSchemaId: uuid().nullable().optional(),\n optionSchema: optionSchema.optional(),\n customFieldsetCode: slugSchema.nullable().optional(),\n isConfigurable: z.boolean().optional(),\n isActive: z.boolean().optional(),\n countryOfOriginCode: z\n .string()\n .trim()\n .toUpperCase()\n .regex(/^[A-Z]{2}$/, 'catalog.products.validation.countryCodeInvalid')\n .nullable()\n .optional(),\n pkwiuCode: z.string().trim().min(1).max(32).nullable().optional(),\n cnCode: z.string().trim().min(1).max(32).nullable().optional(),\n hsCode: z.string().trim().min(1).max(32).nullable().optional(),\n taxClassificationCode: z.string().trim().min(1).max(64).nullable().optional(),\n gtuCodes: z\n .array(z.enum(CATALOG_GTU_CODES))\n .max(13)\n .transform((codes) => Array.from(new Set(codes)).sort())\n .nullable()\n .optional(),\n ageMin: z.coerce.number().int().min(0).max(120).nullable().optional(),\n isExciseGood: z.boolean().optional(),\n exciseCategory: z.enum(CATALOG_EXCISE_CATEGORIES).nullable().optional(),\n requiresPrescription: z.boolean().optional(),\n hazmatClass: z.string().trim().min(1).max(32).nullable().optional(),\n unNumber: z\n .string()\n .trim()\n .regex(/^(?:UN)?[0-9]{4}$/i, 'catalog.products.validation.unNumberInvalid')\n .transform((value) => {\n const upper = value.toUpperCase()\n return upper.startsWith('UN') ? upper : `UN${upper}`\n })\n .nullable()\n .optional(),\n hazmatPackingGroup: z.enum(CATALOG_HAZMAT_PACKING_GROUPS).nullable().optional(),\n containsLithiumBattery: z.boolean().optional(),\n launchAt: z.coerce.date().nullable().optional(),\n endOfLifeAt: z.coerce.date().nullable().optional(),\n availableFrom: z.coerce.date().nullable().optional(),\n availableUntil: z.coerce.date().nullable().optional(),\n minOrderQty: z.coerce.number().int().min(1).nullable().optional(),\n maxOrderQty: z.coerce.number().int().min(1).nullable().optional(),\n orderQtyIncrement: z.coerce.number().int().min(1).nullable().optional(),\n requiresShipping: z.boolean().optional(),\n isQuoteOnly: z.boolean().optional(),\n seoTitle: z.string().trim().min(1).max(255).nullable().optional(),\n seoDescription: z.string().trim().min(1).max(1000).nullable().optional(),\n canonicalUrl: z\n .string()\n .trim()\n .max(500)\n .regex(/^https?:\\/\\/\\S+$/, 'catalog.products.validation.canonicalUrlInvalid')\n .nullable()\n .optional(),\n metadata: metadataSchema,\n offers: z.array(offerInputSchema.omit({ id: true })).optional(),\n categoryIds: z.array(uuid()).max(100).optional(),\n tags: z.array(tagLabelSchema).max(100).optional(),\n})\n\n// Cross-field checks chained on the exported schemas only \u2014 refining the base\n// schema itself would break `.partial()` in the update schema.\nconst productComplianceCrossFieldRefinement = (\n input: {\n minOrderQty?: number | null\n maxOrderQty?: number | null\n launchAt?: Date | null\n endOfLifeAt?: Date | null\n availableFrom?: Date | null\n availableUntil?: Date | null\n },\n ctx: z.RefinementCtx,\n) => {\n if (\n input.minOrderQty != null &&\n input.maxOrderQty != null &&\n input.maxOrderQty < input.minOrderQty\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['maxOrderQty'],\n message: 'catalog.products.validation.orderQtyRange',\n })\n }\n if (input.launchAt && input.endOfLifeAt && input.endOfLifeAt < input.launchAt) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['endOfLifeAt'],\n message: 'catalog.products.validation.lifecycleDateRange',\n })\n }\n if (\n input.availableFrom &&\n input.availableUntil &&\n input.availableUntil < input.availableFrom\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['availableUntil'],\n message: 'catalog.products.validation.availabilityDateRange',\n })\n }\n}\n\nexport const productCreateSchema = productBaseSchema\n .superRefine(productUomCrossFieldRefinement)\n .superRefine(productComplianceCrossFieldRefinement)\n\nexport const productUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(productBaseSchema.partial())\n .extend({\n productType: productTypeSchema.optional(),\n })\n .superRefine(productUomCrossFieldRefinement)\n .superRefine(productComplianceCrossFieldRefinement)\n\n// Base schema without refinements (used for .partial() in update schema)\nconst variantBaseSchema = scoped.extend({\n productId: uuid(),\n name: z.string().trim().max(255).optional(),\n sku: z\n .string()\n .trim()\n .regex(/^[A-Za-z0-9\\-_\\.]+$/)\n .max(191)\n .optional(),\n barcode: z.string().trim().max(191).optional(),\n gtinType: z.enum(CATALOG_GTIN_TYPES).nullable().optional(),\n hsCode: z.string().trim().min(1).max(32).nullable().optional(),\n statusEntryId: uuid().optional(),\n isDefault: z.boolean().optional(),\n isActive: z.boolean().optional(),\n defaultMediaId: uuid().optional().nullable(),\n defaultMediaUrl: z.string().trim().max(500).optional().nullable(),\n weightValue: z.coerce.number().min(0).optional(),\n weightUnit: z.string().trim().max(25).optional(),\n taxRateId: uuid().nullable().optional(),\n taxRate: z.coerce.number().min(0).max(100).optional().nullable(),\n dimensions: z\n .object({\n width: z.coerce.number().min(0).optional(),\n height: z.coerce.number().min(0).optional(),\n depth: z.coerce.number().min(0).optional(),\n unit: z.string().trim().max(25).optional(),\n })\n .optional(),\n metadata: metadataSchema,\n optionValues: variantOptionValuesSchema,\n customFieldsetCode: slugSchema.nullable().optional(),\n})\n\n// Payload-level GTIN check. Partial updates carrying only one of\n// (gtinType, barcode) are re-validated against the merged record state in the\n// catalog.variants.update command \u2014 zod cannot see the stored half here.\nconst variantGtinRefinement =\n (mode: 'create' | 'update') =>\n (\n input: {\n gtinType?: (typeof CATALOG_GTIN_TYPES)[number] | null\n barcode?: string\n },\n ctx: z.RefinementCtx,\n ) => {\n const gtinType = input.gtinType\n if (!gtinType) return\n const barcode = input.barcode\n if (barcode === undefined) {\n if (mode === 'create') {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['barcode'],\n message: 'catalog.variants.validation.gtinBarcodeRequired',\n })\n }\n return\n }\n if (!barcode.trim().length) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['barcode'],\n message: 'catalog.variants.validation.gtinBarcodeRequired',\n })\n return\n }\n if (!isValidGtin(gtinType, normalizeGtinValue(gtinType, barcode))) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['barcode'],\n message: 'catalog.variants.validation.gtinChecksum',\n })\n }\n }\n\nexport const variantCreateSchema = variantBaseSchema.superRefine(\n variantGtinRefinement('create'),\n)\n\nexport const variantUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(variantBaseSchema.partial())\n .superRefine(variantGtinRefinement('update'))\n\nexport const optionSchemaTemplateCreateSchema = scoped.extend({\n name: z.string().trim().min(1).max(255),\n code: slugSchema.optional(),\n description: z.string().trim().max(4000).optional(),\n schema: optionSchema,\n metadata: metadataSchema,\n isActive: z.boolean().optional(),\n})\n\nexport const optionSchemaTemplateUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(optionSchemaTemplateCreateSchema.partial())\n\nconst priceDisplayModeSchema = z.enum(CATALOG_PRICE_DISPLAY_MODES)\n\nexport const priceKindCreateSchema = tenantScoped.extend({\n code: slugSchema,\n title: z.string().trim().min(1).max(255),\n displayMode: priceDisplayModeSchema.default('excluding-tax'),\n currencyCode: currencyCodeSchema.optional(),\n isPromotion: z.boolean().optional(),\n isActive: z.boolean().optional(),\n})\n\nexport const priceKindUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(priceKindCreateSchema.partial())\n\nexport const priceCreateSchema = scoped.extend({\n variantId: uuid().optional(),\n productId: uuid().optional(),\n offerId: uuid().optional(),\n currencyCode: currencyCodeSchema,\n priceKindId: uuid(),\n minQuantity: z.coerce.number().int().min(1).optional(),\n maxQuantity: z.coerce.number().int().min(1).optional(),\n unitPriceNet: catalogPriceAmountSchema.optional(),\n unitPriceGross: catalogPriceAmountSchema.optional(),\n taxRate: z.coerce.number().min(0).max(100).optional(),\n taxRateId: uuid().nullable().optional(),\n channelId: uuid().optional(),\n userId: uuid().optional(),\n userGroupId: uuid().optional(),\n customerId: uuid().optional(),\n customerGroupId: uuid().optional(),\n metadata: metadataSchema,\n startsAt: z.coerce.date().optional(),\n endsAt: z.coerce.date().optional(),\n})\n\nexport const priceUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(priceCreateSchema.partial())\n\nexport const categoryCreateSchema = scoped.extend({\n name: z.string().trim().min(1).max(255),\n slug: slugSchema.optional().nullable(),\n description: z.string().trim().max(2000).optional(),\n parentId: uuid().optional().nullable(),\n isActive: z.boolean().optional(),\n})\n\nexport const categoryUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(categoryCreateSchema.partial())\n\nexport const productUnitConversionCreateSchema = scoped.extend({\n productId: uuid(),\n unitCode: z.string().trim().min(1).max(50),\n toBaseFactor: z.coerce.number().positive().max(1_000_000),\n sortOrder: z.coerce.number().int().optional(),\n isActive: z.boolean().optional(),\n metadata: metadataSchema,\n})\n\nexport const productUnitConversionUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(productUnitConversionCreateSchema.omit({ productId: true }).partial())\n\nexport const productUnitConversionDeleteSchema = scoped.extend({\n id: uuid(),\n})\n\nexport type ProductCreateInput = z.infer<typeof productCreateSchema>\nexport type ProductUpdateInput = z.infer<typeof productUpdateSchema>\nexport type VariantCreateInput = z.infer<typeof variantCreateSchema>\nexport type VariantUpdateInput = z.infer<typeof variantUpdateSchema>\nexport type OptionSchemaTemplateCreateInput = z.infer<typeof optionSchemaTemplateCreateSchema>\nexport type OptionSchemaTemplateUpdateInput = z.infer<typeof optionSchemaTemplateUpdateSchema>\nexport type PriceKindCreateInput = z.infer<typeof priceKindCreateSchema>\nexport type PriceKindUpdateInput = z.infer<typeof priceKindUpdateSchema>\nexport type PriceCreateInput = z.infer<typeof priceCreateSchema>\nexport type PriceUpdateInput = z.infer<typeof priceUpdateSchema>\nexport type CategoryCreateInput = z.infer<typeof categoryCreateSchema>\nexport type CategoryUpdateInput = z.infer<typeof categoryUpdateSchema>\nexport type OfferInput = z.infer<typeof offerInputSchema>\nexport type OfferCreateInput = z.infer<typeof offerCreateSchema>\nexport type OfferUpdateInput = z.infer<typeof offerUpdateSchema>\nexport type ProductUnitConversionCreateInput = z.infer<typeof productUnitConversionCreateSchema>\nexport type ProductUnitConversionUpdateInput = z.infer<typeof productUnitConversionUpdateSchema>\nexport type ProductUnitConversionDeleteInput = z.infer<typeof productUnitConversionDeleteSchema>\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { z } from 'zod'\nimport {\n CATALOG_EXCISE_CATEGORIES,\n CATALOG_GTIN_TYPES,\n CATALOG_GTU_CODES,\n CATALOG_HAZMAT_PACKING_GROUPS,\n CATALOG_PRICE_DISPLAY_MODES,\n CATALOG_PRODUCT_TYPES,\n} from './types'\nimport { isValidGtin, normalizeGtinValue } from '../lib/gtin'\nimport { REFERENCE_UNIT_CODES } from '../lib/unitCodes'\nimport {\n getCatalogPriceAmountValidationMessage,\n validateCatalogPriceAmountInput,\n} from '../lib/priceValidation'\n\nconst uuid = () => z.string().uuid()\n\nconst scoped = z.object({\n organizationId: uuid(),\n tenantId: uuid(),\n})\n\nconst tenantScoped = z.object({\n tenantId: uuid(),\n})\n\nconst currencyCodeSchema = z\n .string()\n .trim()\n .regex(/^[A-Z]{3}$/, 'currency code must be a three-letter ISO code')\n\nconst metadataSchema = z.record(z.string(), z.unknown()).optional()\n\nconst slugSchema = z\n .string()\n .trim()\n .toLowerCase()\n .regex(/^[a-z0-9\\-_]+$/, 'code must contain lowercase letters, digits, hyphen, or underscore')\n .max(150)\n\nconst handleSchema = z\n .string()\n .trim()\n .toLowerCase()\n .regex(/^[a-z0-9\\-_]+$/, 'handle must contain lowercase letters, digits, hyphen, or underscore')\n .max(150)\n\nconst skuSchema = z\n .string()\n .trim()\n .regex(/^[A-Za-z0-9\\-_\\.]+$/, 'SKU may include letters, numbers, hyphen, underscore, or period')\n .max(191)\n\nconst variantOptionValuesSchema = z\n .record(\n z\n .string()\n .trim()\n .min(1)\n .max(191),\n z.string().trim().max(255)\n )\n .optional()\n\nconst optionChoiceSchema = z.object({\n code: slugSchema,\n label: z.string().trim().max(255).optional(),\n})\n\nconst optionDefinitionSchema = z.object({\n code: slugSchema,\n label: z.string().trim().min(1).max(255),\n description: z.string().trim().max(2000).optional(),\n inputType: z.enum(['select', 'text', 'textarea', 'number']),\n isRequired: z.boolean().optional(),\n isMultiple: z.boolean().optional(),\n choices: z.array(optionChoiceSchema).max(200).optional(),\n})\n\nconst optionSchema = z.object({\n version: z.number().int().min(1).optional(),\n name: z.string().trim().max(255).optional(),\n description: z.string().trim().max(4000).optional(),\n options: z.array(optionDefinitionSchema).max(64),\n})\n\nconst tagLabelSchema = z.string().trim().min(1).max(100)\n\nconst offerBaseSchema = z.object({\n channelId: uuid(),\n title: z.string().trim().min(1).max(255),\n description: z.string().trim().max(4000).optional(),\n defaultMediaId: uuid().optional().nullable(),\n defaultMediaUrl: z.string().trim().max(500).optional().nullable(),\n metadata: metadataSchema,\n isActive: z.boolean().optional(),\n})\n\nconst offerInputSchema = offerBaseSchema.extend({\n id: uuid().optional(),\n})\n\nexport const offerCreateSchema = scoped.merge(\n offerBaseSchema.extend({\n productId: uuid(),\n })\n)\n\nexport const offerUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(\n offerBaseSchema\n .extend({\n productId: uuid().optional(),\n })\n .partial()\n )\n\nconst productTypeSchema = z.enum(CATALOG_PRODUCT_TYPES)\nconst uomRoundingModeSchema = z.enum(['half_up', 'down', 'up'])\nconst unitPriceReferenceUnitSchema = z.enum(REFERENCE_UNIT_CODES)\nconst unitPriceConfigSchema = z.object({\n enabled: z.boolean().optional(),\n referenceUnit: unitPriceReferenceUnitSchema.nullable().optional(),\n baseQuantity: z.coerce.number().positive().optional(),\n})\n\nconst catalogPriceAmountSchema = z\n .custom<number>((value) => validateCatalogPriceAmountInput(value).ok, {\n message: getCatalogPriceAmountValidationMessage(),\n })\n .transform((value) => {\n const result = validateCatalogPriceAmountInput(value)\n if (!result.ok) {\n throw new Error('catalogPriceAmountSchema transform reached invalid state')\n }\n return result.numeric\n })\n\nfunction productUomCrossFieldRefinement(\n input: {\n defaultUnit?: string | null\n defaultSalesUnit?: string | null\n unitPriceEnabled?: boolean\n unitPriceReferenceUnit?: string | null\n unitPriceBaseQuantity?: number\n unitPrice?: { enabled?: boolean; referenceUnit?: string | null; baseQuantity?: number }\n },\n ctx: z.RefinementCtx,\n) {\n const defaultUnit = typeof input.defaultUnit === 'string' ? input.defaultUnit.trim() : ''\n const defaultSalesUnit =\n typeof input.defaultSalesUnit === 'string' ? input.defaultSalesUnit.trim() : ''\n if (defaultSalesUnit && !defaultUnit) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['defaultSalesUnit'],\n message: 'catalog.products.validation.baseUnitRequired',\n })\n }\n const unitPriceEnabled = input.unitPrice?.enabled ?? input.unitPriceEnabled ?? false\n if (!unitPriceEnabled) return\n const referenceUnit =\n input.unitPrice?.referenceUnit ?? input.unitPriceReferenceUnit ?? null\n const baseQuantity =\n input.unitPrice?.baseQuantity ?? input.unitPriceBaseQuantity ?? null\n if (!referenceUnit) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['unitPrice'],\n message: 'catalog.products.validation.referenceUnitRequired',\n })\n }\n if (baseQuantity === null || baseQuantity === undefined || Number(baseQuantity) <= 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['unitPrice'],\n message: 'catalog.products.unitPrice.errors.baseQuantity',\n })\n }\n}\n\n// Base schema without refinements (used for .partial() in update schema)\nconst productBaseSchema = scoped.extend({\n title: z.string().trim().min(1).max(255),\n subtitle: z.string().trim().max(255).optional(),\n description: z.string().trim().max(4000).optional(),\n sku: skuSchema.nullable().optional(),\n handle: handleSchema.optional(),\n taxRateId: uuid().nullable().optional(),\n taxRate: z.coerce.number().min(0).max(100).optional().nullable(),\n productType: productTypeSchema.default('simple'),\n statusEntryId: uuid().optional(),\n primaryCurrencyCode: currencyCodeSchema.optional(),\n defaultUnit: z.string().trim().max(50).optional().nullable(),\n defaultSalesUnit: z.string().trim().max(50).optional().nullable(),\n defaultSalesUnitQuantity: z.coerce.number().positive().optional(),\n uomRoundingScale: z.coerce.number().int().min(0).max(6).optional(),\n uomRoundingMode: uomRoundingModeSchema.optional(),\n unitPriceEnabled: z.boolean().optional(),\n unitPriceReferenceUnit: unitPriceReferenceUnitSchema.nullable().optional(),\n unitPriceBaseQuantity: z.coerce.number().positive().optional(),\n unitPrice: unitPriceConfigSchema.optional(),\n defaultMediaId: uuid().optional().nullable(),\n defaultMediaUrl: z.string().trim().max(500).optional().nullable(),\n weightValue: z.coerce.number().min(0).optional().nullable(),\n weightUnit: z.string().trim().max(25).optional().nullable(),\n dimensions: z\n .object({\n width: z.coerce.number().min(0).optional(),\n height: z.coerce.number().min(0).optional(),\n depth: z.coerce.number().min(0).optional(),\n unit: z.string().trim().max(25).optional(),\n })\n .optional()\n .nullable(),\n optionSchemaId: uuid().nullable().optional(),\n optionSchema: optionSchema.optional(),\n customFieldsetCode: slugSchema.nullable().optional(),\n isConfigurable: z.boolean().optional(),\n isActive: z.boolean().optional(),\n countryOfOriginCode: z\n .string()\n .trim()\n .toUpperCase()\n .regex(/^[A-Z]{2}$/, 'catalog.products.validation.countryCodeInvalid')\n .nullable()\n .optional(),\n pkwiuCode: z.string().trim().min(1).max(32).nullable().optional(),\n cnCode: z.string().trim().min(1).max(32).nullable().optional(),\n hsCode: z.string().trim().min(1).max(32).nullable().optional(),\n taxClassificationCode: z.string().trim().min(1).max(64).nullable().optional(),\n gtuCodes: z\n .array(z.enum(CATALOG_GTU_CODES))\n .max(13)\n .transform((codes) => Array.from(new Set(codes)).sort((a, b) => (a < b ? -1 : a > b ? 1 : 0)))\n .nullable()\n .optional(),\n ageMin: z.coerce.number().int().min(0).max(120).nullable().optional(),\n isExciseGood: z.boolean().optional(),\n exciseCategory: z.enum(CATALOG_EXCISE_CATEGORIES).nullable().optional(),\n requiresPrescription: z.boolean().optional(),\n hazmatClass: z.string().trim().min(1).max(32).nullable().optional(),\n unNumber: z\n .string()\n .trim()\n .regex(/^(?:UN)?[0-9]{4}$/i, 'catalog.products.validation.unNumberInvalid')\n .transform((value) => {\n const upper = value.toUpperCase()\n return upper.startsWith('UN') ? upper : `UN${upper}`\n })\n .nullable()\n .optional(),\n hazmatPackingGroup: z.enum(CATALOG_HAZMAT_PACKING_GROUPS).nullable().optional(),\n containsLithiumBattery: z.boolean().optional(),\n launchAt: z.coerce.date().nullable().optional(),\n endOfLifeAt: z.coerce.date().nullable().optional(),\n availableFrom: z.coerce.date().nullable().optional(),\n availableUntil: z.coerce.date().nullable().optional(),\n minOrderQty: z.coerce.number().int().min(1).nullable().optional(),\n maxOrderQty: z.coerce.number().int().min(1).nullable().optional(),\n orderQtyIncrement: z.coerce.number().int().min(1).nullable().optional(),\n requiresShipping: z.boolean().optional(),\n isQuoteOnly: z.boolean().optional(),\n seoTitle: z.string().trim().min(1).max(255).nullable().optional(),\n seoDescription: z.string().trim().min(1).max(1000).nullable().optional(),\n canonicalUrl: z\n .string()\n .trim()\n .max(500)\n .regex(/^https?:\\/\\/\\S+$/, 'catalog.products.validation.canonicalUrlInvalid')\n .nullable()\n .optional(),\n metadata: metadataSchema,\n offers: z.array(offerInputSchema.omit({ id: true })).optional(),\n categoryIds: z.array(uuid()).max(100).optional(),\n tags: z.array(tagLabelSchema).max(100).optional(),\n})\n\n// Cross-field checks chained on the exported schemas only \u2014 refining the base\n// schema itself would break `.partial()` in the update schema.\nconst productComplianceCrossFieldRefinement = (\n input: {\n minOrderQty?: number | null\n maxOrderQty?: number | null\n launchAt?: Date | null\n endOfLifeAt?: Date | null\n availableFrom?: Date | null\n availableUntil?: Date | null\n },\n ctx: z.RefinementCtx,\n) => {\n if (\n input.minOrderQty != null &&\n input.maxOrderQty != null &&\n input.maxOrderQty < input.minOrderQty\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['maxOrderQty'],\n message: 'catalog.products.validation.orderQtyRange',\n })\n }\n if (input.launchAt && input.endOfLifeAt && input.endOfLifeAt < input.launchAt) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['endOfLifeAt'],\n message: 'catalog.products.validation.lifecycleDateRange',\n })\n }\n if (\n input.availableFrom &&\n input.availableUntil &&\n input.availableUntil < input.availableFrom\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['availableUntil'],\n message: 'catalog.products.validation.availabilityDateRange',\n })\n }\n}\n\nexport const productCreateSchema = productBaseSchema\n .superRefine(productUomCrossFieldRefinement)\n .superRefine(productComplianceCrossFieldRefinement)\n\nexport const productUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(productBaseSchema.partial())\n .extend({\n productType: productTypeSchema.optional(),\n })\n .superRefine(productUomCrossFieldRefinement)\n .superRefine(productComplianceCrossFieldRefinement)\n\n// Base schema without refinements (used for .partial() in update schema)\nconst variantBaseSchema = scoped.extend({\n productId: uuid(),\n name: z.string().trim().max(255).optional(),\n sku: z\n .string()\n .trim()\n .regex(/^[A-Za-z0-9\\-_\\.]+$/)\n .max(191)\n .optional(),\n barcode: z.string().trim().max(191).optional(),\n gtinType: z.enum(CATALOG_GTIN_TYPES).nullable().optional(),\n hsCode: z.string().trim().min(1).max(32).nullable().optional(),\n statusEntryId: uuid().optional(),\n isDefault: z.boolean().optional(),\n isActive: z.boolean().optional(),\n defaultMediaId: uuid().optional().nullable(),\n defaultMediaUrl: z.string().trim().max(500).optional().nullable(),\n weightValue: z.coerce.number().min(0).optional(),\n weightUnit: z.string().trim().max(25).optional(),\n taxRateId: uuid().nullable().optional(),\n taxRate: z.coerce.number().min(0).max(100).optional().nullable(),\n dimensions: z\n .object({\n width: z.coerce.number().min(0).optional(),\n height: z.coerce.number().min(0).optional(),\n depth: z.coerce.number().min(0).optional(),\n unit: z.string().trim().max(25).optional(),\n })\n .optional(),\n metadata: metadataSchema,\n optionValues: variantOptionValuesSchema,\n customFieldsetCode: slugSchema.nullable().optional(),\n})\n\n// Payload-level GTIN check. Partial updates carrying only one of\n// (gtinType, barcode) are re-validated against the merged record state in the\n// catalog.variants.update command \u2014 zod cannot see the stored half here.\nconst variantGtinRefinement =\n (mode: 'create' | 'update') =>\n (\n input: {\n gtinType?: (typeof CATALOG_GTIN_TYPES)[number] | null\n barcode?: string\n },\n ctx: z.RefinementCtx,\n ) => {\n const gtinType = input.gtinType\n if (!gtinType) return\n const barcode = input.barcode\n if (barcode === undefined) {\n if (mode === 'create') {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['barcode'],\n message: 'catalog.variants.validation.gtinBarcodeRequired',\n })\n }\n return\n }\n if (!barcode.trim().length) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['barcode'],\n message: 'catalog.variants.validation.gtinBarcodeRequired',\n })\n return\n }\n if (!isValidGtin(gtinType, normalizeGtinValue(gtinType, barcode))) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['barcode'],\n message: 'catalog.variants.validation.gtinChecksum',\n })\n }\n }\n\nexport const variantCreateSchema = variantBaseSchema.superRefine(\n variantGtinRefinement('create'),\n)\n\nexport const variantUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(variantBaseSchema.partial())\n .superRefine(variantGtinRefinement('update'))\n\nexport const optionSchemaTemplateCreateSchema = scoped.extend({\n name: z.string().trim().min(1).max(255),\n code: slugSchema.optional(),\n description: z.string().trim().max(4000).optional(),\n schema: optionSchema,\n metadata: metadataSchema,\n isActive: z.boolean().optional(),\n})\n\nexport const optionSchemaTemplateUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(optionSchemaTemplateCreateSchema.partial())\n\nconst priceDisplayModeSchema = z.enum(CATALOG_PRICE_DISPLAY_MODES)\n\nexport const priceKindCreateSchema = tenantScoped.extend({\n code: slugSchema,\n title: z.string().trim().min(1).max(255),\n displayMode: priceDisplayModeSchema.default('excluding-tax'),\n currencyCode: currencyCodeSchema.optional(),\n isPromotion: z.boolean().optional(),\n isActive: z.boolean().optional(),\n})\n\nexport const priceKindUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(priceKindCreateSchema.partial())\n\nexport const priceCreateSchema = scoped.extend({\n variantId: uuid().optional(),\n productId: uuid().optional(),\n offerId: uuid().optional(),\n currencyCode: currencyCodeSchema,\n priceKindId: uuid(),\n minQuantity: z.coerce.number().int().min(1).optional(),\n maxQuantity: z.coerce.number().int().min(1).optional(),\n unitPriceNet: catalogPriceAmountSchema.optional(),\n unitPriceGross: catalogPriceAmountSchema.optional(),\n taxRate: z.coerce.number().min(0).max(100).optional(),\n taxRateId: uuid().nullable().optional(),\n channelId: uuid().optional(),\n userId: uuid().optional(),\n userGroupId: uuid().optional(),\n customerId: uuid().optional(),\n customerGroupId: uuid().optional(),\n metadata: metadataSchema,\n startsAt: z.coerce.date().optional(),\n endsAt: z.coerce.date().optional(),\n})\n\nexport const priceUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(priceCreateSchema.partial())\n\nexport const categoryCreateSchema = scoped.extend({\n name: z.string().trim().min(1).max(255),\n slug: slugSchema.optional().nullable(),\n description: z.string().trim().max(2000).optional(),\n parentId: uuid().optional().nullable(),\n isActive: z.boolean().optional(),\n})\n\nexport const categoryUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(categoryCreateSchema.partial())\n\nexport const productUnitConversionCreateSchema = scoped.extend({\n productId: uuid(),\n unitCode: z.string().trim().min(1).max(50),\n toBaseFactor: z.coerce.number().positive().max(1_000_000),\n sortOrder: z.coerce.number().int().optional(),\n isActive: z.boolean().optional(),\n metadata: metadataSchema,\n})\n\nexport const productUnitConversionUpdateSchema = z\n .object({\n id: uuid(),\n })\n .merge(productUnitConversionCreateSchema.omit({ productId: true }).partial())\n\nexport const productUnitConversionDeleteSchema = scoped.extend({\n id: uuid(),\n})\n\nexport type ProductCreateInput = z.infer<typeof productCreateSchema>\nexport type ProductUpdateInput = z.infer<typeof productUpdateSchema>\nexport type VariantCreateInput = z.infer<typeof variantCreateSchema>\nexport type VariantUpdateInput = z.infer<typeof variantUpdateSchema>\nexport type OptionSchemaTemplateCreateInput = z.infer<typeof optionSchemaTemplateCreateSchema>\nexport type OptionSchemaTemplateUpdateInput = z.infer<typeof optionSchemaTemplateUpdateSchema>\nexport type PriceKindCreateInput = z.infer<typeof priceKindCreateSchema>\nexport type PriceKindUpdateInput = z.infer<typeof priceKindUpdateSchema>\nexport type PriceCreateInput = z.infer<typeof priceCreateSchema>\nexport type PriceUpdateInput = z.infer<typeof priceUpdateSchema>\nexport type CategoryCreateInput = z.infer<typeof categoryCreateSchema>\nexport type CategoryUpdateInput = z.infer<typeof categoryUpdateSchema>\nexport type OfferInput = z.infer<typeof offerInputSchema>\nexport type OfferCreateInput = z.infer<typeof offerCreateSchema>\nexport type OfferUpdateInput = z.infer<typeof offerUpdateSchema>\nexport type ProductUnitConversionCreateInput = z.infer<typeof productUnitConversionCreateSchema>\nexport type ProductUnitConversionUpdateInput = z.infer<typeof productUnitConversionUpdateSchema>\nexport type ProductUnitConversionDeleteInput = z.infer<typeof productUnitConversionDeleteSchema>\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -101,7 +101,7 @@ function ChannelDetailPage() {
101
101
  capabilityKeys.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: t(
102
102
  "communication_channels.detail.noCapabilities",
103
103
  "No capabilities snapshot recorded for this channel yet."
104
- ) }) : /* @__PURE__ */ jsx("dl", { className: "grid grid-cols-2 gap-x-6 gap-y-1 text-sm md:grid-cols-3", children: capabilityKeys.sort().map((key) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
104
+ ) }) : /* @__PURE__ */ jsx("dl", { className: "grid grid-cols-2 gap-x-6 gap-y-1 text-sm md:grid-cols-3", children: capabilityKeys.sort((a, b) => a.localeCompare(b)).map((key) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
105
105
  /* @__PURE__ */ jsx("dt", { className: "text-muted-foreground", children: key }),
106
106
  /* @__PURE__ */ jsx("dd", { className: "md:col-span-2", children: renderCapabilityValue(capabilities[key]) })
107
107
  ] }, key)) })
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/communication_channels/backend/communication_channels/channels/%5Bid%5D/page.tsx"],
4
- "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { useParams } from 'next/navigation'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { LoadingMessage, ErrorMessage, RecordNotFoundState } from '@open-mercato/ui/backend/detail'\nimport { Tag } from '@open-mercato/ui/primitives/tag'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\ntype ChannelDetail = {\n id: string\n providerKey: string\n channelType: string\n displayName: string\n externalIdentifier: string | null\n capabilities: Record<string, unknown> | null\n isActive: boolean\n}\n\ntype ChannelHealth = {\n channelId: string\n providerKey: string\n channelType: string\n windowHours: number\n totalsLast24h: number\n counts: Record<string, number>\n recentFailures: Array<{\n id: string\n messageId: string\n direction: string\n createdAt: string | null\n lastError: string | null\n transient: boolean | null\n }>\n}\n\nexport default function ChannelDetailPage() {\n const t = useT()\n const params = useParams<{ id: string }>()\n const id = (params?.id as string) ?? ''\n\n const [detail, setDetail] = React.useState<ChannelDetail | null>(null)\n const [health, setHealth] = React.useState<ChannelHealth | null>(null)\n const [isLoading, setIsLoading] = React.useState(true)\n const [errorMessage, setErrorMessage] = React.useState<string | null>(null)\n const [notFound, setNotFound] = React.useState(false)\n\n React.useEffect(() => {\n if (!id) return\n let cancelled = false\n async function load() {\n setIsLoading(true)\n setErrorMessage(null)\n setNotFound(false)\n const [detailRes, healthRes] = await Promise.all([\n apiCall<ChannelDetail>(`/api/communication_channels/channels/${encodeURIComponent(id)}`),\n apiCall<ChannelHealth>(`/api/communication_channels/channels/${encodeURIComponent(id)}/health`),\n ]).catch((err: unknown) => {\n return [\n { ok: false, result: { error: err instanceof Error ? err.message : 'load failed' } },\n { ok: false, result: { error: err instanceof Error ? err.message : 'load failed' } },\n ] as const\n })\n if (cancelled) return\n if (!detailRes.ok) {\n const status = (detailRes as { status?: number }).status\n if (status === 404) {\n setNotFound(true)\n } else {\n const body = detailRes.result as { error?: string } | undefined\n setErrorMessage(\n body?.error ?? t('communication_channels.errors.loadDetail', 'Failed to load channel'),\n )\n }\n setDetail(null)\n setHealth(null)\n } else {\n setDetail(detailRes.result ?? null)\n setHealth(healthRes.ok ? (healthRes.result ?? null) : null)\n }\n setIsLoading(false)\n }\n void load()\n return () => {\n cancelled = true\n }\n }, [id, t])\n\n if (isLoading) {\n return (\n <Page>\n <PageBody>\n <LoadingMessage label={t('communication_channels.detail.loading', 'Loading channel...')} />\n </PageBody>\n </Page>\n )\n }\n if (notFound) {\n return (\n <Page>\n <PageBody>\n <RecordNotFoundState\n label={t('communication_channels.detail.notFound', 'Channel not found')}\n backHref=\"/backend/communication_channels/channels\"\n />\n </PageBody>\n </Page>\n )\n }\n if (errorMessage || !detail) {\n return (\n <Page>\n <PageBody>\n <ErrorMessage\n label={errorMessage ?? t('communication_channels.errors.loadDetail', 'Failed to load channel')}\n />\n </PageBody>\n </Page>\n )\n }\n\n const capabilities = (detail.capabilities ?? {}) as Record<string, unknown>\n const capabilityKeys = Object.keys(capabilities)\n\n return (\n <Page>\n <PageBody>\n <header className=\"mb-4 flex flex-wrap items-baseline justify-between gap-4\">\n <div>\n <h2 className=\"text-2xl font-semibold\">{detail.displayName}</h2>\n <p className=\"text-sm text-muted-foreground\">\n {detail.providerKey} \u00B7 {detail.channelType}\n {detail.externalIdentifier ? ` \u00B7 ${detail.externalIdentifier}` : ''}\n </p>\n </div>\n {detail.isActive ? (\n <Tag variant=\"success\" dot>\n {t('communication_channels.status.active', 'Active')}\n </Tag>\n ) : (\n <Tag variant=\"neutral\">{t('communication_channels.status.inactive', 'Inactive')}</Tag>\n )}\n </header>\n\n <section\n className=\"mb-4 rounded-md border bg-card p-4\"\n aria-label={t('communication_channels.detail.capabilities', 'Capabilities')}\n >\n <header className=\"mb-2 text-overline text-muted-foreground\">\n {t('communication_channels.detail.capabilities', 'Capabilities')}\n </header>\n {capabilityKeys.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">\n {t(\n 'communication_channels.detail.noCapabilities',\n 'No capabilities snapshot recorded for this channel yet.',\n )}\n </p>\n ) : (\n <dl className=\"grid grid-cols-2 gap-x-6 gap-y-1 text-sm md:grid-cols-3\">\n {capabilityKeys.sort().map((key) => (\n <React.Fragment key={key}>\n <dt className=\"text-muted-foreground\">{key}</dt>\n <dd className=\"md:col-span-2\">{renderCapabilityValue(capabilities[key])}</dd>\n </React.Fragment>\n ))}\n </dl>\n )}\n </section>\n\n <section\n className=\"rounded-md border bg-card p-4\"\n aria-label={t('communication_channels.detail.health', 'Delivery health (last 24h)')}\n >\n <header className=\"mb-2 flex items-baseline justify-between text-overline text-muted-foreground\">\n <span>{t('communication_channels.detail.health', 'Delivery health (last 24h)')}</span>\n {health ? (\n <span className=\"text-xs\">\n {health.totalsLast24h}{' '}\n {t('communication_channels.detail.messages', 'messages')}\n </span>\n ) : null}\n </header>\n {health ? (\n <>\n <ul className=\"mb-3 flex flex-wrap gap-2 text-xs\">\n {Object.entries(health.counts).map(([status, count]) => (\n <li key={status}>\n <Tag variant={tagVariantForStatus(status)}>\n {status}: {count}\n </Tag>\n </li>\n ))}\n </ul>\n {health.recentFailures.length > 0 ? (\n <details>\n <summary className=\"cursor-pointer text-sm text-muted-foreground\">\n {t('communication_channels.detail.recentFailures', 'Recent failures')} (\n {health.recentFailures.length})\n </summary>\n <ul className=\"mt-2 space-y-1 text-xs\">\n {health.recentFailures.map((failure) => (\n <li key={failure.id} className=\"rounded border bg-muted p-2\">\n <div className=\"font-mono text-xs text-muted-foreground\">\n {failure.messageId} \u00B7 {failure.direction} \u00B7{' '}\n {failure.createdAt ?? '\u2014'}\n </div>\n {failure.lastError ? (\n <div className=\"mt-1\">{failure.lastError}</div>\n ) : null}\n </li>\n ))}\n </ul>\n </details>\n ) : null}\n </>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {t('communication_channels.detail.noHealth', 'No health data available.')}\n </p>\n )}\n </section>\n </PageBody>\n </Page>\n )\n}\n\nfunction renderCapabilityValue(value: unknown): string {\n if (value === null || value === undefined) return '\u2014'\n if (Array.isArray(value)) return value.join(', ')\n if (typeof value === 'object') return JSON.stringify(value)\n return String(value)\n}\n\nfunction tagVariantForStatus(status: string): 'success' | 'warning' | 'error' | 'info' | 'neutral' {\n switch (status) {\n case 'sent':\n case 'delivered':\n case 'read':\n return 'success'\n case 'failed':\n return 'error'\n case 'pending':\n case 'queued':\n return 'warning'\n default:\n return 'neutral'\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { useParams } from 'next/navigation'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { LoadingMessage, ErrorMessage, RecordNotFoundState } from '@open-mercato/ui/backend/detail'\nimport { Tag } from '@open-mercato/ui/primitives/tag'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\ntype ChannelDetail = {\n id: string\n providerKey: string\n channelType: string\n displayName: string\n externalIdentifier: string | null\n capabilities: Record<string, unknown> | null\n isActive: boolean\n}\n\ntype ChannelHealth = {\n channelId: string\n providerKey: string\n channelType: string\n windowHours: number\n totalsLast24h: number\n counts: Record<string, number>\n recentFailures: Array<{\n id: string\n messageId: string\n direction: string\n createdAt: string | null\n lastError: string | null\n transient: boolean | null\n }>\n}\n\nexport default function ChannelDetailPage() {\n const t = useT()\n const params = useParams<{ id: string }>()\n const id = (params?.id as string) ?? ''\n\n const [detail, setDetail] = React.useState<ChannelDetail | null>(null)\n const [health, setHealth] = React.useState<ChannelHealth | null>(null)\n const [isLoading, setIsLoading] = React.useState(true)\n const [errorMessage, setErrorMessage] = React.useState<string | null>(null)\n const [notFound, setNotFound] = React.useState(false)\n\n React.useEffect(() => {\n if (!id) return\n let cancelled = false\n async function load() {\n setIsLoading(true)\n setErrorMessage(null)\n setNotFound(false)\n const [detailRes, healthRes] = await Promise.all([\n apiCall<ChannelDetail>(`/api/communication_channels/channels/${encodeURIComponent(id)}`),\n apiCall<ChannelHealth>(`/api/communication_channels/channels/${encodeURIComponent(id)}/health`),\n ]).catch((err: unknown) => {\n return [\n { ok: false, result: { error: err instanceof Error ? err.message : 'load failed' } },\n { ok: false, result: { error: err instanceof Error ? err.message : 'load failed' } },\n ] as const\n })\n if (cancelled) return\n if (!detailRes.ok) {\n const status = (detailRes as { status?: number }).status\n if (status === 404) {\n setNotFound(true)\n } else {\n const body = detailRes.result as { error?: string } | undefined\n setErrorMessage(\n body?.error ?? t('communication_channels.errors.loadDetail', 'Failed to load channel'),\n )\n }\n setDetail(null)\n setHealth(null)\n } else {\n setDetail(detailRes.result ?? null)\n setHealth(healthRes.ok ? (healthRes.result ?? null) : null)\n }\n setIsLoading(false)\n }\n void load()\n return () => {\n cancelled = true\n }\n }, [id, t])\n\n if (isLoading) {\n return (\n <Page>\n <PageBody>\n <LoadingMessage label={t('communication_channels.detail.loading', 'Loading channel...')} />\n </PageBody>\n </Page>\n )\n }\n if (notFound) {\n return (\n <Page>\n <PageBody>\n <RecordNotFoundState\n label={t('communication_channels.detail.notFound', 'Channel not found')}\n backHref=\"/backend/communication_channels/channels\"\n />\n </PageBody>\n </Page>\n )\n }\n if (errorMessage || !detail) {\n return (\n <Page>\n <PageBody>\n <ErrorMessage\n label={errorMessage ?? t('communication_channels.errors.loadDetail', 'Failed to load channel')}\n />\n </PageBody>\n </Page>\n )\n }\n\n const capabilities = (detail.capabilities ?? {}) as Record<string, unknown>\n const capabilityKeys = Object.keys(capabilities)\n\n return (\n <Page>\n <PageBody>\n <header className=\"mb-4 flex flex-wrap items-baseline justify-between gap-4\">\n <div>\n <h2 className=\"text-2xl font-semibold\">{detail.displayName}</h2>\n <p className=\"text-sm text-muted-foreground\">\n {detail.providerKey} \u00B7 {detail.channelType}\n {detail.externalIdentifier ? ` \u00B7 ${detail.externalIdentifier}` : ''}\n </p>\n </div>\n {detail.isActive ? (\n <Tag variant=\"success\" dot>\n {t('communication_channels.status.active', 'Active')}\n </Tag>\n ) : (\n <Tag variant=\"neutral\">{t('communication_channels.status.inactive', 'Inactive')}</Tag>\n )}\n </header>\n\n <section\n className=\"mb-4 rounded-md border bg-card p-4\"\n aria-label={t('communication_channels.detail.capabilities', 'Capabilities')}\n >\n <header className=\"mb-2 text-overline text-muted-foreground\">\n {t('communication_channels.detail.capabilities', 'Capabilities')}\n </header>\n {capabilityKeys.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">\n {t(\n 'communication_channels.detail.noCapabilities',\n 'No capabilities snapshot recorded for this channel yet.',\n )}\n </p>\n ) : (\n <dl className=\"grid grid-cols-2 gap-x-6 gap-y-1 text-sm md:grid-cols-3\">\n {capabilityKeys.sort((a, b) => a.localeCompare(b)).map((key) => (\n <React.Fragment key={key}>\n <dt className=\"text-muted-foreground\">{key}</dt>\n <dd className=\"md:col-span-2\">{renderCapabilityValue(capabilities[key])}</dd>\n </React.Fragment>\n ))}\n </dl>\n )}\n </section>\n\n <section\n className=\"rounded-md border bg-card p-4\"\n aria-label={t('communication_channels.detail.health', 'Delivery health (last 24h)')}\n >\n <header className=\"mb-2 flex items-baseline justify-between text-overline text-muted-foreground\">\n <span>{t('communication_channels.detail.health', 'Delivery health (last 24h)')}</span>\n {health ? (\n <span className=\"text-xs\">\n {health.totalsLast24h}{' '}\n {t('communication_channels.detail.messages', 'messages')}\n </span>\n ) : null}\n </header>\n {health ? (\n <>\n <ul className=\"mb-3 flex flex-wrap gap-2 text-xs\">\n {Object.entries(health.counts).map(([status, count]) => (\n <li key={status}>\n <Tag variant={tagVariantForStatus(status)}>\n {status}: {count}\n </Tag>\n </li>\n ))}\n </ul>\n {health.recentFailures.length > 0 ? (\n <details>\n <summary className=\"cursor-pointer text-sm text-muted-foreground\">\n {t('communication_channels.detail.recentFailures', 'Recent failures')} (\n {health.recentFailures.length})\n </summary>\n <ul className=\"mt-2 space-y-1 text-xs\">\n {health.recentFailures.map((failure) => (\n <li key={failure.id} className=\"rounded border bg-muted p-2\">\n <div className=\"font-mono text-xs text-muted-foreground\">\n {failure.messageId} \u00B7 {failure.direction} \u00B7{' '}\n {failure.createdAt ?? '\u2014'}\n </div>\n {failure.lastError ? (\n <div className=\"mt-1\">{failure.lastError}</div>\n ) : null}\n </li>\n ))}\n </ul>\n </details>\n ) : null}\n </>\n ) : (\n <p className=\"text-sm text-muted-foreground\">\n {t('communication_channels.detail.noHealth', 'No health data available.')}\n </p>\n )}\n </section>\n </PageBody>\n </Page>\n )\n}\n\nfunction renderCapabilityValue(value: unknown): string {\n if (value === null || value === undefined) return '\u2014'\n if (Array.isArray(value)) return value.join(', ')\n if (typeof value === 'object') return JSON.stringify(value)\n return String(value)\n}\n\nfunction tagVariantForStatus(status: string): 'success' | 'warning' | 'error' | 'info' | 'neutral' {\n switch (status) {\n case 'sent':\n case 'delivered':\n case 'read':\n return 'success'\n case 'failed':\n return 'error'\n case 'pending':\n case 'queued':\n return 'warning'\n default:\n return 'neutral'\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,40 +1,30 @@
1
- import {
2
- runCrudMutationGuardAfterSuccess,
3
- validateCrudMutationGuard
4
- } from "@open-mercato/shared/lib/crud/mutation-guard";
1
+ import { runRouteMutationGuards } from "@open-mercato/shared/lib/crud/route-mutation-guard";
5
2
  async function validateRouteMutationGuard(params) {
6
3
  const { auth, container, input, req } = params;
7
4
  if (!auth.sub || !auth.tenantId) {
8
5
  return { result: null, afterSuccess: async () => void 0 };
9
6
  }
10
- const base = {
11
- tenantId: auth.tenantId,
12
- organizationId: auth.orgId ?? null,
13
- userId: auth.sub,
14
- resourceKind: input.resourceKind,
15
- resourceId: input.resourceId,
16
- operation: input.operation ?? "custom",
17
- requestMethod: req.method,
18
- requestHeaders: req.headers
19
- };
20
- const result = await validateCrudMutationGuard(container, {
21
- ...base,
22
- mutationPayload: input.mutationPayload ?? null
7
+ const guarded = await runRouteMutationGuards({
8
+ container,
9
+ req,
10
+ auth: {
11
+ userId: auth.sub,
12
+ tenantId: auth.tenantId,
13
+ organizationId: auth.orgId ?? null
14
+ },
15
+ input: {
16
+ resourceKind: input.resourceKind,
17
+ resourceId: input.resourceId,
18
+ operation: input.operation ?? "custom",
19
+ mutationPayload: input.mutationPayload ?? null
20
+ }
23
21
  });
24
- if (result && !result.ok) {
25
- return {
26
- response: Response.json(result.body, { status: result.status })
27
- };
22
+ if (!guarded.ok) {
23
+ return { response: guarded.response };
28
24
  }
29
25
  return {
30
- result,
31
- afterSuccess: async () => {
32
- if (!result?.ok || !result.shouldRunAfterSuccess) return;
33
- await runCrudMutationGuardAfterSuccess(container, {
34
- ...base,
35
- metadata: result.metadata ?? null
36
- });
37
- }
26
+ result: { ok: true },
27
+ afterSuccess: guarded.runAfterSuccess
38
28
  };
39
29
  }
40
30
  export {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/communication_channels/lib/route-mutation-guard.ts"],
4
- "sourcesContent": ["import type { AwilixContainer } from 'awilix'\nimport {\n runCrudMutationGuardAfterSuccess,\n validateCrudMutationGuard,\n type CrudMutationGuardValidationResult,\n} from '@open-mercato/shared/lib/crud/mutation-guard'\n\ntype RouteAuth = {\n sub?: string | null\n tenantId?: string | null\n orgId?: string | null\n}\n\ntype RouteMutationGuardInput = {\n resourceKind: string\n resourceId: string\n operation?: 'create' | 'update' | 'delete' | 'custom'\n mutationPayload?: Record<string, unknown> | null\n}\n\nexport type RouteMutationGuardContext = {\n result: CrudMutationGuardValidationResult | null\n afterSuccess: () => Promise<void>\n}\n\nexport async function validateRouteMutationGuard(params: {\n container: AwilixContainer\n req: Request\n auth: RouteAuth\n input: RouteMutationGuardInput\n}): Promise<RouteMutationGuardContext | { response: Response }> {\n const { auth, container, input, req } = params\n if (!auth.sub || !auth.tenantId) {\n return { result: null, afterSuccess: async () => undefined }\n }\n\n const base = {\n tenantId: auth.tenantId,\n organizationId: auth.orgId ?? null,\n userId: auth.sub,\n resourceKind: input.resourceKind,\n resourceId: input.resourceId,\n operation: input.operation ?? 'custom',\n requestMethod: req.method,\n requestHeaders: req.headers,\n } as const\n\n const result = await validateCrudMutationGuard(container, {\n ...base,\n mutationPayload: input.mutationPayload ?? null,\n })\n if (result && !result.ok) {\n return {\n response: Response.json(result.body, { status: result.status }),\n }\n }\n\n return {\n result,\n afterSuccess: async () => {\n if (!result?.ok || !result.shouldRunAfterSuccess) return\n await runCrudMutationGuardAfterSuccess(container, {\n ...base,\n metadata: result.metadata ?? null,\n })\n },\n }\n}\n"],
5
- "mappings": "AACA;AAAA,EACE;AAAA,EACA;AAAA,OAEK;AAoBP,eAAsB,2BAA2B,QAKe;AAC9D,QAAM,EAAE,MAAM,WAAW,OAAO,IAAI,IAAI;AACxC,MAAI,CAAC,KAAK,OAAO,CAAC,KAAK,UAAU;AAC/B,WAAO,EAAE,QAAQ,MAAM,cAAc,YAAY,OAAU;AAAA,EAC7D;AAEA,QAAM,OAAO;AAAA,IACX,UAAU,KAAK;AAAA,IACf,gBAAgB,KAAK,SAAS;AAAA,IAC9B,QAAQ,KAAK;AAAA,IACb,cAAc,MAAM;AAAA,IACpB,YAAY,MAAM;AAAA,IAClB,WAAW,MAAM,aAAa;AAAA,IAC9B,eAAe,IAAI;AAAA,IACnB,gBAAgB,IAAI;AAAA,EACtB;AAEA,QAAM,SAAS,MAAM,0BAA0B,WAAW;AAAA,IACxD,GAAG;AAAA,IACH,iBAAiB,MAAM,mBAAmB;AAAA,EAC5C,CAAC;AACD,MAAI,UAAU,CAAC,OAAO,IAAI;AACxB,WAAO;AAAA,MACL,UAAU,SAAS,KAAK,OAAO,MAAM,EAAE,QAAQ,OAAO,OAAO,CAAC;AAAA,IAChE;AAAA,EACF;AAEA,SAAO;AAAA,IACL;AAAA,IACA,cAAc,YAAY;AACxB,UAAI,CAAC,QAAQ,MAAM,CAAC,OAAO,sBAAuB;AAClD,YAAM,iCAAiC,WAAW;AAAA,QAChD,GAAG;AAAA,QACH,UAAU,OAAO,YAAY;AAAA,MAC/B,CAAC;AAAA,IACH;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import type { AwilixContainer } from 'awilix'\nimport { runRouteMutationGuards } from '@open-mercato/shared/lib/crud/route-mutation-guard'\n\ntype RouteAuth = {\n sub?: string | null\n tenantId?: string | null\n orgId?: string | null\n}\n\ntype RouteMutationGuardInput = {\n resourceKind: string\n resourceId: string\n operation?: 'create' | 'update' | 'delete' | 'custom'\n mutationPayload?: Record<string, unknown> | null\n}\n\nexport type RouteMutationGuardContext = {\n /**\n * Marker kept for source compatibility with callers; the registry result is\n * fully handled inside the wrapper, so callers only need `afterSuccess`.\n */\n result: { ok: true } | null\n afterSuccess: () => Promise<void>\n}\n\n/**\n * Run a communication-channels custom write route through the full mutation\n * guard registry (`runRouteMutationGuards`) instead of only the legacy DI\n * service. Returns `{ response }` when a guard blocks the mutation, or\n * `{ result, afterSuccess }` to run after a successful write \u2014 preserving the\n * shape the dependent routes already consume.\n */\nexport async function validateRouteMutationGuard(params: {\n container: AwilixContainer\n req: Request\n auth: RouteAuth\n input: RouteMutationGuardInput\n}): Promise<RouteMutationGuardContext | { response: Response }> {\n const { auth, container, input, req } = params\n if (!auth.sub || !auth.tenantId) {\n return { result: null, afterSuccess: async () => undefined }\n }\n\n const guarded = await runRouteMutationGuards({\n container,\n req,\n auth: {\n userId: auth.sub,\n tenantId: auth.tenantId,\n organizationId: auth.orgId ?? null,\n },\n input: {\n resourceKind: input.resourceKind,\n resourceId: input.resourceId,\n operation: input.operation ?? 'custom',\n mutationPayload: input.mutationPayload ?? null,\n },\n })\n\n if (!guarded.ok) {\n return { response: guarded.response }\n }\n\n return {\n result: { ok: true },\n afterSuccess: guarded.runAfterSuccess,\n }\n}\n"],
5
+ "mappings": "AACA,SAAS,8BAA8B;AA+BvC,eAAsB,2BAA2B,QAKe;AAC9D,QAAM,EAAE,MAAM,WAAW,OAAO,IAAI,IAAI;AACxC,MAAI,CAAC,KAAK,OAAO,CAAC,KAAK,UAAU;AAC/B,WAAO,EAAE,QAAQ,MAAM,cAAc,YAAY,OAAU;AAAA,EAC7D;AAEA,QAAM,UAAU,MAAM,uBAAuB;AAAA,IAC3C;AAAA,IACA;AAAA,IACA,MAAM;AAAA,MACJ,QAAQ,KAAK;AAAA,MACb,UAAU,KAAK;AAAA,MACf,gBAAgB,KAAK,SAAS;AAAA,IAChC;AAAA,IACA,OAAO;AAAA,MACL,cAAc,MAAM;AAAA,MACpB,YAAY,MAAM;AAAA,MAClB,WAAW,MAAM,aAAa;AAAA,MAC9B,iBAAiB,MAAM,mBAAmB;AAAA,IAC5C;AAAA,EACF,CAAC;AAED,MAAI,CAAC,QAAQ,IAAI;AACf,WAAO,EAAE,UAAU,QAAQ,SAAS;AAAA,EACtC;AAEA,SAAO;AAAA,IACL,QAAQ,EAAE,IAAI,KAAK;AAAA,IACnB,cAAc,QAAQ;AAAA,EACxB;AACF;",
6
6
  "names": []
7
7
  }
@@ -438,10 +438,10 @@ function DealsKanbanPage() {
438
438
  () => ({
439
439
  pipelineId: selectedPipelineId,
440
440
  search: search.trim(),
441
- status: statusFilters.slice().sort().join(","),
442
- owners: ownerFilters.slice().sort().join(","),
443
- people: peopleFilters.slice().sort().join(","),
444
- companies: companyFilters.slice().sort().join(","),
441
+ status: statusFilters.slice().sort((a, b) => a < b ? -1 : a > b ? 1 : 0).join(","),
442
+ owners: ownerFilters.slice().sort((a, b) => a < b ? -1 : a > b ? 1 : 0).join(","),
443
+ people: peopleFilters.slice().sort((a, b) => a < b ? -1 : a > b ? 1 : 0).join(","),
444
+ companies: companyFilters.slice().sort((a, b) => a < b ? -1 : a > b ? 1 : 0).join(","),
445
445
  closeFrom: closeDateFilter.from ?? "",
446
446
  closeTo: closeDateFilter.to ?? "",
447
447
  currency: currencyFilter ?? ""