@powerhousedao/service-offering 1.0.0-dev.3 → 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.
- package/dist/document-models/facet/v1/actions.d.ts +3 -1
- package/dist/document-models/facet/v1/actions.d.ts.map +1 -1
- package/dist/document-models/facet/v1/gen/controller.d.ts +4 -0
- package/dist/document-models/facet/v1/gen/controller.d.ts.map +1 -0
- package/dist/document-models/facet/v1/gen/controller.js +3 -0
- package/dist/document-models/facet/v1/gen/document-model.d.ts.map +1 -1
- package/dist/document-models/facet/v1/gen/document-model.js +31 -7
- package/dist/document-models/facet/v1/gen/document-schema.d.ts +6 -6
- package/dist/document-models/facet/v1/gen/index.d.ts +1 -0
- package/dist/document-models/facet/v1/gen/index.d.ts.map +1 -1
- package/dist/document-models/facet/v1/gen/index.js +1 -0
- package/dist/document-models/facet/v1/gen/option-management/error.d.ts +27 -1
- package/dist/document-models/facet/v1/gen/option-management/error.d.ts.map +1 -1
- package/dist/document-models/facet/v1/gen/option-management/error.js +23 -1
- package/dist/document-models/facet/v1/gen/ph-factories.js +2 -2
- package/dist/document-models/facet/v1/gen/schema/types.d.ts +2 -2
- package/dist/document-models/facet/v1/gen/schema/types.d.ts.map +1 -1
- package/dist/document-models/facet/v1/gen/schema/zod.js +2 -2
- package/dist/document-models/facet/v1/gen/utils.js +2 -2
- package/dist/document-models/facet/v1/module.d.ts +1 -1
- package/dist/document-models/facet/v1/module.d.ts.map +1 -1
- package/dist/document-models/facet/v1/module.js +4 -1
- package/dist/document-models/resource-instance/v1/actions.d.ts +4 -1
- package/dist/document-models/resource-instance/v1/actions.d.ts.map +1 -1
- package/dist/document-models/resource-instance/v1/gen/configuration-management/error.d.ts +34 -1
- package/dist/document-models/resource-instance/v1/gen/configuration-management/error.d.ts.map +1 -1
- package/dist/document-models/resource-instance/v1/gen/configuration-management/error.js +32 -1
- package/dist/document-models/resource-instance/v1/gen/controller.d.ts +4 -0
- package/dist/document-models/resource-instance/v1/gen/controller.d.ts.map +1 -0
- package/dist/document-models/resource-instance/v1/gen/controller.js +3 -0
- package/dist/document-models/resource-instance/v1/gen/document-model.d.ts.map +1 -1
- package/dist/document-models/resource-instance/v1/gen/document-model.js +222 -70
- package/dist/document-models/resource-instance/v1/gen/document-schema.d.ts +0 -6
- package/dist/document-models/resource-instance/v1/gen/document-schema.d.ts.map +1 -1
- package/dist/document-models/resource-instance/v1/gen/index.d.ts +1 -0
- package/dist/document-models/resource-instance/v1/gen/index.d.ts.map +1 -1
- package/dist/document-models/resource-instance/v1/gen/index.js +1 -0
- package/dist/document-models/resource-instance/v1/gen/instance-management/actions.d.ts +6 -2
- package/dist/document-models/resource-instance/v1/gen/instance-management/actions.d.ts.map +1 -1
- package/dist/document-models/resource-instance/v1/gen/instance-management/creators.d.ts +3 -2
- package/dist/document-models/resource-instance/v1/gen/instance-management/creators.d.ts.map +1 -1
- package/dist/document-models/resource-instance/v1/gen/instance-management/creators.js +2 -1
- package/dist/document-models/resource-instance/v1/gen/instance-management/error.d.ts +98 -1
- package/dist/document-models/resource-instance/v1/gen/instance-management/error.d.ts.map +1 -1
- package/dist/document-models/resource-instance/v1/gen/instance-management/error.js +112 -1
- package/dist/document-models/resource-instance/v1/gen/instance-management/operations.d.ts +2 -1
- package/dist/document-models/resource-instance/v1/gen/instance-management/operations.d.ts.map +1 -1
- package/dist/document-models/resource-instance/v1/gen/ph-factories.d.ts.map +1 -1
- package/dist/document-models/resource-instance/v1/gen/ph-factories.js +0 -2
- package/dist/document-models/resource-instance/v1/gen/reducer.d.ts.map +1 -1
- package/dist/document-models/resource-instance/v1/gen/reducer.js +6 -1
- package/dist/document-models/resource-instance/v1/gen/schema/types.d.ts +3 -3
- package/dist/document-models/resource-instance/v1/gen/schema/types.d.ts.map +1 -1
- package/dist/document-models/resource-instance/v1/gen/schema/zod.d.ts +2 -1
- package/dist/document-models/resource-instance/v1/gen/schema/zod.d.ts.map +1 -1
- package/dist/document-models/resource-instance/v1/gen/schema/zod.js +5 -3
- package/dist/document-models/resource-instance/v1/gen/utils.d.ts.map +1 -1
- package/dist/document-models/resource-instance/v1/gen/utils.js +0 -2
- package/dist/document-models/resource-instance/v1/module.d.ts +1 -1
- package/dist/document-models/resource-instance/v1/module.d.ts.map +1 -1
- package/dist/document-models/resource-instance/v1/module.js +4 -1
- package/dist/document-models/resource-instance/v1/src/reducers/configuration-management.d.ts.map +1 -1
- package/dist/document-models/resource-instance/v1/src/reducers/configuration-management.js +57 -53
- package/dist/document-models/resource-instance/v1/src/reducers/instance-management.d.ts.map +1 -1
- package/dist/document-models/resource-instance/v1/src/reducers/instance-management.js +57 -21
- package/dist/document-models/resource-instance/v1/tests/instance-management.test.js +11 -1
- package/dist/document-models/resource-template/v1/actions.d.ts +3 -1
- package/dist/document-models/resource-template/v1/actions.d.ts.map +1 -1
- package/dist/document-models/resource-template/v1/gen/audience-management/error.d.ts +20 -1
- package/dist/document-models/resource-template/v1/gen/audience-management/error.d.ts.map +1 -1
- package/dist/document-models/resource-template/v1/gen/audience-management/error.js +16 -1
- package/dist/document-models/resource-template/v1/gen/controller.d.ts +4 -0
- package/dist/document-models/resource-template/v1/gen/controller.d.ts.map +1 -0
- package/dist/document-models/resource-template/v1/gen/controller.js +3 -0
- package/dist/document-models/resource-template/v1/gen/document-model.d.ts.map +1 -1
- package/dist/document-models/resource-template/v1/gen/document-model.js +207 -89
- package/dist/document-models/resource-template/v1/gen/document-schema.d.ts +12 -12
- package/dist/document-models/resource-template/v1/gen/facet-targeting/error.d.ts +27 -1
- package/dist/document-models/resource-template/v1/gen/facet-targeting/error.d.ts.map +1 -1
- package/dist/document-models/resource-template/v1/gen/facet-targeting/error.js +23 -1
- package/dist/document-models/resource-template/v1/gen/index.d.ts +1 -0
- package/dist/document-models/resource-template/v1/gen/index.d.ts.map +1 -1
- package/dist/document-models/resource-template/v1/gen/index.js +1 -0
- package/dist/document-models/resource-template/v1/gen/option-group-management/error.d.ts +27 -1
- package/dist/document-models/resource-template/v1/gen/option-group-management/error.d.ts.map +1 -1
- package/dist/document-models/resource-template/v1/gen/option-group-management/error.js +23 -1
- package/dist/document-models/resource-template/v1/gen/ph-factories.js +3 -3
- package/dist/document-models/resource-template/v1/gen/schema/types.d.ts +4 -4
- package/dist/document-models/resource-template/v1/gen/schema/types.d.ts.map +1 -1
- package/dist/document-models/resource-template/v1/gen/schema/zod.js +4 -4
- package/dist/document-models/resource-template/v1/gen/service-management/error.d.ts +51 -1
- package/dist/document-models/resource-template/v1/gen/service-management/error.d.ts.map +1 -1
- package/dist/document-models/resource-template/v1/gen/service-management/error.js +49 -1
- package/dist/document-models/resource-template/v1/gen/utils.js +3 -3
- package/dist/document-models/resource-template/v1/module.d.ts +1 -1
- package/dist/document-models/resource-template/v1/module.d.ts.map +1 -1
- package/dist/document-models/resource-template/v1/module.js +4 -1
- package/dist/document-models/resource-template/v1/src/reducers/option-group-management.d.ts.map +1 -1
- package/dist/document-models/resource-template/v1/src/reducers/option-group-management.js +2 -21
- package/dist/document-models/service-offering/v1/actions.d.ts +3 -1
- package/dist/document-models/service-offering/v1/actions.d.ts.map +1 -1
- package/dist/document-models/service-offering/v1/gen/controller.d.ts +4 -0
- package/dist/document-models/service-offering/v1/gen/controller.d.ts.map +1 -0
- package/dist/document-models/service-offering/v1/gen/controller.js +3 -0
- package/dist/document-models/service-offering/v1/gen/document-model.d.ts.map +1 -1
- package/dist/document-models/service-offering/v1/gen/document-model.js +421 -199
- package/dist/document-models/service-offering/v1/gen/document-schema.d.ts +9 -9
- package/dist/document-models/service-offering/v1/gen/index.d.ts +1 -0
- package/dist/document-models/service-offering/v1/gen/index.d.ts.map +1 -1
- package/dist/document-models/service-offering/v1/gen/index.js +1 -0
- package/dist/document-models/service-offering/v1/gen/offering/error.d.ts +41 -1
- package/dist/document-models/service-offering/v1/gen/offering/error.d.ts.map +1 -1
- package/dist/document-models/service-offering/v1/gen/offering/error.js +37 -1
- package/dist/document-models/service-offering/v1/gen/option-groups/error.d.ts +55 -1
- package/dist/document-models/service-offering/v1/gen/option-groups/error.d.ts.map +1 -1
- package/dist/document-models/service-offering/v1/gen/option-groups/error.js +53 -1
- package/dist/document-models/service-offering/v1/gen/ph-factories.js +3 -3
- package/dist/document-models/service-offering/v1/gen/schema/types.d.ts +134 -61
- package/dist/document-models/service-offering/v1/gen/schema/types.d.ts.map +1 -1
- package/dist/document-models/service-offering/v1/gen/schema/zod.d.ts +35 -10
- package/dist/document-models/service-offering/v1/gen/schema/zod.d.ts.map +1 -1
- package/dist/document-models/service-offering/v1/gen/schema/zod.js +182 -64
- package/dist/document-models/service-offering/v1/gen/services/error.d.ts +20 -1
- package/dist/document-models/service-offering/v1/gen/services/error.d.ts.map +1 -1
- package/dist/document-models/service-offering/v1/gen/services/error.js +16 -1
- package/dist/document-models/service-offering/v1/gen/tiers/error.d.ts +100 -1
- package/dist/document-models/service-offering/v1/gen/tiers/error.d.ts.map +1 -1
- package/dist/document-models/service-offering/v1/gen/tiers/error.js +106 -1
- package/dist/document-models/service-offering/v1/gen/utils.js +4 -4
- package/dist/document-models/service-offering/v1/module.d.ts +1 -1
- package/dist/document-models/service-offering/v1/module.d.ts.map +1 -1
- package/dist/document-models/service-offering/v1/module.js +4 -1
- package/dist/document-models/service-offering/v1/src/reducers/offering.d.ts.map +1 -1
- package/dist/document-models/service-offering/v1/src/reducers/offering.js +20 -12
- package/dist/document-models/service-offering/v1/src/reducers/option-groups.d.ts.map +1 -1
- package/dist/document-models/service-offering/v1/src/reducers/option-groups.js +157 -39
- package/dist/document-models/service-offering/v1/src/reducers/services.d.ts.map +1 -1
- package/dist/document-models/service-offering/v1/src/reducers/services.js +17 -14
- package/dist/document-models/service-offering/v1/src/reducers/tiers.d.ts.map +1 -1
- package/dist/document-models/service-offering/v1/src/reducers/tiers.js +111 -78
- package/dist/document-models/service-offering/v1/src/utils.d.ts +60 -1
- package/dist/document-models/service-offering/v1/src/utils.d.ts.map +1 -1
- package/dist/document-models/service-offering/v1/src/utils.js +173 -1
- package/dist/document-models/service-offering/v1/tests/option-groups.test.js +1 -1
- package/dist/document-models/service-offering/v1/utils.d.ts +3 -0
- package/dist/document-models/service-offering/v1/utils.d.ts.map +1 -1
- package/dist/document-models/subscription-instance/v1/actions.d.ts +3 -1
- package/dist/document-models/subscription-instance/v1/actions.d.ts.map +1 -1
- package/dist/document-models/subscription-instance/v1/gen/controller.d.ts +4 -0
- package/dist/document-models/subscription-instance/v1/gen/controller.d.ts.map +1 -0
- package/dist/document-models/subscription-instance/v1/gen/controller.js +3 -0
- package/dist/document-models/subscription-instance/v1/gen/document-model.d.ts.map +1 -1
- package/dist/document-models/subscription-instance/v1/gen/document-model.js +488 -246
- package/dist/document-models/subscription-instance/v1/gen/document-schema.d.ts +3 -3
- package/dist/document-models/subscription-instance/v1/gen/index.d.ts +1 -0
- package/dist/document-models/subscription-instance/v1/gen/index.d.ts.map +1 -1
- package/dist/document-models/subscription-instance/v1/gen/index.js +1 -0
- package/dist/document-models/subscription-instance/v1/gen/metrics/error.d.ts +73 -1
- package/dist/document-models/subscription-instance/v1/gen/metrics/error.d.ts.map +1 -1
- package/dist/document-models/subscription-instance/v1/gen/metrics/error.js +86 -1
- package/dist/document-models/subscription-instance/v1/gen/ph-factories.js +1 -1
- package/dist/document-models/subscription-instance/v1/gen/schema/types.d.ts +199 -82
- package/dist/document-models/subscription-instance/v1/gen/schema/types.d.ts.map +1 -1
- package/dist/document-models/subscription-instance/v1/gen/schema/zod.d.ts +22 -12
- package/dist/document-models/subscription-instance/v1/gen/schema/zod.d.ts.map +1 -1
- package/dist/document-models/subscription-instance/v1/gen/schema/zod.js +230 -84
- package/dist/document-models/subscription-instance/v1/gen/service/error.d.ts +62 -1
- package/dist/document-models/subscription-instance/v1/gen/service/error.d.ts.map +1 -1
- package/dist/document-models/subscription-instance/v1/gen/service/error.js +60 -1
- package/dist/document-models/subscription-instance/v1/gen/service-group/error.d.ts +39 -1
- package/dist/document-models/subscription-instance/v1/gen/service-group/error.d.ts.map +1 -1
- package/dist/document-models/subscription-instance/v1/gen/service-group/error.js +39 -1
- package/dist/document-models/subscription-instance/v1/gen/subscription/error.d.ts +55 -1
- package/dist/document-models/subscription-instance/v1/gen/subscription/error.d.ts.map +1 -1
- package/dist/document-models/subscription-instance/v1/gen/subscription/error.js +51 -1
- package/dist/document-models/subscription-instance/v1/gen/utils.js +2 -2
- package/dist/document-models/subscription-instance/v1/module.d.ts +1 -1
- package/dist/document-models/subscription-instance/v1/module.d.ts.map +1 -1
- package/dist/document-models/subscription-instance/v1/module.js +4 -1
- package/dist/document-models/subscription-instance/v1/src/reducers/customer.d.ts.map +1 -1
- package/dist/document-models/subscription-instance/v1/src/reducers/customer.js +1 -0
- package/dist/document-models/subscription-instance/v1/src/reducers/metrics.d.ts.map +1 -1
- package/dist/document-models/subscription-instance/v1/src/reducers/metrics.js +70 -45
- package/dist/document-models/subscription-instance/v1/src/reducers/service-group.d.ts.map +1 -1
- package/dist/document-models/subscription-instance/v1/src/reducers/service-group.js +108 -30
- package/dist/document-models/subscription-instance/v1/src/reducers/service.d.ts.map +1 -1
- package/dist/document-models/subscription-instance/v1/src/reducers/service.js +108 -39
- package/dist/document-models/subscription-instance/v1/src/reducers/subscription.d.ts.map +1 -1
- package/dist/document-models/subscription-instance/v1/src/reducers/subscription.js +193 -35
- package/dist/editors/resource-instance-editor/editor.d.ts.map +1 -1
- package/dist/editors/resource-instance-editor/editor.js +13 -3
- package/dist/editors/service-offering-editor/components/ResourceTemplateSelector.d.ts.map +1 -1
- package/dist/editors/service-offering-editor/components/ResourceTemplateSelector.js +4 -2
- package/dist/editors/service-offering-editor/components/ServiceCatalog.d.ts.map +1 -1
- package/dist/editors/service-offering-editor/components/ServiceCatalog.js +189 -32
- package/dist/editors/service-offering-editor/components/TheMatrix.d.ts +1 -1
- package/dist/editors/service-offering-editor/components/TheMatrix.d.ts.map +1 -1
- package/dist/editors/service-offering-editor/components/TheMatrix.js +295 -140
- package/dist/editors/service-offering-editor/components/TierDefinition.d.ts.map +1 -1
- package/dist/editors/service-offering-editor/components/TierDefinition.js +2 -0
- package/dist/editors/service-offering-editor/components/TierPricingOptionsPanel.js +3 -3
- package/dist/editors/service-offering-editor/components/pricing-utils.d.ts.map +1 -1
- package/dist/editors/service-offering-editor/components/pricing-utils.js +26 -7
- package/dist/editors/subscription-instance-editor/components/BillingPanel.d.ts.map +1 -1
- package/dist/editors/subscription-instance-editor/components/BillingPanel.js +4 -4
- package/dist/editors/subscription-instance-editor/components/CustomerInfo.d.ts.map +1 -1
- package/dist/editors/subscription-instance-editor/components/CustomerInfo.js +3 -2
- package/dist/editors/subscription-instance-editor/components/ImportServiceConfigButton.d.ts +3 -0
- package/dist/editors/subscription-instance-editor/components/ImportServiceConfigButton.d.ts.map +1 -1
- package/dist/editors/subscription-instance-editor/components/ImportServiceConfigButton.js +12 -0
- package/dist/editors/subscription-instance-editor/components/MetricActions.d.ts.map +1 -1
- package/dist/editors/subscription-instance-editor/components/MetricActions.js +4 -2
- package/dist/editors/subscription-instance-editor/components/MockDataButton.d.ts.map +1 -1
- package/dist/editors/subscription-instance-editor/components/MockDataButton.js +214 -2
- package/dist/editors/subscription-instance-editor/components/OperatorNotes.js +1 -1
- package/dist/editors/subscription-instance-editor/components/ServicesPanel.d.ts.map +1 -1
- package/dist/editors/subscription-instance-editor/components/ServicesPanel.js +9 -20
- package/dist/editors/subscription-instance-editor/components/SubscriptionActions.d.ts.map +1 -1
- package/dist/editors/subscription-instance-editor/components/SubscriptionActions.js +8 -9
- package/dist/editors/subscription-instance-editor/components/SubscriptionHeader.d.ts.map +1 -1
- package/dist/editors/subscription-instance-editor/components/SubscriptionHeader.js +1 -1
- package/dist/editors/subscription-instance-editor/components/billing-utils.d.ts +14 -6
- package/dist/editors/subscription-instance-editor/components/billing-utils.d.ts.map +1 -1
- package/dist/editors/subscription-instance-editor/components/billing-utils.js +19 -23
- package/dist/editors/subscription-instance-editor/components/mapOfferingToSubscription.d.ts +16 -2
- package/dist/editors/subscription-instance-editor/components/mapOfferingToSubscription.d.ts.map +1 -1
- package/dist/editors/subscription-instance-editor/components/mapOfferingToSubscription.js +155 -6
- package/dist/powerhouse.manifest.json +29 -3
- package/dist/style.css +14 -0
- package/dist/subgraphs/resources-services/resolvers.d.ts +2 -2
- package/dist/subgraphs/resources-services/resolvers.d.ts.map +1 -1
- package/dist/subgraphs/resources-services/resolvers.js +262 -196
- package/package.json +22 -18
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TierDefinition.d.ts","sourceRoot":"","sources":["../../../../editors/service-offering-editor/components/TierDefinition.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EACV,uBAAuB,EACvB,qBAAqB,EAItB,MAAM,kEAAkE,CAAC;AAW1E,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,uBAAuB,CAAC;IAClC,QAAQ,EAAE,gBAAgB,CAAC,qBAAqB,CAAC,CAAC;CACnD;AAsFD,wBAAgB,cAAc,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,mBAAmB,
|
|
1
|
+
{"version":3,"file":"TierDefinition.d.ts","sourceRoot":"","sources":["../../../../editors/service-offering-editor/components/TierDefinition.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EACV,uBAAuB,EACvB,qBAAqB,EAItB,MAAM,kEAAkE,CAAC;AAW1E,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,uBAAuB,CAAC;IAClC,QAAQ,EAAE,gBAAgB,CAAC,qBAAqB,CAAC,CAAC;CACnD;AAsFD,wBAAgB,cAAc,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,mBAAmB,2CA4WzE"}
|
|
@@ -93,6 +93,7 @@ export function TierDefinition({ document, dispatch }) {
|
|
|
93
93
|
dispatch(addTier({
|
|
94
94
|
id: generateId(),
|
|
95
95
|
name: newTier.name.trim(),
|
|
96
|
+
currency: newTier.currency,
|
|
96
97
|
isCustomPricing: newTier.isCustomPricing,
|
|
97
98
|
lastModified: new Date().toISOString(),
|
|
98
99
|
}));
|
|
@@ -122,6 +123,7 @@ export function TierDefinition({ document, dispatch }) {
|
|
|
122
123
|
dispatch(addTier({
|
|
123
124
|
id: generateId(),
|
|
124
125
|
name: tierConfig.name,
|
|
126
|
+
currency: "USD",
|
|
125
127
|
isCustomPricing: tierConfig.isCustomPricing,
|
|
126
128
|
lastModified: now,
|
|
127
129
|
}));
|
|
@@ -27,11 +27,11 @@ export function BillingCycleConfigPanel({ basePrice, currency, billingCycleDisco
|
|
|
27
27
|
const isCycleEnabled = (cycle) => {
|
|
28
28
|
if (cycle === "MONTHLY")
|
|
29
29
|
return true;
|
|
30
|
-
return billingCycleDiscounts.some((d) => d.
|
|
30
|
+
return billingCycleDiscounts.some((d) => d.billingCycle === cycle);
|
|
31
31
|
};
|
|
32
32
|
const getDiscountValue = (cycle) => {
|
|
33
|
-
const entry = billingCycleDiscounts.find((d) => d.
|
|
34
|
-
return entry?.discountValue ?? 0;
|
|
33
|
+
const entry = billingCycleDiscounts.find((d) => d.billingCycle === cycle);
|
|
34
|
+
return entry?.discountRule?.discountValue ?? 0;
|
|
35
35
|
};
|
|
36
36
|
const getCycleTotal = (cycle) => {
|
|
37
37
|
if (!hasBasePrice)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pricing-utils.d.ts","sourceRoot":"","sources":["../../../../editors/service-offering-editor/components/pricing-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACZ,MAAM,kEAAkE,CAAC;AAE1E,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"pricing-utils.d.ts","sourceRoot":"","sources":["../../../../editors/service-offering-editor/components/pricing-utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACZ,MAAM,kEAAkE,CAAC;AAE1E,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAM7D,CAAC;AAGF,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAM7D,CAAC;AAGF,eAAO,MAAM,0BAA0B,EAAE,MAAM,CAAC,YAAY,EAAE,MAAM,CAMnE,CAAC;AAGF,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAc,GAAG,MAAM,CAM5E;AAGD,eAAO,MAAM,wBAAwB,EAAE,YAAY,EAKlD,CAAC;AAIF,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,kBAAkB,EAAE,CAAC;IACrC,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B;AA0BD,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,WAAW,EAAE,EAC5B,YAAY,EAAE,YAAY,EAC1B,MAAM,CAAC,EAAE,MAAM,GACd,mBAAmB,CA0CrB;AAKD,wBAAgB,4BAA4B,CAAC,SAAS,EAAE;IACtD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACnE,GAAG;IACF,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;CACtB,CAiCA;AAKD,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,WAAW,EAAE,EAC5B,kBAAkB,EAAE,YAAY,EAChC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,GAC5C;IAAE,aAAa,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAkBtE"}
|
|
@@ -3,19 +3,25 @@ export const BILLING_CYCLE_MONTHS = {
|
|
|
3
3
|
QUARTERLY: 3,
|
|
4
4
|
SEMI_ANNUAL: 6,
|
|
5
5
|
ANNUAL: 12,
|
|
6
|
+
ONE_TIME: 0,
|
|
6
7
|
};
|
|
8
|
+
// Human-readable billing cycle labels
|
|
7
9
|
export const BILLING_CYCLE_LABELS = {
|
|
8
10
|
MONTHLY: "monthly",
|
|
9
11
|
QUARTERLY: "quarterly",
|
|
10
12
|
SEMI_ANNUAL: "semi-annually",
|
|
11
13
|
ANNUAL: "annually",
|
|
14
|
+
ONE_TIME: "one-time",
|
|
12
15
|
};
|
|
16
|
+
// Short labels for dropdowns
|
|
13
17
|
export const BILLING_CYCLE_SHORT_LABELS = {
|
|
14
18
|
MONTHLY: "Month",
|
|
15
19
|
QUARTERLY: "Quarter",
|
|
16
20
|
SEMI_ANNUAL: "6 Months",
|
|
17
21
|
ANNUAL: "Year",
|
|
22
|
+
ONE_TIME: "One Time",
|
|
18
23
|
};
|
|
24
|
+
// Format price with currency symbol
|
|
19
25
|
export function formatPrice(amount, currency = "USD") {
|
|
20
26
|
const symbol = currency === "USD" ? "$" : currency;
|
|
21
27
|
return `${symbol}${amount.toLocaleString("en-US", {
|
|
@@ -23,20 +29,25 @@ export function formatPrice(amount, currency = "USD") {
|
|
|
23
29
|
maximumFractionDigits: 2,
|
|
24
30
|
})}`;
|
|
25
31
|
}
|
|
32
|
+
// Get available billing cycles (excluding ONE_TIME for most cases)
|
|
26
33
|
export const RECURRING_BILLING_CYCLES = [
|
|
27
34
|
"MONTHLY",
|
|
28
35
|
"QUARTERLY",
|
|
29
36
|
"SEMI_ANNUAL",
|
|
30
37
|
"ANNUAL",
|
|
31
38
|
];
|
|
39
|
+
// Get the monthly recurring price for a specific group-tier pair
|
|
40
|
+
// Reads from tierDependentPricing first, falls back to standalonePricing
|
|
32
41
|
function getGroupPriceForTier(group, tierId) {
|
|
33
42
|
const tierPricing = group.tierDependentPricing?.find((tp) => tp.tierId === tierId);
|
|
34
43
|
if (tierPricing) {
|
|
35
|
-
const
|
|
36
|
-
|
|
44
|
+
const monthlyPricing = tierPricing.recurringPricing?.find((p) => p.billingCycle === "MONTHLY");
|
|
45
|
+
const amount = monthlyPricing?.amount ?? 0;
|
|
46
|
+
return { amount, hasPrice: monthlyPricing != null && amount > 0 };
|
|
37
47
|
}
|
|
38
|
-
const
|
|
39
|
-
|
|
48
|
+
const monthlyPricing = group.standalonePricing?.recurringPricing?.find((p) => p.billingCycle === "MONTHLY");
|
|
49
|
+
const amount = monthlyPricing?.amount ?? 0;
|
|
50
|
+
return { amount, hasPrice: monthlyPricing != null && amount > 0 };
|
|
40
51
|
}
|
|
41
52
|
export function calculateTierRecurringPrice(regularGroups, billingCycle, tierId) {
|
|
42
53
|
const breakdown = [];
|
|
@@ -51,9 +62,10 @@ export function calculateTierRecurringPrice(regularGroups, billingCycle, tierId)
|
|
|
51
62
|
hasPrice = tierPrice.hasPrice;
|
|
52
63
|
}
|
|
53
64
|
else {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
65
|
+
// Legacy: no tierId, read from standalone
|
|
66
|
+
const monthlyPricing = group.standalonePricing?.recurringPricing?.find((p) => p.billingCycle === "MONTHLY");
|
|
67
|
+
amount = monthlyPricing?.amount ?? 0;
|
|
68
|
+
hasPrice = monthlyPricing != null && amount > 0;
|
|
57
69
|
}
|
|
58
70
|
if (!hasPrice) {
|
|
59
71
|
missingPriceGroups.push(group.name);
|
|
@@ -74,6 +86,9 @@ export function calculateTierRecurringPrice(regularGroups, billingCycle, tierId)
|
|
|
74
86
|
missingPriceGroups,
|
|
75
87
|
};
|
|
76
88
|
}
|
|
89
|
+
// Calculate effective setup price after applying discount
|
|
90
|
+
// Returns base amount, effective amount (floored at 0), and savings
|
|
91
|
+
// Works with both SetupCostPerCycle (ServiceGroup) and SetupCost (OptionGroup)
|
|
77
92
|
export function calculateEffectiveSetupPrice(setupCost) {
|
|
78
93
|
const baseAmount = setupCost.amount;
|
|
79
94
|
const discount = setupCost.discount;
|
|
@@ -104,11 +119,15 @@ export function calculateEffectiveSetupPrice(setupCost) {
|
|
|
104
119
|
hasDiscount: true,
|
|
105
120
|
};
|
|
106
121
|
}
|
|
122
|
+
// Detect billing cycle majority among regular groups
|
|
123
|
+
// Returns suggestion when >50% of groups share a cycle different from current global
|
|
124
|
+
// groupOverrides: runtime cycle overrides keyed by group.id (from UI state)
|
|
107
125
|
export function detectMajorityCycle(regularGroups, currentGlobalCycle, groupOverrides) {
|
|
108
126
|
const cycleCounts = new Map();
|
|
109
127
|
if (regularGroups.length === 0)
|
|
110
128
|
return null;
|
|
111
129
|
for (const group of regularGroups) {
|
|
130
|
+
// Effective cycle: override if set, otherwise global
|
|
112
131
|
const effectiveCycle = groupOverrides?.[group.id] || currentGlobalCycle;
|
|
113
132
|
cycleCounts.set(effectiveCycle, (cycleCounts.get(effectiveCycle) || 0) + 1);
|
|
114
133
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BillingPanel.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/BillingPanel.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC7B,MAAM,uEAAuE,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"BillingPanel.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/BillingPanel.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC7B,MAAM,uEAAuE,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAY5C,UAAU,iBAAiB;IACzB,QAAQ,EAAE,4BAA4B,CAAC;IACvC,QAAQ,EAAE,gBAAgB,CAAC,0BAA0B,CAAC,CAAC;IACvD,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,EAAE,iBAAiB,2CA8O3D"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from "react";
|
|
3
|
-
import { formatCurrency, formatDate, formatBillingCycleSuffix, computeBillingBreakdown, } from "./billing-utils.js";
|
|
3
|
+
import { formatCurrency, formatDate, formatBillingCycleSuffix, formatDiscountBadge, computeBillingBreakdown, } from "./billing-utils.js";
|
|
4
4
|
export function BillingPanel({ document }) {
|
|
5
5
|
const state = document.state.global;
|
|
6
6
|
const breakdown = computeBillingBreakdown(state);
|
|
@@ -27,14 +27,14 @@ export function BillingPanel({ document }) {
|
|
|
27
27
|
.filter((g) => g.recurringAmount != null && g.recurringAmount > 0)
|
|
28
28
|
.map((group) => (_jsx(GroupFixedCostRow, { group: group, currency: currency }, group.groupId))), state.services
|
|
29
29
|
.filter((svc) => svc.recurringCost)
|
|
30
|
-
.map((svc) => (_jsxs("div", { className: "si-billing-line", children: [
|
|
30
|
+
.map((svc) => (_jsxs("div", { className: "si-billing-line", children: [_jsxs("span", { className: "si-billing-line__name", children: [svc.name || "Service", svc.recurringCost?.billingCycle && (_jsx("span", { className: "si-billing-line__cycle", children: formatBillingCycleSuffix(svc.recurringCost.billingCycle) }))] }), _jsx("span", { className: "si-billing-line__amount", children: formatCurrency(svc.recurringCost.amount, currency) })] }, svc.id)))] }), _jsxs("div", { className: "si-billing-section-subtotal", children: [_jsx("span", { className: "si-billing-section-subtotal__label", children: "Fixed Subtotal" }), _jsx("span", { className: "si-billing-section-subtotal__amount", children: formatCurrency(breakdown.fixedTotal, currency) })] })] })), (breakdown.groupBreakdowns.some((g) => g.metricOverages.length > 0) ||
|
|
31
31
|
breakdown.standaloneOverages.length > 0) && (_jsxs("div", { className: "si-billing-section", children: [_jsx("div", { className: "si-billing-section-label", children: _jsx("span", { className: "si-billing-section-label__text", children: "Dynamic Costs *" }) }), _jsxs("div", { className: "si-billing-section__lines", children: [breakdown.groupBreakdowns
|
|
32
32
|
.filter((g) => g.metricOverages.length > 0)
|
|
33
33
|
.map((group) => (_jsx(GroupMetricOverageRows, { group: group, currency: currency }, group.groupId))), breakdown.standaloneOverages.map((overage) => (_jsx(MetricOverageRow, { overage: overage, currency: currency }, overage.metricId)))] }), _jsxs("div", { className: "si-billing-section-subtotal", children: [_jsx("span", { className: "si-billing-section-subtotal__label", children: "Dynamic Subtotal *" }), _jsx("span", { className: "si-billing-section-subtotal__amount", children: formatCurrency(breakdown.dynamicTotal, currency) })] })] })), _jsxs("div", { className: "si-billing-total", children: [hasFixedCosts && hasDynamicCosts && (_jsx("div", { className: "si-billing-total__breakdown", children: _jsxs("span", { className: "si-billing-total__detail", children: ["Fixed ", formatCurrency(breakdown.fixedTotal, currency), " + Dynamic", " ", formatCurrency(breakdown.dynamicTotal, currency)] }) })), _jsxs("div", { className: "si-billing-total__row", children: [_jsxs("span", { className: "si-billing-total__label", children: ["Total Projected", hasDynamicCosts ? " *" : ""] }), _jsxs("span", { className: "si-billing-total__amount", children: [formatCurrency(projectedTotal, currency), breakdown.billingCycle && (_jsx("span", { className: "si-billing-total__cycle", children: formatBillingCycleSuffix(breakdown.billingCycle) }))] })] })] }), breakdown.setupLines.length > 0 && (_jsx(SetupCostsSection, { setupLines: breakdown.setupLines, setupTotal: breakdown.setupTotal, currency: currency, expanded: setupExpanded, onToggle: () => setSetupExpanded(!setupExpanded) }))] }));
|
|
34
34
|
}
|
|
35
35
|
// ─── Sub-components ─────────────────────────────────────────
|
|
36
36
|
function GroupFixedCostRow({ group, currency, }) {
|
|
37
|
-
return (_jsx("div", { className: "si-billing-group", children: _jsxs("div", { className: "si-billing-group__row", children: [_jsxs("span", { className: "si-billing-group__name", children: [group.groupName, group.optional && (_jsx("span", { className: "si-badge si-badge--violet si-badge--sm", style: { marginLeft: 8 }, children: "Add-on" }))] }),
|
|
37
|
+
return (_jsx("div", { className: "si-billing-group", children: _jsxs("div", { className: "si-billing-group__row", children: [_jsxs("span", { className: "si-billing-group__name", children: [group.groupName, group.optional && (_jsx("span", { className: "si-badge si-badge--violet si-badge--sm", style: { marginLeft: 8 }, children: "Add-on" })), group.recurringCycle && (_jsx("span", { className: "si-billing-line__cycle", children: formatBillingCycleSuffix(group.recurringCycle) }))] }), _jsxs("span", { className: "si-billing-group__amount-block", children: [group.discount && (_jsxs(_Fragment, { children: [_jsx("span", { className: "si-billing-group__original", children: formatCurrency(group.discount.originalAmount, currency) }), _jsx("span", { className: "si-billing-group__discount-badge", children: formatDiscountBadge(group.discount) })] })), _jsx("span", { className: "si-billing-group__amount", children: formatCurrency(group.recurringAmount ?? 0, group.recurringCurrency) })] })] }) }));
|
|
38
38
|
}
|
|
39
39
|
function GroupMetricOverageRows({ group, currency, }) {
|
|
40
40
|
return (_jsxs("div", { className: "si-billing-group-metrics", children: [_jsx("div", { className: "si-billing-group-metrics__header", children: group.groupName }), group.metricOverages.map((overage) => (_jsx(MetricOverageRow, { overage: overage, currency: currency }, overage.metricId)))] }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CustomerInfo.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/CustomerInfo.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAE7B,MAAM,uEAAuE,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAI5C,UAAU,iBAAiB;IACzB,QAAQ,EAAE,4BAA4B,CAAC;IACvC,QAAQ,EAAE,gBAAgB,CAAC,0BAA0B,CAAC,CAAC;IACvD,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"CustomerInfo.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/CustomerInfo.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAE7B,MAAM,uEAAuE,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAI5C,UAAU,iBAAiB;IACzB,QAAQ,EAAE,4BAA4B,CAAC;IACvC,QAAQ,EAAE,gBAAgB,CAAC,0BAA0B,CAAC,CAAC;IACvD,IAAI,EAAE,QAAQ,CAAC;CAChB;AAED,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,iBAAiB,2CAoQ3E"}
|
|
@@ -38,9 +38,10 @@ export function CustomerInfo({ document, dispatch, mode }) {
|
|
|
38
38
|
const handleSaveType = useCallback(() => {
|
|
39
39
|
dispatch(setCustomerType({
|
|
40
40
|
customerType: editType,
|
|
41
|
+
teamMemberCount: editType === "TEAM" ? editMemberCount : undefined,
|
|
41
42
|
}));
|
|
42
43
|
setIsEditingType(false);
|
|
43
|
-
}, [dispatch, editType]);
|
|
44
|
+
}, [dispatch, editType, editMemberCount]);
|
|
44
45
|
const handleCancelType = useCallback(() => {
|
|
45
46
|
setEditType(state.customerType || "INDIVIDUAL");
|
|
46
47
|
setEditMemberCount(state.teamMemberCount || 1);
|
|
@@ -51,5 +52,5 @@ export function CustomerInfo({ document, dispatch, mode }) {
|
|
|
51
52
|
};
|
|
52
53
|
// Edit button component for reuse
|
|
53
54
|
const EditButton = ({ onClick }) => (_jsx("button", { type: "button", className: "si-customer-info__edit-btn", onClick: onClick, "aria-label": "Edit", children: _jsx("svg", { viewBox: "0 0 20 20", fill: "currentColor", children: _jsx("path", { d: "M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z" }) }) }));
|
|
54
|
-
return (_jsxs("div", { className: "si-panel si-panel--compact", children: [_jsx("div", { className: "si-panel__header", children: _jsx("h3", { className: "si-panel__title", children: mode === "client" ? "Your Information" : "Customer Information" }) }), _jsxs("div", { className: "si-customer-info", children: [_jsxs("div", { className: "si-customer-info__section", children: [_jsxs("div", { className: "si-customer-info__row", children: [_jsx("span", { className: "si-customer-info__label", children: "Name" }), isEditingName ? (_jsxs("div", { className: "si-customer-info__edit-field", children: [_jsx("input", { type: "text", className: "si-input si-input--sm", value: editName, onChange: (e) => setEditName(e.target.value), placeholder: "Enter name..." }), _jsxs("div", { className: "si-customer-info__edit-actions", children: [_jsx("button", { type: "button", className: "si-btn si-btn--xs si-btn--ghost", onClick: handleCancelName, children: "Cancel" }), _jsx("button", { type: "button", className: "si-btn si-btn--xs si-btn--primary", onClick: handleSaveName, children: "Save" })] })] })) : (_jsxs("span", { className: "si-customer-info__value", children: [state.customerName || (_jsx("span", { className: "si-customer-info__value--empty", children: "Not set" })), _jsx(EditButton, { onClick: () => setIsEditingName(true) })] }))] }), _jsxs("div", { className: "si-customer-info__row", children: [_jsx("span", { className: "si-customer-info__label", children: "Email" }), isEditingEmail ? (_jsxs("div", { className: "si-customer-info__edit-field", children: [_jsx("input", { type: "email", className: "si-input si-input--sm", value: editEmail, onChange: (e) => setEditEmail(e.target.value), placeholder: "email@example.com" }), _jsxs("div", { className: "si-customer-info__edit-actions", children: [_jsx("button", { type: "button", className: "si-btn si-btn--xs si-btn--ghost", onClick: handleCancelEmail, children: "Cancel" }), _jsx("button", { type: "button", className: "si-btn si-btn--xs si-btn--primary", onClick: handleSaveEmail, disabled: editEmail !== "" && !isValidEmail(editEmail), children: "Save" })] })] })) : (_jsxs("span", { className: "si-customer-info__value", children: [state.customerEmail || (_jsx("span", { className: "si-customer-info__value--empty", children: "Not set" })), _jsx(EditButton, { onClick: () => setIsEditingEmail(true) })] }))] }), _jsxs("div", { className: "si-customer-info__row", children: [_jsx("span", { className: "si-customer-info__label", children: "Type" }), isEditingType ? (_jsxs("div", { className: "si-customer-info__edit-field", children: [_jsxs("div", { className: "si-customer-info__type-edit", children: [_jsxs("select", { className: "si-input si-input--sm si-select", value: editType, onChange: (e) => setEditType(e.target.value), children: [_jsx("option", { value: "INDIVIDUAL", children: "Individual" }), _jsx("option", { value: "TEAM", children: "Team" })] }), editType === "TEAM" && (_jsx("input", { type: "number", className: "si-input si-input--sm si-input--number", value: editMemberCount, onChange: (e) => setEditMemberCount(parseInt(e.target.value) || 1), min: "1", placeholder: "Members" }))] }), _jsxs("div", { className: "si-customer-info__edit-actions", children: [_jsx("button", { type: "button", className: "si-btn si-btn--xs si-btn--ghost", onClick: handleCancelType, children: "Cancel" }), _jsx("button", { type: "button", className: "si-btn si-btn--xs si-btn--primary", onClick: handleSaveType, children: "Save" })] })] })) : (_jsxs("span", { className: "si-customer-info__value", children: [state.customerType ? (_jsxs(_Fragment, { children: [state.customerType === "TEAM" ? "Team" : "Individual", state.customerType === "TEAM" && state.teamMemberCount && (_jsxs("span", { className: "si-customer-info__detail", children: [" ", "(", state.teamMemberCount, " members)"] }))] })) : (_jsx("span", { className: "si-customer-info__value--empty", children: "Not set" })), _jsx(EditButton, { onClick: () => setIsEditingType(true) })] }))] })] }), mode === "operator" && state.budget && (_jsx("div", { className: "si-customer-info__section", children: _jsxs("div", { className: "si-customer-info__row", children: [_jsx("span", { className: "si-customer-info__label", children: "Budget Category" }), _jsx("span", { className: "si-customer-info__value", children: state.budget.
|
|
55
|
+
return (_jsxs("div", { className: "si-panel si-panel--compact", children: [_jsx("div", { className: "si-panel__header", children: _jsx("h3", { className: "si-panel__title", children: mode === "client" ? "Your Information" : "Customer Information" }) }), _jsxs("div", { className: "si-customer-info", children: [_jsxs("div", { className: "si-customer-info__section", children: [_jsxs("div", { className: "si-customer-info__row", children: [_jsx("span", { className: "si-customer-info__label", children: "Name" }), isEditingName ? (_jsxs("div", { className: "si-customer-info__edit-field", children: [_jsx("input", { type: "text", className: "si-input si-input--sm", value: editName, onChange: (e) => setEditName(e.target.value), placeholder: "Enter name..." }), _jsxs("div", { className: "si-customer-info__edit-actions", children: [_jsx("button", { type: "button", className: "si-btn si-btn--xs si-btn--ghost", onClick: handleCancelName, children: "Cancel" }), _jsx("button", { type: "button", className: "si-btn si-btn--xs si-btn--primary", onClick: handleSaveName, children: "Save" })] })] })) : (_jsxs("span", { className: "si-customer-info__value", children: [state.customerName || (_jsx("span", { className: "si-customer-info__value--empty", children: "Not set" })), _jsx(EditButton, { onClick: () => setIsEditingName(true) })] }))] }), _jsxs("div", { className: "si-customer-info__row", children: [_jsx("span", { className: "si-customer-info__label", children: "Email" }), isEditingEmail ? (_jsxs("div", { className: "si-customer-info__edit-field", children: [_jsx("input", { type: "email", className: "si-input si-input--sm", value: editEmail, onChange: (e) => setEditEmail(e.target.value), placeholder: "email@example.com" }), _jsxs("div", { className: "si-customer-info__edit-actions", children: [_jsx("button", { type: "button", className: "si-btn si-btn--xs si-btn--ghost", onClick: handleCancelEmail, children: "Cancel" }), _jsx("button", { type: "button", className: "si-btn si-btn--xs si-btn--primary", onClick: handleSaveEmail, disabled: editEmail !== "" && !isValidEmail(editEmail), children: "Save" })] })] })) : (_jsxs("span", { className: "si-customer-info__value", children: [state.customerEmail || (_jsx("span", { className: "si-customer-info__value--empty", children: "Not set" })), _jsx(EditButton, { onClick: () => setIsEditingEmail(true) })] }))] }), _jsxs("div", { className: "si-customer-info__row", children: [_jsx("span", { className: "si-customer-info__label", children: "Type" }), isEditingType ? (_jsxs("div", { className: "si-customer-info__edit-field", children: [_jsxs("div", { className: "si-customer-info__type-edit", children: [_jsxs("select", { className: "si-input si-input--sm si-select", value: editType, onChange: (e) => setEditType(e.target.value), children: [_jsx("option", { value: "INDIVIDUAL", children: "Individual" }), _jsx("option", { value: "TEAM", children: "Team" })] }), editType === "TEAM" && (_jsx("input", { type: "number", className: "si-input si-input--sm si-input--number", value: editMemberCount, onChange: (e) => setEditMemberCount(parseInt(e.target.value) || 1), min: "1", placeholder: "Members" }))] }), _jsxs("div", { className: "si-customer-info__edit-actions", children: [_jsx("button", { type: "button", className: "si-btn si-btn--xs si-btn--ghost", onClick: handleCancelType, children: "Cancel" }), _jsx("button", { type: "button", className: "si-btn si-btn--xs si-btn--primary", onClick: handleSaveType, children: "Save" })] })] })) : (_jsxs("span", { className: "si-customer-info__value", children: [state.customerType ? (_jsxs(_Fragment, { children: [state.customerType === "TEAM" ? "Team" : "Individual", state.customerType === "TEAM" && state.teamMemberCount && (_jsxs("span", { className: "si-customer-info__detail", children: [" ", "(", state.teamMemberCount, " members)"] }))] })) : (_jsx("span", { className: "si-customer-info__value--empty", children: "Not set" })), _jsx(EditButton, { onClick: () => setIsEditingType(true) })] }))] })] }), mode === "operator" && state.budget && (_jsx("div", { className: "si-customer-info__section", children: _jsxs("div", { className: "si-customer-info__row", children: [_jsx("span", { className: "si-customer-info__label", children: "Budget Category" }), _jsx("span", { className: "si-customer-info__value", children: state.budget.label })] }) }))] })] }));
|
|
55
56
|
}
|
|
@@ -5,8 +5,11 @@ import type { BillingCycle } from "../../../document-models/subscription-instanc
|
|
|
5
5
|
interface ImportServiceConfigButtonProps {
|
|
6
6
|
document: SubscriptionInstanceDocument;
|
|
7
7
|
dispatch: DocumentDispatch<SubscriptionInstanceAction>;
|
|
8
|
+
/** The Service Offering state to import from (from browser store) */
|
|
8
9
|
offeringState?: ServiceOfferingState;
|
|
10
|
+
/** The selected tier ID */
|
|
9
11
|
selectedTierId?: string;
|
|
12
|
+
/** The selected billing cycle */
|
|
10
13
|
selectedBillingCycle?: BillingCycle;
|
|
11
14
|
}
|
|
12
15
|
export declare function ImportServiceConfigButton({ document, dispatch, offeringState, selectedTierId, selectedBillingCycle, }: ImportServiceConfigButtonProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/editors/subscription-instance-editor/components/ImportServiceConfigButton.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImportServiceConfigButton.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/ImportServiceConfigButton.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC7B,MAAM,uEAAuE,CAAC;AAE/E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kEAAkE,CAAC;
|
|
1
|
+
{"version":3,"file":"ImportServiceConfigButton.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/ImportServiceConfigButton.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC7B,MAAM,uEAAuE,CAAC;AAE/E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kEAAkE,CAAC;AAG7G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uEAAuE,CAAC;AAG1G,UAAU,8BAA8B;IACtC,QAAQ,EAAE,4BAA4B,CAAC;IACvC,QAAQ,EAAE,gBAAgB,CAAC,0BAA0B,CAAC,CAAC;IACvD,qEAAqE;IACrE,aAAa,CAAC,EAAE,oBAAoB,CAAC;IACrC,2BAA2B;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,iCAAiC;IACjC,oBAAoB,CAAC,EAAE,YAAY,CAAC;CACrC;AAED,wBAAgB,yBAAyB,CAAC,EACxC,QAAQ,EACR,QAAQ,EACR,aAAa,EACb,cAAc,EACd,oBAAoB,GACrB,EAAE,8BAA8B,2CA8DhC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback } from "react";
|
|
3
3
|
import { initializeSubscription } from "../../../document-models/subscription-instance/v1/gen/subscription/creators.js";
|
|
4
|
+
import { getUserSelectionPriceBreakdown } from "../../../document-models/service-offering/v1/src/utils.js";
|
|
4
5
|
import { mapOfferingToSubscription } from "./mapOfferingToSubscription.js";
|
|
5
6
|
export function ImportServiceConfigButton({ document, dispatch, offeringState, selectedTierId, selectedBillingCycle, }) {
|
|
6
7
|
const hasServices = document.state.global.services.length > 0 ||
|
|
@@ -9,11 +10,22 @@ export function ImportServiceConfigButton({ document, dispatch, offeringState, s
|
|
|
9
10
|
const importServiceConfig = useCallback(() => {
|
|
10
11
|
if (!offeringState || !selectedTierId || !selectedBillingCycle)
|
|
11
12
|
return;
|
|
13
|
+
// Wrap global state to match ServiceOfferingPHState shape for price breakdown
|
|
14
|
+
const phState = {
|
|
15
|
+
global: offeringState,
|
|
16
|
+
local: {},
|
|
17
|
+
};
|
|
18
|
+
const priceBreakdown = getUserSelectionPriceBreakdown(phState, {
|
|
19
|
+
tierId: selectedTierId,
|
|
20
|
+
billingCycle: selectedBillingCycle,
|
|
21
|
+
optionGroupIds: [],
|
|
22
|
+
});
|
|
12
23
|
const input = mapOfferingToSubscription({
|
|
13
24
|
offering: offeringState,
|
|
14
25
|
tierId: selectedTierId,
|
|
15
26
|
selectedBillingCycle,
|
|
16
27
|
createdAt: new Date().toISOString(),
|
|
28
|
+
priceBreakdown,
|
|
17
29
|
});
|
|
18
30
|
dispatch(initializeSubscription(input));
|
|
19
31
|
}, [dispatch, offeringState, selectedTierId, selectedBillingCycle]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MetricActions.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/MetricActions.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,uEAAuE,CAAC;AACxH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uEAAuE,CAAC;AAO3G,UAAU,kBAAkB;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,gBAAgB,CAAC,0BAA0B,CAAC,CAAC;IACvD,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,MAAM,EACN,QAAQ,EACR,UAAU,GACX,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"MetricActions.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/MetricActions.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,uEAAuE,CAAC;AACxH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uEAAuE,CAAC;AAO3G,UAAU,kBAAkB;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,gBAAgB,CAAC,0BAA0B,CAAC,CAAC;IACvD,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,wBAAgB,aAAa,CAAC,EAC5B,SAAS,EACT,MAAM,EACN,QAAQ,EACR,UAAU,GACX,EAAE,kBAAkB,kDAwKpB;AAED,UAAU,2BAA2B;IACnC,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,aAAa,CAAC;IACtB,QAAQ,EAAE,gBAAgB,CAAC,0BAA0B,CAAC,CAAC;CACxD;AAED,wBAAgB,sBAAsB,CAAC,EACrC,MAAM,EACN,OAAO,EACP,SAAS,EACT,MAAM,EACN,QAAQ,GACT,EAAE,2BAA2B,kDAmE7B"}
|
|
@@ -8,14 +8,16 @@ export function MetricActions({ serviceId, metric, dispatch, isOperator, }) {
|
|
|
8
8
|
dispatch(incrementMetricUsage({
|
|
9
9
|
serviceId,
|
|
10
10
|
metricId: metric.id,
|
|
11
|
-
amount,
|
|
11
|
+
incrementBy: amount,
|
|
12
|
+
currentTime: new Date().toISOString(),
|
|
12
13
|
}));
|
|
13
14
|
}, [dispatch, serviceId, metric.id]);
|
|
14
15
|
const handleDecrement = useCallback((amount = 1) => {
|
|
15
16
|
dispatch(decrementMetricUsage({
|
|
16
17
|
serviceId,
|
|
17
18
|
metricId: metric.id,
|
|
18
|
-
amount,
|
|
19
|
+
decrementBy: amount,
|
|
20
|
+
currentTime: new Date().toISOString(),
|
|
19
21
|
}));
|
|
20
22
|
}, [dispatch, serviceId, metric.id]);
|
|
21
23
|
const handleAdjust = useCallback(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MockDataButton.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/MockDataButton.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC7B,MAAM,uEAAuE,CAAC;AAS/E,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,4BAA4B,CAAC;IACvC,QAAQ,EAAE,gBAAgB,CAAC,0BAA0B,CAAC,CAAC;CACxD;AAED,wBAAgB,cAAc,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,mBAAmB,
|
|
1
|
+
{"version":3,"file":"MockDataButton.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/MockDataButton.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC7B,MAAM,uEAAuE,CAAC;AAS/E,UAAU,mBAAmB;IAC3B,QAAQ,EAAE,4BAA4B,CAAC;IACvC,QAAQ,EAAE,gBAAgB,CAAC,0BAA0B,CAAC,CAAC;CACxD;AAED,wBAAgB,cAAc,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,mBAAmB,2CAySzE"}
|
|
@@ -10,28 +10,240 @@ export function MockDataButton({ document, dispatch }) {
|
|
|
10
10
|
const oneMonthAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString();
|
|
11
11
|
const oneMonthFromNow = new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString();
|
|
12
12
|
const twoMonthsFromNow = new Date(Date.now() + 60 * 24 * 60 * 60 * 1000).toISOString();
|
|
13
|
+
// 1. Initialize subscription with full service group structure
|
|
14
|
+
// Pricing lives at the SERVICE GROUP level, not per-service
|
|
13
15
|
if (!document.state.global.customerId) {
|
|
14
16
|
dispatch(initializeSubscription({
|
|
15
17
|
createdAt: oneMonthAgo,
|
|
16
18
|
customerId: `phid:customer:${generateId()}`,
|
|
17
19
|
customerName: "Acme Corporation",
|
|
18
20
|
customerEmail: "billing@acme.example.com",
|
|
21
|
+
resourceId: `phid:resource:${generateId()}`,
|
|
22
|
+
resourceLabel: "Enterprise Cloud Platform",
|
|
19
23
|
tierName: "Professional",
|
|
20
24
|
tierPricingOptionId: generateId(),
|
|
21
25
|
tierPrice: 726,
|
|
22
26
|
tierCurrency: "USD",
|
|
23
|
-
tierPricingMode: "
|
|
27
|
+
tierPricingMode: "CALCULATED",
|
|
24
28
|
selectedBillingCycle: "MONTHLY",
|
|
25
29
|
globalCurrency: "USD",
|
|
30
|
+
autoRenew: true,
|
|
31
|
+
serviceGroups: [
|
|
32
|
+
// === Core Infrastructure (recurring, group-level price: $726/mo) ===
|
|
33
|
+
{
|
|
34
|
+
id: generateId(),
|
|
35
|
+
name: "Core Infrastructure",
|
|
36
|
+
optional: false,
|
|
37
|
+
costType: "RECURRING",
|
|
38
|
+
recurringAmount: 726,
|
|
39
|
+
recurringCurrency: "USD",
|
|
40
|
+
recurringBillingCycle: "MONTHLY",
|
|
41
|
+
setupAmount: 500,
|
|
42
|
+
setupCurrency: "USD",
|
|
43
|
+
services: [
|
|
44
|
+
{
|
|
45
|
+
id: generateId(),
|
|
46
|
+
name: "Cloud Compute",
|
|
47
|
+
description: "Scalable virtual machines with automatic load balancing",
|
|
48
|
+
metrics: [
|
|
49
|
+
{
|
|
50
|
+
id: generateId(),
|
|
51
|
+
name: "vCPU Hours",
|
|
52
|
+
unitName: "hours",
|
|
53
|
+
currentUsage: 1250,
|
|
54
|
+
freeLimit: 1000,
|
|
55
|
+
paidLimit: 2000,
|
|
56
|
+
unitCostAmount: 0.05,
|
|
57
|
+
unitCostCurrency: "USD",
|
|
58
|
+
unitCostBillingCycle: "MONTHLY",
|
|
59
|
+
usageResetPeriod: "MONTHLY",
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
id: generateId(),
|
|
63
|
+
name: "RAM GB-Hours",
|
|
64
|
+
unitName: "GB-hours",
|
|
65
|
+
currentUsage: 3200,
|
|
66
|
+
freeLimit: 3000,
|
|
67
|
+
paidLimit: 5000,
|
|
68
|
+
usageResetPeriod: "MONTHLY",
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
id: generateId(),
|
|
72
|
+
name: "Active Instances",
|
|
73
|
+
unitName: "instances",
|
|
74
|
+
currentUsage: 8,
|
|
75
|
+
freeLimit: 10,
|
|
76
|
+
paidLimit: 20,
|
|
77
|
+
},
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
id: generateId(),
|
|
82
|
+
name: "Object Storage",
|
|
83
|
+
description: "Unlimited cloud storage with CDN integration",
|
|
84
|
+
metrics: [
|
|
85
|
+
{
|
|
86
|
+
id: generateId(),
|
|
87
|
+
name: "Storage Used",
|
|
88
|
+
unitName: "GB",
|
|
89
|
+
currentUsage: 450,
|
|
90
|
+
freeLimit: 500,
|
|
91
|
+
paidLimit: 2000,
|
|
92
|
+
unitCostAmount: 0.02,
|
|
93
|
+
unitCostCurrency: "USD",
|
|
94
|
+
unitCostBillingCycle: "MONTHLY",
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
id: generateId(),
|
|
98
|
+
name: "Bandwidth Out",
|
|
99
|
+
unitName: "GB",
|
|
100
|
+
currentUsage: 280,
|
|
101
|
+
freeLimit: 500,
|
|
102
|
+
usageResetPeriod: "MONTHLY",
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: generateId(),
|
|
106
|
+
name: "API Requests",
|
|
107
|
+
unitName: "requests",
|
|
108
|
+
currentUsage: 125000,
|
|
109
|
+
freeLimit: 100000,
|
|
110
|
+
paidLimit: 500000,
|
|
111
|
+
unitCostAmount: 0.001,
|
|
112
|
+
unitCostCurrency: "USD",
|
|
113
|
+
unitCostBillingCycle: "MONTHLY",
|
|
114
|
+
usageResetPeriod: "MONTHLY",
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
id: generateId(),
|
|
120
|
+
name: "Managed Database",
|
|
121
|
+
description: "PostgreSQL with automatic backups and failover",
|
|
122
|
+
metrics: [
|
|
123
|
+
{
|
|
124
|
+
id: generateId(),
|
|
125
|
+
name: "Database Size",
|
|
126
|
+
unitName: "GB",
|
|
127
|
+
currentUsage: 85,
|
|
128
|
+
freeLimit: 50,
|
|
129
|
+
paidLimit: 100,
|
|
130
|
+
unitCostAmount: 0.5,
|
|
131
|
+
unitCostCurrency: "USD",
|
|
132
|
+
unitCostBillingCycle: "MONTHLY",
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
id: generateId(),
|
|
136
|
+
name: "Connections",
|
|
137
|
+
unitName: "connections",
|
|
138
|
+
currentUsage: 45,
|
|
139
|
+
freeLimit: 50,
|
|
140
|
+
paidLimit: 100,
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
id: generateId(),
|
|
146
|
+
name: "Global CDN",
|
|
147
|
+
description: "Content delivery network with edge caching",
|
|
148
|
+
metrics: [
|
|
149
|
+
{
|
|
150
|
+
id: generateId(),
|
|
151
|
+
name: "Cache Hit Rate",
|
|
152
|
+
unitName: "%",
|
|
153
|
+
currentUsage: 94,
|
|
154
|
+
limit: 100,
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
id: generateId(),
|
|
158
|
+
name: "Edge Requests",
|
|
159
|
+
unitName: "M requests",
|
|
160
|
+
currentUsage: 12,
|
|
161
|
+
freeLimit: 10,
|
|
162
|
+
paidLimit: 50,
|
|
163
|
+
unitCostAmount: 5,
|
|
164
|
+
unitCostCurrency: "USD",
|
|
165
|
+
unitCostBillingCycle: "MONTHLY",
|
|
166
|
+
usageResetPeriod: "MONTHLY",
|
|
167
|
+
},
|
|
168
|
+
],
|
|
169
|
+
},
|
|
170
|
+
],
|
|
171
|
+
},
|
|
172
|
+
// === Security Suite (optional add-on, group-level price: $178/mo) ===
|
|
173
|
+
{
|
|
174
|
+
id: generateId(),
|
|
175
|
+
name: "Security Suite",
|
|
176
|
+
optional: true,
|
|
177
|
+
costType: "RECURRING",
|
|
178
|
+
recurringAmount: 178,
|
|
179
|
+
recurringCurrency: "USD",
|
|
180
|
+
recurringBillingCycle: "MONTHLY",
|
|
181
|
+
setupAmount: 750,
|
|
182
|
+
setupCurrency: "USD",
|
|
183
|
+
services: [
|
|
184
|
+
{
|
|
185
|
+
id: generateId(),
|
|
186
|
+
name: "DDoS Protection",
|
|
187
|
+
description: "Advanced DDoS mitigation with real-time monitoring",
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
id: generateId(),
|
|
191
|
+
name: "WAF",
|
|
192
|
+
description: "Web Application Firewall with custom rules",
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
id: generateId(),
|
|
196
|
+
name: "Security Audit & Onboarding",
|
|
197
|
+
description: "Initial security assessment and configuration",
|
|
198
|
+
},
|
|
199
|
+
],
|
|
200
|
+
},
|
|
201
|
+
// === Premium Support (optional add-on, group-level price: $498/mo) ===
|
|
202
|
+
{
|
|
203
|
+
id: generateId(),
|
|
204
|
+
name: "Premium Support",
|
|
205
|
+
optional: true,
|
|
206
|
+
costType: "RECURRING",
|
|
207
|
+
recurringAmount: 498,
|
|
208
|
+
recurringCurrency: "USD",
|
|
209
|
+
recurringBillingCycle: "MONTHLY",
|
|
210
|
+
setupAmount: 1200,
|
|
211
|
+
setupCurrency: "USD",
|
|
212
|
+
services: [
|
|
213
|
+
{
|
|
214
|
+
id: generateId(),
|
|
215
|
+
name: "24/7 Priority Support",
|
|
216
|
+
description: "Direct access to senior engineers with 15-min response time",
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
id: generateId(),
|
|
220
|
+
name: "Dedicated Account Manager",
|
|
221
|
+
description: "Personal account manager for strategic guidance",
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
id: generateId(),
|
|
225
|
+
name: "Team Onboarding Workshop",
|
|
226
|
+
description: "Customized training sessions for your engineering team",
|
|
227
|
+
},
|
|
228
|
+
],
|
|
229
|
+
},
|
|
230
|
+
],
|
|
26
231
|
}));
|
|
27
232
|
}
|
|
233
|
+
// 2. Activate subscription
|
|
28
234
|
dispatch(activateSubscription({
|
|
29
|
-
|
|
235
|
+
activatedSince: oneMonthAgo,
|
|
30
236
|
}));
|
|
237
|
+
// 3. Set renewal date
|
|
31
238
|
dispatch(setRenewalDate({ renewalDate: twoMonthsFromNow }));
|
|
239
|
+
// 4. Set customer type
|
|
32
240
|
dispatch(setCustomerType({
|
|
33
241
|
customerType: "TEAM",
|
|
242
|
+
teamMemberCount: 12,
|
|
34
243
|
}));
|
|
244
|
+
// 5. Billing projection
|
|
245
|
+
// Core: $726/mo + Security: $178/mo + Support: $498/mo = $1,402/mo
|
|
246
|
+
// Plus metric overages: vCPU 250 × $0.05 = $12.50, API 25k × $0.001 = $25, DB 35 × $0.50 = $17.50, Edge 2M × $5 = $10
|
|
35
247
|
dispatch(updateBillingProjection({
|
|
36
248
|
nextBillingDate: oneMonthFromNow,
|
|
37
249
|
projectedBillAmount: 1467,
|
|
@@ -6,7 +6,7 @@ export function OperatorNotes({ document, dispatch }) {
|
|
|
6
6
|
const [isEditing, setIsEditing] = useState(false);
|
|
7
7
|
const [notes, setNotes] = useState(currentNotes);
|
|
8
8
|
const handleSave = useCallback(() => {
|
|
9
|
-
dispatch(setOperatorNotes({
|
|
9
|
+
dispatch(setOperatorNotes({ operatorNotes: notes || null }));
|
|
10
10
|
setIsEditing(false);
|
|
11
11
|
}, [dispatch, notes]);
|
|
12
12
|
const handleCancel = useCallback(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ServicesPanel.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/ServicesPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC7B,MAAM,uEAAuE,CAAC;AAK/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"ServicesPanel.d.ts","sourceRoot":"","sources":["../../../../editors/subscription-instance-editor/components/ServicesPanel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EACV,0BAA0B,EAC1B,4BAA4B,EAC7B,MAAM,uEAAuE,CAAC;AAK/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAQ5C,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,4BAA4B,CAAC;IACvC,QAAQ,EAAE,gBAAgB,CAAC,0BAA0B,CAAC,CAAC;IACvD,IAAI,EAAE,QAAQ,CAAC;CAChB;AAkKD,wBAAgB,aAAa,CAAC,EAC5B,QAAQ,EACR,QAAQ,EACR,IAAI,GACL,EAAE,kBAAkB,2CA6KpB"}
|