@powerhousedao/service-offering 1.0.0-dev.4 → 1.0.0-dev.5

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 (235) hide show
  1. package/dist/document-models/facet/v1/actions.d.ts +3 -1
  2. package/dist/document-models/facet/v1/actions.d.ts.map +1 -1
  3. package/dist/document-models/facet/v1/gen/controller.d.ts +4 -0
  4. package/dist/document-models/facet/v1/gen/controller.d.ts.map +1 -0
  5. package/dist/document-models/facet/v1/gen/controller.js +3 -0
  6. package/dist/document-models/facet/v1/gen/document-model.d.ts.map +1 -1
  7. package/dist/document-models/facet/v1/gen/document-model.js +31 -7
  8. package/dist/document-models/facet/v1/gen/document-schema.d.ts +6 -6
  9. package/dist/document-models/facet/v1/gen/index.d.ts +1 -0
  10. package/dist/document-models/facet/v1/gen/index.d.ts.map +1 -1
  11. package/dist/document-models/facet/v1/gen/index.js +1 -0
  12. package/dist/document-models/facet/v1/gen/option-management/error.d.ts +27 -1
  13. package/dist/document-models/facet/v1/gen/option-management/error.d.ts.map +1 -1
  14. package/dist/document-models/facet/v1/gen/option-management/error.js +23 -1
  15. package/dist/document-models/facet/v1/gen/ph-factories.js +2 -2
  16. package/dist/document-models/facet/v1/gen/schema/types.d.ts +2 -2
  17. package/dist/document-models/facet/v1/gen/schema/types.d.ts.map +1 -1
  18. package/dist/document-models/facet/v1/gen/schema/zod.js +2 -2
  19. package/dist/document-models/facet/v1/gen/utils.js +2 -2
  20. package/dist/document-models/facet/v1/module.d.ts +1 -1
  21. package/dist/document-models/facet/v1/module.d.ts.map +1 -1
  22. package/dist/document-models/facet/v1/module.js +4 -1
  23. package/dist/document-models/resource-instance/v1/actions.d.ts +4 -1
  24. package/dist/document-models/resource-instance/v1/actions.d.ts.map +1 -1
  25. package/dist/document-models/resource-instance/v1/gen/configuration-management/error.d.ts +34 -1
  26. package/dist/document-models/resource-instance/v1/gen/configuration-management/error.d.ts.map +1 -1
  27. package/dist/document-models/resource-instance/v1/gen/configuration-management/error.js +32 -1
  28. package/dist/document-models/resource-instance/v1/gen/controller.d.ts +4 -0
  29. package/dist/document-models/resource-instance/v1/gen/controller.d.ts.map +1 -0
  30. package/dist/document-models/resource-instance/v1/gen/controller.js +3 -0
  31. package/dist/document-models/resource-instance/v1/gen/document-model.d.ts.map +1 -1
  32. package/dist/document-models/resource-instance/v1/gen/document-model.js +222 -70
  33. package/dist/document-models/resource-instance/v1/gen/document-schema.d.ts +0 -6
  34. package/dist/document-models/resource-instance/v1/gen/document-schema.d.ts.map +1 -1
  35. package/dist/document-models/resource-instance/v1/gen/index.d.ts +1 -0
  36. package/dist/document-models/resource-instance/v1/gen/index.d.ts.map +1 -1
  37. package/dist/document-models/resource-instance/v1/gen/index.js +1 -0
  38. package/dist/document-models/resource-instance/v1/gen/instance-management/actions.d.ts +6 -2
  39. package/dist/document-models/resource-instance/v1/gen/instance-management/actions.d.ts.map +1 -1
  40. package/dist/document-models/resource-instance/v1/gen/instance-management/creators.d.ts +3 -2
  41. package/dist/document-models/resource-instance/v1/gen/instance-management/creators.d.ts.map +1 -1
  42. package/dist/document-models/resource-instance/v1/gen/instance-management/creators.js +2 -1
  43. package/dist/document-models/resource-instance/v1/gen/instance-management/error.d.ts +98 -1
  44. package/dist/document-models/resource-instance/v1/gen/instance-management/error.d.ts.map +1 -1
  45. package/dist/document-models/resource-instance/v1/gen/instance-management/error.js +112 -1
  46. package/dist/document-models/resource-instance/v1/gen/instance-management/operations.d.ts +2 -1
  47. package/dist/document-models/resource-instance/v1/gen/instance-management/operations.d.ts.map +1 -1
  48. package/dist/document-models/resource-instance/v1/gen/ph-factories.d.ts.map +1 -1
  49. package/dist/document-models/resource-instance/v1/gen/ph-factories.js +0 -2
  50. package/dist/document-models/resource-instance/v1/gen/reducer.d.ts.map +1 -1
  51. package/dist/document-models/resource-instance/v1/gen/reducer.js +6 -1
  52. package/dist/document-models/resource-instance/v1/gen/schema/types.d.ts +3 -3
  53. package/dist/document-models/resource-instance/v1/gen/schema/types.d.ts.map +1 -1
  54. package/dist/document-models/resource-instance/v1/gen/schema/zod.d.ts +2 -1
  55. package/dist/document-models/resource-instance/v1/gen/schema/zod.d.ts.map +1 -1
  56. package/dist/document-models/resource-instance/v1/gen/schema/zod.js +5 -3
  57. package/dist/document-models/resource-instance/v1/gen/utils.d.ts.map +1 -1
  58. package/dist/document-models/resource-instance/v1/gen/utils.js +0 -2
  59. package/dist/document-models/resource-instance/v1/module.d.ts +1 -1
  60. package/dist/document-models/resource-instance/v1/module.d.ts.map +1 -1
  61. package/dist/document-models/resource-instance/v1/module.js +4 -1
  62. package/dist/document-models/resource-instance/v1/src/reducers/configuration-management.d.ts.map +1 -1
  63. package/dist/document-models/resource-instance/v1/src/reducers/configuration-management.js +57 -53
  64. package/dist/document-models/resource-instance/v1/src/reducers/instance-management.d.ts.map +1 -1
  65. package/dist/document-models/resource-instance/v1/src/reducers/instance-management.js +57 -21
  66. package/dist/document-models/resource-instance/v1/tests/instance-management.test.js +11 -1
  67. package/dist/document-models/resource-template/v1/actions.d.ts +3 -1
  68. package/dist/document-models/resource-template/v1/actions.d.ts.map +1 -1
  69. package/dist/document-models/resource-template/v1/gen/audience-management/error.d.ts +20 -1
  70. package/dist/document-models/resource-template/v1/gen/audience-management/error.d.ts.map +1 -1
  71. package/dist/document-models/resource-template/v1/gen/audience-management/error.js +16 -1
  72. package/dist/document-models/resource-template/v1/gen/controller.d.ts +4 -0
  73. package/dist/document-models/resource-template/v1/gen/controller.d.ts.map +1 -0
  74. package/dist/document-models/resource-template/v1/gen/controller.js +3 -0
  75. package/dist/document-models/resource-template/v1/gen/document-model.d.ts.map +1 -1
  76. package/dist/document-models/resource-template/v1/gen/document-model.js +207 -89
  77. package/dist/document-models/resource-template/v1/gen/document-schema.d.ts +12 -12
  78. package/dist/document-models/resource-template/v1/gen/facet-targeting/error.d.ts +27 -1
  79. package/dist/document-models/resource-template/v1/gen/facet-targeting/error.d.ts.map +1 -1
  80. package/dist/document-models/resource-template/v1/gen/facet-targeting/error.js +23 -1
  81. package/dist/document-models/resource-template/v1/gen/index.d.ts +1 -0
  82. package/dist/document-models/resource-template/v1/gen/index.d.ts.map +1 -1
  83. package/dist/document-models/resource-template/v1/gen/index.js +1 -0
  84. package/dist/document-models/resource-template/v1/gen/option-group-management/error.d.ts +27 -1
  85. package/dist/document-models/resource-template/v1/gen/option-group-management/error.d.ts.map +1 -1
  86. package/dist/document-models/resource-template/v1/gen/option-group-management/error.js +23 -1
  87. package/dist/document-models/resource-template/v1/gen/ph-factories.js +3 -3
  88. package/dist/document-models/resource-template/v1/gen/schema/types.d.ts +4 -4
  89. package/dist/document-models/resource-template/v1/gen/schema/types.d.ts.map +1 -1
  90. package/dist/document-models/resource-template/v1/gen/schema/zod.js +4 -4
  91. package/dist/document-models/resource-template/v1/gen/service-management/error.d.ts +51 -1
  92. package/dist/document-models/resource-template/v1/gen/service-management/error.d.ts.map +1 -1
  93. package/dist/document-models/resource-template/v1/gen/service-management/error.js +49 -1
  94. package/dist/document-models/resource-template/v1/gen/utils.js +3 -3
  95. package/dist/document-models/resource-template/v1/module.d.ts +1 -1
  96. package/dist/document-models/resource-template/v1/module.d.ts.map +1 -1
  97. package/dist/document-models/resource-template/v1/module.js +4 -1
  98. package/dist/document-models/resource-template/v1/src/reducers/option-group-management.d.ts.map +1 -1
  99. package/dist/document-models/resource-template/v1/src/reducers/option-group-management.js +2 -21
  100. package/dist/document-models/service-offering/v1/actions.d.ts +3 -1
  101. package/dist/document-models/service-offering/v1/actions.d.ts.map +1 -1
  102. package/dist/document-models/service-offering/v1/gen/controller.d.ts +4 -0
  103. package/dist/document-models/service-offering/v1/gen/controller.d.ts.map +1 -0
  104. package/dist/document-models/service-offering/v1/gen/controller.js +3 -0
  105. package/dist/document-models/service-offering/v1/gen/document-model.d.ts.map +1 -1
  106. package/dist/document-models/service-offering/v1/gen/document-model.js +421 -199
  107. package/dist/document-models/service-offering/v1/gen/document-schema.d.ts +9 -9
  108. package/dist/document-models/service-offering/v1/gen/index.d.ts +1 -0
  109. package/dist/document-models/service-offering/v1/gen/index.d.ts.map +1 -1
  110. package/dist/document-models/service-offering/v1/gen/index.js +1 -0
  111. package/dist/document-models/service-offering/v1/gen/offering/error.d.ts +41 -1
  112. package/dist/document-models/service-offering/v1/gen/offering/error.d.ts.map +1 -1
  113. package/dist/document-models/service-offering/v1/gen/offering/error.js +37 -1
  114. package/dist/document-models/service-offering/v1/gen/option-groups/error.d.ts +55 -1
  115. package/dist/document-models/service-offering/v1/gen/option-groups/error.d.ts.map +1 -1
  116. package/dist/document-models/service-offering/v1/gen/option-groups/error.js +53 -1
  117. package/dist/document-models/service-offering/v1/gen/ph-factories.js +3 -3
  118. package/dist/document-models/service-offering/v1/gen/schema/types.d.ts +134 -61
  119. package/dist/document-models/service-offering/v1/gen/schema/types.d.ts.map +1 -1
  120. package/dist/document-models/service-offering/v1/gen/schema/zod.d.ts +35 -10
  121. package/dist/document-models/service-offering/v1/gen/schema/zod.d.ts.map +1 -1
  122. package/dist/document-models/service-offering/v1/gen/schema/zod.js +182 -64
  123. package/dist/document-models/service-offering/v1/gen/services/error.d.ts +20 -1
  124. package/dist/document-models/service-offering/v1/gen/services/error.d.ts.map +1 -1
  125. package/dist/document-models/service-offering/v1/gen/services/error.js +16 -1
  126. package/dist/document-models/service-offering/v1/gen/tiers/error.d.ts +100 -1
  127. package/dist/document-models/service-offering/v1/gen/tiers/error.d.ts.map +1 -1
  128. package/dist/document-models/service-offering/v1/gen/tiers/error.js +106 -1
  129. package/dist/document-models/service-offering/v1/gen/utils.js +4 -4
  130. package/dist/document-models/service-offering/v1/module.d.ts +1 -1
  131. package/dist/document-models/service-offering/v1/module.d.ts.map +1 -1
  132. package/dist/document-models/service-offering/v1/module.js +4 -1
  133. package/dist/document-models/service-offering/v1/src/reducers/offering.d.ts.map +1 -1
  134. package/dist/document-models/service-offering/v1/src/reducers/offering.js +20 -12
  135. package/dist/document-models/service-offering/v1/src/reducers/option-groups.d.ts.map +1 -1
  136. package/dist/document-models/service-offering/v1/src/reducers/option-groups.js +157 -39
  137. package/dist/document-models/service-offering/v1/src/reducers/services.d.ts.map +1 -1
  138. package/dist/document-models/service-offering/v1/src/reducers/services.js +17 -14
  139. package/dist/document-models/service-offering/v1/src/reducers/tiers.d.ts.map +1 -1
  140. package/dist/document-models/service-offering/v1/src/reducers/tiers.js +111 -78
  141. package/dist/document-models/service-offering/v1/src/utils.d.ts +60 -1
  142. package/dist/document-models/service-offering/v1/src/utils.d.ts.map +1 -1
  143. package/dist/document-models/service-offering/v1/src/utils.js +173 -1
  144. package/dist/document-models/service-offering/v1/tests/option-groups.test.js +1 -1
  145. package/dist/document-models/service-offering/v1/utils.d.ts +3 -0
  146. package/dist/document-models/service-offering/v1/utils.d.ts.map +1 -1
  147. package/dist/document-models/subscription-instance/v1/actions.d.ts +3 -1
  148. package/dist/document-models/subscription-instance/v1/actions.d.ts.map +1 -1
  149. package/dist/document-models/subscription-instance/v1/gen/controller.d.ts +4 -0
  150. package/dist/document-models/subscription-instance/v1/gen/controller.d.ts.map +1 -0
  151. package/dist/document-models/subscription-instance/v1/gen/controller.js +3 -0
  152. package/dist/document-models/subscription-instance/v1/gen/document-model.d.ts.map +1 -1
  153. package/dist/document-models/subscription-instance/v1/gen/document-model.js +488 -246
  154. package/dist/document-models/subscription-instance/v1/gen/document-schema.d.ts +3 -3
  155. package/dist/document-models/subscription-instance/v1/gen/index.d.ts +1 -0
  156. package/dist/document-models/subscription-instance/v1/gen/index.d.ts.map +1 -1
  157. package/dist/document-models/subscription-instance/v1/gen/index.js +1 -0
  158. package/dist/document-models/subscription-instance/v1/gen/metrics/error.d.ts +73 -1
  159. package/dist/document-models/subscription-instance/v1/gen/metrics/error.d.ts.map +1 -1
  160. package/dist/document-models/subscription-instance/v1/gen/metrics/error.js +86 -1
  161. package/dist/document-models/subscription-instance/v1/gen/ph-factories.js +1 -1
  162. package/dist/document-models/subscription-instance/v1/gen/schema/types.d.ts +199 -82
  163. package/dist/document-models/subscription-instance/v1/gen/schema/types.d.ts.map +1 -1
  164. package/dist/document-models/subscription-instance/v1/gen/schema/zod.d.ts +22 -12
  165. package/dist/document-models/subscription-instance/v1/gen/schema/zod.d.ts.map +1 -1
  166. package/dist/document-models/subscription-instance/v1/gen/schema/zod.js +230 -84
  167. package/dist/document-models/subscription-instance/v1/gen/service/error.d.ts +62 -1
  168. package/dist/document-models/subscription-instance/v1/gen/service/error.d.ts.map +1 -1
  169. package/dist/document-models/subscription-instance/v1/gen/service/error.js +60 -1
  170. package/dist/document-models/subscription-instance/v1/gen/service-group/error.d.ts +39 -1
  171. package/dist/document-models/subscription-instance/v1/gen/service-group/error.d.ts.map +1 -1
  172. package/dist/document-models/subscription-instance/v1/gen/service-group/error.js +39 -1
  173. package/dist/document-models/subscription-instance/v1/gen/subscription/error.d.ts +55 -1
  174. package/dist/document-models/subscription-instance/v1/gen/subscription/error.d.ts.map +1 -1
  175. package/dist/document-models/subscription-instance/v1/gen/subscription/error.js +51 -1
  176. package/dist/document-models/subscription-instance/v1/gen/utils.js +2 -2
  177. package/dist/document-models/subscription-instance/v1/module.d.ts +1 -1
  178. package/dist/document-models/subscription-instance/v1/module.d.ts.map +1 -1
  179. package/dist/document-models/subscription-instance/v1/module.js +4 -1
  180. package/dist/document-models/subscription-instance/v1/src/reducers/customer.d.ts.map +1 -1
  181. package/dist/document-models/subscription-instance/v1/src/reducers/customer.js +1 -0
  182. package/dist/document-models/subscription-instance/v1/src/reducers/metrics.d.ts.map +1 -1
  183. package/dist/document-models/subscription-instance/v1/src/reducers/metrics.js +70 -45
  184. package/dist/document-models/subscription-instance/v1/src/reducers/service-group.d.ts.map +1 -1
  185. package/dist/document-models/subscription-instance/v1/src/reducers/service-group.js +108 -30
  186. package/dist/document-models/subscription-instance/v1/src/reducers/service.d.ts.map +1 -1
  187. package/dist/document-models/subscription-instance/v1/src/reducers/service.js +108 -39
  188. package/dist/document-models/subscription-instance/v1/src/reducers/subscription.d.ts.map +1 -1
  189. package/dist/document-models/subscription-instance/v1/src/reducers/subscription.js +193 -35
  190. package/dist/editors/resource-instance-editor/editor.d.ts.map +1 -1
  191. package/dist/editors/resource-instance-editor/editor.js +13 -3
  192. package/dist/editors/service-offering-editor/components/ResourceTemplateSelector.d.ts.map +1 -1
  193. package/dist/editors/service-offering-editor/components/ResourceTemplateSelector.js +4 -2
  194. package/dist/editors/service-offering-editor/components/ServiceCatalog.d.ts.map +1 -1
  195. package/dist/editors/service-offering-editor/components/ServiceCatalog.js +189 -32
  196. package/dist/editors/service-offering-editor/components/TheMatrix.d.ts +1 -1
  197. package/dist/editors/service-offering-editor/components/TheMatrix.d.ts.map +1 -1
  198. package/dist/editors/service-offering-editor/components/TheMatrix.js +295 -140
  199. package/dist/editors/service-offering-editor/components/TierDefinition.d.ts.map +1 -1
  200. package/dist/editors/service-offering-editor/components/TierDefinition.js +2 -0
  201. package/dist/editors/service-offering-editor/components/TierPricingOptionsPanel.js +3 -3
  202. package/dist/editors/service-offering-editor/components/pricing-utils.d.ts.map +1 -1
  203. package/dist/editors/service-offering-editor/components/pricing-utils.js +26 -7
  204. package/dist/editors/subscription-instance-editor/components/BillingPanel.d.ts.map +1 -1
  205. package/dist/editors/subscription-instance-editor/components/BillingPanel.js +4 -4
  206. package/dist/editors/subscription-instance-editor/components/CustomerInfo.d.ts.map +1 -1
  207. package/dist/editors/subscription-instance-editor/components/CustomerInfo.js +3 -2
  208. package/dist/editors/subscription-instance-editor/components/ImportServiceConfigButton.d.ts +3 -0
  209. package/dist/editors/subscription-instance-editor/components/ImportServiceConfigButton.d.ts.map +1 -1
  210. package/dist/editors/subscription-instance-editor/components/ImportServiceConfigButton.js +12 -0
  211. package/dist/editors/subscription-instance-editor/components/MetricActions.d.ts.map +1 -1
  212. package/dist/editors/subscription-instance-editor/components/MetricActions.js +4 -2
  213. package/dist/editors/subscription-instance-editor/components/MockDataButton.d.ts.map +1 -1
  214. package/dist/editors/subscription-instance-editor/components/MockDataButton.js +214 -2
  215. package/dist/editors/subscription-instance-editor/components/OperatorNotes.js +1 -1
  216. package/dist/editors/subscription-instance-editor/components/ServicesPanel.d.ts.map +1 -1
  217. package/dist/editors/subscription-instance-editor/components/ServicesPanel.js +9 -20
  218. package/dist/editors/subscription-instance-editor/components/SubscriptionActions.d.ts.map +1 -1
  219. package/dist/editors/subscription-instance-editor/components/SubscriptionActions.js +8 -9
  220. package/dist/editors/subscription-instance-editor/components/SubscriptionHeader.d.ts.map +1 -1
  221. package/dist/editors/subscription-instance-editor/components/SubscriptionHeader.js +1 -1
  222. package/dist/editors/subscription-instance-editor/components/billing-utils.d.ts +14 -6
  223. package/dist/editors/subscription-instance-editor/components/billing-utils.d.ts.map +1 -1
  224. package/dist/editors/subscription-instance-editor/components/billing-utils.js +19 -23
  225. package/dist/editors/subscription-instance-editor/components/mapOfferingToSubscription.d.ts +16 -2
  226. package/dist/editors/subscription-instance-editor/components/mapOfferingToSubscription.d.ts.map +1 -1
  227. package/dist/editors/subscription-instance-editor/components/mapOfferingToSubscription.js +155 -6
  228. package/dist/powerhouse.manifest.json +29 -3
  229. package/dist/style.css +14 -0
  230. package/dist/subgraphs/resources-services/resolvers.d.ts +1 -1
  231. package/dist/subgraphs/resources-services/resolvers.d.ts.map +1 -1
  232. package/dist/subgraphs/resources-services/resolvers.js +272 -158
  233. package/dist/subgraphs/resources-services/schema.d.ts.map +1 -1
  234. package/dist/subgraphs/resources-services/schema.js +107 -41
  235. package/package.json +22 -18
@@ -107,6 +107,7 @@ export function ServiceCatalog({ document, dispatch }) {
107
107
  QUARTERLY: "",
108
108
  SEMI_ANNUAL: "",
109
109
  ANNUAL: "",
110
+ ONE_TIME: "",
110
111
  });
111
112
  // Per-tier pricing state for edit modal
112
113
  const [editTierTab, setEditTierTab] = useState(null);
@@ -148,6 +149,8 @@ export function ServiceCatalog({ document, dispatch }) {
148
149
  name: "New Group",
149
150
  isAddOn: false,
150
151
  defaultSelected: true,
152
+ costType: "RECURRING",
153
+ availableBillingCycles: inheritedCycles,
151
154
  lastModified: new Date().toISOString(),
152
155
  }));
153
156
  // Construct minimal group shape to open Edit modal immediately
@@ -194,6 +197,7 @@ export function ServiceCatalog({ document, dispatch }) {
194
197
  : "recurring";
195
198
  setEditGroupType(groupType);
196
199
  setEditGroupPrice(group.price?.toString() || "");
200
+ // Initialize per-tier setup fee discounts from tier-dependent pricing
197
201
  const SUBSCRIPTION_CYCLES = [
198
202
  "MONTHLY",
199
203
  "QUARTERLY",
@@ -206,6 +210,17 @@ export function ServiceCatalog({ document, dispatch }) {
206
210
  c,
207
211
  { discountType: "PERCENTAGE", discountValue: "" },
208
212
  ]));
213
+ const tierPricingEntry = group.tierDependentPricing?.find((tp) => tp.tierId === tier.id);
214
+ if (tierPricingEntry?.setupCostDiscounts) {
215
+ tierPricingEntry.setupCostDiscounts.forEach((d) => {
216
+ if (d.billingCycle && d.discountRule) {
217
+ emptyDiscounts[d.billingCycle] = {
218
+ discountType: d.discountRule.discountType,
219
+ discountValue: d.discountRule.discountValue?.toString() || "",
220
+ };
221
+ }
222
+ });
223
+ }
209
224
  setupTierDiscounts[tier.id] = emptyDiscounts;
210
225
  }
211
226
  setEditSetupTierDiscounts(setupTierDiscounts);
@@ -223,17 +238,21 @@ export function ServiceCatalog({ document, dispatch }) {
223
238
  else {
224
239
  setEditGroupPricingMode("STANDALONE");
225
240
  }
226
- setEditGroupSetupCost("");
227
- setEditGroupBasePrice(group.standalonePricing?.amount?.toString() || "");
241
+ // Initialize standalone pricing (for add-ons in STANDALONE mode or fallback)
242
+ setEditGroupSetupCost(group.standalonePricing?.setupCost?.amount?.toString() || "");
243
+ const monthlyPricing = group.standalonePricing?.recurringPricing?.find((p) => p.billingCycle === "MONTHLY");
244
+ setEditGroupBasePrice(monthlyPricing?.amount?.toString() || "");
245
+ // Initialize per-group billing cycle discounts (flat amount only)
228
246
  const discounts = {
229
247
  MONTHLY: "",
230
248
  QUARTERLY: "",
231
249
  SEMI_ANNUAL: "",
232
250
  ANNUAL: "",
251
+ ONE_TIME: "",
233
252
  };
234
253
  group.billingCycleDiscounts?.forEach((d) => {
235
- if (d.cycle && d.discountValue) {
236
- discounts[d.cycle] = d.discountValue.toString();
254
+ if (d.billingCycle && d.discountRule?.discountValue) {
255
+ discounts[d.billingCycle] = d.discountRule.discountValue.toString();
237
256
  }
238
257
  });
239
258
  setEditGroupDiscounts(discounts);
@@ -243,22 +262,39 @@ export function ServiceCatalog({ document, dispatch }) {
243
262
  const tierDiscounts = {};
244
263
  for (const tier of tiers) {
245
264
  const tierPricingEntry = group.tierDependentPricing?.find((tp) => tp.tierId === tier.id);
265
+ const tierMonthlyPricing = tierPricingEntry?.recurringPricing?.find((p) => p.billingCycle === "MONTHLY");
266
+ // If no tier pricing exists but group has standalone pricing, use standalone as starting point
246
267
  if (tierPricingEntry) {
247
- tierPrices[tier.id] = tierPricingEntry.amount?.toString() || "";
268
+ tierPrices[tier.id] = tierMonthlyPricing?.amount?.toString() || "";
269
+ tierSetupCosts[tier.id] =
270
+ tierPricingEntry.setupCost?.amount?.toString() || "";
248
271
  }
249
- else if (group.standalonePricing) {
250
- tierPrices[tier.id] = group.standalonePricing.amount?.toString() || "";
272
+ else if (monthlyPricing) {
273
+ // Pre-fill from standalone as migration aid
274
+ tierPrices[tier.id] = monthlyPricing.amount?.toString() || "";
275
+ tierSetupCosts[tier.id] =
276
+ group.standalonePricing?.setupCost?.amount?.toString() || "";
251
277
  }
252
278
  else {
253
279
  tierPrices[tier.id] = "";
280
+ tierSetupCosts[tier.id] = "";
254
281
  }
255
- tierSetupCosts[tier.id] = "";
282
+ // Per-tier discounts: populate from tierDependentPricing[].recurringPricing[].discount
256
283
  const tierDiscountValues = {
257
284
  MONTHLY: "",
258
285
  QUARTERLY: "",
259
286
  SEMI_ANNUAL: "",
260
287
  ANNUAL: "",
288
+ ONE_TIME: "",
261
289
  };
290
+ if (tierPricingEntry) {
291
+ tierPricingEntry.recurringPricing?.forEach((rp) => {
292
+ if (rp.discount && rp.discount.discountValue > 0) {
293
+ tierDiscountValues[rp.billingCycle] =
294
+ rp.discount.discountValue.toString();
295
+ }
296
+ });
297
+ }
262
298
  tierDiscounts[tier.id] = tierDiscountValues;
263
299
  }
264
300
  setEditTierPrices(tierPrices);
@@ -271,56 +307,153 @@ export function ServiceCatalog({ document, dispatch }) {
271
307
  return;
272
308
  const isSetup = editGroupType === "setup";
273
309
  const isAddOn = editGroupType === "addon";
310
+ const costType = isSetup ? "SETUP" : "RECURRING";
274
311
  const price = editGroupPrice ? parseFloat(editGroupPrice) : null;
312
+ // Update the option group in the document
275
313
  dispatch(updateOptionGroup({
276
314
  id: editingGroup.id,
277
315
  name: editGroupName.trim(),
278
316
  isAddOn,
279
317
  defaultSelected: !isAddOn,
318
+ costType,
319
+ availableBillingCycles: isSetup ? ["ONE_TIME"] : editGroupBillingCycles,
320
+ price: price ?? undefined,
321
+ currency: price ? "USD" : undefined,
280
322
  lastModified: new Date().toISOString(),
281
323
  }));
324
+ // Save setup pricing: base cost via standalone, per-tier discounts via tier pricing
282
325
  if (isSetup && price && price > 0) {
283
326
  const now = new Date().toISOString();
327
+ // Store base setup cost via standalone pricing
284
328
  dispatch(setOptionGroupStandalonePricing({
285
329
  optionGroupId: editingGroup.id,
286
- amount: price,
287
- currency: "USD",
330
+ setupCost: { amount: price, currency: "USD" },
331
+ recurringPricing: [],
288
332
  lastModified: now,
289
333
  }));
334
+ // Store per-tier setup fee discounts
335
+ for (const tier of tiers) {
336
+ if (tier.isCustomPricing)
337
+ continue;
338
+ const tierDiscountEntries = editSetupTierDiscounts[tier.id];
339
+ const setupCostDiscounts = Object.entries(tierDiscountEntries || {})
340
+ .filter(([, d]) => parseFloat(d.discountValue) > 0)
341
+ .map(([cycle, d]) => ({
342
+ billingCycle: cycle,
343
+ discountRule: {
344
+ discountType: "PERCENTAGE",
345
+ discountValue: parseFloat(d.discountValue),
346
+ },
347
+ }));
348
+ const existingTierPricing = editingGroup.tierDependentPricing?.find((tp) => tp.tierId === tier.id);
349
+ if (existingTierPricing) {
350
+ dispatch(updateOptionGroupTierPricing({
351
+ optionGroupId: editingGroup.id,
352
+ tierId: tier.id,
353
+ setupCost: { amount: price, currency: "USD" },
354
+ setupCostDiscounts,
355
+ recurringPricing: [],
356
+ lastModified: now,
357
+ }));
358
+ }
359
+ else {
360
+ dispatch(addOptionGroupTierPricing({
361
+ optionGroupId: editingGroup.id,
362
+ tierPricingId: generateId(),
363
+ tierId: tier.id,
364
+ setupCost: { amount: price, currency: "USD" },
365
+ setupCostDiscounts,
366
+ recurringPricing: [],
367
+ lastModified: now,
368
+ }));
369
+ }
370
+ }
290
371
  }
372
+ // Save pricing based on mode
291
373
  if (!isSetup && editGroupPricingMode === "TIER_DEPENDENT") {
374
+ // Per-tier pricing: dispatch addOptionGroupTierPricing or updateOptionGroupTierPricing per tier
292
375
  const now = new Date().toISOString();
293
376
  for (const tier of tiers) {
294
377
  if (tier.isCustomPricing)
295
- continue;
378
+ continue; // Skip custom tiers
296
379
  const baseMonthly = parseFloat(editTierPrices[tier.id]) || 0;
380
+ const setupCostVal = parseFloat(editTierSetupCosts[tier.id]) || 0;
381
+ const setupCost = setupCostVal > 0
382
+ ? { amount: setupCostVal, currency: "USD" }
383
+ : undefined;
384
+ const recurringPricing = editGroupBillingCycles
385
+ .filter(() => baseMonthly > 0)
386
+ .map((cycle) => {
387
+ const discountPct = parseFloat(editTierDiscounts[tier.id]?.[cycle] || "0") || 0;
388
+ return {
389
+ id: generateId(),
390
+ billingCycle: cycle,
391
+ amount: baseMonthly,
392
+ currency: "USD",
393
+ discount: discountPct > 0
394
+ ? {
395
+ discountType: "PERCENTAGE",
396
+ discountValue: discountPct,
397
+ }
398
+ : undefined,
399
+ };
400
+ });
297
401
  const existingTierPricing = editingGroup.tierDependentPricing?.find((tp) => tp.tierId === tier.id);
298
402
  if (existingTierPricing) {
299
403
  dispatch(updateOptionGroupTierPricing({
300
404
  optionGroupId: editingGroup.id,
301
405
  tierId: tier.id,
302
- amount: baseMonthly,
303
- currency: "USD",
406
+ setupCost,
407
+ recurringPricing,
304
408
  lastModified: now,
305
409
  }));
306
410
  }
307
411
  else {
308
412
  dispatch(addOptionGroupTierPricing({
309
413
  optionGroupId: editingGroup.id,
414
+ tierPricingId: generateId(),
310
415
  tierId: tier.id,
311
- amount: baseMonthly,
312
- currency: "USD",
416
+ setupCost,
417
+ recurringPricing,
313
418
  lastModified: now,
314
419
  }));
315
420
  }
316
421
  }
317
422
  }
318
423
  else if (!isSetup && editGroupPricingMode === "STANDALONE") {
424
+ // Standalone pricing (add-ons or groups with no tiers)
425
+ const setupCost = editGroupSetupCost && parseFloat(editGroupSetupCost) > 0
426
+ ? {
427
+ amount: parseFloat(editGroupSetupCost),
428
+ currency: "USD",
429
+ }
430
+ : undefined;
319
431
  const baseMonthly = parseFloat(editGroupBasePrice) || 0;
320
- dispatch(setOptionGroupStandalonePricing({
321
- optionGroupId: editingGroup.id,
432
+ const recurringPricing = editGroupBillingCycles
433
+ .filter(() => baseMonthly > 0)
434
+ .map((cycle) => ({
435
+ id: generateId(),
436
+ billingCycle: cycle,
322
437
  amount: baseMonthly,
323
438
  currency: "USD",
439
+ }));
440
+ const billingCycleDiscounts = editGroupBillingCycles
441
+ .map((cycle) => {
442
+ const discountPct = parseFloat(editGroupDiscounts[cycle]) || 0;
443
+ return {
444
+ billingCycle: cycle,
445
+ discountRule: {
446
+ discountType: "PERCENTAGE",
447
+ discountValue: discountPct,
448
+ },
449
+ };
450
+ })
451
+ .filter((d) => d.discountRule.discountValue > 0);
452
+ dispatch(setOptionGroupStandalonePricing({
453
+ optionGroupId: editingGroup.id,
454
+ setupCost,
455
+ recurringPricing,
456
+ billingCycleDiscounts,
324
457
  lastModified: new Date().toISOString(),
325
458
  }));
326
459
  }
@@ -353,12 +486,14 @@ export function ServiceCatalog({ document, dispatch }) {
353
486
  optionGroupId: selectedGroupId || undefined,
354
487
  lastModified: now,
355
488
  }));
489
+ // Create ServiceLevelBindings for each selected tier
356
490
  selectedTierIds.forEach((tierId) => {
357
491
  dispatch(addServiceLevel({
358
- id: generateId(),
492
+ serviceLevelId: generateId(),
359
493
  serviceId,
360
494
  tierId,
361
495
  level: "INCLUDED",
496
+ optionGroupId: selectedGroupId || undefined,
362
497
  lastModified: now,
363
498
  }));
364
499
  });
@@ -366,6 +501,7 @@ export function ServiceCatalog({ document, dispatch }) {
366
501
  setSelectedTierIds(new Set());
367
502
  setIsAddingService(false);
368
503
  };
504
+ // Quick-add service from template (reduces activation energy)
369
505
  const handleAddFromTemplate = (template) => {
370
506
  if (!selectedGroupId)
371
507
  return;
@@ -380,12 +516,14 @@ export function ServiceCatalog({ document, dispatch }) {
380
516
  optionGroupId: selectedGroupId,
381
517
  lastModified: now,
382
518
  }));
519
+ // Auto-include in all tiers for convenience (can be changed later)
383
520
  tiers.forEach((tier) => {
384
521
  dispatch(addServiceLevel({
385
- id: generateId(),
522
+ serviceLevelId: generateId(),
386
523
  serviceId,
387
524
  tierId: tier.id,
388
525
  level: "INCLUDED",
526
+ optionGroupId: selectedGroupId,
389
527
  lastModified: now,
390
528
  }));
391
529
  });
@@ -406,20 +544,29 @@ export function ServiceCatalog({ document, dispatch }) {
406
544
  // Find existing service level binding for this service-tier combo
407
545
  const existingBinding = tier.serviceLevels.find((sl) => sl.serviceId === serviceId);
408
546
  if (isIncluded) {
409
- if (!existingBinding) {
547
+ // Add or update service level binding
548
+ if (existingBinding) {
549
+ // Service level exists, might need to update it if level changed
550
+ // (for now we just use INCLUDED)
551
+ }
552
+ else {
553
+ // Create new service level binding
554
+ const service = services.find((s) => s.id === serviceId);
410
555
  dispatch(addServiceLevel({
411
- id: generateId(),
556
+ serviceLevelId: generateId(),
412
557
  serviceId,
413
558
  tierId,
414
559
  level: "INCLUDED",
560
+ optionGroupId: service?.optionGroupId || undefined,
415
561
  lastModified: now,
416
562
  }));
417
563
  }
418
564
  }
419
565
  else {
566
+ // Remove service level binding
420
567
  if (existingBinding) {
421
568
  dispatch(removeServiceLevel({
422
- id: existingBinding.id,
569
+ serviceLevelId: existingBinding.id,
423
570
  tierId,
424
571
  lastModified: now,
425
572
  }));
@@ -467,7 +614,9 @@ export function ServiceCatalog({ document, dispatch }) {
467
614
  : color === "emerald"
468
615
  ? "border-emerald-500 bg-emerald-50 text-emerald-700"
469
616
  : "border-violet-500 bg-violet-50 text-violet-700"
470
- : "border-slate-200 bg-white text-slate-600 hover:border-slate-300"}`, style: fontSans, children: label }, type))) })] }), editGroupType !== "setup" && (_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx("label", { className: "text-xs font-semibold uppercase tracking-[0.05em] text-slate-500", style: fontSans, children: "Available Billing Cycles" }), _jsx("div", { className: "flex flex-col gap-2.5 p-3 bg-slate-50 rounded-[10px]", children: Object.entries(BILLING_CYCLE_SHORT_LABELS).map(([value, label]) => (_jsxs("label", { className: "flex items-center gap-2.5 cursor-pointer text-sm text-slate-700", children: [_jsx("input", { type: "checkbox", checked: editGroupBillingCycles.includes(value), onChange: (e) => {
617
+ : "border-slate-200 bg-white text-slate-600 hover:border-slate-300"}`, style: fontSans, children: label }, type))) })] }), editGroupType !== "setup" && (_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx("label", { className: "text-xs font-semibold uppercase tracking-[0.05em] text-slate-500", style: fontSans, children: "Available Billing Cycles" }), _jsx("div", { className: "flex flex-col gap-2.5 p-3 bg-slate-50 rounded-[10px]", children: Object.entries(BILLING_CYCLE_SHORT_LABELS)
618
+ .filter(([value]) => value !== "ONE_TIME")
619
+ .map(([value, label]) => (_jsxs("label", { className: "flex items-center gap-2.5 cursor-pointer text-sm text-slate-700", children: [_jsx("input", { type: "checkbox", checked: editGroupBillingCycles.includes(value), onChange: (e) => {
471
620
  if (e.target.checked) {
472
621
  setEditGroupBillingCycles([
473
622
  ...editGroupBillingCycles,
@@ -495,20 +644,25 @@ export function ServiceCatalog({ document, dispatch }) {
495
644
  return (_jsxs("div", { className: "flex items-center gap-2 p-3 bg-slate-50 border border-dashed border-slate-300 rounded-md text-xs text-slate-500 italic", children: [_jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", width: "16", height: "16", children: _jsx("path", { d: "M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" }) }), _jsx("span", { children: "Price negotiated per customer. No group-level price input for custom tiers." })] }));
496
645
  }
497
646
  const tierBase = parseFloat(editTierPrices[activeTier.id]) || 0;
498
- const tierAmount = activeTier.pricing?.amount ?? 0;
647
+ const tierAmount = activeTier.pricing.amount ?? 0;
648
+ // Budget: sum of other groups' prices for this tier
499
649
  const otherGroupsTotal = regularGroups
500
650
  .filter((g) => editingGroup && g.id !== editingGroup.id)
501
651
  .reduce((sum, g) => {
502
652
  const tp = g.tierDependentPricing?.find((p) => p.tierId === activeTier.id);
503
- if (tp)
504
- return sum + (tp.amount ?? 0);
505
- return sum + (g.standalonePricing?.amount ?? 0);
653
+ const mp = tp?.recurringPricing?.find((p) => p.billingCycle === "MONTHLY");
654
+ if (mp)
655
+ return sum + (mp.amount ?? 0);
656
+ // Fallback to standalone
657
+ const sp = g.standalonePricing?.recurringPricing?.find((p) => p.billingCycle === "MONTHLY");
658
+ return sum + (sp?.amount ?? 0);
506
659
  }, 0);
507
660
  const projectedTotal = otherGroupsTotal + tierBase;
508
661
  return (_jsxs("div", { style: { animation: "catalog__fade-in 0.15s ease" }, children: [_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsxs("label", { className: "text-xs font-semibold uppercase tracking-[0.05em] text-slate-500", style: fontSans, children: ["Recurring Price (", activeTier.name, ")"] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-sm text-slate-500", children: "$" }), _jsx("input", { type: "number", value: editTierPrices[activeTier.id] || "", onChange: (e) => setEditTierPrices({
509
662
  ...editTierPrices,
510
663
  [activeTier.id]: e.target.value,
511
- }), placeholder: "0.00", className: "flex-1 px-2.5 py-2 text-sm text-slate-800 bg-white border-[1.5px] border-slate-200 rounded-md focus:outline-none focus:border-violet-500 focus:shadow-[0_0_0_2px_rgb(237,233,254)]", style: fontSans, step: "0.01" })] })] }), tierAmount > 0 && (_jsxs("div", { className: "mt-2 p-2 px-2.5 bg-slate-50 border border-slate-200 rounded-md", children: [_jsxs("span", { className: "block text-[0.6875rem] font-semibold text-slate-700 mb-1.5", children: [activeTier.name, " budget:", " ", formatPrice(projectedTotal), "/mo of", " ", formatPrice(tierAmount), "/mo"] }), _jsxs("div", { className: "flex items-center gap-1.5 py-[3px]", children: [_jsx("div", { className: "flex-1 h-[5px] bg-slate-200 rounded-full overflow-hidden", children: _jsx("div", { className: `h-full rounded-full transition-[width] duration-200 ease-linear ${projectedTotal > tierAmount ? "bg-rose-500" : "bg-emerald-500"}`, style: {
664
+ }), placeholder: "0.00", className: "flex-1 px-2.5 py-2 text-sm text-slate-800 bg-white border-[1.5px] border-slate-200 rounded-md focus:outline-none focus:border-violet-500 focus:shadow-[0_0_0_2px_rgb(237,233,254)]", style: fontSans, step: "0.01" })] })] }), tierAmount > 0 &&
665
+ activeTier.pricingMode !== "CALCULATED" && (_jsxs("div", { className: "mt-2 p-2 px-2.5 bg-slate-50 border border-slate-200 rounded-md", children: [_jsxs("span", { className: "block text-[0.6875rem] font-semibold text-slate-700 mb-1.5", children: [activeTier.name, " budget:", " ", formatPrice(projectedTotal), "/mo of", " ", formatPrice(tierAmount), "/mo"] }), _jsxs("div", { className: "flex items-center gap-1.5 py-[3px]", children: [_jsx("div", { className: "flex-1 h-[5px] bg-slate-200 rounded-full overflow-hidden", children: _jsx("div", { className: `h-full rounded-full transition-[width] duration-200 ease-linear ${projectedTotal > tierAmount ? "bg-rose-500" : "bg-emerald-500"}`, style: {
512
666
  width: `${Math.min((projectedTotal / tierAmount) * 100, 100)}%`,
513
667
  } }) }), _jsxs("span", { className: `shrink-0 text-[0.625rem] ${projectedTotal > tierAmount ? "text-rose-600 font-semibold" : "text-slate-600"}`, style: fontMono, children: [formatPrice(projectedTotal), " /", " ", formatPrice(tierAmount), projectedTotal > tierAmount && (_jsxs("span", { className: "text-rose-500 font-bold", children: [" ", "+", formatPrice(projectedTotal - tierAmount)] }))] })] })] })), _jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx("label", { className: "text-xs font-semibold uppercase tracking-[0.05em] text-slate-500", style: fontSans, children: "Setup Cost (one-time)" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-sm text-slate-500", children: "$" }), _jsx("input", { type: "number", value: editTierSetupCosts[activeTier.id] || "", onChange: (e) => setEditTierSetupCosts({
514
668
  ...editTierSetupCosts,
@@ -523,7 +677,9 @@ export function ServiceCatalog({ document, dispatch }) {
523
677
  QUARTERLY: "Quarterly",
524
678
  SEMI_ANNUAL: "Semi-Annual",
525
679
  ANNUAL: "Annual",
680
+ ONE_TIME: "One-Time",
526
681
  }[cycle];
682
+ // Percentage discount from user input (always editable)
527
683
  const discountPct = parseFloat(editTierDiscounts[activeTier.id]?.[cycle] || "0") || 0;
528
684
  let effective = null;
529
685
  let savingsPct = 0;
@@ -559,6 +715,7 @@ export function ServiceCatalog({ document, dispatch }) {
559
715
  QUARTERLY: "Quarterly",
560
716
  SEMI_ANNUAL: "Semi-Annual",
561
717
  ANNUAL: "Annual",
718
+ ONE_TIME: "One-Time",
562
719
  }[cycle];
563
720
  const shortLabel = `${months}mo`;
564
721
  return (_jsxs("div", { className: `border border-slate-200 rounded-[10px] px-3.5 py-2.5 transition-[150ms] ${base > 0 ? "bg-white" : "bg-slate-50"}`, children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsx("span", { className: "text-sm font-semibold text-slate-700", children: cycleLabel }), total !== null ? (_jsx("span", { className: "text-[0.9375rem] font-bold text-slate-800", style: fontMono, children: formatPrice(total, "USD") })) : (_jsx("span", { className: "text-sm text-slate-400", children: "--" }))] }), base > 0 && (_jsxs("div", { className: "flex gap-4 mt-2 pt-2 border-t border-dashed border-slate-200", children: [!isMonthly && (_jsxs("div", { className: "flex-1 flex flex-col gap-0.5", children: [_jsx("span", { className: "text-[0.625rem] font-medium uppercase tracking-[0.06em] text-violet-500", style: fontMono, children: "Standard Price" }), _jsxs("span", { className: "text-[0.8125rem] text-slate-600 flex items-baseline gap-1.5", children: ["$", base, " \u00D7 ", shortLabel, _jsx("span", { className: "font-semibold text-slate-700", children: formatPrice(total ?? 0, "USD") })] })] })), _jsxs("div", { className: "flex-1 flex flex-col gap-0.5", children: [_jsx("span", { className: "text-[0.625rem] font-medium uppercase tracking-[0.06em] text-violet-500", style: fontMono, children: "Discount" }), _jsxs("div", { className: "flex items-center border border-slate-200 rounded-[10px] overflow-hidden transition-all duration-150 h-[34px] focus-within:border-violet-400 focus-within:shadow-[0_0_0_3px_rgba(124,58,237,0.1)]", children: [_jsx("input", { type: "number", value: editGroupDiscounts[cycle], onChange: (e) => setEditGroupDiscounts({
@@ -661,7 +818,7 @@ export function ServiceCatalog({ document, dispatch }) {
661
818
  newSet.delete(tier.id);
662
819
  }
663
820
  setSelectedTierIds(newSet);
664
- }, className: "w-[18px] h-[18px] shrink-0 accent-emerald-600 cursor-pointer" }), _jsx("span", { className: `flex-1 text-sm font-medium ${isSelected ? "text-emerald-800" : "text-slate-800"}`, children: tier.name }), tier.pricing?.amount != null && (_jsxs("span", { className: `text-xs font-medium whitespace-nowrap ${isSelected ? "text-emerald-600" : "text-slate-500"}`, children: ["$", tier.pricing.amount] }))] }, tier.id));
821
+ }, className: "w-[18px] h-[18px] shrink-0 accent-emerald-600 cursor-pointer" }), _jsx("span", { className: `flex-1 text-sm font-medium ${isSelected ? "text-emerald-800" : "text-slate-800"}`, children: tier.name }), tier.pricing.amount !== null && (_jsxs("span", { className: `text-xs font-medium whitespace-nowrap ${isSelected ? "text-emerald-600" : "text-slate-500"}`, children: ["$", tier.pricing.amount] }))] }, tier.id));
665
822
  }) }), selectedTierIds.size === 0 && (_jsx("p", { className: "text-xs text-slate-500 mt-2 m-0 italic", children: "Select at least one tier to include this service" }))] })), tiers.length === 0 && (_jsxs("div", { className: "flex items-start gap-3 px-4 py-3.5 rounded-[10px] mb-5 bg-amber-50 border border-amber-200 text-amber-700", children: [_jsx("svg", { className: "w-5 h-5 shrink-0 mt-px", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.75", children: _jsx("path", { d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" }) }), _jsx("p", { className: "text-[0.8125rem] m-0 leading-relaxed", children: "No tiers defined yet. Define tiers in the Tier Definition tab first to specify which tiers include this service." })] })), _jsxs("div", { className: "flex gap-2", children: [_jsx("button", { onClick: handleAddService, disabled: !newService.title.trim(), className: "flex-1 px-4 py-2.5 text-[0.8125rem] font-semibold rounded-[10px] border-none cursor-pointer flex items-center justify-center gap-1.5 transition-all duration-150 text-white hover:enabled:-translate-y-px disabled:opacity-50 disabled:cursor-not-allowed", style: {
666
823
  ...fontSans,
667
824
  background: "linear-gradient(135deg, #7c3aed 0%, #6d28d9 100%)",
@@ -695,8 +852,8 @@ function GroupButton({ group, serviceCount, isSelected, onSelect, onEdit, onDele
695
852
  .join(", ") }))] }), _jsxs("div", { className: "flex items-center gap-2 text-xs text-slate-500 mt-0.5", children: [_jsxs("span", { children: [serviceCount, " services", serviceCount === 0 && (_jsxs("span", { className: "text-[0.6875rem] text-amber-600", children: [" ", "\u2014 add services"] }))] }), group.costType === "SETUP" && group.price != null && (_jsx("span", { className: "text-amber-600", children: formatPrice(group.price, "USD") })), group.isAddOn && group.price != null && (_jsx("span", { className: "text-amber-600", children: formatPrice(group.price, "USD") })), !isSetup &&
696
853
  !group.isAddOn &&
697
854
  (() => {
698
- const monthlyPrice = group.tierDependentPricing?.[0]?.amount ??
699
- group.standalonePricing?.amount;
855
+ const monthlyPrice = group.tierDependentPricing?.[0]?.recurringPricing?.find((p) => p.billingCycle === "MONTHLY")?.amount ??
856
+ group.standalonePricing?.recurringPricing?.find((p) => p.billingCycle === "MONTHLY")?.amount;
700
857
  return monthlyPrice != null && monthlyPrice > 0 ? (_jsxs("span", { className: "text-amber-600", children: [formatPrice(monthlyPrice, "USD"), "/mo"] })) : null;
701
858
  })()] })] }), isHovered && (_jsxs("div", { className: "absolute right-2.5 top-1/2 -translate-y-1/2 flex gap-0.5", style: { animation: "so-fade-in 150ms ease-out" }, children: [_jsx("button", { onClick: (e) => {
702
859
  e.stopPropagation();
@@ -763,6 +920,6 @@ function ServiceCard({ service, tiers, optionGroups, onUpdate, onDelete, onToggl
763
920
  ? "border-emerald-500 bg-emerald-50 hover:border-emerald-600"
764
921
  : "border-slate-200 hover:border-slate-300 hover:bg-slate-50"}`, children: [_jsx("input", { type: "checkbox", checked: isIncluded, onChange: (e) => {
765
922
  onToggleTier(service.id, tier.id, e.target.checked);
766
- }, className: "w-[18px] h-[18px] shrink-0 accent-emerald-600 cursor-pointer" }), _jsx("span", { className: `flex-1 text-sm font-medium ${isIncluded ? "text-emerald-800" : "text-slate-800"}`, children: tier.name }), tier.pricing?.amount != null && (_jsxs("span", { className: `text-xs font-medium whitespace-nowrap ${isIncluded ? "text-emerald-600" : "text-slate-500"}`, children: ["$", tier.pricing.amount] }))] }, tier.id));
923
+ }, className: "w-[18px] h-[18px] shrink-0 accent-emerald-600 cursor-pointer" }), _jsx("span", { className: `flex-1 text-sm font-medium ${isIncluded ? "text-emerald-800" : "text-slate-800"}`, children: tier.name }), tier.pricing.amount !== null && (_jsxs("span", { className: `text-xs font-medium whitespace-nowrap ${isIncluded ? "text-emerald-600" : "text-slate-500"}`, children: ["$", tier.pricing.amount] }))] }, tier.id));
767
924
  }) })] }))] }))] }));
768
925
  }
@@ -1,5 +1,5 @@
1
1
  import { type DocumentDispatch } from "@powerhousedao/reactor-browser";
2
- import type { ServiceOfferingDocument, ServiceOfferingAction } from "@powerhousedao/service-offering/document-models/service-offering";
2
+ import { type ServiceOfferingDocument, type ServiceOfferingAction } from "@powerhousedao/service-offering/document-models/service-offering";
3
3
  interface TheMatrixProps {
4
4
  document: ServiceOfferingDocument;
5
5
  dispatch: DocumentDispatch<ServiceOfferingAction>;
@@ -1 +1 @@
1
- {"version":3,"file":"TheMatrix.d.ts","sourceRoot":"","sources":["../../../../editors/service-offering-editor/components/TheMatrix.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,gBAAgB,EAEtB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EACV,uBAAuB,EACvB,qBAAqB,EAQtB,MAAM,kEAAkE,CAAC;AAqB1E,UAAU,cAAc;IACtB,QAAQ,EAAE,uBAAuB,CAAC;IAClC,QAAQ,EAAE,gBAAgB,CAAC,qBAAqB,CAAC,CAAC;CACnD;AAgDD,wBAAgB,SAAS,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,cAAc,2CAsvE/D"}
1
+ {"version":3,"file":"TheMatrix.d.ts","sourceRoot":"","sources":["../../../../editors/service-offering-editor/components/TheMatrix.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,gBAAgB,EAEtB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAS3B,MAAM,kEAAkE,CAAC;AA2B1E,UAAU,cAAc;IACtB,QAAQ,EAAE,uBAAuB,CAAC;IAClC,QAAQ,EAAE,gBAAgB,CAAC,qBAAqB,CAAC,CAAC;CACnD;AAgDD,wBAAgB,SAAS,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,cAAc,2CAy7E/D"}