@dainamite/cpq 0.6.0 → 0.7.0

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 (164) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/modules/cpq/backend/cpq/inventory/AssetsTable.js +3 -9
  3. package/dist/modules/cpq/backend/cpq/inventory/AssetsTable.js.map +2 -2
  4. package/dist/modules/cpq/backend/cpq/inventory/SubscriptionsTable.js +21 -25
  5. package/dist/modules/cpq/backend/cpq/inventory/SubscriptionsTable.js.map +2 -2
  6. package/dist/modules/cpq/backend/cpq/inventory/assets/[id]/page.js +48 -47
  7. package/dist/modules/cpq/backend/cpq/inventory/assets/[id]/page.js.map +2 -2
  8. package/dist/modules/cpq/backend/cpq/inventory/assets/[id]/page.meta.js +1 -1
  9. package/dist/modules/cpq/backend/cpq/inventory/assets/[id]/page.meta.js.map +2 -2
  10. package/dist/modules/cpq/backend/cpq/inventory/page.meta.js +2 -2
  11. package/dist/modules/cpq/backend/cpq/inventory/page.meta.js.map +2 -2
  12. package/dist/modules/cpq/backend/cpq/inventory/shared.js +37 -2
  13. package/dist/modules/cpq/backend/cpq/inventory/shared.js.map +2 -2
  14. package/dist/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.js +154 -178
  15. package/dist/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.js.map +2 -2
  16. package/dist/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.meta.js +1 -1
  17. package/dist/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.meta.js.map +2 -2
  18. package/dist/modules/cpq/backend/cpq/offerings/[id]/page.js +168 -143
  19. package/dist/modules/cpq/backend/cpq/offerings/[id]/page.js.map +2 -2
  20. package/dist/modules/cpq/backend/cpq/offerings/page.js +36 -34
  21. package/dist/modules/cpq/backend/cpq/offerings/page.js.map +2 -2
  22. package/dist/modules/cpq/backend/cpq/orders/[id]/page.js +69 -66
  23. package/dist/modules/cpq/backend/cpq/orders/[id]/page.js.map +2 -2
  24. package/dist/modules/cpq/backend/cpq/orders/page.js +6 -6
  25. package/dist/modules/cpq/backend/cpq/orders/page.js.map +2 -2
  26. package/dist/modules/cpq/backend/cpq/price-rules/PriceRuleForm.js +41 -36
  27. package/dist/modules/cpq/backend/cpq/price-rules/PriceRuleForm.js.map +2 -2
  28. package/dist/modules/cpq/backend/cpq/price-rules/[id]/page.js +76 -72
  29. package/dist/modules/cpq/backend/cpq/price-rules/[id]/page.js.map +2 -2
  30. package/dist/modules/cpq/backend/cpq/price-rules/[id]/page.meta.js +1 -1
  31. package/dist/modules/cpq/backend/cpq/price-rules/[id]/page.meta.js.map +2 -2
  32. package/dist/modules/cpq/backend/cpq/price-rules/page.js +18 -15
  33. package/dist/modules/cpq/backend/cpq/price-rules/page.js.map +2 -2
  34. package/dist/modules/cpq/backend/cpq/pricing/[id]/EntriesEditor.js +23 -21
  35. package/dist/modules/cpq/backend/cpq/pricing/[id]/EntriesEditor.js.map +2 -2
  36. package/dist/modules/cpq/backend/cpq/pricing/[id]/ImportPreview.js +22 -50
  37. package/dist/modules/cpq/backend/cpq/pricing/[id]/ImportPreview.js.map +2 -2
  38. package/dist/modules/cpq/backend/cpq/pricing/[id]/page.js +74 -52
  39. package/dist/modules/cpq/backend/cpq/pricing/[id]/page.js.map +2 -2
  40. package/dist/modules/cpq/backend/cpq/pricing/[id]/xlsxImport.js +20 -17
  41. package/dist/modules/cpq/backend/cpq/pricing/[id]/xlsxImport.js.map +2 -2
  42. package/dist/modules/cpq/backend/cpq/pricing/page.js +1 -1
  43. package/dist/modules/cpq/backend/cpq/pricing/page.js.map +2 -2
  44. package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/ArcQuoteConfigurator.js +115 -123
  45. package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/ArcQuoteConfigurator.js.map +2 -2
  46. package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/PriceAdjustmentDialog.js +6 -3
  47. package/dist/modules/cpq/backend/cpq/quotes/[id]/_components/PriceAdjustmentDialog.js.map +2 -2
  48. package/dist/modules/cpq/backend/cpq/quotes/[id]/page.js +129 -94
  49. package/dist/modules/cpq/backend/cpq/quotes/[id]/page.js.map +2 -2
  50. package/dist/modules/cpq/backend/cpq/quotes/page.js +23 -19
  51. package/dist/modules/cpq/backend/cpq/quotes/page.js.map +2 -2
  52. package/dist/modules/cpq/backend/cpq/specifications/[id]/DependsOnRulesEditor.js +19 -15
  53. package/dist/modules/cpq/backend/cpq/specifications/[id]/DependsOnRulesEditor.js.map +2 -2
  54. package/dist/modules/cpq/backend/cpq/specifications/[id]/page.js +171 -178
  55. package/dist/modules/cpq/backend/cpq/specifications/[id]/page.js.map +2 -2
  56. package/dist/modules/cpq/backend/cpq/specifications/page.js +2 -2
  57. package/dist/modules/cpq/backend/cpq/specifications/page.js.map +2 -2
  58. package/dist/modules/cpq/backend/cpq/wizards/[definitionCode]/detail/page.js +60 -50
  59. package/dist/modules/cpq/backend/cpq/wizards/[definitionCode]/detail/page.js.map +2 -2
  60. package/dist/modules/cpq/backend/cpq/wizards/[definitionCode]/page.js +22 -18
  61. package/dist/modules/cpq/backend/cpq/wizards/[definitionCode]/page.js.map +2 -2
  62. package/dist/modules/cpq/backend/cpq/wizards/page.js +1 -1
  63. package/dist/modules/cpq/backend/cpq/wizards/page.js.map +2 -2
  64. package/dist/modules/cpq/components/ArcLineDiff.js +2 -2
  65. package/dist/modules/cpq/components/ArcLineDiff.js.map +2 -2
  66. package/dist/modules/cpq/components/ChargeBreakdownTable.js +4 -10
  67. package/dist/modules/cpq/components/ChargeBreakdownTable.js.map +2 -2
  68. package/dist/modules/cpq/components/PriceWaterfall.js +3 -1
  69. package/dist/modules/cpq/components/PriceWaterfall.js.map +2 -2
  70. package/dist/modules/cpq/components/PricingSummaryCard.js +1 -6
  71. package/dist/modules/cpq/components/PricingSummaryCard.js.map +2 -2
  72. package/dist/modules/cpq/components/StatusPath.js +5 -3
  73. package/dist/modules/cpq/components/StatusPath.js.map +2 -2
  74. package/dist/modules/cpq/components/useCpqRowActions.js +10 -22
  75. package/dist/modules/cpq/components/useCpqRowActions.js.map +2 -2
  76. package/dist/modules/cpq/i18n/de.json +1220 -0
  77. package/dist/modules/cpq/i18n/en.json +1220 -0
  78. package/dist/modules/cpq/i18n/es.json +1220 -0
  79. package/dist/modules/cpq/i18n/pl.json +1220 -0
  80. package/dist/modules/cpq/widgets/injection/customer-inventory/widget.client.js +39 -31
  81. package/dist/modules/cpq/widgets/injection/customer-inventory/widget.client.js.map +2 -2
  82. package/dist/modules/cpq/widgets/injection/order-cpq-tab/widget.client.js +13 -5
  83. package/dist/modules/cpq/widgets/injection/order-cpq-tab/widget.client.js.map +2 -2
  84. package/dist/modules/cpq/widgets/injection/quote-configurator/widget.client.js +41 -21
  85. package/dist/modules/cpq/widgets/injection/quote-configurator/widget.client.js.map +2 -2
  86. package/dist/modules/cpq/widgets/injection-table.js +2 -2
  87. package/dist/modules/cpq/widgets/injection-table.js.map +2 -2
  88. package/dist/modules/cpq/workflows/WizardRunner.js +10 -8
  89. package/dist/modules/cpq/workflows/WizardRunner.js.map +2 -2
  90. package/dist/modules/cpq/workflows/WizardTrigger.js +15 -9
  91. package/dist/modules/cpq/workflows/WizardTrigger.js.map +2 -2
  92. package/dist/modules/cpq/workflows/steps/CustomerSelectStep.js +9 -7
  93. package/dist/modules/cpq/workflows/steps/CustomerSelectStep.js.map +2 -2
  94. package/dist/modules/cpq/workflows/steps/InventorySelectStep.js +9 -4
  95. package/dist/modules/cpq/workflows/steps/InventorySelectStep.js.map +2 -2
  96. package/dist/modules/cpq/workflows/steps/ItemListStep.js +16 -19
  97. package/dist/modules/cpq/workflows/steps/ItemListStep.js.map +2 -2
  98. package/dist/modules/cpq/workflows/steps/OfferingSelectStep.js +19 -32
  99. package/dist/modules/cpq/workflows/steps/OfferingSelectStep.js.map +2 -2
  100. package/dist/modules/cpq/workflows/steps/ProductConfigureStep.js +8 -6
  101. package/dist/modules/cpq/workflows/steps/ProductConfigureStep.js.map +2 -2
  102. package/dist/modules/cpq/workflows/steps/ReviewStep.js +32 -30
  103. package/dist/modules/cpq/workflows/steps/ReviewStep.js.map +2 -2
  104. package/dist/modules/cpq/workflows/steps/index.js +12 -0
  105. package/dist/modules/cpq/workflows/steps/index.js.map +2 -2
  106. package/package.json +1 -1
  107. package/src/modules/cpq/__tests__/i18n/dictionaries.test.ts +62 -0
  108. package/src/modules/cpq/__tests__/i18n/hardcodedStrings.test.ts +35 -0
  109. package/src/modules/cpq/__tests__/i18n/sourceScan.ts +109 -0
  110. package/src/modules/cpq/backend/cpq/inventory/AssetsTable.tsx +3 -9
  111. package/src/modules/cpq/backend/cpq/inventory/SubscriptionsTable.tsx +22 -26
  112. package/src/modules/cpq/backend/cpq/inventory/assets/[id]/page.meta.ts +1 -1
  113. package/src/modules/cpq/backend/cpq/inventory/assets/[id]/page.tsx +43 -46
  114. package/src/modules/cpq/backend/cpq/inventory/page.meta.ts +2 -2
  115. package/src/modules/cpq/backend/cpq/inventory/shared.tsx +37 -1
  116. package/src/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.meta.ts +1 -1
  117. package/src/modules/cpq/backend/cpq/inventory/subscriptions/[id]/page.tsx +134 -112
  118. package/src/modules/cpq/backend/cpq/offerings/[id]/page.tsx +169 -130
  119. package/src/modules/cpq/backend/cpq/offerings/page.tsx +34 -24
  120. package/src/modules/cpq/backend/cpq/orders/[id]/page.tsx +66 -43
  121. package/src/modules/cpq/backend/cpq/orders/page.tsx +6 -6
  122. package/src/modules/cpq/backend/cpq/price-rules/PriceRuleForm.tsx +48 -34
  123. package/src/modules/cpq/backend/cpq/price-rules/[id]/page.meta.ts +1 -1
  124. package/src/modules/cpq/backend/cpq/price-rules/[id]/page.tsx +76 -70
  125. package/src/modules/cpq/backend/cpq/price-rules/page.tsx +25 -16
  126. package/src/modules/cpq/backend/cpq/pricing/[id]/EntriesEditor.tsx +24 -18
  127. package/src/modules/cpq/backend/cpq/pricing/[id]/ImportPreview.tsx +29 -19
  128. package/src/modules/cpq/backend/cpq/pricing/[id]/page.tsx +95 -47
  129. package/src/modules/cpq/backend/cpq/pricing/[id]/xlsxImport.ts +23 -15
  130. package/src/modules/cpq/backend/cpq/pricing/page.tsx +1 -1
  131. package/src/modules/cpq/backend/cpq/quotes/[id]/_components/ArcQuoteConfigurator.tsx +111 -88
  132. package/src/modules/cpq/backend/cpq/quotes/[id]/_components/PriceAdjustmentDialog.tsx +3 -3
  133. package/src/modules/cpq/backend/cpq/quotes/[id]/page.tsx +134 -89
  134. package/src/modules/cpq/backend/cpq/quotes/page.tsx +29 -21
  135. package/src/modules/cpq/backend/cpq/specifications/[id]/DependsOnRulesEditor.tsx +19 -15
  136. package/src/modules/cpq/backend/cpq/specifications/[id]/page.tsx +171 -171
  137. package/src/modules/cpq/backend/cpq/specifications/page.tsx +2 -2
  138. package/src/modules/cpq/backend/cpq/wizards/[definitionCode]/detail/page.tsx +51 -41
  139. package/src/modules/cpq/backend/cpq/wizards/[definitionCode]/page.tsx +17 -13
  140. package/src/modules/cpq/backend/cpq/wizards/page.tsx +1 -1
  141. package/src/modules/cpq/components/ArcLineDiff.tsx +2 -2
  142. package/src/modules/cpq/components/ChargeBreakdownTable.tsx +4 -2
  143. package/src/modules/cpq/components/PriceWaterfall.tsx +4 -2
  144. package/src/modules/cpq/components/PricingSummaryCard.tsx +1 -1
  145. package/src/modules/cpq/components/StatusPath.tsx +7 -4
  146. package/src/modules/cpq/components/useCpqRowActions.tsx +17 -25
  147. package/src/modules/cpq/i18n/de.json +1220 -0
  148. package/src/modules/cpq/i18n/en.json +1220 -0
  149. package/src/modules/cpq/i18n/es.json +1220 -0
  150. package/src/modules/cpq/i18n/pl.json +1220 -0
  151. package/src/modules/cpq/widgets/injection/customer-inventory/widget.client.tsx +38 -31
  152. package/src/modules/cpq/widgets/injection/order-cpq-tab/widget.client.tsx +7 -5
  153. package/src/modules/cpq/widgets/injection/quote-configurator/widget.client.tsx +36 -21
  154. package/src/modules/cpq/widgets/injection-table.ts +8 -2
  155. package/src/modules/cpq/workflows/WizardRunner.tsx +8 -5
  156. package/src/modules/cpq/workflows/WizardTrigger.tsx +15 -9
  157. package/src/modules/cpq/workflows/steps/CustomerSelectStep.tsx +11 -7
  158. package/src/modules/cpq/workflows/steps/InventorySelectStep.tsx +9 -5
  159. package/src/modules/cpq/workflows/steps/ItemListStep.tsx +18 -12
  160. package/src/modules/cpq/workflows/steps/OfferingSelectStep.tsx +20 -16
  161. package/src/modules/cpq/workflows/steps/ProductConfigureStep.tsx +8 -6
  162. package/src/modules/cpq/workflows/steps/ReviewStep.tsx +33 -18
  163. package/src/modules/cpq/workflows/steps/index.ts +12 -0
  164. package/src/modules/cpq/workflows/types.ts +4 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/cpq/backend/cpq/quotes/%5Bid%5D/page.tsx"],
4
- "sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { useRouter, useParams, useSearchParams } from 'next/navigation'\nimport ArcQuoteConfigurator, {\n type AttachedTarget,\n} from './_components/ArcQuoteConfigurator'\nimport { StatusPath } from '../../../../components/StatusPath'\nimport { ArrowRight, ExternalLink, Plus, RotateCcw } from 'lucide-react'\nimport { Alert, AlertTitle, AlertDescription } from '@open-mercato/ui/primitives/alert'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Tag } from '@open-mercato/ui/primitives/tag'\nimport { FormHeader } from '@open-mercato/ui/backend/forms'\nimport type { ActionItem } from '@open-mercato/ui/backend/forms/ActionsDropdown'\nimport { NumberInput } from '../../../../components/NumberInput'\nimport { ChargeBreakdownTable } from '../../../../components/ChargeBreakdownTable'\nimport { PricingSummaryCard } from '../../../../components/PricingSummaryCard'\nimport { ArcLineDiff, LineActionBadge } from '../../../../components/ArcLineDiff'\nimport { ADJUST_PRICE_FEATURE } from '../../../../lib/priceAdjustmentView'\nimport { arcRecurringDelta } from '../../../../lib/quoteSummaryView'\nimport { usePriceAdjustments } from './_components/usePriceAdjustments'\nimport { PriceAdjustmentsPanel } from './_components/PriceAdjustmentsPanel'\nimport { ArcLineRemovalProvider, useArcLineRemoval, useArcLineRemovalUi } from './_components/arcLineRemoval'\nimport { AdjustChargeAction, DiscountLineAction, ManualAdjustmentActions, PriceAdjustmentProvider, usePriceAdjustmentUi } from './_components/priceAdjustmentContext'\nimport { useGrantedFeatures } from '../../../../components/useGrantedFeatures'\nimport { canRecalculateQuote, QUOTE_MANAGE_FEATURE } from '../../../../lib/quotePermissions'\nimport {\n formatStatusLabel,\n quoteCpqStatusMap,\n type QuoteCpqStatus,\n} from '../../../../components/statusMaps'\n\n// \u2500\u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ntype ConstrainedAttribute = {\n code: string\n name: string\n attributeType: string\n isRequired: boolean\n options: Array<{ value: string; label: string }> | null\n constraints: Record<string, unknown> | null\n defaultValue: unknown | null\n helpText: string | null\n}\n\ntype TierBreakdownEntry = { tier: number; from: number; to: number; pricePerUnit: number; quantity: number; subtotal: number }\ntype RuleAdjustment = {\n ruleCode: string; ruleName: string; ruleType: string; value: number; unitPriceBefore: number; unitPriceAfter: number; delta: number\n /** Negotiated-pricing fields; absent on legacy snapshots (treated as rules). */\n origin?: 'rule' | 'manual'; adjustmentId?: string; reasonCode?: string; createdByUserId?: string\n}\ntype AdjustmentErrorEntry = { adjustmentId: string; quoteLineId: string; chargeCode?: string; code: string }\n\ntype ResolvedCharge = {\n chargeCode: string\n chargeName: string\n chargeType: 'nrc' | 'mrc' | 'usage'\n pricingMethod?: 'flat' | 'tiered' | 'per_unit'\n unitPrice: number\n quantity: number | null\n totalPrice: number | null\n currencyCode: string\n breakdown?: { tiers: TierBreakdownEntry[] } | null\n note?: string | null\n adjustments?: RuleAdjustment[] | null\n listUnitPrice?: number\n listTotalPrice?: number | null\n standardUnitPrice?: number\n standardTotalPrice?: number | null\n adjustmentErrors?: AdjustmentErrorEntry[]\n}\n\ntype QuoteLineAction = 'add' | 'modify' | 'cancel'\n\ntype ArcLineSource = {\n subscriptionItemId: string\n name: string\n mrcAmount: number\n nrcAmount: number\n quantity: number\n}\n\ntype QuoteLine = {\n lineId: string\n offeringId: string | null\n productId?: string | null\n offeringName: string\n offeringType: string | null\n parentLineId: string | null\n action: QuoteLineAction\n quantity: number\n configuration: Record<string, unknown>\n nrcTotal: number\n mrcTotal: number\n charges: ResolvedCharge[]\n isConfigured: boolean\n validationErrors: Array<{ message: string }> | null\n arcSource: ArcLineSource | null\n targetSubscriptionId: string | null\n}\n\ntype QuoteResult = {\n id: string\n quoteId: string\n quoteNumber: string\n customerId: string\n customerName: string | null\n cpqStatus: string\n version: number\n pricingRevision?: number\n currencyCode: string\n convertedOrderId: string | null\n validationResult: { valid: boolean; errors: Array<{ message: string }> }\n adjustmentErrors?: AdjustmentErrorEntry[]\n pricingSummary: {\n nrcTotal: number\n mrcTotal: number\n usageCharges: Array<{ chargeCode: string; chargeName: string; unitPrice: number; note: string | null }>\n usageTotalEstimated: number | null\n currencyCode: string\n listNrcTotal?: number\n listMrcTotal?: number\n dealValue?: { list: number; standard: number; offer: number }\n discountDepth?: { rule: number | null; manual: number | null; total: number | null; maxLineManual: number | null }\n ruleDiscountTotal?: number\n manualDiscountTotal?: number\n }\n lines: QuoteLine[]\n}\n\ntype Offering = {\n id: string\n code: string\n name: string\n description?: string | null\n specId: string\n lifecycleStatus: string\n}\n\ntype BundleTreeSlot = {\n slotId: string\n componentGroup: string\n name: string\n cardinalityMin: number\n cardinalityMax: number | null\n components: Array<{\n componentId: string\n childOffering: { offeringId: string; offeringCode: string; offeringName: string; offeringType: string }\n isDefault: boolean\n sortOrder: number\n }>\n}\n\ntype BundleTree = {\n offeringId: string\n offeringName: string\n offeringType: string\n slots: BundleTreeSlot[]\n}\n\n// \u2500\u2500\u2500 Constants \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n// `ALLOWED_TRANSITIONS` used to mirror the backend state machine on the\n// client to gate the inline status menu. Per product decision the UI\n// now lets the operator jump between any pair of statuses; the backend\n// is the single source of truth, so the table is no longer needed here.\n\nfunction fmt(amount: number, currency: string): string {\n return new Intl.NumberFormat('en-US', { style: 'currency', currency }).format(amount)\n}\n\nasync function apiJson<T>(url: string, init?: RequestInit): Promise<T> {\n const res = await fetch(url, init)\n const json = await res.json()\n if (!res.ok) throw new Error(json?.error ?? `Request failed (${res.status})`)\n return json as T\n}\n\n// \u2500\u2500\u2500 Header sub-components \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction MetaCard({ label, children }: { label: string; children: React.ReactNode }) {\n return (\n <div className=\"rounded-lg border bg-card p-4\">\n <div className=\"text-[10px] font-medium uppercase tracking-wide text-muted-foreground\">\n {label}\n </div>\n <div className=\"mt-1 text-sm\">{children}</div>\n </div>\n )\n}\n\n// Pricing-summary figure: label, monospace amount, and an optional smaller\n// bracketed note (discount depth / change %) inline after the amount.\nfunction MoreActionsDropdown({ items }: { items: ActionItem[] }) {\n // Local dropdown \u2014 `ActionsDropdown` inside FormHeader.actionsContent\n // would conflict with the inline button placement. This is a thin\n // <details>-style trigger; menuActions on FormHeader would render it\n // inside the header layout, but here we want it adjacent to other\n // primary buttons.\n const [open, setOpen] = React.useState(false)\n const ref = React.useRef<HTMLDivElement>(null)\n React.useEffect(() => {\n if (!open) return\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false)\n }\n document.addEventListener('mousedown', handler)\n return () => document.removeEventListener('mousedown', handler)\n }, [open])\n\n if (items.length === 0) return null\n return (\n <div className=\"relative\" ref={ref}>\n <Button type=\"button\" variant=\"outline\" onClick={() => setOpen((v) => !v)}>\n Actions\n <svg className=\"h-3 w-3 ml-1\" fill=\"none\" viewBox=\"0 0 24 24\" strokeWidth=\"2\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19.5 8.25l-7.5 7.5-7.5-7.5\" />\n </svg>\n </Button>\n {open && (\n <div className=\"absolute right-0 top-full mt-1 z-50 min-w-[200px] rounded-md border bg-popover shadow-md py-1\">\n {items.map((item) => {\n const isDelete = item.id === 'delete'\n return (\n <button\n key={item.id}\n type=\"button\"\n onClick={() => { setOpen(false); item.onSelect() }}\n disabled={item.disabled || item.loading}\n // Use bg-accent on hover (same token as Radix-style menu items in OM)\n // and tint delete with destructive colors so the affordance is obvious.\n className={\n 'w-full px-3 py-2 text-left text-sm flex items-center gap-2 transition-colors ' +\n 'disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-transparent ' +\n (isDelete\n ? 'text-destructive hover:bg-destructive/10 focus:bg-destructive/10 focus:outline-none'\n : 'hover:bg-accent focus:bg-accent focus:outline-none')\n }\n >\n {item.icon ? <item.icon className=\"h-4 w-4 text-muted-foreground\" /> : null}\n <span>{item.label}</span>\n </button>\n )\n })}\n </div>\n )}\n </div>\n )\n}\n\nfunction buildMoreActions({\n recalculate,\n canRecalculate,\n submitting,\n deletable,\n onDelete,\n deleting,\n}: {\n recalculate: () => void\n canRecalculate: boolean\n submitting: boolean\n deletable: boolean\n onDelete: () => void\n deleting: boolean\n}): ActionItem[] {\n const items: ActionItem[] = []\n // Recalculate persists prices: offered only to users with cpq.quotes.manage\n // and only on non-terminal quotes (the API refuses both otherwise).\n if (canRecalculate) {\n items.push({\n id: 'recalculate',\n label: 'Recalculate',\n onSelect: recalculate,\n loading: submitting,\n disabled: submitting,\n })\n }\n if (deletable) {\n items.push({\n id: 'delete',\n label: 'Delete',\n onSelect: onDelete,\n disabled: deleting,\n loading: deleting,\n })\n }\n return items\n}\n\n// \u2500\u2500\u2500 Main Page \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport default function CpqQuoteDetailPage(props: { params?: { id?: string } }) {\n const router = useRouter()\n const urlParams = useParams()\n const searchParams = useSearchParams()\n const cpqConfigId = (props.params?.id ?? urlParams?.id) as string\n const isNew = cpqConfigId === 'new'\n\n const t = useT()\n const [cpqQuote, setCpqQuote] = React.useState<QuoteResult | null>(null)\n const grantedFeatures = useGrantedFeatures([QUOTE_MANAGE_FEATURE, ADJUST_PRICE_FEATURE])\n const [loading, setLoading] = React.useState(true)\n const [error, setError] = React.useState<string | null>(null)\n const [submitting, setSubmitting] = React.useState(false)\n\n // Configurator state\n const [view, setView] = React.useState<'summary' | 'add-offering' | 'configure' | 'edit'>('summary')\n const [offerings, setOfferings] = React.useState<Offering[]>([])\n const [offeringsLoading, setOfferingsLoading] = React.useState(false)\n const [offeringSearch, setOfferingSearch] = React.useState('')\n const [selectedOffering, setSelectedOffering] = React.useState<Offering | null>(null)\n const [attributes, setAttributes] = React.useState<ConstrainedAttribute[]>([])\n const [config, setConfig] = React.useState<Record<string, unknown>>({})\n const [quantity, setQuantity] = React.useState(1)\n const [editingLineId, setEditingLineId] = React.useState<string | null>(null)\n const [addingToParentLineId, setAddingToParentLineId] = React.useState<string | null>(null)\n // XD-250 multi-target ARC: when adding a top-level offering operator can\n // pick 1..N target subs (default = all) and we fire one POST per target.\n // For \"Add Component\" to a bundle, this is forced to a single id (the\n // parent line's target) since a bundle component must follow its bundle.\n const [addingTargetSubIds, setAddingTargetSubIds] = React.useState<string[]>([])\n const [expandedLines, setExpandedLines] = React.useState<Set<string>>(new Set())\n const [converting, setConverting] = React.useState(false)\n const [transitioning, setTransitioning] = React.useState(false)\n const [deleting, setDeleting] = React.useState(false)\n const [showDeleteConfirm, setShowDeleteConfirm] = React.useState(false)\n const [pricingDetail, setPricingDetail] = React.useState<{ lineIdx: number; chargeIdx: number } | null>(null)\n\n // \u2500\u2500\u2500 XD-250 ARC state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const [arcTargets, setArcTargets] = React.useState<AttachedTarget[]>([])\n const [arcQuoteType, setArcQuoteType] = React.useState<'new' | 'amend' | 'renew' | 'cancel'>('new')\n const [arcDrawerOpen, setArcDrawerOpen] = React.useState(false)\n\n const loadArcTargets = React.useCallback(async () => {\n try {\n const res = await fetch(`/api/cpq/quotes/${cpqConfigId}/target-subscriptions`)\n if (!res.ok) return\n const data = await res.json()\n const items: AttachedTarget[] = data.items ?? []\n setArcTargets(items)\n if (items.length > 0) {\n setArcQuoteType(items[0].quoteType as 'amend' | 'renew' | 'cancel')\n } else {\n setArcQuoteType('new')\n }\n } catch {\n // best-effort \u2014 non-ARC quotes have no targets, that's fine.\n }\n }, [cpqConfigId])\n\n React.useEffect(() => {\n if (!cpqConfigId || isNew) return\n void loadArcTargets()\n }, [cpqConfigId, isNew, loadArcTargets])\n\n // \u2500\u2500\u2500 Negotiated prices \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const reloadQuote = React.useCallback(async () => {\n try {\n setCpqQuote(await apiJson<QuoteResult>(`/api/cpq/quotes/${cpqConfigId}`))\n } catch (err) {\n setError((err as Error).message)\n }\n }, [cpqConfigId])\n const priceAdjustments = usePriceAdjustments<QuoteResult>({\n quote: isNew ? null : cpqQuote,\n quoteType: arcQuoteType,\n canAdjust: grantedFeatures.includes(QUOTE_MANAGE_FEATURE) && grantedFeatures.includes(ADJUST_PRICE_FEATURE),\n onQuote: setCpqQuote,\n reloadQuote,\n })\n\n // \u2500\u2500\u2500 Load or create \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n React.useEffect(() => {\n if (isNew) {\n // Create new CPQ quote from query params\n const quoteId = searchParams.get('quoteId')\n const customerId = searchParams.get('customerId')\n if (!customerId) {\n setError('customerId is required to create a CPQ quote')\n setLoading(false)\n return\n }\n async function create() {\n try {\n const body: Record<string, string> = { customerId: customerId! }\n if (quoteId) body.quoteId = quoteId\n const result = await apiJson<QuoteResult>('/api/cpq/quotes', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n })\n router.replace(`/backend/cpq/quotes/${result.id}`)\n } catch (err) {\n setError((err as Error).message)\n setLoading(false)\n }\n }\n create()\n return\n }\n\n let cancelled = false\n async function load() {\n try {\n const result = await apiJson<QuoteResult>(`/api/cpq/quotes/${cpqConfigId}`)\n if (!cancelled) setCpqQuote(result)\n } catch (err) {\n if (!cancelled) setError((err as Error).message)\n } finally {\n if (!cancelled) setLoading(false)\n }\n }\n load()\n return () => { cancelled = true }\n }, [cpqConfigId, isNew, searchParams, router])\n\n // \u2500\u2500\u2500 Actions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const loadOfferings = async () => {\n setOfferingsLoading(true)\n try {\n const result = await apiJson<{ items: Offering[] }>('/api/cpq/product-offerings?pageSize=100&lifecycleStatus=active')\n setOfferings(result.items ?? [])\n } catch { setOfferings([]) }\n finally { setOfferingsLoading(false) }\n }\n\n const loadAttributes = async (offeringId: string, currentConfig: Record<string, unknown> = {}) => {\n try {\n const params = new URLSearchParams({ offeringId })\n if (Object.keys(currentConfig).length > 0) params.set('configuration', JSON.stringify(currentConfig))\n const result = await apiJson<{ attributes: ConstrainedAttribute[] }>(`/api/cpq/quotes/attributes?${params}`)\n setAttributes(result.attributes ?? [])\n } catch { setAttributes([]) }\n }\n\n const addItem = async () => {\n if (!cpqQuote || !selectedOffering) return\n try {\n setSubmitting(true); setError(null)\n // XD-250 multi-target ARC: when \u22652 targets selected, fire one POST per\n // target \u2014 backend creates one line per request, each tagged with its\n // own targetSubscriptionId. Single target / non-ARC quote: list is\n // empty or 1-elem, we just do one POST and let the server auto-inherit.\n const targetsToPost = addingTargetSubIds.length > 0 ? addingTargetSubIds : [null]\n let lastResult: QuoteResult | null = null\n for (const tid of targetsToPost) {\n const body: Record<string, unknown> = { offeringId: selectedOffering.id, configuration: config, quantity }\n if (addingToParentLineId) body.parentLineId = addingToParentLineId\n if (tid) body.targetSubscriptionId = tid\n lastResult = await apiJson<QuoteResult>(`/api/cpq/quotes/${cpqQuote.id}/items`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n })\n }\n if (lastResult) setCpqQuote(lastResult)\n resetConfigState()\n setView('summary')\n } catch (err) { setError((err as Error).message) }\n finally { setSubmitting(false) }\n }\n\n const updateItem = async (lineId: string) => {\n if (!cpqQuote) return\n try {\n setSubmitting(true); setError(null)\n const result = await apiJson<QuoteResult>(`/api/cpq/quotes/${cpqQuote.id}/items/${lineId}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ configuration: config, quantity }),\n })\n setCpqQuote(result)\n resetConfigState()\n setView('summary')\n } catch (err) { setError((err as Error).message) }\n finally { setSubmitting(false) }\n }\n\n // Amend / Renew: removing an existing subscription item confirms first and\n // marks it for removal (a `cancel` line) instead of deleting the line.\n const lineRemoval = useArcLineRemoval<QuoteResult>({\n quote: isNew ? null : cpqQuote,\n quoteType: arcQuoteType,\n onQuote: setCpqQuote,\n onError: setError,\n })\n const removeItem = lineRemoval.remove\n\n const recalculate = async () => {\n if (!cpqQuote) return\n try {\n setSubmitting(true); setError(null)\n const result = await apiJson<QuoteResult>(`/api/cpq/quotes/${cpqQuote.id}/recalculate`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ save: true }),\n })\n setCpqQuote(result)\n } catch (err) { setError((err as Error).message) }\n finally { setSubmitting(false) }\n }\n\n const convertToOrder = async () => {\n if (!cpqQuote) return\n try {\n setConverting(true); setError(null)\n const result = await apiJson<{ id: string }>('/api/cpq/orders', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ quoteId: cpqQuote.id }),\n })\n router.push(`/backend/cpq/orders/${result.id}`)\n } catch (err) { setError((err as Error).message) }\n finally { setConverting(false) }\n }\n\n const transitionStatus = async (targetStatus: string) => {\n if (!cpqQuote) return\n try {\n setTransitioning(true); setError(null)\n const result = await apiJson<QuoteResult>(`/api/cpq/quotes/${cpqQuote.id}/status`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ targetStatus }),\n })\n setCpqQuote(result)\n } catch (err) { setError((err as Error).message) }\n finally { setTransitioning(false) }\n }\n\n const deleteQuote = async () => {\n if (!cpqQuote) return\n try {\n setDeleting(true); setError(null); setShowDeleteConfirm(false)\n await apiJson<{ ok: boolean }>(`/api/cpq/quotes/${cpqQuote.id}`, { method: 'DELETE' })\n router.push('/backend/cpq/quotes')\n } catch (err) { setError((err as Error).message) }\n finally { setDeleting(false) }\n }\n\n const resetConfigState = () => {\n setSelectedOffering(null)\n setAttributes([])\n setConfig({})\n setQuantity(1)\n setEditingLineId(null)\n setAddingToParentLineId(null)\n }\n\n const startAddOffering = () => {\n resetConfigState()\n // Default: apply to all attached targets (operator can uncheck in the picker).\n setAddingTargetSubIds(arcTargets.map((t) => t.subscriptionId))\n loadOfferings()\n setView('add-offering')\n }\n\n const startAddComponent = async (parentLineId: string, offeringId?: string) => {\n setSelectedOffering(null)\n setAttributes([])\n setConfig({})\n setQuantity(1)\n setEditingLineId(null)\n setAddingToParentLineId(parentLineId)\n // Inherit the parent line's target so a bundle component lands on the\n // same subscription as its parent (XD-250 multi-target ARC). For\n // components there's no choice \u2014 bundle \u2194 component must agree.\n const parent = cpqQuote?.lines.find((l) => l.lineId === parentLineId)\n const inherited = parent?.targetSubscriptionId ?? arcTargets[0]?.subscriptionId\n setAddingTargetSubIds(inherited ? [inherited] : [])\n if (offeringId) {\n try {\n const result = await apiJson<{ items: Offering[] }>('/api/cpq/product-offerings?pageSize=100&lifecycleStatus=active')\n const match = (result.items ?? []).find((o) => o.id === offeringId)\n if (match) {\n selectOffering(match)\n return\n }\n } catch { /* fall through to browser */ }\n }\n loadOfferings()\n setView('add-offering')\n }\n\n const selectOffering = (o: Offering) => {\n setSelectedOffering(o); setConfig({}); setQuantity(1)\n loadAttributes(o.id)\n setView('configure')\n }\n\n const startEditLine = (line: QuoteLine) => {\n setEditingLineId(line.lineId)\n setConfig(line.configuration ?? {})\n setQuantity(line.quantity)\n if (line.offeringId) loadAttributes(line.offeringId, line.configuration ?? {})\n setView('edit')\n }\n\n const toggleLine = (id: string) => {\n setExpandedLines((prev) => { const n = new Set(prev); n.has(id) ? n.delete(id) : n.add(id); return n })\n }\n\n // \u2500\u2500\u2500 Render: loading / error \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n if (loading) {\n return (\n <div className=\"flex items-center gap-2 py-12 justify-center text-sm text-muted-foreground\">\n <Spinner /> Loading\u2026\n </div>\n )\n }\n\n if (!cpqQuote) {\n return (\n <div className=\"space-y-4\">\n <button onClick={() => router.push('/backend/cpq/quotes')} className=\"text-sm text-muted-foreground hover:text-foreground\">\u2190 Back to Quotes</button>\n {error && <ErrorBanner message={error} />}\n <div className=\"rounded-lg border bg-card p-6 text-center text-sm text-muted-foreground\">Quote not found.</div>\n </div>\n )\n }\n\n // \u2500\u2500\u2500 Render: detail \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const { pricingSummary: summary, currencyCode: currency } = cpqQuote\n const arcDelta = arcQuoteType === 'amend' || arcQuoteType === 'renew' ? arcRecurringDelta(cpqQuote.lines) : null\n\n const arcEditable = ['new', 'incomplete', 'ready'].includes(cpqQuote.cpqStatus)\n const isMergeRenew =\n arcQuoteType === 'renew' &&\n arcTargets.length >= 2 &&\n arcTargets.every((t) => t.mergeAction === 'absorb')\n\n // XD-250 multi-target ARC: map subscriptionId \u2192 friendly code (e.g. SUB-...).\n // Used for the per-line target badge so the operator can see which sub each\n // line acts on; only meaningful when there are 2+ targets. Plain map (not\n // useMemo) because this whole block is after the loading / not-found early\n // returns \u2014 adding a hook here would violate Rules of Hooks. Tiny N (count\n // of attached ARC targets) so re-building per render is fine.\n const arcTargetCodeMap = new Map<string, string>()\n for (const t of arcTargets) {\n if (t.subscription?.code) arcTargetCodeMap.set(t.subscriptionId, t.subscription.code)\n }\n\n return (\n <PriceAdjustmentProvider value={priceAdjustments.ui}>\n <ArcLineRemovalProvider value={lineRemoval.ui}>\n <div className=\"space-y-6\">\n {priceAdjustments.elements}\n {lineRemoval.ConfirmDialogElement}\n {arcDrawerOpen && (\n <ArcQuoteConfigurator\n quoteId={cpqQuote.id}\n customerId={cpqQuote.customerId}\n customerName={cpqQuote.customerName}\n currencyCode={cpqQuote.currencyCode}\n initialType={arcQuoteType}\n initialTargets={arcTargets}\n editable={arcEditable}\n onClose={() => setArcDrawerOpen(false)}\n onChanged={async () => {\n await loadArcTargets()\n // Drawer attached / detached targets \u2014 backend may have mirrored\n // items from new targets (XD-250 multi-target ARC), so refetch\n // the full quote to pick up the new lines without a hard refresh.\n try {\n const fresh = await apiJson<QuoteResult>(`/api/cpq/quotes/${cpqQuote.id}`)\n setCpqQuote(fresh)\n } catch {\n /* ignore \u2014 loadArcTargets already surfaced any error */\n }\n }}\n />\n )}\n {/* Header \u2014 uses the standard Open Mercato `FormHeader mode=\"detail\"`\n so CPQ matches the rest of the admin. Title is just the quote\n number (no \"Quote \u2026\" prefix); badges sit underneath; secondary\n context (customer / version / currency) lives in dedicated meta\n cards below the header, not in a thin meta line. */}\n <FormHeader\n mode=\"detail\"\n backHref=\"/backend/cpq/quotes\"\n backLabel=\"Back to CPQ Quotes\"\n entityTypeLabel=\"CPQ Quote\"\n title={cpqQuote.quoteNumber || cpqQuote.customerName || 'Untitled'}\n statusBadge={\n <div className=\"flex flex-wrap items-center gap-2 pt-1\">\n <Tag variant={quoteCpqStatusMap[cpqQuote.cpqStatus as QuoteCpqStatus] ?? 'neutral'} dot>\n {formatStatusLabel(cpqQuote.cpqStatus)}\n </Tag>\n {arcQuoteType !== 'new' && (\n <Tag variant=\"brand\" className=\"uppercase\">{arcQuoteType}</Tag>\n )}\n {cpqQuote.convertedOrderId && <Tag variant=\"success\" dot>Converted</Tag>}\n </div>\n }\n // FormHeader.detail ignores `utilityActions` whenever `actionsContent`\n // is set, so we render the \"View Sales Quote\" link inline alongside\n // the primary actions to keep it visible.\n actionsContent={\n <>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => router.push(`/backend/sales/quotes/${cpqQuote.quoteId}`)}\n >\n <ExternalLink className=\"h-3.5 w-3.5\" />\n View Sales Quote\n </Button>\n {cpqQuote.convertedOrderId ? (\n <Button\n type=\"button\"\n onClick={() => router.push(`/backend/cpq/orders/${cpqQuote.convertedOrderId}`)}\n >\n <ArrowRight className=\"h-4 w-4\" />\n Go to order\n </Button>\n ) : view !== 'summary' ? (\n <Button type=\"button\" variant=\"outline\" onClick={() => { resetConfigState(); setView('summary') }}>\n Cancel\n </Button>\n ) : (\n <>\n <Button type=\"button\" onClick={startAddOffering}>\n <Plus className=\"h-4 w-4\" />\n Add Offering\n </Button>\n {arcEditable && (\n <Button type=\"button\" variant=\"outline\" onClick={() => setArcDrawerOpen(true)}>\n Modify Subscription\n </Button>\n )}\n {cpqQuote.cpqStatus === 'accepted' && (\n <Button type=\"button\" onClick={convertToOrder} disabled={converting}>\n {converting ? <Spinner /> : <ArrowRight className=\"h-4 w-4\" />}\n Convert to Order\n </Button>\n )}\n <MoreActionsDropdown\n items={buildMoreActions({\n recalculate,\n canRecalculate: canRecalculateQuote(grantedFeatures, cpqQuote.cpqStatus),\n submitting,\n deletable: !['accepted', 'rejected', 'cancelled'].includes(cpqQuote.cpqStatus),\n onDelete: () => setShowDeleteConfirm(true),\n deleting,\n })}\n />\n </>\n )}\n </>\n }\n />\n\n {/* Per user feedback, order below the FormHeader is:\n 1. Status path (operator-facing lifecycle nav)\n 2. ARC info (amend/renew/cancel banner with targets)\n 3. Customer / Version / Currency meta cards\n 4. Pricing summary + line items (further down in the page)\n Status path and ARC info are higher because they describe what\n the user is *doing*; the meta cards are reference info. */}\n\n {/* Status path \u2014 every step is clickable so the operator can move\n between any pair of statuses. Backend enforces ARC-specific\n guards (validateArcQuote on submit-for-approval) but no longer\n gates simple transitions. */}\n <div className=\"flex items-center gap-3 flex-wrap\">\n <StatusPath\n // Per product decision the quote status path lets the operator\n // jump between any pair of statuses, so `allowedTransitions` is\n // omitted \u2014 backend validates ARC-specific guards.\n // `pre_approved` aliases into the `approved` slot for layout.\n current={cpqQuote.cpqStatus}\n path={\n cpqQuote.cpqStatus === 'pre_approved'\n ? ['new', 'incomplete', 'ready', 'in_approval', 'pre_approved', 'with_customer', 'accepted']\n : ['new', 'incomplete', 'ready', 'in_approval', 'approved', 'with_customer', 'accepted']\n }\n terminals={['rejected', 'cancelled']}\n statusMap={quoteCpqStatusMap}\n onTransition={transitionStatus}\n disabled={transitioning}\n ariaLabel=\"Quote status path\"\n />\n {transitioning && <Spinner />}\n </div>\n\n {error && <ErrorBanner message={error} onDismiss={() => setError(null)} />}\n\n {arcQuoteType !== 'new' && arcTargets.length > 0 && (\n <div className=\"rounded-md border border-brand-violet/30 bg-brand-violet/10 px-4 py-3 text-sm text-brand-violet\">\n <div className=\"flex items-center justify-between\">\n <div>\n <span className=\"font-medium uppercase\">{arcQuoteType}</span>\n {' \u2022 '}\n {arcTargets.length} target{arcTargets.length === 1 ? '' : 's'}:\n {' '}\n {arcTargets.map((t, i) => (\n <span key={t.id}>\n {i > 0 && ', '}\n <button\n onClick={() =>\n router.push(`/backend/cpq/inventory/subscriptions/${t.subscriptionId}`)\n }\n className=\"text-brand-violet hover:underline\"\n >\n {t.subscription?.code ?? t.subscriptionId.slice(0, 8)}\n </button>\n </span>\n ))}\n {isMergeRenew && (\n <span className=\"ml-2 text-status-warning-text font-medium\">\n \u2022 Merging into a new contract\n </span>\n )}\n </div>\n </div>\n </div>\n )}\n\n {/* Meta cards \u2014 secondary reference info (customer, version,\n currency). Mirrors the sidebar tiles in the standard\n sales-document detail layout. */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3\">\n <MetaCard label=\"Customer\">\n {cpqQuote.customerName ? (\n <span className=\"font-medium\">{cpqQuote.customerName}</span>\n ) : (\n <span className=\"font-mono text-xs text-muted-foreground\">\n {cpqQuote.customerId.slice(0, 8)}\u2026\n </span>\n )}\n </MetaCard>\n <MetaCard label=\"Version\">\n <span className=\"font-medium\">v{cpqQuote.version}</span>\n </MetaCard>\n <MetaCard label=\"Currency\">\n <span className=\"font-medium\">{currency}</span>\n </MetaCard>\n </div>\n\n {showDeleteConfirm && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50\" onClick={() => setShowDeleteConfirm(false)}>\n <div className=\"w-full max-w-sm rounded-lg border bg-card shadow-xl\" onClick={(e) => e.stopPropagation()}>\n <div className=\"px-4 py-3 border-b\">\n <h3 className=\"text-sm font-medium\">Delete Quote</h3>\n </div>\n <div className=\"p-4\">\n <p className=\"text-sm text-muted-foreground\">Are you sure you want to delete this quote? This will soft-delete the quote and all its line items.</p>\n </div>\n <div className=\"flex justify-end gap-2 px-4 py-3 border-t\">\n <Button type=\"button\" variant=\"outline\" onClick={() => setShowDeleteConfirm(false)}>\n Cancel\n </Button>\n <Button type=\"button\" variant=\"destructive\" onClick={deleteQuote} disabled={deleting}>\n {deleting ? <Spinner /> : null} Delete\n </Button>\n </div>\n </div>\n </div>\n )}\n\n {/* Summary view */}\n {view === 'summary' && (\n <>\n <PricingSummaryCard summary={summary} currency={currency} arcDelta={arcDelta} />\n\n {/* Validation errors */}\n {!cpqQuote.validationResult.valid && (\n <Alert variant=\"warning\">\n <AlertTitle>Validation Issues</AlertTitle>\n <AlertDescription>\n {/* Stacked <span>s rather than <ul>/<li>: before Open Mercato\n 0.8 AlertDescription rendered a <p>, where a list is invalid\n HTML and a Next 16 hydration error. It is a <div> now, so a\n list would be fine; the spans are kept as harmless. */}\n <span className=\"text-xs space-y-0.5 block\">\n {cpqQuote.validationResult.errors.map((e, i) => (\n <span key={i} className=\"block\">\u2014 {e.message}</span>\n ))}\n </span>\n </AlertDescription>\n </Alert>\n )}\n\n {/* Amend lines the rep reconfigured are re-priced at today's catalog\n price (server marks them `_arcRepriced`); negotiated prices are\n not carried over yet (later release). */}\n {arcQuoteType === 'amend' && cpqQuote.lines.some((l) => l.action !== 'cancel' && l.configuration?._arcRepriced === true) && (\n <Alert status=\"information\" style=\"lighter\">\n <AlertTitle>\n {t('cpq.quotes.arc.repricedTitle', 'Some existing items use the current catalog price')}\n </AlertTitle>\n <AlertDescription>\n {t(\n 'cpq.quotes.arc.repricedDescription',\n \"Reconfigured lines were re-priced at today's catalog price. Negotiated prices from the subscription are not carried over to reconfigured lines yet.\",\n )}\n </AlertDescription>\n </Alert>\n )}\n\n {/* Quote Lines */}\n <QuoteLineTree\n lines={cpqQuote.lines}\n currency={currency}\n expandedLines={expandedLines}\n pricingDetail={pricingDetail}\n targetCodes={arcTargetCodeMap}\n onToggleLine={toggleLine}\n onEditLine={startEditLine}\n onRemoveLine={removeItem}\n onAddComponent={startAddComponent}\n onTogglePricingDetail={(lineIdx, chargeIdx) =>\n setPricingDetail(\n pricingDetail?.lineIdx === lineIdx && pricingDetail?.chargeIdx === chargeIdx\n ? null\n : { lineIdx, chargeIdx },\n )\n }\n />\n\n <PriceAdjustmentsPanel\n quoteId={cpqQuote.id}\n items={priceAdjustments.items}\n total={priceAdjustments.total}\n lines={cpqQuote.lines}\n currency={currency}\n errorsById={priceAdjustments.errorsById}\n />\n </>\n )}\n\n {/* Add offering \u2014 browse */}\n {view === 'add-offering' && (\n <>\n {addingToParentLineId && (\n <Alert variant=\"info\">\n Adding component to bundle: <span className=\"font-medium\">{cpqQuote.lines.find((l) => l.lineId === addingToParentLineId)?.offeringName ?? 'Bundle'}</span>\n </Alert>\n )}\n <OfferingBrowser\n offerings={offerings}\n loading={offeringsLoading}\n search={offeringSearch}\n onSearchChange={setOfferingSearch}\n onSelect={selectOffering}\n />\n </>\n )}\n\n {/* Configure new offering */}\n {view === 'configure' && selectedOffering && (\n <ConfigurePanel\n title={addingToParentLineId ? `Add Component: ${selectedOffering.name}` : `Configure: ${selectedOffering.name}`}\n attributes={attributes}\n config={config}\n quantity={quantity}\n arcTargetOptions={\n arcTargets.length >= 2 && !addingToParentLineId\n ? arcTargets.map((t) => ({\n subscriptionId: t.subscriptionId,\n code: t.subscription?.code ?? t.subscriptionId.slice(0, 8),\n name: t.subscription?.name ?? null,\n }))\n : null\n }\n arcSelectedTargetIds={addingTargetSubIds}\n onArcTargetToggle={(subId) => {\n setAddingTargetSubIds((prev) =>\n prev.includes(subId) ? prev.filter((id) => id !== subId) : [...prev, subId],\n )\n }}\n onConfigChange={(key, value) => {\n const next = { ...config, [key]: value }\n setConfig(next)\n if (selectedOffering) loadAttributes(selectedOffering.id, next)\n }}\n onQuantityChange={setQuantity}\n onSubmit={addItem}\n submitLabel=\"Add to Quote\"\n submitting={submitting}\n />\n )}\n\n {/* Edit existing line */}\n {view === 'edit' && editingLineId && (\n <ConfigurePanel\n title={`Edit: ${cpqQuote.lines.find((l) => l.lineId === editingLineId)?.offeringName ?? 'Line'}`}\n attributes={attributes}\n config={config}\n quantity={quantity}\n arcTargetOptions={null}\n arcSelectedTargetIds={[]}\n onArcTargetToggle={() => {}}\n onConfigChange={(key, value) => {\n const next = { ...config, [key]: value }\n setConfig(next)\n const line = cpqQuote.lines.find((l) => l.lineId === editingLineId)\n if (line?.offeringId) loadAttributes(line.offeringId, next)\n }}\n onQuantityChange={setQuantity}\n onSubmit={() => updateItem(editingLineId)}\n submitLabel=\"Update Line\"\n submitting={submitting}\n />\n )}\n </div>\n </ArcLineRemovalProvider>\n </PriceAdjustmentProvider>\n )\n}\n\n// \u2500\u2500\u2500 Sub-components \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction QuoteLineTree({ lines, currency, expandedLines, pricingDetail, targetCodes, onToggleLine, onEditLine, onRemoveLine, onAddComponent, onTogglePricingDetail }: {\n lines: QuoteLine[]; currency: string; expandedLines: Set<string>\n pricingDetail: { lineIdx: number; chargeIdx: number } | null\n targetCodes: Map<string, string>\n onToggleLine: (id: string) => void; onEditLine: (line: QuoteLine) => void\n onRemoveLine: (lineId: string) => void; onAddComponent: (parentLineId: string, offeringId?: string) => void\n onTogglePricingDetail: (lineIdx: number, chargeIdx: number) => void\n}) {\n const [bundleTrees, setBundleTrees] = React.useState<Map<string, BundleTree>>(new Map())\n const [loadingTrees, setLoadingTrees] = React.useState<Set<string>>(new Set())\n\n const rootLines = lines.filter((l) => !l.parentLineId)\n const childrenByParent = new Map<string, QuoteLine[]>()\n for (const line of lines) {\n if (line.parentLineId) {\n const arr = childrenByParent.get(line.parentLineId) ?? []\n arr.push(line)\n childrenByParent.set(line.parentLineId, arr)\n }\n }\n\n const fetchBundleTree = React.useCallback(async (offeringId: string) => {\n if (bundleTrees.has(offeringId) || loadingTrees.has(offeringId)) return\n setLoadingTrees((prev) => new Set(prev).add(offeringId))\n try {\n const result = await apiJson<{ tree: BundleTree }>(`/api/cpq/bundle-tree?offeringId=${offeringId}`)\n setBundleTrees((prev) => new Map(prev).set(offeringId, result.tree))\n } catch { /* ignore \u2014 will just not show structure */ }\n finally { setLoadingTrees((prev) => { const n = new Set(prev); n.delete(offeringId); return n }) }\n }, [bundleTrees, loadingTrees])\n\n return (\n <div>\n <h3 className=\"text-sm font-medium mb-2 px-1\">Line Items</h3>\n {lines.length === 0 ? (\n <div className=\"rounded-lg border bg-card py-8 text-center text-sm text-muted-foreground\">\n No items configured yet. Click &quot;Add Offering&quot; to start.\n </div>\n ) : (\n <div className=\"rounded-lg border bg-card divide-y\">\n {rootLines.map((line) => {\n const lineIdx = lines.indexOf(line)\n const isBundle = line.offeringType === 'bundle'\n const children = childrenByParent.get(line.lineId) ?? []\n const isExpanded = expandedLines.has(line.lineId)\n const bundleTree = isBundle && line.offeringId ? bundleTrees.get(line.offeringId) : undefined\n const treeLoading = isBundle && line.offeringId ? loadingTrees.has(line.offeringId) : false\n\n if (isBundle && isExpanded && line.offeringId && !bundleTree && !treeLoading) {\n fetchBundleTree(line.offeringId)\n }\n\n return (\n <div key={line.lineId}>\n <QuoteLineRow\n line={line} lineIdx={lineIdx} currency={currency}\n isExpanded={isExpanded}\n pricingDetail={pricingDetail} isBundle={isBundle}\n childCount={children.length} indent={0}\n targetCodes={targetCodes}\n onToggle={() => onToggleLine(line.lineId)}\n onEdit={() => onEditLine(line)}\n onRemove={() => onRemoveLine(line.lineId)}\n onAddComponent={isBundle ? () => onAddComponent(line.lineId) : undefined}\n onTogglePricingDetail={onTogglePricingDetail}\n />\n {/* Bundle structure: slots and child lines */}\n {isBundle && isExpanded && (\n <BundleSlotPanel\n bundleTree={bundleTree}\n treeLoading={treeLoading}\n children={children}\n allLines={lines}\n currency={currency}\n expandedLines={expandedLines}\n pricingDetail={pricingDetail}\n parentLineId={line.lineId}\n targetCodes={targetCodes}\n onToggleLine={onToggleLine}\n onEditLine={onEditLine}\n onRemoveLine={onRemoveLine}\n onAddComponent={onAddComponent}\n onTogglePricingDetail={onTogglePricingDetail}\n />\n )}\n </div>\n )\n })}\n </div>\n )}\n </div>\n )\n}\n\nfunction BundleSlotPanel({ bundleTree, treeLoading, children, allLines, currency, expandedLines, pricingDetail, parentLineId, targetCodes, onToggleLine, onEditLine, onRemoveLine, onAddComponent, onTogglePricingDetail }: {\n bundleTree: BundleTree | undefined; treeLoading: boolean\n children: QuoteLine[]; allLines: QuoteLine[]; currency: string\n expandedLines: Set<string>; pricingDetail: { lineIdx: number; chargeIdx: number } | null\n parentLineId: string\n targetCodes: Map<string, string>\n onToggleLine: (id: string) => void; onEditLine: (line: QuoteLine) => void\n onRemoveLine: (lineId: string) => void; onAddComponent: (parentLineId: string, offeringId?: string) => void\n onTogglePricingDetail: (lineIdx: number, chargeIdx: number) => void\n}) {\n if (treeLoading) {\n return (\n <div className=\"border-t bg-muted/5 px-8 py-3\">\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\"><Spinner /> Loading bundle structure\u2026</div>\n </div>\n )\n }\n\n if (!bundleTree || bundleTree.slots.length === 0) {\n if (children.length === 0) return null\n return (\n <div className=\"border-t bg-muted/5\">\n {children.map((child) => {\n const childIdx = allLines.indexOf(child)\n return (\n <QuoteLineRow\n key={child.lineId}\n line={child} lineIdx={childIdx} currency={currency}\n isExpanded={expandedLines.has(child.lineId)}\n pricingDetail={pricingDetail} isBundle={false}\n childCount={0} indent={1}\n targetCodes={targetCodes}\n onToggle={() => onToggleLine(child.lineId)}\n onEdit={() => onEditLine(child)}\n onRemove={() => onRemoveLine(child.lineId)}\n onTogglePricingDetail={onTogglePricingDetail}\n />\n )\n })}\n </div>\n )\n }\n\n const childOfferingIds = new Set(children.map((c) => c.offeringId).filter(Boolean))\n\n return (\n <div className=\"border-t bg-muted/5\">\n {bundleTree.slots.map((slot) => {\n const filledChildren = children.filter((c) =>\n slot.components.some((comp) => comp.childOffering.offeringId === c.offeringId),\n )\n const filledCount = filledChildren.length\n const isRequired = slot.cardinalityMin > 0\n const isFull = slot.cardinalityMax != null && filledCount >= slot.cardinalityMax\n const canAdd = !isFull\n\n return (\n <div key={slot.slotId} className=\"border-b last:border-b-0\">\n {/* Slot header */}\n <div className=\"flex items-center gap-2 px-6 py-2 bg-muted/20\">\n <span className=\"text-xs font-medium text-muted-foreground uppercase tracking-wide\">{slot.name}</span>\n {isRequired ? (\n <Tag variant=\"warning\" className=\"text-[10px] px-1.5\">required</Tag>\n ) : (\n <Tag variant=\"neutral\" className=\"text-[10px] px-1.5\">optional</Tag>\n )}\n <span className=\"text-[10px] text-muted-foreground\">\n {filledCount}/{slot.cardinalityMax ?? '\u221E'}\n {slot.cardinalityMin > 0 && ` (min ${slot.cardinalityMin})`}\n </span>\n <div className=\"flex-1\" />\n {/* Available offerings in this slot */}\n <div className=\"flex items-center gap-1\">\n {slot.components.map((comp) => {\n const isFilled = childOfferingIds.has(comp.childOffering.offeringId)\n return (\n <button\n key={comp.componentId}\n onClick={() => !isFilled && canAdd && onAddComponent(parentLineId, comp.childOffering.offeringId)}\n disabled={isFilled || !canAdd}\n className={`inline-flex items-center gap-1 rounded border px-2 py-1 text-[11px] font-medium transition-colors ${\n isFilled\n ? 'border-status-success-border bg-status-success-bg text-status-success-text cursor-default'\n : canAdd\n ? 'border-border hover:border-primary hover:bg-primary/5 hover:text-primary cursor-pointer'\n : 'border-border text-muted-foreground opacity-50 cursor-not-allowed'\n }`}\n title={isFilled ? 'Already added' : canAdd ? `Add ${comp.childOffering.offeringName}` : 'Slot is full'}\n >\n {isFilled ? (\n <svg className=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" strokeWidth=\"2\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\" />\n </svg>\n ) : (\n <svg className=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" strokeWidth=\"2\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M12 4.5v15m7.5-7.5h-15\" />\n </svg>\n )}\n {comp.childOffering.offeringName}\n </button>\n )\n })}\n </div>\n </div>\n {/* Filled child lines for this slot */}\n {filledChildren.map((child) => {\n const childIdx = allLines.indexOf(child)\n return (\n <QuoteLineRow\n key={child.lineId}\n line={child} lineIdx={childIdx} currency={currency}\n isExpanded={expandedLines.has(child.lineId)}\n pricingDetail={pricingDetail} isBundle={false}\n childCount={0} indent={1}\n targetCodes={targetCodes}\n onToggle={() => onToggleLine(child.lineId)}\n onEdit={() => onEditLine(child)}\n onRemove={() => onRemoveLine(child.lineId)}\n onTogglePricingDetail={onTogglePricingDetail}\n />\n )\n })}\n </div>\n )\n })}\n {/* Show any child lines not matching any slot */}\n {children.filter((c) => !bundleTree.slots.some((s) => s.components.some((comp) => comp.childOffering.offeringId === c.offeringId))).map((child) => {\n const childIdx = allLines.indexOf(child)\n return (\n <QuoteLineRow\n key={child.lineId}\n line={child} lineIdx={childIdx} currency={currency}\n isExpanded={expandedLines.has(child.lineId)}\n pricingDetail={pricingDetail} isBundle={false}\n childCount={0} indent={1}\n targetCodes={targetCodes}\n onToggle={() => onToggleLine(child.lineId)}\n onEdit={() => onEditLine(child)}\n onRemove={() => onRemoveLine(child.lineId)}\n onTogglePricingDetail={onTogglePricingDetail}\n />\n )\n })}\n </div>\n )\n}\n\nfunction QuoteLineRow({ line, lineIdx, currency, isExpanded, pricingDetail, isBundle, childCount, indent, targetCodes, onToggle, onEdit, onRemove, onAddComponent, onTogglePricingDetail }: {\n line: QuoteLine; lineIdx: number; currency: string; isExpanded: boolean\n pricingDetail: { lineIdx: number; chargeIdx: number } | null\n isBundle: boolean; childCount: number; indent: number\n targetCodes: Map<string, string>\n onToggle: () => void; onEdit: () => void; onRemove: () => void\n onAddComponent?: () => void\n onTogglePricingDetail: (lineIdx: number, chargeIdx: number) => void\n}) {\n const t = useT()\n const adjustmentUi = usePriceAdjustmentUi()\n const removalUi = useArcLineRemovalUi()\n const isRemoved = removalUi?.isRemoved(line) ?? false\n const paddingLeft = indent > 0 ? `${indent * 2 + 1}rem` : undefined\n const chargeActions = {\n reasonLabels: adjustmentUi?.reasonLabels,\n renderChargeActions: (charge: ResolvedCharge) => <AdjustChargeAction line={line} charge={charge} />,\n renderManualActions: (adjustmentId: string) => <ManualAdjustmentActions adjustmentId={adjustmentId} />,\n }\n\n return (\n <div>\n <div className={`flex items-center gap-3 px-4 py-3 hover:bg-muted/30 transition-colors ${isRemoved ? 'bg-muted/20' : ''}`} style={paddingLeft ? { paddingLeft } : undefined} data-testid=\"cpq-quote-line\" data-removed={isRemoved ? 'true' : undefined}>\n {/* Expand toggle */}\n <button onClick={onToggle} className=\"flex h-5 w-5 shrink-0 items-center justify-center rounded text-muted-foreground hover:text-foreground\">\n <svg className={`h-4 w-4 transition-transform ${isExpanded ? 'rotate-90' : ''}`} fill=\"none\" viewBox=\"0 0 24 24\" strokeWidth=\"2\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M8.25 4.5l7.5 7.5-7.5 7.5\" />\n </svg>\n </button>\n\n {/* Line info */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n {indent > 0 && (\n <span className=\"text-muted-foreground text-xs\">\u2514</span>\n )}\n {isBundle && (\n <Tag variant=\"brand\" className=\"px-1.5 text-xs\">bundle</Tag>\n )}\n <span className={`font-medium text-sm ${isRemoved ? 'text-muted-foreground line-through' : ''}`}>{line.offeringName}</span>\n {line.quantity > 1 && <span className=\"rounded bg-muted px-1.5 py-0.5 text-xs font-medium\">\u00D7{line.quantity}</span>}\n <LineActionBadge\n action={line.action}\n label={isRemoved ? t('cpq.quotes.arc.lineRemoved', 'remove') : undefined}\n title={isRemoved ? t('cpq.quotes.arc.lineRemovedHint', 'This item is cancelled on the subscription when the order is activated') : undefined}\n />\n {!isRemoved && line.configuration?._arcPriceFrozen === true && (\n <Tag\n variant=\"neutral\"\n className=\"px-1.5 text-xs\"\n title={t(\n 'cpq.quotes.arc.priceKeptHint',\n 'Price kept from the subscription \u2014 it changes only if you reconfigure this line',\n )}\n >\n {t('cpq.quotes.arc.priceKept', 'price kept')}\n </Tag>\n )}\n {targetCodes.size >= 2 && line.targetSubscriptionId && targetCodes.get(line.targetSubscriptionId) && (\n <Tag\n variant=\"brand\"\n className=\"px-1.5 text-xs\"\n title={`Acts on subscription ${targetCodes.get(line.targetSubscriptionId)}`}\n >\n \u2192 {targetCodes.get(line.targetSubscriptionId)}\n </Tag>\n )}\n {isRemoved ? null : line.isConfigured ? (\n <Tag variant=\"success\" className=\"px-1.5 text-xs\">configured</Tag>\n ) : (\n <Tag variant=\"warning\" className=\"px-1.5 text-xs\">incomplete</Tag>\n )}\n {isBundle && (\n <span className=\"text-xs text-muted-foreground\">{childCount} component{childCount !== 1 ? 's' : ''}</span>\n )}\n </div>\n {line.validationErrors && line.validationErrors.length > 0 && (\n <p className=\"text-xs text-destructive mt-0.5\">{line.validationErrors[0].message}</p>\n )}\n </div>\n\n {/* Pricing */}\n <div className=\"shrink-0 text-right text-xs space-y-0.5\">\n {isRemoved && line.arcSource && line.arcSource.mrcAmount > 0 && (\n <div>\n <span className=\"text-muted-foreground\">MRC </span>\n <span className=\"font-mono text-muted-foreground line-through\">{fmt(line.arcSource.mrcAmount, currency)}</span>\n </div>\n )}\n {line.nrcTotal > 0 && <div><span className=\"text-muted-foreground\">NRC </span><span className=\"font-mono font-medium\">{fmt(line.nrcTotal, currency)}</span></div>}\n {line.mrcTotal > 0 && <div><span className=\"text-muted-foreground\">MRC </span><span className=\"font-mono font-medium\">{fmt(line.mrcTotal, currency)}</span></div>}\n </div>\n\n {/* Actions */}\n {isRemoved ? (\n <div className=\"flex items-center gap-1 shrink-0\">\n <Button\n type=\"button\" variant=\"ghost\" size=\"sm\"\n onClick={() => removalUi?.restore(line.lineId)}\n title={t('cpq.quotes.arc.restoreHint', 'Keep this item on the subscription')}\n data-testid=\"cpq-line-restore\"\n >\n <RotateCcw className=\"h-4 w-4\" />\n {t('cpq.quotes.arc.restore', 'Restore')}\n </Button>\n </div>\n ) : (\n <div className=\"flex items-center gap-1 shrink-0\">\n <DiscountLineAction line={line} />\n {onAddComponent && (\n <button onClick={onAddComponent} className=\"rounded p-1.5 text-muted-foreground hover:text-primary hover:bg-primary/5 transition-colors\" title=\"Add Component\">\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" strokeWidth=\"1.5\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M12 4.5v15m7.5-7.5h-15\" />\n </svg>\n </button>\n )}\n <button onClick={onEdit} className=\"rounded p-1.5 text-muted-foreground hover:text-foreground hover:bg-muted transition-colors\" title=\"Edit\">\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" strokeWidth=\"1.5\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10\" />\n </svg>\n </button>\n <button onClick={onRemove} className=\"rounded p-1.5 text-muted-foreground hover:text-destructive hover:bg-destructive/10 transition-colors\" title=\"Remove\">\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" strokeWidth=\"1.5\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0\" />\n </svg>\n </button>\n </div>\n )}\n </div>\n\n {/* Charge breakdown (non-bundle or any expanded line) */}\n {isExpanded && !isBundle && line.charges.length > 0 && (\n <ChargeBreakdown line={line} lineIdx={lineIdx} currency={currency} pricingDetail={pricingDetail} onTogglePricingDetail={onTogglePricingDetail} {...chargeActions} />\n )}\n {/* For bundles: show own charges first, then children are rendered by parent */}\n {isExpanded && isBundle && line.charges.length > 0 && (\n <ChargeBreakdown line={line} lineIdx={lineIdx} currency={currency} pricingDetail={pricingDetail} onTogglePricingDetail={onTogglePricingDetail} {...chargeActions} />\n )}\n {/* XD-250 ARC: before/after preview, below the charges, when line mirrors a sub item */}\n {isExpanded && line.arcSource && (\n <div className=\"border-t bg-muted/10 px-12 py-2\">\n <ArcLineDiff line={line} currency={currency} />\n </div>\n )}\n {/* Fallback: line has no per-charge breakdown and no ARC diff (truly empty) */}\n {isExpanded && line.charges.length === 0 && !line.arcSource && (\n <LineSummaryFallback line={line} currency={currency} />\n )}\n </div>\n )\n}\n\nfunction LineSummaryFallback({ line, currency }: { line: QuoteLine; currency: string }) {\n const hasTotals = line.nrcTotal > 0 || line.mrcTotal > 0\n const mirroredFromItemId = (line.configuration?._arcMirroredFromItemId as string | undefined) ?? null\n return (\n <div className=\"border-t bg-muted/10 px-12 py-2 text-xs text-muted-foreground space-y-1\">\n <div>\n No detailed charge breakdown available for this line.\n {mirroredFromItemId && ' Mirrored from existing subscription item.'}\n </div>\n {hasTotals && (\n <div className=\"flex gap-4\">\n {line.nrcTotal > 0 && (\n <span>NRC <span className=\"font-mono font-medium text-foreground\">{fmt(line.nrcTotal, currency)}</span></span>\n )}\n {line.mrcTotal > 0 && (\n <span>MRC <span className=\"font-mono font-medium text-foreground\">{fmt(line.mrcTotal, currency)}</span></span>\n )}\n </div>\n )}\n </div>\n )\n}\n\nfunction ChargeBreakdown({ line, lineIdx, pricingDetail, onTogglePricingDetail, ...tableProps }: {\n line: QuoteLine; lineIdx: number; currency: string\n pricingDetail: { lineIdx: number; chargeIdx: number } | null\n onTogglePricingDetail: (lineIdx: number, chargeIdx: number) => void\n reasonLabels?: Record<string, string>\n renderChargeActions?: (charge: ResolvedCharge) => React.ReactNode\n renderManualActions?: (adjustmentId: string) => React.ReactNode\n}) {\n return (\n <div className=\"border-t bg-muted/10 px-12 py-2\">\n <ChargeBreakdownTable\n charges={line.charges}\n openDetailIndex={pricingDetail?.lineIdx === lineIdx ? pricingDetail.chargeIdx : null}\n onToggleDetail={(chargeIdx) => onTogglePricingDetail(lineIdx, chargeIdx)}\n {...tableProps}\n />\n </div>\n )\n}\n\nfunction Spinner() {\n return (\n <svg className=\"h-4 w-4 animate-spin\" viewBox=\"0 0 24 24\" fill=\"none\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\" />\n <path className=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z\" />\n </svg>\n )\n}\n\nfunction ErrorBanner({ message, onDismiss }: { message: string; onDismiss?: () => void }) {\n return (\n <Alert variant=\"destructive\" className=\"flex items-start gap-2\">\n <span className=\"flex-1\">{message}</span>\n {onDismiss && (\n <button\n onClick={onDismiss}\n className=\"text-destructive/70 hover:text-destructive text-sm font-bold\"\n aria-label=\"Dismiss\"\n >\n \u00D7\n </button>\n )}\n </Alert>\n )\n}\n\nfunction OfferingBrowser({ offerings, loading, search, onSearchChange, onSelect }: {\n offerings: Offering[]; loading: boolean; search: string; onSearchChange: (v: string) => void; onSelect: (o: Offering) => void\n}) {\n const filtered = offerings.filter((o) => {\n if (!search.trim()) return true\n const q = search.toLowerCase()\n return o.name.toLowerCase().includes(q) || o.code.toLowerCase().includes(q) || (o.description ?? '').toLowerCase().includes(q)\n })\n\n return (\n <div className=\"space-y-3\">\n <h3 className=\"text-sm font-medium px-1\">Select Product Offering</h3>\n <div className=\"relative\">\n <svg className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground\" fill=\"none\" viewBox=\"0 0 24 24\" strokeWidth=\"2\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z\" />\n </svg>\n <input type=\"text\" placeholder=\"Search offerings\u2026\" value={search} onChange={(e) => onSearchChange(e.target.value)}\n className=\"w-full rounded-md border bg-background pl-10 pr-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/50\" />\n </div>\n {loading ? (\n <div className=\"flex items-center gap-2 py-8 justify-center text-sm text-muted-foreground\"><Spinner /> Loading offerings\u2026</div>\n ) : filtered.length === 0 ? (\n <div className=\"py-8 text-center text-sm text-muted-foreground\">{search ? 'No offerings match your search.' : 'No active offerings available.'}</div>\n ) : (\n <div className=\"grid gap-2 sm:grid-cols-2 lg:grid-cols-3\">\n {filtered.map((offering) => (\n <button key={offering.id} onClick={() => onSelect(offering)}\n className=\"rounded-lg border bg-card p-4 text-left hover:border-primary hover:bg-primary/5 transition-colors group\">\n <p className=\"text-sm font-medium group-hover:text-primary transition-colors\">{offering.name}</p>\n <p className=\"text-xs text-muted-foreground font-mono mt-0.5\">{offering.code}</p>\n {offering.description && <p className=\"text-xs text-muted-foreground mt-1 line-clamp-2\">{offering.description}</p>}\n </button>\n ))}\n </div>\n )}\n </div>\n )\n}\n\nfunction ConfigurePanel({ title, attributes, config, quantity, arcTargetOptions, arcSelectedTargetIds, onArcTargetToggle, onConfigChange, onQuantityChange, onSubmit, submitLabel, submitting }: {\n title: string; attributes: ConstrainedAttribute[]; config: Record<string, unknown>; quantity: number\n arcTargetOptions: Array<{ subscriptionId: string; code: string; name: string | null }> | null\n arcSelectedTargetIds: string[]\n onArcTargetToggle: (subId: string) => void\n onConfigChange: (key: string, value: unknown) => void; onQuantityChange: (q: number) => void\n onSubmit: () => void; submitLabel: string; submitting: boolean\n}) {\n const noTargetsPicked =\n arcTargetOptions !== null && arcTargetOptions.length > 0 && arcSelectedTargetIds.length === 0\n return (\n <div className=\"rounded-lg border bg-card\">\n <div className=\"border-b px-4 py-3\"><h3 className=\"text-sm font-medium\">{title}</h3></div>\n <div className=\"p-4 space-y-4\">\n {arcTargetOptions && arcTargetOptions.length > 0 && (\n <div>\n <label className=\"block text-sm font-medium mb-1\">\n Apply to subscription(s)\n <span className=\"text-destructive ml-1\">*</span>\n </label>\n <div className=\"space-y-1.5 rounded-md border bg-background px-3 py-2\">\n {arcTargetOptions.map((opt) => {\n const checked = arcSelectedTargetIds.includes(opt.subscriptionId)\n return (\n <label\n key={opt.subscriptionId}\n className=\"flex items-center gap-2 text-sm cursor-pointer hover:bg-muted/40 rounded px-1 py-0.5\"\n >\n <input\n type=\"checkbox\"\n checked={checked}\n onChange={() => onArcTargetToggle(opt.subscriptionId)}\n className=\"h-4 w-4 rounded border-border\"\n />\n <span className=\"font-mono font-medium\">{opt.code}</span>\n {opt.name && <span className=\"text-muted-foreground\">\u2014 {opt.name}</span>}\n </label>\n )\n })}\n </div>\n <p className=\"text-xs text-muted-foreground mt-1\">\n Pick one or more \u2014 a separate line will be created on each selected subscription.\n </p>\n {noTargetsPicked && (\n <p className=\"text-xs text-destructive mt-1\">Select at least one target.</p>\n )}\n </div>\n )}\n <div>\n <label className=\"block text-sm font-medium mb-1\">Quantity</label>\n <NumberInput\n integer\n min={1}\n value={quantity}\n onChange={(n) => onQuantityChange(Math.max(1, n ?? 1))}\n className=\"w-24\"\n />\n </div>\n {attributes.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">No configurable attributes for this offering.</p>\n ) : (\n attributes.map((attr) => <AttributeField key={attr.code} attribute={attr} value={config[attr.code]} onChange={(v) => onConfigChange(attr.code, v)} />)\n )}\n </div>\n <div className=\"border-t px-4 py-3 flex justify-end\">\n <button onClick={onSubmit} disabled={submitting || noTargetsPicked}\n className=\"inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow-sm hover:bg-primary/90 transition-colors disabled:opacity-50\">\n {submitting ? <Spinner /> : null} {submitLabel}\n </button>\n </div>\n </div>\n )\n}\n\nfunction AttributeField({ attribute, value, onChange }: { attribute: ConstrainedAttribute; value: unknown; onChange: (v: unknown) => void }) {\n const { code, name, attributeType, isRequired, options, constraints, helpText, defaultValue } = attribute\n const currentValue = value ?? defaultValue ?? ''\n\n return (\n <div>\n <label className=\"block text-sm font-medium mb-1\">\n {name}{isRequired && <span className=\"text-destructive ml-0.5\">*</span>}\n </label>\n {(attributeType === 'select' || attributeType === 'enum') && options && options.length > 0 ? (\n <select value={String(currentValue)} onChange={(e) => onChange(e.target.value)}\n className=\"w-full rounded-md border bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/50\">\n <option value=\"\">\u2014 Select \u2014</option>\n {options.map((opt) => <option key={opt.value} value={opt.value}>{opt.label}</option>)}\n </select>\n ) : attributeType === 'boolean' ? (\n <label className=\"flex items-center gap-2\">\n <input type=\"checkbox\" checked={Boolean(currentValue)} onChange={(e) => onChange(e.target.checked)} className=\"rounded border-border\" />\n <span className=\"text-sm text-muted-foreground\">{helpText ?? 'Enable'}</span>\n </label>\n ) : attributeType === 'number' ? (\n <NumberInput\n value={\n typeof currentValue === 'number'\n ? currentValue\n : currentValue === '' || currentValue == null\n ? null\n : Number(currentValue)\n }\n min={(constraints as Record<string, unknown>)?.min as number | undefined}\n max={(constraints as Record<string, unknown>)?.max as number | undefined}\n onChange={(n) => onChange(n ?? '')}\n />\n ) : (\n <input type=\"text\" value={String(currentValue)} onChange={(e) => onChange(e.target.value)}\n className=\"w-full rounded-md border bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/50\" />\n )}\n {helpText && attributeType !== 'boolean' && <p className=\"text-xs text-muted-foreground mt-1\">{helpText}</p>}\n </div>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\nimport * as React from 'react'\nimport { useT, type TranslateFn } from '@open-mercato/shared/lib/i18n/context'\nimport { useRouter, useParams, useSearchParams } from 'next/navigation'\nimport ArcQuoteConfigurator, {\n type AttachedTarget,\n} from './_components/ArcQuoteConfigurator'\nimport { StatusPath } from '../../../../components/StatusPath'\nimport { ArrowRight, ExternalLink, Plus, RotateCcw } from 'lucide-react'\nimport { Alert, AlertTitle, AlertDescription } from '@open-mercato/ui/primitives/alert'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Tag } from '@open-mercato/ui/primitives/tag'\nimport { FormHeader } from '@open-mercato/ui/backend/forms'\nimport type { ActionItem } from '@open-mercato/ui/backend/forms/ActionsDropdown'\nimport { NumberInput } from '../../../../components/NumberInput'\nimport { ChargeBreakdownTable } from '../../../../components/ChargeBreakdownTable'\nimport { PricingSummaryCard } from '../../../../components/PricingSummaryCard'\nimport { ArcLineDiff, LineActionBadge } from '../../../../components/ArcLineDiff'\nimport { ADJUST_PRICE_FEATURE } from '../../../../lib/priceAdjustmentView'\nimport { arcRecurringDelta } from '../../../../lib/quoteSummaryView'\nimport { usePriceAdjustments } from './_components/usePriceAdjustments'\nimport { PriceAdjustmentsPanel } from './_components/PriceAdjustmentsPanel'\nimport { ArcLineRemovalProvider, useArcLineRemoval, useArcLineRemovalUi } from './_components/arcLineRemoval'\nimport { AdjustChargeAction, DiscountLineAction, ManualAdjustmentActions, PriceAdjustmentProvider, usePriceAdjustmentUi } from './_components/priceAdjustmentContext'\nimport { useGrantedFeatures } from '../../../../components/useGrantedFeatures'\nimport { canRecalculateQuote, QUOTE_MANAGE_FEATURE } from '../../../../lib/quotePermissions'\nimport {\n formatStatusLabel,\n quoteCpqStatusMap,\n type QuoteCpqStatus,\n} from '../../../../components/statusMaps'\n\n// \u2500\u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ntype ConstrainedAttribute = {\n code: string\n name: string\n attributeType: string\n isRequired: boolean\n options: Array<{ value: string; label: string }> | null\n constraints: Record<string, unknown> | null\n defaultValue: unknown | null\n helpText: string | null\n}\n\ntype TierBreakdownEntry = { tier: number; from: number; to: number; pricePerUnit: number; quantity: number; subtotal: number }\ntype RuleAdjustment = {\n ruleCode: string; ruleName: string; ruleType: string; value: number; unitPriceBefore: number; unitPriceAfter: number; delta: number\n /** Negotiated-pricing fields; absent on legacy snapshots (treated as rules). */\n origin?: 'rule' | 'manual'; adjustmentId?: string; reasonCode?: string; createdByUserId?: string\n}\ntype AdjustmentErrorEntry = { adjustmentId: string; quoteLineId: string; chargeCode?: string; code: string }\n\ntype ResolvedCharge = {\n chargeCode: string\n chargeName: string\n chargeType: 'nrc' | 'mrc' | 'usage'\n pricingMethod?: 'flat' | 'tiered' | 'per_unit'\n unitPrice: number\n quantity: number | null\n totalPrice: number | null\n currencyCode: string\n breakdown?: { tiers: TierBreakdownEntry[] } | null\n note?: string | null\n adjustments?: RuleAdjustment[] | null\n listUnitPrice?: number\n listTotalPrice?: number | null\n standardUnitPrice?: number\n standardTotalPrice?: number | null\n adjustmentErrors?: AdjustmentErrorEntry[]\n}\n\ntype QuoteLineAction = 'add' | 'modify' | 'cancel'\n\ntype ArcLineSource = {\n subscriptionItemId: string\n name: string\n mrcAmount: number\n nrcAmount: number\n quantity: number\n}\n\ntype QuoteLine = {\n lineId: string\n offeringId: string | null\n productId?: string | null\n offeringName: string\n offeringType: string | null\n parentLineId: string | null\n action: QuoteLineAction\n quantity: number\n configuration: Record<string, unknown>\n nrcTotal: number\n mrcTotal: number\n charges: ResolvedCharge[]\n isConfigured: boolean\n validationErrors: Array<{ message: string }> | null\n arcSource: ArcLineSource | null\n targetSubscriptionId: string | null\n}\n\ntype QuoteResult = {\n id: string\n quoteId: string\n quoteNumber: string\n customerId: string\n customerName: string | null\n cpqStatus: string\n version: number\n pricingRevision?: number\n currencyCode: string\n convertedOrderId: string | null\n validationResult: { valid: boolean; errors: Array<{ message: string }> }\n adjustmentErrors?: AdjustmentErrorEntry[]\n pricingSummary: {\n nrcTotal: number\n mrcTotal: number\n usageCharges: Array<{ chargeCode: string; chargeName: string; unitPrice: number; note: string | null }>\n usageTotalEstimated: number | null\n currencyCode: string\n listNrcTotal?: number\n listMrcTotal?: number\n dealValue?: { list: number; standard: number; offer: number }\n discountDepth?: { rule: number | null; manual: number | null; total: number | null; maxLineManual: number | null }\n ruleDiscountTotal?: number\n manualDiscountTotal?: number\n }\n lines: QuoteLine[]\n}\n\ntype Offering = {\n id: string\n code: string\n name: string\n description?: string | null\n specId: string\n lifecycleStatus: string\n}\n\ntype BundleTreeSlot = {\n slotId: string\n componentGroup: string\n name: string\n cardinalityMin: number\n cardinalityMax: number | null\n components: Array<{\n componentId: string\n childOffering: { offeringId: string; offeringCode: string; offeringName: string; offeringType: string }\n isDefault: boolean\n sortOrder: number\n }>\n}\n\ntype BundleTree = {\n offeringId: string\n offeringName: string\n offeringType: string\n slots: BundleTreeSlot[]\n}\n\n// \u2500\u2500\u2500 Constants \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n// `ALLOWED_TRANSITIONS` used to mirror the backend state machine on the\n// client to gate the inline status menu. Per product decision the UI\n// now lets the operator jump between any pair of statuses; the backend\n// is the single source of truth, so the table is no longer needed here.\n\nfunction fmt(amount: number, currency: string): string {\n return new Intl.NumberFormat('en-US', { style: 'currency', currency }).format(amount)\n}\n\nasync function apiJson<T>(t: TranslateFn, url: string, init?: RequestInit): Promise<T> {\n const res = await fetch(url, init)\n const json = await res.json()\n if (!res.ok) throw new Error(json?.error ?? t('cpq.common.requestFailed', 'Request failed ({status})', { status: res.status }))\n return json as T\n}\n\nfunction quoteTypeLabel(t: TranslateFn, quoteType: string): string {\n switch (quoteType) {\n case 'amend':\n return t('cpq.quotes.type.amend', 'amend')\n case 'renew':\n return t('cpq.quotes.type.renew', 'renew')\n case 'cancel':\n return t('cpq.quotes.type.cancel', 'cancel')\n default:\n return quoteType\n }\n}\n\n// \u2500\u2500\u2500 Header sub-components \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction MetaCard({ label, children }: { label: string; children: React.ReactNode }) {\n return (\n <div className=\"rounded-lg border bg-card p-4\">\n <div className=\"text-[10px] font-medium uppercase tracking-wide text-muted-foreground\">\n {label}\n </div>\n <div className=\"mt-1 text-sm\">{children}</div>\n </div>\n )\n}\n\n// Pricing-summary figure: label, monospace amount, and an optional smaller\n// bracketed note (discount depth / change %) inline after the amount.\nfunction MoreActionsDropdown({ items }: { items: ActionItem[] }) {\n // Local dropdown \u2014 `ActionsDropdown` inside FormHeader.actionsContent\n // would conflict with the inline button placement. This is a thin\n // <details>-style trigger; menuActions on FormHeader would render it\n // inside the header layout, but here we want it adjacent to other\n // primary buttons.\n const t = useT()\n const [open, setOpen] = React.useState(false)\n const ref = React.useRef<HTMLDivElement>(null)\n React.useEffect(() => {\n if (!open) return\n const handler = (e: MouseEvent) => {\n if (ref.current && !ref.current.contains(e.target as Node)) setOpen(false)\n }\n document.addEventListener('mousedown', handler)\n return () => document.removeEventListener('mousedown', handler)\n }, [open])\n\n if (items.length === 0) return null\n return (\n <div className=\"relative\" ref={ref}>\n <Button type=\"button\" variant=\"outline\" onClick={() => setOpen((v) => !v)}>\n {t('cpq.quotes.detail.actions', 'Actions')}\n <svg className=\"h-3 w-3 ml-1\" fill=\"none\" viewBox=\"0 0 24 24\" strokeWidth=\"2\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M19.5 8.25l-7.5 7.5-7.5-7.5\" />\n </svg>\n </Button>\n {open && (\n <div className=\"absolute right-0 top-full mt-1 z-50 min-w-[200px] rounded-md border bg-popover shadow-md py-1\">\n {items.map((item) => {\n const isDelete = item.id === 'delete'\n return (\n <button\n key={item.id}\n type=\"button\"\n onClick={() => { setOpen(false); item.onSelect() }}\n disabled={item.disabled || item.loading}\n // Use bg-accent on hover (same token as Radix-style menu items in OM)\n // and tint delete with destructive colors so the affordance is obvious.\n className={\n 'w-full px-3 py-2 text-left text-sm flex items-center gap-2 transition-colors ' +\n 'disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:bg-transparent ' +\n (isDelete\n ? 'text-destructive hover:bg-destructive/10 focus:bg-destructive/10 focus:outline-none'\n : 'hover:bg-accent focus:bg-accent focus:outline-none')\n }\n >\n {item.icon ? <item.icon className=\"h-4 w-4 text-muted-foreground\" /> : null}\n <span>{item.label}</span>\n </button>\n )\n })}\n </div>\n )}\n </div>\n )\n}\n\nfunction buildMoreActions({\n t,\n recalculate,\n canRecalculate,\n submitting,\n deletable,\n onDelete,\n deleting,\n}: {\n t: TranslateFn\n recalculate: () => void\n canRecalculate: boolean\n submitting: boolean\n deletable: boolean\n onDelete: () => void\n deleting: boolean\n}): ActionItem[] {\n const items: ActionItem[] = []\n // Recalculate persists prices: offered only to users with cpq.quotes.manage\n // and only on non-terminal quotes (the API refuses both otherwise).\n if (canRecalculate) {\n items.push({\n id: 'recalculate',\n label: t('cpq.quotes.detail.recalculate', 'Recalculate'),\n onSelect: recalculate,\n loading: submitting,\n disabled: submitting,\n })\n }\n if (deletable) {\n items.push({\n id: 'delete',\n label: t('cpq.common.delete', 'Delete'),\n onSelect: onDelete,\n disabled: deleting,\n loading: deleting,\n })\n }\n return items\n}\n\n// \u2500\u2500\u2500 Main Page \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport default function CpqQuoteDetailPage(props: { params?: { id?: string } }) {\n const router = useRouter()\n const urlParams = useParams()\n const searchParams = useSearchParams()\n const cpqConfigId = (props.params?.id ?? urlParams?.id) as string\n const isNew = cpqConfigId === 'new'\n\n const t = useT()\n const [cpqQuote, setCpqQuote] = React.useState<QuoteResult | null>(null)\n const grantedFeatures = useGrantedFeatures([QUOTE_MANAGE_FEATURE, ADJUST_PRICE_FEATURE])\n const [loading, setLoading] = React.useState(true)\n const [error, setError] = React.useState<string | null>(null)\n const [submitting, setSubmitting] = React.useState(false)\n\n // Configurator state\n const [view, setView] = React.useState<'summary' | 'add-offering' | 'configure' | 'edit'>('summary')\n const [offerings, setOfferings] = React.useState<Offering[]>([])\n const [offeringsLoading, setOfferingsLoading] = React.useState(false)\n const [offeringSearch, setOfferingSearch] = React.useState('')\n const [selectedOffering, setSelectedOffering] = React.useState<Offering | null>(null)\n const [attributes, setAttributes] = React.useState<ConstrainedAttribute[]>([])\n const [config, setConfig] = React.useState<Record<string, unknown>>({})\n const [quantity, setQuantity] = React.useState(1)\n const [editingLineId, setEditingLineId] = React.useState<string | null>(null)\n const [addingToParentLineId, setAddingToParentLineId] = React.useState<string | null>(null)\n // XD-250 multi-target ARC: when adding a top-level offering operator can\n // pick 1..N target subs (default = all) and we fire one POST per target.\n // For \"Add Component\" to a bundle, this is forced to a single id (the\n // parent line's target) since a bundle component must follow its bundle.\n const [addingTargetSubIds, setAddingTargetSubIds] = React.useState<string[]>([])\n const [expandedLines, setExpandedLines] = React.useState<Set<string>>(new Set())\n const [converting, setConverting] = React.useState(false)\n const [transitioning, setTransitioning] = React.useState(false)\n const [deleting, setDeleting] = React.useState(false)\n const [showDeleteConfirm, setShowDeleteConfirm] = React.useState(false)\n const [pricingDetail, setPricingDetail] = React.useState<{ lineIdx: number; chargeIdx: number } | null>(null)\n\n // \u2500\u2500\u2500 XD-250 ARC state \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const [arcTargets, setArcTargets] = React.useState<AttachedTarget[]>([])\n const [arcQuoteType, setArcQuoteType] = React.useState<'new' | 'amend' | 'renew' | 'cancel'>('new')\n const [arcDrawerOpen, setArcDrawerOpen] = React.useState(false)\n\n const loadArcTargets = React.useCallback(async () => {\n try {\n const res = await fetch(`/api/cpq/quotes/${cpqConfigId}/target-subscriptions`)\n if (!res.ok) return\n const data = await res.json()\n const items: AttachedTarget[] = data.items ?? []\n setArcTargets(items)\n if (items.length > 0) {\n setArcQuoteType(items[0].quoteType as 'amend' | 'renew' | 'cancel')\n } else {\n setArcQuoteType('new')\n }\n } catch {\n // best-effort \u2014 non-ARC quotes have no targets, that's fine.\n }\n }, [cpqConfigId])\n\n React.useEffect(() => {\n if (!cpqConfigId || isNew) return\n void loadArcTargets()\n }, [cpqConfigId, isNew, loadArcTargets])\n\n // \u2500\u2500\u2500 Negotiated prices \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const reloadQuote = React.useCallback(async () => {\n try {\n setCpqQuote(await apiJson<QuoteResult>(t, `/api/cpq/quotes/${cpqConfigId}`))\n } catch (err) {\n setError((err as Error).message)\n }\n }, [cpqConfigId, t])\n const priceAdjustments = usePriceAdjustments<QuoteResult>({\n quote: isNew ? null : cpqQuote,\n quoteType: arcQuoteType,\n canAdjust: grantedFeatures.includes(QUOTE_MANAGE_FEATURE) && grantedFeatures.includes(ADJUST_PRICE_FEATURE),\n onQuote: setCpqQuote,\n reloadQuote,\n })\n\n // \u2500\u2500\u2500 Load or create \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n React.useEffect(() => {\n if (isNew) {\n // Create new CPQ quote from query params\n const quoteId = searchParams.get('quoteId')\n const customerId = searchParams.get('customerId')\n if (!customerId) {\n setError(t('cpq.quotes.detail.customerIdRequired', 'customerId is required to create a CPQ quote'))\n setLoading(false)\n return\n }\n async function create() {\n try {\n const body: Record<string, string> = { customerId: customerId! }\n if (quoteId) body.quoteId = quoteId\n const result = await apiJson<QuoteResult>(t, '/api/cpq/quotes', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n })\n router.replace(`/backend/cpq/quotes/${result.id}`)\n } catch (err) {\n setError((err as Error).message)\n setLoading(false)\n }\n }\n create()\n return\n }\n\n let cancelled = false\n async function load() {\n try {\n const result = await apiJson<QuoteResult>(t, `/api/cpq/quotes/${cpqConfigId}`)\n if (!cancelled) setCpqQuote(result)\n } catch (err) {\n if (!cancelled) setError((err as Error).message)\n } finally {\n if (!cancelled) setLoading(false)\n }\n }\n load()\n return () => { cancelled = true }\n }, [cpqConfigId, isNew, searchParams, router, t])\n\n // \u2500\u2500\u2500 Actions \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const loadOfferings = async () => {\n setOfferingsLoading(true)\n try {\n const result = await apiJson<{ items: Offering[] }>(t, '/api/cpq/product-offerings?pageSize=100&lifecycleStatus=active')\n setOfferings(result.items ?? [])\n } catch { setOfferings([]) }\n finally { setOfferingsLoading(false) }\n }\n\n const loadAttributes = async (offeringId: string, currentConfig: Record<string, unknown> = {}) => {\n try {\n const params = new URLSearchParams({ offeringId })\n if (Object.keys(currentConfig).length > 0) params.set('configuration', JSON.stringify(currentConfig))\n const result = await apiJson<{ attributes: ConstrainedAttribute[] }>(t, `/api/cpq/quotes/attributes?${params}`)\n setAttributes(result.attributes ?? [])\n } catch { setAttributes([]) }\n }\n\n const addItem = async () => {\n if (!cpqQuote || !selectedOffering) return\n try {\n setSubmitting(true); setError(null)\n // XD-250 multi-target ARC: when \u22652 targets selected, fire one POST per\n // target \u2014 backend creates one line per request, each tagged with its\n // own targetSubscriptionId. Single target / non-ARC quote: list is\n // empty or 1-elem, we just do one POST and let the server auto-inherit.\n const targetsToPost = addingTargetSubIds.length > 0 ? addingTargetSubIds : [null]\n let lastResult: QuoteResult | null = null\n for (const tid of targetsToPost) {\n const body: Record<string, unknown> = { offeringId: selectedOffering.id, configuration: config, quantity }\n if (addingToParentLineId) body.parentLineId = addingToParentLineId\n if (tid) body.targetSubscriptionId = tid\n lastResult = await apiJson<QuoteResult>(t, `/api/cpq/quotes/${cpqQuote.id}/items`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n })\n }\n if (lastResult) setCpqQuote(lastResult)\n resetConfigState()\n setView('summary')\n } catch (err) { setError((err as Error).message) }\n finally { setSubmitting(false) }\n }\n\n const updateItem = async (lineId: string) => {\n if (!cpqQuote) return\n try {\n setSubmitting(true); setError(null)\n const result = await apiJson<QuoteResult>(t, `/api/cpq/quotes/${cpqQuote.id}/items/${lineId}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ configuration: config, quantity }),\n })\n setCpqQuote(result)\n resetConfigState()\n setView('summary')\n } catch (err) { setError((err as Error).message) }\n finally { setSubmitting(false) }\n }\n\n // Amend / Renew: removing an existing subscription item confirms first and\n // marks it for removal (a `cancel` line) instead of deleting the line.\n const lineRemoval = useArcLineRemoval<QuoteResult>({\n quote: isNew ? null : cpqQuote,\n quoteType: arcQuoteType,\n onQuote: setCpqQuote,\n onError: setError,\n })\n const removeItem = lineRemoval.remove\n\n const recalculate = async () => {\n if (!cpqQuote) return\n try {\n setSubmitting(true); setError(null)\n const result = await apiJson<QuoteResult>(t, `/api/cpq/quotes/${cpqQuote.id}/recalculate`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ save: true }),\n })\n setCpqQuote(result)\n } catch (err) { setError((err as Error).message) }\n finally { setSubmitting(false) }\n }\n\n const convertToOrder = async () => {\n if (!cpqQuote) return\n try {\n setConverting(true); setError(null)\n const result = await apiJson<{ id: string }>(t, '/api/cpq/orders', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ quoteId: cpqQuote.id }),\n })\n router.push(`/backend/cpq/orders/${result.id}`)\n } catch (err) { setError((err as Error).message) }\n finally { setConverting(false) }\n }\n\n const transitionStatus = async (targetStatus: string) => {\n if (!cpqQuote) return\n try {\n setTransitioning(true); setError(null)\n const result = await apiJson<QuoteResult>(t, `/api/cpq/quotes/${cpqQuote.id}/status`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ targetStatus }),\n })\n setCpqQuote(result)\n } catch (err) { setError((err as Error).message) }\n finally { setTransitioning(false) }\n }\n\n const deleteQuote = async () => {\n if (!cpqQuote) return\n try {\n setDeleting(true); setError(null); setShowDeleteConfirm(false)\n await apiJson<{ ok: boolean }>(t, `/api/cpq/quotes/${cpqQuote.id}`, { method: 'DELETE' })\n router.push('/backend/cpq/quotes')\n } catch (err) { setError((err as Error).message) }\n finally { setDeleting(false) }\n }\n\n const resetConfigState = () => {\n setSelectedOffering(null)\n setAttributes([])\n setConfig({})\n setQuantity(1)\n setEditingLineId(null)\n setAddingToParentLineId(null)\n }\n\n const startAddOffering = () => {\n resetConfigState()\n // Default: apply to all attached targets (operator can uncheck in the picker).\n setAddingTargetSubIds(arcTargets.map((t) => t.subscriptionId))\n loadOfferings()\n setView('add-offering')\n }\n\n const startAddComponent = async (parentLineId: string, offeringId?: string) => {\n setSelectedOffering(null)\n setAttributes([])\n setConfig({})\n setQuantity(1)\n setEditingLineId(null)\n setAddingToParentLineId(parentLineId)\n // Inherit the parent line's target so a bundle component lands on the\n // same subscription as its parent (XD-250 multi-target ARC). For\n // components there's no choice \u2014 bundle \u2194 component must agree.\n const parent = cpqQuote?.lines.find((l) => l.lineId === parentLineId)\n const inherited = parent?.targetSubscriptionId ?? arcTargets[0]?.subscriptionId\n setAddingTargetSubIds(inherited ? [inherited] : [])\n if (offeringId) {\n try {\n const result = await apiJson<{ items: Offering[] }>(t, '/api/cpq/product-offerings?pageSize=100&lifecycleStatus=active')\n const match = (result.items ?? []).find((o) => o.id === offeringId)\n if (match) {\n selectOffering(match)\n return\n }\n } catch { /* fall through to browser */ }\n }\n loadOfferings()\n setView('add-offering')\n }\n\n const selectOffering = (o: Offering) => {\n setSelectedOffering(o); setConfig({}); setQuantity(1)\n loadAttributes(o.id)\n setView('configure')\n }\n\n const startEditLine = (line: QuoteLine) => {\n setEditingLineId(line.lineId)\n setConfig(line.configuration ?? {})\n setQuantity(line.quantity)\n if (line.offeringId) loadAttributes(line.offeringId, line.configuration ?? {})\n setView('edit')\n }\n\n const toggleLine = (id: string) => {\n setExpandedLines((prev) => { const n = new Set(prev); n.has(id) ? n.delete(id) : n.add(id); return n })\n }\n\n // \u2500\u2500\u2500 Render: loading / error \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n if (loading) {\n return (\n <div className=\"flex items-center gap-2 py-12 justify-center text-sm text-muted-foreground\">\n <Spinner /> {t('cpq.quotes.detail.loading', 'Loading\u2026')}\n </div>\n )\n }\n\n if (!cpqQuote) {\n return (\n <div className=\"space-y-4\">\n <button onClick={() => router.push('/backend/cpq/quotes')} className=\"text-sm text-muted-foreground hover:text-foreground\">{t('cpq.quotes.detail.backToQuotes', '\u2190 Back to Quotes')}</button>\n {error && <ErrorBanner message={error} />}\n <div className=\"rounded-lg border bg-card p-6 text-center text-sm text-muted-foreground\">{t('cpq.quotes.detail.notFound', 'Quote not found.')}</div>\n </div>\n )\n }\n\n // \u2500\u2500\u2500 Render: detail \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const { pricingSummary: summary, currencyCode: currency } = cpqQuote\n const arcDelta = arcQuoteType === 'amend' || arcQuoteType === 'renew' ? arcRecurringDelta(cpqQuote.lines) : null\n\n const arcEditable = ['new', 'incomplete', 'ready'].includes(cpqQuote.cpqStatus)\n const isMergeRenew =\n arcQuoteType === 'renew' &&\n arcTargets.length >= 2 &&\n arcTargets.every((t) => t.mergeAction === 'absorb')\n\n // XD-250 multi-target ARC: map subscriptionId \u2192 friendly code (e.g. SUB-...).\n // Used for the per-line target badge so the operator can see which sub each\n // line acts on; only meaningful when there are 2+ targets. Plain map (not\n // useMemo) because this whole block is after the loading / not-found early\n // returns \u2014 adding a hook here would violate Rules of Hooks. Tiny N (count\n // of attached ARC targets) so re-building per render is fine.\n const arcTargetCodeMap = new Map<string, string>()\n for (const t of arcTargets) {\n if (t.subscription?.code) arcTargetCodeMap.set(t.subscriptionId, t.subscription.code)\n }\n\n return (\n <PriceAdjustmentProvider value={priceAdjustments.ui}>\n <ArcLineRemovalProvider value={lineRemoval.ui}>\n <div className=\"space-y-6\">\n {priceAdjustments.elements}\n {lineRemoval.ConfirmDialogElement}\n {arcDrawerOpen && (\n <ArcQuoteConfigurator\n quoteId={cpqQuote.id}\n customerId={cpqQuote.customerId}\n customerName={cpqQuote.customerName}\n currencyCode={cpqQuote.currencyCode}\n initialType={arcQuoteType}\n initialTargets={arcTargets}\n editable={arcEditable}\n onClose={() => setArcDrawerOpen(false)}\n onChanged={async () => {\n await loadArcTargets()\n // Drawer attached / detached targets \u2014 backend may have mirrored\n // items from new targets (XD-250 multi-target ARC), so refetch\n // the full quote to pick up the new lines without a hard refresh.\n try {\n const fresh = await apiJson<QuoteResult>(t, `/api/cpq/quotes/${cpqQuote.id}`)\n setCpqQuote(fresh)\n } catch {\n /* ignore \u2014 loadArcTargets already surfaced any error */\n }\n }}\n />\n )}\n {/* Header \u2014 uses the standard Open Mercato `FormHeader mode=\"detail\"`\n so CPQ matches the rest of the admin. Title is just the quote\n number (no \"Quote \u2026\" prefix); badges sit underneath; secondary\n context (customer / version / currency) lives in dedicated meta\n cards below the header, not in a thin meta line. */}\n <FormHeader\n mode=\"detail\"\n backHref=\"/backend/cpq/quotes\"\n backLabel={t('cpq.quotes.detail.backLabel', 'Back to CPQ Quotes')}\n entityTypeLabel={t('cpq.quotes.detail.entityType', 'CPQ Quote')}\n title={cpqQuote.quoteNumber || cpqQuote.customerName || t('cpq.quotes.detail.untitled', 'Untitled')}\n statusBadge={\n <div className=\"flex flex-wrap items-center gap-2 pt-1\">\n <Tag variant={quoteCpqStatusMap[cpqQuote.cpqStatus as QuoteCpqStatus] ?? 'neutral'} dot>\n {formatStatusLabel(cpqQuote.cpqStatus)}\n </Tag>\n {arcQuoteType !== 'new' && (\n <Tag variant=\"brand\" className=\"uppercase\">{quoteTypeLabel(t, arcQuoteType)}</Tag>\n )}\n {cpqQuote.convertedOrderId && <Tag variant=\"success\" dot>{t('cpq.quotes.detail.converted', 'Converted')}</Tag>}\n </div>\n }\n // FormHeader.detail ignores `utilityActions` whenever `actionsContent`\n // is set, so we render the \"View Sales Quote\" link inline alongside\n // the primary actions to keep it visible.\n actionsContent={\n <>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={() => router.push(`/backend/sales/quotes/${cpqQuote.quoteId}`)}\n >\n <ExternalLink className=\"h-3.5 w-3.5\" />\n {t('cpq.quotes.detail.viewSalesQuote', 'View Sales Quote')}\n </Button>\n {cpqQuote.convertedOrderId ? (\n <Button\n type=\"button\"\n onClick={() => router.push(`/backend/cpq/orders/${cpqQuote.convertedOrderId}`)}\n >\n <ArrowRight className=\"h-4 w-4\" />\n {t('cpq.quotes.detail.goToOrder', 'Go to order')}\n </Button>\n ) : view !== 'summary' ? (\n <Button type=\"button\" variant=\"outline\" onClick={() => { resetConfigState(); setView('summary') }}>\n {t('cpq.common.cancel', 'Cancel')}\n </Button>\n ) : (\n <>\n <Button type=\"button\" onClick={startAddOffering}>\n <Plus className=\"h-4 w-4\" />\n {t('cpq.quotes.detail.addOffering', 'Add Offering')}\n </Button>\n {arcEditable && (\n <Button type=\"button\" variant=\"outline\" onClick={() => setArcDrawerOpen(true)}>\n {t('cpq.quotes.detail.modifySubscription', 'Modify Subscription')}\n </Button>\n )}\n {cpqQuote.cpqStatus === 'accepted' && (\n <Button type=\"button\" onClick={convertToOrder} disabled={converting}>\n {converting ? <Spinner /> : <ArrowRight className=\"h-4 w-4\" />}\n {t('cpq.quotes.detail.convertToOrder', 'Convert to Order')}\n </Button>\n )}\n <MoreActionsDropdown\n items={buildMoreActions({\n t,\n recalculate,\n canRecalculate: canRecalculateQuote(grantedFeatures, cpqQuote.cpqStatus),\n submitting,\n deletable: !['accepted', 'rejected', 'cancelled'].includes(cpqQuote.cpqStatus),\n onDelete: () => setShowDeleteConfirm(true),\n deleting,\n })}\n />\n </>\n )}\n </>\n }\n />\n\n {/* Per user feedback, order below the FormHeader is:\n 1. Status path (operator-facing lifecycle nav)\n 2. ARC info (amend/renew/cancel banner with targets)\n 3. Customer / Version / Currency meta cards\n 4. Pricing summary + line items (further down in the page)\n Status path and ARC info are higher because they describe what\n the user is *doing*; the meta cards are reference info. */}\n\n {/* Status path \u2014 every step is clickable so the operator can move\n between any pair of statuses. Backend enforces ARC-specific\n guards (validateArcQuote on submit-for-approval) but no longer\n gates simple transitions. */}\n <div className=\"flex items-center gap-3 flex-wrap\">\n <StatusPath\n // Per product decision the quote status path lets the operator\n // jump between any pair of statuses, so `allowedTransitions` is\n // omitted \u2014 backend validates ARC-specific guards.\n // `pre_approved` aliases into the `approved` slot for layout.\n current={cpqQuote.cpqStatus}\n path={\n cpqQuote.cpqStatus === 'pre_approved'\n ? ['new', 'incomplete', 'ready', 'in_approval', 'pre_approved', 'with_customer', 'accepted']\n : ['new', 'incomplete', 'ready', 'in_approval', 'approved', 'with_customer', 'accepted']\n }\n terminals={['rejected', 'cancelled']}\n statusMap={quoteCpqStatusMap}\n onTransition={transitionStatus}\n disabled={transitioning}\n ariaLabel={t('cpq.quotes.detail.statusPath', 'Quote status path')}\n />\n {transitioning && <Spinner />}\n </div>\n\n {error && <ErrorBanner message={error} onDismiss={() => setError(null)} />}\n\n {arcQuoteType !== 'new' && arcTargets.length > 0 && (\n <div className=\"rounded-md border border-brand-violet/30 bg-brand-violet/10 px-4 py-3 text-sm text-brand-violet\">\n <div className=\"flex items-center justify-between\">\n <div>\n <span className=\"font-medium uppercase\">{quoteTypeLabel(t, arcQuoteType)}</span>\n {' \u2022 '}\n {arcTargets.length === 1\n ? t('cpq.quotes.detail.arcTargets.one', '{count} target:', { count: arcTargets.length })\n : t('cpq.quotes.detail.arcTargets.other', '{count} targets:', { count: arcTargets.length })}\n {' '}\n {arcTargets.map((t, i) => (\n <span key={t.id}>\n {i > 0 && ', '}\n <button\n onClick={() =>\n router.push(`/backend/cpq/inventory/subscriptions/${t.subscriptionId}`)\n }\n className=\"text-brand-violet hover:underline\"\n >\n {t.subscription?.code ?? t.subscriptionId.slice(0, 8)}\n </button>\n </span>\n ))}\n {isMergeRenew && (\n <span className=\"ml-2 text-status-warning-text font-medium\">\n {t('cpq.quotes.detail.mergingRenew', '\u2022 Merging into a new contract')}\n </span>\n )}\n </div>\n </div>\n </div>\n )}\n\n {/* Meta cards \u2014 secondary reference info (customer, version,\n currency). Mirrors the sidebar tiles in the standard\n sales-document detail layout. */}\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3\">\n <MetaCard label={t('cpq.quotes.detail.meta.customer', 'Customer')}>\n {cpqQuote.customerName ? (\n <span className=\"font-medium\">{cpqQuote.customerName}</span>\n ) : (\n <span className=\"font-mono text-xs text-muted-foreground\">\n {cpqQuote.customerId.slice(0, 8)}\u2026\n </span>\n )}\n </MetaCard>\n <MetaCard label={t('cpq.quotes.detail.meta.version', 'Version')}>\n <span className=\"font-medium\">v{cpqQuote.version}</span>\n </MetaCard>\n <MetaCard label={t('cpq.quotes.detail.meta.currency', 'Currency')}>\n <span className=\"font-medium\">{currency}</span>\n </MetaCard>\n </div>\n\n {showDeleteConfirm && (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center bg-black/50\" onClick={() => setShowDeleteConfirm(false)}>\n <div className=\"w-full max-w-sm rounded-lg border bg-card shadow-xl\" onClick={(e) => e.stopPropagation()}>\n <div className=\"px-4 py-3 border-b\">\n <h3 className=\"text-sm font-medium\">{t('cpq.quotes.detail.deleteConfirm.title', 'Delete Quote')}</h3>\n </div>\n <div className=\"p-4\">\n <p className=\"text-sm text-muted-foreground\">{t('cpq.quotes.detail.deleteConfirm.text', 'Are you sure you want to delete this quote? This will soft-delete the quote and all its line items.')}</p>\n </div>\n <div className=\"flex justify-end gap-2 px-4 py-3 border-t\">\n <Button type=\"button\" variant=\"outline\" onClick={() => setShowDeleteConfirm(false)}>\n {t('cpq.common.cancel', 'Cancel')}\n </Button>\n <Button type=\"button\" variant=\"destructive\" onClick={deleteQuote} disabled={deleting}>\n {deleting ? <Spinner /> : null} {t('cpq.common.delete', 'Delete')}\n </Button>\n </div>\n </div>\n </div>\n )}\n\n {/* Summary view */}\n {view === 'summary' && (\n <>\n <PricingSummaryCard summary={summary} currency={currency} arcDelta={arcDelta} />\n\n {/* Validation errors */}\n {!cpqQuote.validationResult.valid && (\n <Alert variant=\"warning\">\n <AlertTitle>{t('cpq.quotes.detail.validationIssues', 'Validation Issues')}</AlertTitle>\n <AlertDescription>\n {/* Stacked <span>s rather than <ul>/<li>: before Open Mercato\n 0.8 AlertDescription rendered a <p>, where a list is invalid\n HTML and a Next 16 hydration error. It is a <div> now, so a\n list would be fine; the spans are kept as harmless. */}\n <span className=\"text-xs space-y-0.5 block\">\n {cpqQuote.validationResult.errors.map((e, i) => (\n <span key={i} className=\"block\">\u2014 {e.message}</span>\n ))}\n </span>\n </AlertDescription>\n </Alert>\n )}\n\n {/* Amend lines the rep reconfigured are re-priced at today's catalog\n price (server marks them `_arcRepriced`); negotiated prices are\n not carried over yet (later release). */}\n {arcQuoteType === 'amend' && cpqQuote.lines.some((l) => l.action !== 'cancel' && l.configuration?._arcRepriced === true) && (\n <Alert status=\"information\" style=\"lighter\">\n <AlertTitle>\n {t('cpq.quotes.arc.repricedTitle', 'Some existing items use the current catalog price')}\n </AlertTitle>\n <AlertDescription>\n {t(\n 'cpq.quotes.arc.repricedDescription',\n \"Reconfigured lines were re-priced at today's catalog price. Negotiated prices from the subscription are not carried over to reconfigured lines yet.\",\n )}\n </AlertDescription>\n </Alert>\n )}\n\n {/* Quote Lines */}\n <QuoteLineTree\n lines={cpqQuote.lines}\n currency={currency}\n expandedLines={expandedLines}\n pricingDetail={pricingDetail}\n targetCodes={arcTargetCodeMap}\n onToggleLine={toggleLine}\n onEditLine={startEditLine}\n onRemoveLine={removeItem}\n onAddComponent={startAddComponent}\n onTogglePricingDetail={(lineIdx, chargeIdx) =>\n setPricingDetail(\n pricingDetail?.lineIdx === lineIdx && pricingDetail?.chargeIdx === chargeIdx\n ? null\n : { lineIdx, chargeIdx },\n )\n }\n />\n\n <PriceAdjustmentsPanel\n quoteId={cpqQuote.id}\n items={priceAdjustments.items}\n total={priceAdjustments.total}\n lines={cpqQuote.lines}\n currency={currency}\n errorsById={priceAdjustments.errorsById}\n />\n </>\n )}\n\n {/* Add offering \u2014 browse */}\n {view === 'add-offering' && (\n <>\n {addingToParentLineId && (\n <Alert variant=\"info\">\n {t('cpq.quotes.detail.addingComponentTo', 'Adding component to bundle:')}{' '}\n <span className=\"font-medium\">{cpqQuote.lines.find((l) => l.lineId === addingToParentLineId)?.offeringName ?? t('cpq.quotes.detail.bundleFallback', 'Bundle')}</span>\n </Alert>\n )}\n <OfferingBrowser\n offerings={offerings}\n loading={offeringsLoading}\n search={offeringSearch}\n onSearchChange={setOfferingSearch}\n onSelect={selectOffering}\n />\n </>\n )}\n\n {/* Configure new offering */}\n {view === 'configure' && selectedOffering && (\n <ConfigurePanel\n title={\n addingToParentLineId\n ? t('cpq.quotes.detail.configure.addComponentTitle', 'Add Component: {name}', { name: selectedOffering.name })\n : t('cpq.quotes.detail.configure.configureTitle', 'Configure: {name}', { name: selectedOffering.name })\n }\n attributes={attributes}\n config={config}\n quantity={quantity}\n arcTargetOptions={\n arcTargets.length >= 2 && !addingToParentLineId\n ? arcTargets.map((t) => ({\n subscriptionId: t.subscriptionId,\n code: t.subscription?.code ?? t.subscriptionId.slice(0, 8),\n name: t.subscription?.name ?? null,\n }))\n : null\n }\n arcSelectedTargetIds={addingTargetSubIds}\n onArcTargetToggle={(subId) => {\n setAddingTargetSubIds((prev) =>\n prev.includes(subId) ? prev.filter((id) => id !== subId) : [...prev, subId],\n )\n }}\n onConfigChange={(key, value) => {\n const next = { ...config, [key]: value }\n setConfig(next)\n if (selectedOffering) loadAttributes(selectedOffering.id, next)\n }}\n onQuantityChange={setQuantity}\n onSubmit={addItem}\n submitLabel={t('cpq.quotes.detail.configure.addToQuote', 'Add to Quote')}\n submitting={submitting}\n />\n )}\n\n {/* Edit existing line */}\n {view === 'edit' && editingLineId && (\n <ConfigurePanel\n title={t('cpq.quotes.detail.configure.editTitle', 'Edit: {name}', {\n name: cpqQuote.lines.find((l) => l.lineId === editingLineId)?.offeringName ?? t('cpq.quotes.detail.configure.lineFallback', 'Line'),\n })}\n attributes={attributes}\n config={config}\n quantity={quantity}\n arcTargetOptions={null}\n arcSelectedTargetIds={[]}\n onArcTargetToggle={() => {}}\n onConfigChange={(key, value) => {\n const next = { ...config, [key]: value }\n setConfig(next)\n const line = cpqQuote.lines.find((l) => l.lineId === editingLineId)\n if (line?.offeringId) loadAttributes(line.offeringId, next)\n }}\n onQuantityChange={setQuantity}\n onSubmit={() => updateItem(editingLineId)}\n submitLabel={t('cpq.quotes.detail.configure.updateLine', 'Update Line')}\n submitting={submitting}\n />\n )}\n </div>\n </ArcLineRemovalProvider>\n </PriceAdjustmentProvider>\n )\n}\n\n// \u2500\u2500\u2500 Sub-components \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction QuoteLineTree({ lines, currency, expandedLines, pricingDetail, targetCodes, onToggleLine, onEditLine, onRemoveLine, onAddComponent, onTogglePricingDetail }: {\n lines: QuoteLine[]; currency: string; expandedLines: Set<string>\n pricingDetail: { lineIdx: number; chargeIdx: number } | null\n targetCodes: Map<string, string>\n onToggleLine: (id: string) => void; onEditLine: (line: QuoteLine) => void\n onRemoveLine: (lineId: string) => void; onAddComponent: (parentLineId: string, offeringId?: string) => void\n onTogglePricingDetail: (lineIdx: number, chargeIdx: number) => void\n}) {\n const t = useT()\n const [bundleTrees, setBundleTrees] = React.useState<Map<string, BundleTree>>(new Map())\n const [loadingTrees, setLoadingTrees] = React.useState<Set<string>>(new Set())\n\n const rootLines = lines.filter((l) => !l.parentLineId)\n const childrenByParent = new Map<string, QuoteLine[]>()\n for (const line of lines) {\n if (line.parentLineId) {\n const arr = childrenByParent.get(line.parentLineId) ?? []\n arr.push(line)\n childrenByParent.set(line.parentLineId, arr)\n }\n }\n\n const fetchBundleTree = React.useCallback(async (offeringId: string) => {\n if (bundleTrees.has(offeringId) || loadingTrees.has(offeringId)) return\n setLoadingTrees((prev) => new Set(prev).add(offeringId))\n try {\n const result = await apiJson<{ tree: BundleTree }>(t, `/api/cpq/bundle-tree?offeringId=${offeringId}`)\n setBundleTrees((prev) => new Map(prev).set(offeringId, result.tree))\n } catch { /* ignore \u2014 will just not show structure */ }\n finally { setLoadingTrees((prev) => { const n = new Set(prev); n.delete(offeringId); return n }) }\n }, [bundleTrees, loadingTrees, t])\n\n return (\n <div>\n <h3 className=\"text-sm font-medium mb-2 px-1\">{t('cpq.quotes.detail.lineItems', 'Line Items')}</h3>\n {lines.length === 0 ? (\n <div className=\"rounded-lg border bg-card py-8 text-center text-sm text-muted-foreground\">\n {t('cpq.quotes.detail.noLines', 'No items configured yet. Click \"Add Offering\" to start.')}\n </div>\n ) : (\n <div className=\"rounded-lg border bg-card divide-y\">\n {rootLines.map((line) => {\n const lineIdx = lines.indexOf(line)\n const isBundle = line.offeringType === 'bundle'\n const children = childrenByParent.get(line.lineId) ?? []\n const isExpanded = expandedLines.has(line.lineId)\n const bundleTree = isBundle && line.offeringId ? bundleTrees.get(line.offeringId) : undefined\n const treeLoading = isBundle && line.offeringId ? loadingTrees.has(line.offeringId) : false\n\n if (isBundle && isExpanded && line.offeringId && !bundleTree && !treeLoading) {\n fetchBundleTree(line.offeringId)\n }\n\n return (\n <div key={line.lineId}>\n <QuoteLineRow\n line={line} lineIdx={lineIdx} currency={currency}\n isExpanded={isExpanded}\n pricingDetail={pricingDetail} isBundle={isBundle}\n childCount={children.length} indent={0}\n targetCodes={targetCodes}\n onToggle={() => onToggleLine(line.lineId)}\n onEdit={() => onEditLine(line)}\n onRemove={() => onRemoveLine(line.lineId)}\n onAddComponent={isBundle ? () => onAddComponent(line.lineId) : undefined}\n onTogglePricingDetail={onTogglePricingDetail}\n />\n {/* Bundle structure: slots and child lines */}\n {isBundle && isExpanded && (\n <BundleSlotPanel\n bundleTree={bundleTree}\n treeLoading={treeLoading}\n children={children}\n allLines={lines}\n currency={currency}\n expandedLines={expandedLines}\n pricingDetail={pricingDetail}\n parentLineId={line.lineId}\n targetCodes={targetCodes}\n onToggleLine={onToggleLine}\n onEditLine={onEditLine}\n onRemoveLine={onRemoveLine}\n onAddComponent={onAddComponent}\n onTogglePricingDetail={onTogglePricingDetail}\n />\n )}\n </div>\n )\n })}\n </div>\n )}\n </div>\n )\n}\n\nfunction BundleSlotPanel({ bundleTree, treeLoading, children, allLines, currency, expandedLines, pricingDetail, parentLineId, targetCodes, onToggleLine, onEditLine, onRemoveLine, onAddComponent, onTogglePricingDetail }: {\n bundleTree: BundleTree | undefined; treeLoading: boolean\n children: QuoteLine[]; allLines: QuoteLine[]; currency: string\n expandedLines: Set<string>; pricingDetail: { lineIdx: number; chargeIdx: number } | null\n parentLineId: string\n targetCodes: Map<string, string>\n onToggleLine: (id: string) => void; onEditLine: (line: QuoteLine) => void\n onRemoveLine: (lineId: string) => void; onAddComponent: (parentLineId: string, offeringId?: string) => void\n onTogglePricingDetail: (lineIdx: number, chargeIdx: number) => void\n}) {\n const t = useT()\n if (treeLoading) {\n return (\n <div className=\"border-t bg-muted/5 px-8 py-3\">\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\"><Spinner /> {t('cpq.quotes.bundle.loadingStructure', 'Loading bundle structure\u2026')}</div>\n </div>\n )\n }\n\n if (!bundleTree || bundleTree.slots.length === 0) {\n if (children.length === 0) return null\n return (\n <div className=\"border-t bg-muted/5\">\n {children.map((child) => {\n const childIdx = allLines.indexOf(child)\n return (\n <QuoteLineRow\n key={child.lineId}\n line={child} lineIdx={childIdx} currency={currency}\n isExpanded={expandedLines.has(child.lineId)}\n pricingDetail={pricingDetail} isBundle={false}\n childCount={0} indent={1}\n targetCodes={targetCodes}\n onToggle={() => onToggleLine(child.lineId)}\n onEdit={() => onEditLine(child)}\n onRemove={() => onRemoveLine(child.lineId)}\n onTogglePricingDetail={onTogglePricingDetail}\n />\n )\n })}\n </div>\n )\n }\n\n const childOfferingIds = new Set(children.map((c) => c.offeringId).filter(Boolean))\n\n return (\n <div className=\"border-t bg-muted/5\">\n {bundleTree.slots.map((slot) => {\n const filledChildren = children.filter((c) =>\n slot.components.some((comp) => comp.childOffering.offeringId === c.offeringId),\n )\n const filledCount = filledChildren.length\n const isRequired = slot.cardinalityMin > 0\n const isFull = slot.cardinalityMax != null && filledCount >= slot.cardinalityMax\n const canAdd = !isFull\n\n return (\n <div key={slot.slotId} className=\"border-b last:border-b-0\">\n {/* Slot header */}\n <div className=\"flex items-center gap-2 px-6 py-2 bg-muted/20\">\n <span className=\"text-xs font-medium text-muted-foreground uppercase tracking-wide\">{slot.name}</span>\n {isRequired ? (\n <Tag variant=\"warning\" className=\"text-[10px] px-1.5\">{t('cpq.quotes.bundle.slotRequired', 'required')}</Tag>\n ) : (\n <Tag variant=\"neutral\" className=\"text-[10px] px-1.5\">{t('cpq.quotes.bundle.slotOptional', 'optional')}</Tag>\n )}\n <span className=\"text-[10px] text-muted-foreground\">\n {filledCount}/{slot.cardinalityMax ?? '\u221E'}\n {slot.cardinalityMin > 0 && ' '}\n {slot.cardinalityMin > 0 && t('cpq.quotes.bundle.slotMin', '(min {min})', { min: slot.cardinalityMin })}\n </span>\n <div className=\"flex-1\" />\n {/* Available offerings in this slot */}\n <div className=\"flex items-center gap-1\">\n {slot.components.map((comp) => {\n const isFilled = childOfferingIds.has(comp.childOffering.offeringId)\n return (\n <button\n key={comp.componentId}\n onClick={() => !isFilled && canAdd && onAddComponent(parentLineId, comp.childOffering.offeringId)}\n disabled={isFilled || !canAdd}\n className={`inline-flex items-center gap-1 rounded border px-2 py-1 text-[11px] font-medium transition-colors ${\n isFilled\n ? 'border-status-success-border bg-status-success-bg text-status-success-text cursor-default'\n : canAdd\n ? 'border-border hover:border-primary hover:bg-primary/5 hover:text-primary cursor-pointer'\n : 'border-border text-muted-foreground opacity-50 cursor-not-allowed'\n }`}\n title={\n isFilled\n ? t('cpq.quotes.bundle.alreadyAdded', 'Already added')\n : canAdd\n ? t('cpq.quotes.bundle.addComponent', 'Add {name}', { name: comp.childOffering.offeringName })\n : t('cpq.quotes.bundle.slotFull', 'Slot is full')\n }\n >\n {isFilled ? (\n <svg className=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" strokeWidth=\"2\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M4.5 12.75l6 6 9-13.5\" />\n </svg>\n ) : (\n <svg className=\"h-3 w-3\" fill=\"none\" viewBox=\"0 0 24 24\" strokeWidth=\"2\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M12 4.5v15m7.5-7.5h-15\" />\n </svg>\n )}\n {comp.childOffering.offeringName}\n </button>\n )\n })}\n </div>\n </div>\n {/* Filled child lines for this slot */}\n {filledChildren.map((child) => {\n const childIdx = allLines.indexOf(child)\n return (\n <QuoteLineRow\n key={child.lineId}\n line={child} lineIdx={childIdx} currency={currency}\n isExpanded={expandedLines.has(child.lineId)}\n pricingDetail={pricingDetail} isBundle={false}\n childCount={0} indent={1}\n targetCodes={targetCodes}\n onToggle={() => onToggleLine(child.lineId)}\n onEdit={() => onEditLine(child)}\n onRemove={() => onRemoveLine(child.lineId)}\n onTogglePricingDetail={onTogglePricingDetail}\n />\n )\n })}\n </div>\n )\n })}\n {/* Show any child lines not matching any slot */}\n {children.filter((c) => !bundleTree.slots.some((s) => s.components.some((comp) => comp.childOffering.offeringId === c.offeringId))).map((child) => {\n const childIdx = allLines.indexOf(child)\n return (\n <QuoteLineRow\n key={child.lineId}\n line={child} lineIdx={childIdx} currency={currency}\n isExpanded={expandedLines.has(child.lineId)}\n pricingDetail={pricingDetail} isBundle={false}\n childCount={0} indent={1}\n targetCodes={targetCodes}\n onToggle={() => onToggleLine(child.lineId)}\n onEdit={() => onEditLine(child)}\n onRemove={() => onRemoveLine(child.lineId)}\n onTogglePricingDetail={onTogglePricingDetail}\n />\n )\n })}\n </div>\n )\n}\n\nfunction QuoteLineRow({ line, lineIdx, currency, isExpanded, pricingDetail, isBundle, childCount, indent, targetCodes, onToggle, onEdit, onRemove, onAddComponent, onTogglePricingDetail }: {\n line: QuoteLine; lineIdx: number; currency: string; isExpanded: boolean\n pricingDetail: { lineIdx: number; chargeIdx: number } | null\n isBundle: boolean; childCount: number; indent: number\n targetCodes: Map<string, string>\n onToggle: () => void; onEdit: () => void; onRemove: () => void\n onAddComponent?: () => void\n onTogglePricingDetail: (lineIdx: number, chargeIdx: number) => void\n}) {\n const t = useT()\n const adjustmentUi = usePriceAdjustmentUi()\n const removalUi = useArcLineRemovalUi()\n const isRemoved = removalUi?.isRemoved(line) ?? false\n const paddingLeft = indent > 0 ? `${indent * 2 + 1}rem` : undefined\n const chargeActions = {\n reasonLabels: adjustmentUi?.reasonLabels,\n renderChargeActions: (charge: ResolvedCharge) => <AdjustChargeAction line={line} charge={charge} />,\n renderManualActions: (adjustmentId: string) => <ManualAdjustmentActions adjustmentId={adjustmentId} />,\n }\n\n return (\n <div>\n <div className={`flex items-center gap-3 px-4 py-3 hover:bg-muted/30 transition-colors ${isRemoved ? 'bg-muted/20' : ''}`} style={paddingLeft ? { paddingLeft } : undefined} data-testid=\"cpq-quote-line\" data-removed={isRemoved ? 'true' : undefined}>\n {/* Expand toggle */}\n <button onClick={onToggle} className=\"flex h-5 w-5 shrink-0 items-center justify-center rounded text-muted-foreground hover:text-foreground\">\n <svg className={`h-4 w-4 transition-transform ${isExpanded ? 'rotate-90' : ''}`} fill=\"none\" viewBox=\"0 0 24 24\" strokeWidth=\"2\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M8.25 4.5l7.5 7.5-7.5 7.5\" />\n </svg>\n </button>\n\n {/* Line info */}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n {indent > 0 && (\n <span className=\"text-muted-foreground text-xs\">\u2514</span>\n )}\n {isBundle && (\n <Tag variant=\"brand\" className=\"px-1.5 text-xs\">{t('cpq.lines.bundle', 'bundle')}</Tag>\n )}\n <span className={`font-medium text-sm ${isRemoved ? 'text-muted-foreground line-through' : ''}`}>{line.offeringName}</span>\n {line.quantity > 1 && <span className=\"rounded bg-muted px-1.5 py-0.5 text-xs font-medium\">\u00D7{line.quantity}</span>}\n <LineActionBadge\n action={line.action}\n label={isRemoved ? t('cpq.quotes.arc.lineRemoved', 'remove') : undefined}\n title={isRemoved ? t('cpq.quotes.arc.lineRemovedHint', 'This item is cancelled on the subscription when the order is activated') : undefined}\n />\n {!isRemoved && line.configuration?._arcPriceFrozen === true && (\n <Tag\n variant=\"neutral\"\n className=\"px-1.5 text-xs\"\n title={t(\n 'cpq.quotes.arc.priceKeptHint',\n 'Price kept from the subscription \u2014 it changes only if you reconfigure this line',\n )}\n >\n {t('cpq.quotes.arc.priceKept', 'price kept')}\n </Tag>\n )}\n {targetCodes.size >= 2 && line.targetSubscriptionId && targetCodes.get(line.targetSubscriptionId) && (\n <Tag\n variant=\"brand\"\n className=\"px-1.5 text-xs\"\n title={t('cpq.quotes.detail.actsOnSubscription', 'Acts on subscription {code}', { code: targetCodes.get(line.targetSubscriptionId) ?? '' })}\n >\n \u2192 {targetCodes.get(line.targetSubscriptionId)}\n </Tag>\n )}\n {isRemoved ? null : line.isConfigured ? (\n <Tag variant=\"success\" className=\"px-1.5 text-xs\">{t('cpq.quotes.detail.lineConfigured', 'configured')}</Tag>\n ) : (\n <Tag variant=\"warning\" className=\"px-1.5 text-xs\">{t('cpq.quotes.detail.lineIncomplete', 'incomplete')}</Tag>\n )}\n {isBundle && (\n <span className=\"text-xs text-muted-foreground\">\n {childCount !== 1\n ? t('cpq.lines.componentCount.other', '{count} components', { count: childCount })\n : t('cpq.lines.componentCount.one', '{count} component', { count: childCount })}\n </span>\n )}\n </div>\n {line.validationErrors && line.validationErrors.length > 0 && (\n <p className=\"text-xs text-destructive mt-0.5\">{line.validationErrors[0].message}</p>\n )}\n </div>\n\n {/* Pricing */}\n <div className=\"shrink-0 text-right text-xs space-y-0.5\">\n {isRemoved && line.arcSource && line.arcSource.mrcAmount > 0 && (\n <div>\n <span className=\"text-muted-foreground\">{t('cpq.lines.mrc', 'MRC')} </span>\n <span className=\"font-mono text-muted-foreground line-through\">{fmt(line.arcSource.mrcAmount, currency)}</span>\n </div>\n )}\n {line.nrcTotal > 0 && <div><span className=\"text-muted-foreground\">{t('cpq.lines.nrc', 'NRC')} </span><span className=\"font-mono font-medium\">{fmt(line.nrcTotal, currency)}</span></div>}\n {line.mrcTotal > 0 && <div><span className=\"text-muted-foreground\">{t('cpq.lines.mrc', 'MRC')} </span><span className=\"font-mono font-medium\">{fmt(line.mrcTotal, currency)}</span></div>}\n </div>\n\n {/* Actions */}\n {isRemoved ? (\n <div className=\"flex items-center gap-1 shrink-0\">\n <Button\n type=\"button\" variant=\"ghost\" size=\"sm\"\n onClick={() => removalUi?.restore(line.lineId)}\n title={t('cpq.quotes.arc.restoreHint', 'Keep this item on the subscription')}\n data-testid=\"cpq-line-restore\"\n >\n <RotateCcw className=\"h-4 w-4\" />\n {t('cpq.quotes.arc.restore', 'Restore')}\n </Button>\n </div>\n ) : (\n <div className=\"flex items-center gap-1 shrink-0\">\n <DiscountLineAction line={line} />\n {onAddComponent && (\n <button onClick={onAddComponent} className=\"rounded p-1.5 text-muted-foreground hover:text-primary hover:bg-primary/5 transition-colors\" title={t('cpq.quotes.detail.addComponent', 'Add Component')}>\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" strokeWidth=\"1.5\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M12 4.5v15m7.5-7.5h-15\" />\n </svg>\n </button>\n )}\n <button onClick={onEdit} className=\"rounded p-1.5 text-muted-foreground hover:text-foreground hover:bg-muted transition-colors\" title={t('cpq.common.edit', 'Edit')}>\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" strokeWidth=\"1.5\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10\" />\n </svg>\n </button>\n <button onClick={onRemove} className=\"rounded p-1.5 text-muted-foreground hover:text-destructive hover:bg-destructive/10 transition-colors\" title={t('cpq.quotes.detail.removeLine', 'Remove')}>\n <svg className=\"h-4 w-4\" fill=\"none\" viewBox=\"0 0 24 24\" strokeWidth=\"1.5\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0\" />\n </svg>\n </button>\n </div>\n )}\n </div>\n\n {/* Charge breakdown (non-bundle or any expanded line) */}\n {isExpanded && !isBundle && line.charges.length > 0 && (\n <ChargeBreakdown line={line} lineIdx={lineIdx} currency={currency} pricingDetail={pricingDetail} onTogglePricingDetail={onTogglePricingDetail} {...chargeActions} />\n )}\n {/* For bundles: show own charges first, then children are rendered by parent */}\n {isExpanded && isBundle && line.charges.length > 0 && (\n <ChargeBreakdown line={line} lineIdx={lineIdx} currency={currency} pricingDetail={pricingDetail} onTogglePricingDetail={onTogglePricingDetail} {...chargeActions} />\n )}\n {/* XD-250 ARC: before/after preview, below the charges, when line mirrors a sub item */}\n {isExpanded && line.arcSource && (\n <div className=\"border-t bg-muted/10 px-12 py-2\">\n <ArcLineDiff line={line} currency={currency} />\n </div>\n )}\n {/* Fallback: line has no per-charge breakdown and no ARC diff (truly empty) */}\n {isExpanded && line.charges.length === 0 && !line.arcSource && (\n <LineSummaryFallback line={line} currency={currency} />\n )}\n </div>\n )\n}\n\nfunction LineSummaryFallback({ line, currency }: { line: QuoteLine; currency: string }) {\n const t = useT()\n const hasTotals = line.nrcTotal > 0 || line.mrcTotal > 0\n const mirroredFromItemId = (line.configuration?._arcMirroredFromItemId as string | undefined) ?? null\n return (\n <div className=\"border-t bg-muted/10 px-12 py-2 text-xs text-muted-foreground space-y-1\">\n <div>\n {t('cpq.quotes.detail.noBreakdown', 'No detailed charge breakdown available for this line.')}\n {mirroredFromItemId && ' '}\n {mirroredFromItemId && t('cpq.orders.detail.mirroredItem', 'Mirrored from existing subscription item.')}\n </div>\n {hasTotals && (\n <div className=\"flex gap-4\">\n {line.nrcTotal > 0 && (\n <span>{t('cpq.lines.nrc', 'NRC')} <span className=\"font-mono font-medium text-foreground\">{fmt(line.nrcTotal, currency)}</span></span>\n )}\n {line.mrcTotal > 0 && (\n <span>{t('cpq.lines.mrc', 'MRC')} <span className=\"font-mono font-medium text-foreground\">{fmt(line.mrcTotal, currency)}</span></span>\n )}\n </div>\n )}\n </div>\n )\n}\n\nfunction ChargeBreakdown({ line, lineIdx, pricingDetail, onTogglePricingDetail, ...tableProps }: {\n line: QuoteLine; lineIdx: number; currency: string\n pricingDetail: { lineIdx: number; chargeIdx: number } | null\n onTogglePricingDetail: (lineIdx: number, chargeIdx: number) => void\n reasonLabels?: Record<string, string>\n renderChargeActions?: (charge: ResolvedCharge) => React.ReactNode\n renderManualActions?: (adjustmentId: string) => React.ReactNode\n}) {\n return (\n <div className=\"border-t bg-muted/10 px-12 py-2\">\n <ChargeBreakdownTable\n charges={line.charges}\n openDetailIndex={pricingDetail?.lineIdx === lineIdx ? pricingDetail.chargeIdx : null}\n onToggleDetail={(chargeIdx) => onTogglePricingDetail(lineIdx, chargeIdx)}\n {...tableProps}\n />\n </div>\n )\n}\n\nfunction Spinner() {\n return (\n <svg className=\"h-4 w-4 animate-spin\" viewBox=\"0 0 24 24\" fill=\"none\">\n <circle className=\"opacity-25\" cx=\"12\" cy=\"12\" r=\"10\" stroke=\"currentColor\" strokeWidth=\"4\" />\n <path className=\"opacity-75\" fill=\"currentColor\" d=\"M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z\" />\n </svg>\n )\n}\n\nfunction ErrorBanner({ message, onDismiss }: { message: string; onDismiss?: () => void }) {\n const t = useT()\n return (\n <Alert variant=\"destructive\" className=\"flex items-start gap-2\">\n <span className=\"flex-1\">{message}</span>\n {onDismiss && (\n <button\n onClick={onDismiss}\n className=\"text-destructive/70 hover:text-destructive text-sm font-bold\"\n aria-label={t('cpq.common.dismiss', 'Dismiss')}\n >\n \u00D7\n </button>\n )}\n </Alert>\n )\n}\n\nfunction OfferingBrowser({ offerings, loading, search, onSearchChange, onSelect }: {\n offerings: Offering[]; loading: boolean; search: string; onSearchChange: (v: string) => void; onSelect: (o: Offering) => void\n}) {\n const t = useT()\n const filtered = offerings.filter((o) => {\n if (!search.trim()) return true\n const q = search.toLowerCase()\n return o.name.toLowerCase().includes(q) || o.code.toLowerCase().includes(q) || (o.description ?? '').toLowerCase().includes(q)\n })\n\n return (\n <div className=\"space-y-3\">\n <h3 className=\"text-sm font-medium px-1\">{t('cpq.quotes.offeringBrowser.title', 'Select Product Offering')}</h3>\n <div className=\"relative\">\n <svg className=\"absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground\" fill=\"none\" viewBox=\"0 0 24 24\" strokeWidth=\"2\" stroke=\"currentColor\">\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" d=\"M21 21l-5.197-5.197m0 0A7.5 7.5 0 105.196 5.196a7.5 7.5 0 0010.607 10.607z\" />\n </svg>\n <input type=\"text\" placeholder={t('cpq.quotes.offeringBrowser.searchPlaceholder', 'Search offerings\u2026')} value={search} onChange={(e) => onSearchChange(e.target.value)}\n className=\"w-full rounded-md border bg-background pl-10 pr-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/50\" />\n </div>\n {loading ? (\n <div className=\"flex items-center gap-2 py-8 justify-center text-sm text-muted-foreground\"><Spinner /> {t('cpq.quotes.offeringBrowser.loading', 'Loading offerings\u2026')}</div>\n ) : filtered.length === 0 ? (\n <div className=\"py-8 text-center text-sm text-muted-foreground\">{search ? t('cpq.quotes.offeringBrowser.noMatch', 'No offerings match your search.') : t('cpq.quotes.offeringBrowser.empty', 'No active offerings available.')}</div>\n ) : (\n <div className=\"grid gap-2 sm:grid-cols-2 lg:grid-cols-3\">\n {filtered.map((offering) => (\n <button key={offering.id} onClick={() => onSelect(offering)}\n className=\"rounded-lg border bg-card p-4 text-left hover:border-primary hover:bg-primary/5 transition-colors group\">\n <p className=\"text-sm font-medium group-hover:text-primary transition-colors\">{offering.name}</p>\n <p className=\"text-xs text-muted-foreground font-mono mt-0.5\">{offering.code}</p>\n {offering.description && <p className=\"text-xs text-muted-foreground mt-1 line-clamp-2\">{offering.description}</p>}\n </button>\n ))}\n </div>\n )}\n </div>\n )\n}\n\nfunction ConfigurePanel({ title, attributes, config, quantity, arcTargetOptions, arcSelectedTargetIds, onArcTargetToggle, onConfigChange, onQuantityChange, onSubmit, submitLabel, submitting }: {\n title: string; attributes: ConstrainedAttribute[]; config: Record<string, unknown>; quantity: number\n arcTargetOptions: Array<{ subscriptionId: string; code: string; name: string | null }> | null\n arcSelectedTargetIds: string[]\n onArcTargetToggle: (subId: string) => void\n onConfigChange: (key: string, value: unknown) => void; onQuantityChange: (q: number) => void\n onSubmit: () => void; submitLabel: string; submitting: boolean\n}) {\n const t = useT()\n const noTargetsPicked =\n arcTargetOptions !== null && arcTargetOptions.length > 0 && arcSelectedTargetIds.length === 0\n return (\n <div className=\"rounded-lg border bg-card\">\n <div className=\"border-b px-4 py-3\"><h3 className=\"text-sm font-medium\">{title}</h3></div>\n <div className=\"p-4 space-y-4\">\n {arcTargetOptions && arcTargetOptions.length > 0 && (\n <div>\n <label className=\"block text-sm font-medium mb-1\">\n {t('cpq.quotes.detail.configure.applyToSubscriptions', 'Apply to subscription(s)')}\n <span className=\"text-destructive ml-1\">*</span>\n </label>\n <div className=\"space-y-1.5 rounded-md border bg-background px-3 py-2\">\n {arcTargetOptions.map((opt) => {\n const checked = arcSelectedTargetIds.includes(opt.subscriptionId)\n return (\n <label\n key={opt.subscriptionId}\n className=\"flex items-center gap-2 text-sm cursor-pointer hover:bg-muted/40 rounded px-1 py-0.5\"\n >\n <input\n type=\"checkbox\"\n checked={checked}\n onChange={() => onArcTargetToggle(opt.subscriptionId)}\n className=\"h-4 w-4 rounded border-border\"\n />\n <span className=\"font-mono font-medium\">{opt.code}</span>\n {opt.name && <span className=\"text-muted-foreground\">\u2014 {opt.name}</span>}\n </label>\n )\n })}\n </div>\n <p className=\"text-xs text-muted-foreground mt-1\">\n {t('cpq.quotes.detail.configure.applyToSubscriptionsHint', 'Pick one or more \u2014 a separate line will be created on each selected subscription.')}\n </p>\n {noTargetsPicked && (\n <p className=\"text-xs text-destructive mt-1\">{t('cpq.quotes.detail.configure.selectTarget', 'Select at least one target.')}</p>\n )}\n </div>\n )}\n <div>\n <label className=\"block text-sm font-medium mb-1\">{t('cpq.quotes.detail.configure.quantity', 'Quantity')}</label>\n <NumberInput\n integer\n min={1}\n value={quantity}\n onChange={(n) => onQuantityChange(Math.max(1, n ?? 1))}\n className=\"w-24\"\n />\n </div>\n {attributes.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">{t('cpq.quotes.detail.configure.noAttributes', 'No configurable attributes for this offering.')}</p>\n ) : (\n attributes.map((attr) => <AttributeField key={attr.code} attribute={attr} value={config[attr.code]} onChange={(v) => onConfigChange(attr.code, v)} />)\n )}\n </div>\n <div className=\"border-t px-4 py-3 flex justify-end\">\n <button onClick={onSubmit} disabled={submitting || noTargetsPicked}\n className=\"inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow-sm hover:bg-primary/90 transition-colors disabled:opacity-50\">\n {submitting ? <Spinner /> : null} {submitLabel}\n </button>\n </div>\n </div>\n )\n}\n\nfunction AttributeField({ attribute, value, onChange }: { attribute: ConstrainedAttribute; value: unknown; onChange: (v: unknown) => void }) {\n const t = useT()\n const { code, name, attributeType, isRequired, options, constraints, helpText, defaultValue } = attribute\n const currentValue = value ?? defaultValue ?? ''\n\n return (\n <div>\n <label className=\"block text-sm font-medium mb-1\">\n {name}{isRequired && <span className=\"text-destructive ml-0.5\">*</span>}\n </label>\n {(attributeType === 'select' || attributeType === 'enum') && options && options.length > 0 ? (\n <select value={String(currentValue)} onChange={(e) => onChange(e.target.value)}\n className=\"w-full rounded-md border bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/50\">\n <option value=\"\">{t('cpq.quotes.detail.configure.selectPlaceholder', '\u2014 Select \u2014')}</option>\n {options.map((opt) => <option key={opt.value} value={opt.value}>{opt.label}</option>)}\n </select>\n ) : attributeType === 'boolean' ? (\n <label className=\"flex items-center gap-2\">\n <input type=\"checkbox\" checked={Boolean(currentValue)} onChange={(e) => onChange(e.target.checked)} className=\"rounded border-border\" />\n <span className=\"text-sm text-muted-foreground\">{helpText ?? t('cpq.quotes.detail.configure.enable', 'Enable')}</span>\n </label>\n ) : attributeType === 'number' ? (\n <NumberInput\n value={\n typeof currentValue === 'number'\n ? currentValue\n : currentValue === '' || currentValue == null\n ? null\n : Number(currentValue)\n }\n min={(constraints as Record<string, unknown>)?.min as number | undefined}\n max={(constraints as Record<string, unknown>)?.max as number | undefined}\n onChange={(n) => onChange(n ?? '')}\n />\n ) : (\n <input type=\"text\" value={String(currentValue)} onChange={(e) => onChange(e.target.value)}\n className=\"w-full rounded-md border bg-background px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-primary/50\" />\n )}\n {helpText && attributeType !== 'boolean' && <p className=\"text-xs text-muted-foreground mt-1\">{helpText}</p>}\n </div>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["t"]
7
7
  }