@eric-emg/symphiq-components 1.2.199 → 1.2.201

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.
@@ -1,4 +1,4 @@
1
- import { ViewModeEnum, MetricStatusEnum, TrendDirectionEnum, CompetitiveScoreEnum, MetricEnum, DimensionEnum, UiDataPeriodEnum, UiDataComparePeriodEnum, ChartTypeEnum, IconSourceEnum, ProfileAnalysisRecommendationPriorityEnum, ProfileItemTypeEnum, PriceVsCompetitorsEnum, DifferentiationStrengthEnum, ThreatLevelEnum, normalizeToV3, FocusAreaDetailStatusEnum, FocusAreaDomainEnumUtil, FocusAreaDomainEnum, ShopDataLoadStatusEnum, MetricEnumUtil, NumberTypeEnum, AiDynamicContentStatusEnum, FocusAreaHealthEnum, ProfileAnalysisPriorityEnum, CapabilityStateEnum, QuadrantEnum, AdvantageEnum, OverallGradeEnum, OperationalMaturityEnum, ProfileAnalysisEffortLevelEnum, ProfileAnalysisImpactLevelEnum, ProfileAnalysisTypeEnum, LineChartUseCaseEnum, BarChartUseCaseEnum } from '@jebgem/model';
1
+ import { ViewModeEnum, MetricStatusEnum, TrendDirectionEnum, CompetitiveScoreEnum, MetricEnum, DimensionEnum, UiDataPeriodEnum, UiDataComparePeriodEnum, ChartTypeEnum, IconSourceEnum, ProfileAnalysisRecommendationPriorityEnum, ProfileItemTypeEnum, PriceVsCompetitorsEnum, DifferentiationStrengthEnum, ThreatLevelEnum, normalizeToV3, FocusAreaDetailStatusEnum, FocusAreaDomainEnumUtil, FocusAreaDomainEnum, ShopDataLoadStatusEnum, MetricEnumUtil, NumberTypeEnum, FunnelMetricTypeEnum, AiDynamicContentStatusEnum, FocusAreaHealthEnum, ProfileAnalysisPriorityEnum, CapabilityStateEnum, QuadrantEnum, AdvantageEnum, OverallGradeEnum, OperationalMaturityEnum, ProfileAnalysisEffortLevelEnum, ProfileAnalysisImpactLevelEnum, ProfileAnalysisTypeEnum, LineChartUseCaseEnum, BarChartUseCaseEnum } from '@jebgem/model';
2
2
  export * from '@jebgem/model';
3
3
  import * as i0 from '@angular/core';
4
4
  import { Injectable, signal, computed, input, ChangeDetectionStrategy, Component, output, inject, ElementRef, Renderer2, effect, Directive, HostListener, untracked, ViewChild, PLATFORM_ID, Inject, Input } from '@angular/core';
@@ -56430,26 +56430,49 @@ class InitialTargetSettingComponent {
56430
56430
  }, ...(ngDevMode ? [{ debugName: "percentageIncrease" }] : []));
56431
56431
  this.displayedMetricCalculations = computed(() => {
56432
56432
  const response = this.storedResponse();
56433
- if (!response || !response.relatedMetricTargets) {
56433
+ if (!response) {
56434
56434
  return [];
56435
56435
  }
56436
- return response.relatedMetricTargets.map((metricValue) => {
56437
- const metric = metricValue.metric;
56438
- const funnelMetric = this.funnelMetrics().find(fm => fm.relatedMetric === metric);
56439
- const currentValue = sumMetricFromUiData(this.mainUiData(), metric, 'priorYear');
56440
- const targetValue = parseFloat(metricValue.value || '0');
56441
- return {
56442
- metric,
56443
- funnelMetric: funnelMetric?.funnelMetric,
56444
- currentValue,
56445
- targetValue,
56446
- percentageIncrease: response.equalRelatedMetricIncreasePercent || 0,
56447
- isFunnelStage: funnelMetric?.funnelMetric === metric,
56448
- funnelInd: funnelMetric?.funnelInd,
56449
- relatedInd: funnelMetric?.relatedInd,
56450
- description: funnelMetric?.relatedMetricDescription
56451
- };
56452
- });
56436
+ const results = [];
56437
+ if (response.funnelMetricValues) {
56438
+ response.funnelMetricValues.forEach((metricValue) => {
56439
+ const metric = metricValue.metric;
56440
+ const funnelMetric = this.funnelMetrics().find(fm => fm.funnelMetric === metric && fm.funnelMetric === fm.relatedMetric);
56441
+ const currentValue = sumMetricFromUiData(this.mainUiData(), metric, 'priorYear');
56442
+ const { targetValue, percentageIncrease } = this.parseMetricValue(metricValue.value);
56443
+ results.push({
56444
+ metric,
56445
+ funnelMetric: metric,
56446
+ currentValue,
56447
+ targetValue,
56448
+ percentageIncrease,
56449
+ isFunnelStage: true,
56450
+ funnelInd: funnelMetric?.funnelInd,
56451
+ relatedInd: 0,
56452
+ description: funnelMetric?.funnelMetricDescription
56453
+ });
56454
+ });
56455
+ }
56456
+ if (response.relatedMetricTargets) {
56457
+ response.relatedMetricTargets.forEach((metricValue) => {
56458
+ const metric = metricValue.metric;
56459
+ const funnelMetric = this.funnelMetrics().find(fm => fm.relatedMetric === metric);
56460
+ const currentValue = sumMetricFromUiData(this.mainUiData(), metric, 'priorYear');
56461
+ const { targetValue, percentageIncrease } = this.parseMetricValue(metricValue.value);
56462
+ results.push({
56463
+ metric,
56464
+ funnelMetric: funnelMetric?.funnelMetric,
56465
+ currentValue,
56466
+ targetValue,
56467
+ percentageIncrease: percentageIncrease || response.equalRelatedMetricIncreasePercent || 0,
56468
+ isFunnelStage: false,
56469
+ funnelInd: funnelMetric?.funnelInd,
56470
+ relatedInd: funnelMetric?.relatedInd,
56471
+ description: funnelMetric?.relatedMetricDescription
56472
+ });
56473
+ });
56474
+ }
56475
+ return results;
56453
56476
  }, ...(ngDevMode ? [{ debugName: "displayedMetricCalculations" }] : []));
56454
56477
  this.displayedTargetRevenue = computed(() => {
56455
56478
  const response = this.storedResponse();
@@ -56523,6 +56546,28 @@ class InitialTargetSettingComponent {
56523
56546
  }
56524
56547
  }, { allowSignalWrites: true });
56525
56548
  }
56549
+ parseMetricValue(value) {
56550
+ if (!value)
56551
+ return { targetValue: 0, percentageIncrease: 0 };
56552
+ let targetValue = 0;
56553
+ let percentageIncrease = 0;
56554
+ const arrowMatch = value.match(/\([\d.,]+\s*->\s*([\d.,]+)\)/);
56555
+ if (arrowMatch) {
56556
+ targetValue = parseFloat(arrowMatch[1].replace(/,/g, ''));
56557
+ }
56558
+ const targetMatch = value.match(/target:\s*([\d.,]+)/);
56559
+ if (targetMatch) {
56560
+ targetValue = parseFloat(targetMatch[1].replace(/,/g, ''));
56561
+ }
56562
+ const percentMatch = value.match(/([-\d.]+)%\s*(increase|change|decrease)?/);
56563
+ if (percentMatch) {
56564
+ percentageIncrease = parseFloat(percentMatch[1]);
56565
+ }
56566
+ if (!arrowMatch && !targetMatch) {
56567
+ targetValue = parseFloat(value.replace(/,/g, '')) || 0;
56568
+ }
56569
+ return { targetValue, percentageIncrease };
56570
+ }
56526
56571
  ngAfterViewInit() {
56527
56572
  setTimeout(() => {
56528
56573
  this.absoluteInputRef?.nativeElement?.focus();
@@ -56574,7 +56619,8 @@ class InitialTargetSettingComponent {
56574
56619
  this.calculationState.set('calculating');
56575
56620
  const request = {
56576
56621
  shopId: this.shopId(),
56577
- targetRevenue: this.calculatedRevenue()
56622
+ targetRevenue: this.calculatedRevenue(),
56623
+ funnelType: FunnelMetricTypeEnum.REVENUE,
56578
56624
  };
56579
56625
  this.calculateRevenueRequest.emit(request);
56580
56626
  }
@@ -56801,214 +56847,214 @@ class InitialTargetSettingComponent {
56801
56847
  AreaChartComponent
56802
56848
  ],
56803
56849
  changeDetection: ChangeDetectionStrategy.OnPush,
56804
- template: `
56805
- <div class="space-y-8 pb-32">
56806
- <div [ngClass]="sectionCardClasses()" class="rounded-2xl border shadow-lg p-8">
56807
- <h2 [ngClass]="sectionTitleClasses()" class="text-2xl font-bold mb-6">
56808
- Calculate Your Revenue Target
56809
- </h2>
56810
-
56811
- <div class="grid lg:grid-cols-2 gap-8">
56812
- <div class="space-y-6">
56813
- <div>
56814
- <label [ngClass]="labelClasses()" class="block text-sm font-semibold mb-2">
56815
- {{ currentYear() }} Revenue
56816
- </label>
56817
- <div class="space-y-1 mb-4">
56818
- <p [ngClass]="priorYearLabelClasses()" class="text-xs">
56819
- {{ priorYear() }} Revenue: {{ formatCurrency(priorYearRevenue()) }}
56820
- </p>
56821
- @if (currentPaceProjection() > 0) {
56822
- <p [ngClass]="priorYearLabelClasses()" class="text-xs">
56823
- Current Pace Projection: {{ formatCurrency(currentPaceProjection()) }}
56824
- </p>
56825
- }
56826
- </div>
56827
-
56828
- <div class="flex gap-2 mb-4">
56829
- <button
56830
- (click)="setInputMode('absolute')"
56831
- [ngClass]="inputModeButtonClasses('absolute')"
56832
- class="flex-1 py-2 px-4 rounded-lg text-sm font-semibold transition-all">
56833
- Absolute Amount
56834
- </button>
56835
- <button
56836
- (click)="setInputMode('percentage')"
56837
- [ngClass]="inputModeButtonClasses('percentage')"
56838
- class="flex-1 py-2 px-4 rounded-lg text-sm font-semibold transition-all">
56839
- % Increase
56840
- </button>
56841
- </div>
56842
-
56843
- @if (inputMode() === 'absolute') {
56844
- <div class="relative">
56845
- <span [ngClass]="inputPrefixClasses()" class="absolute left-4 top-1/2 -translate-y-1/2 text-xl font-bold">
56846
- $
56847
- </span>
56848
- <input
56849
- #absoluteInputRef
56850
- type="number"
56851
- [(ngModel)]="absoluteInput"
56852
- (ngModelChange)="onAbsoluteInputChange()"
56853
- [ngClass]="inputClasses()"
56854
- class="w-full pl-10 pr-4 py-4 rounded-xl text-2xl font-bold border-2 transition-all"
56855
- placeholder="0"
56856
- min="0"
56857
- step="1000">
56858
- </div>
56859
- } @else {
56860
- <div class="relative">
56861
- <input
56862
- #percentageInputRef
56863
- type="number"
56864
- [(ngModel)]="percentageInput"
56865
- (ngModelChange)="onPercentageInputChange()"
56866
- [ngClass]="inputClasses()"
56867
- class="w-full pr-10 pl-4 py-4 rounded-xl text-2xl font-bold border-2 transition-all"
56868
- placeholder="0"
56869
- min="0"
56870
- max="1000"
56871
- step="0.1">
56872
- <span [ngClass]="inputSuffixClasses()" class="absolute right-4 top-1/2 -translate-y-1/2 text-xl font-bold">
56873
- %
56874
- </span>
56875
- </div>
56876
- }
56877
- </div>
56878
-
56879
- @if (calculatedRevenue() > 0) {
56880
- <div [ngClass]="calculatedValuesCardClasses()" class="p-6 rounded-xl border-2">
56881
- <div class="space-y-4">
56882
- <div>
56883
- <p [ngClass]="calculatedLabelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
56884
- {{ currentYear() }} Revenue Target
56885
- </p>
56886
- <p [ngClass]="calculatedValueClasses()" class="text-3xl font-bold">
56887
- {{ formatCurrency(calculatedRevenue()) }}
56888
- </p>
56889
- </div>
56890
- <div class="grid grid-cols-2 gap-4 pt-4" [ngClass]="calculatedDividerClasses()">
56891
- <div>
56892
- <p [ngClass]="calculatedLabelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
56893
- Increase Amount
56894
- </p>
56895
- <p [ngClass]="calculatedSecondaryClasses()" class="text-xl font-bold">
56896
- {{ formatCurrency(calculatedRevenue() - priorYearRevenue()) }}
56897
- </p>
56898
- </div>
56899
- <div>
56900
- <p [ngClass]="calculatedLabelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
56901
- % Growth
56902
- </p>
56903
- <p [ngClass]="calculatedSecondaryClasses()" class="text-xl font-bold">
56904
- +{{ formatPercentage(percentageIncrease(), 1) }}
56905
- </p>
56906
- </div>
56907
- </div>
56908
- @if (currentPaceProjection() > 0 && gapToClose().amount !== 0) {
56909
- <div class="grid grid-cols-2 gap-4 pt-4" [ngClass]="calculatedDividerClasses()">
56910
- <div>
56911
- <p [ngClass]="calculatedLabelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
56912
- Gap to Close
56913
- </p>
56914
- <p [ngClass]="calculatedSecondaryClasses()" class="text-xl font-bold">
56915
- {{ formatCurrency(absValue(gapToClose().amount)) }}
56916
- </p>
56917
- </div>
56918
- <div>
56919
- <p [ngClass]="calculatedLabelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
56920
- Additional Growth Needed
56921
- </p>
56922
- <p [ngClass]="calculatedSecondaryClasses()" class="text-xl font-bold">
56923
- {{ gapToClose().amount > 0 ? '+' : '' }}{{ formatPercentage(gapToClose().percentage, 1) }}
56924
- </p>
56925
- </div>
56926
- </div>
56927
- }
56928
- </div>
56929
- </div>
56930
- }
56931
- </div>
56932
-
56933
- <div>
56934
- <p [ngClass]="chartTitleClasses()" class="text-sm font-semibold mb-3">
56935
- Year-over-Year Revenue Trend
56936
- </p>
56937
- <div [ngClass]="chartContainerClasses()" class="rounded-xl border p-4">
56938
- @if (revenueChartData()) {
56939
- <symphiq-area-chart
56940
- [chart]="revenueChartData()!"
56941
- [showAxisLabels]="true"
56942
- [viewMode]="viewMode()"
56943
- [currencySymbol]="'$'"
56944
- [height]="'320px'"
56945
- />
56946
- } @else {
56947
- <div class="h-64 flex items-center justify-center">
56948
- <p [ngClass]="noDataClasses()" class="text-sm">
56949
- No revenue data available
56950
- </p>
56951
- </div>
56952
- }
56953
- </div>
56954
- </div>
56955
- </div>
56956
- </div>
56957
-
56958
- @if (showMetricsVisualization()) {
56959
- <div [ngClass]="sectionCardClasses()" class="rounded-2xl border shadow-lg p-8">
56960
- <div class="mb-6">
56961
- <h2 [ngClass]="sectionTitleClasses()" class="text-2xl font-bold mb-2">
56962
- Contributing Metrics
56963
- </h2>
56964
- <p [ngClass]="sectionDescriptionClasses()" class="text-sm">
56965
- To achieve your revenue target of {{ formatCurrency(displayedTargetRevenue()) }}, the following metrics need to improve by these amounts. These improvements compound through your funnel to drive revenue growth.
56966
- </p>
56967
- </div>
56968
-
56969
- <symphiq-funnel-metrics-visualization
56970
- [viewMode]="viewMode()"
56971
- [calculations]="displayedMetricCalculations()"
56972
- [pacingMetrics]="pacingMetrics()"
56973
- />
56974
- </div>
56975
- }
56976
-
56977
- <symphiq-sticky-submit-bar
56978
- [viewMode]="viewMode()"
56979
- [isValid]="isValid()"
56980
- [isSubmitting]="isCalculating()"
56981
- [validationMessage]="validationMessage()"
56982
- [buttonText]="submitButtonText()"
56983
- (submitClick)="handleSubmitClick()"
56984
- />
56985
-
56986
- @if (calculationState() === 'results') {
56987
- <div class="fixed bottom-24 left-0 right-0 z-40 pb-4 px-4">
56988
- <div class="max-w-7xl mx-auto flex gap-4 justify-center">
56989
- <button
56990
- (click)="handleAdjustTarget()"
56991
- [ngClass]="secondaryButtonClasses()"
56992
- class="px-6 py-3 rounded-xl font-semibold transition-all shadow-lg">
56993
- Adjust Revenue Target
56994
- </button>
56995
- </div>
56996
- </div>
56997
- }
56998
-
56999
- @if (calculationState() === 'input' && hasStoredResponse()) {
57000
- <div class="fixed bottom-32 left-0 right-0 z-40 pb-4 px-4">
57001
- <div class="max-w-7xl mx-auto flex gap-4 justify-center">
57002
- <button
57003
- (click)="handleCancel()"
57004
- [ngClass]="cancelButtonClasses()"
57005
- class="px-6 py-3 rounded-xl font-semibold transition-all shadow-lg">
57006
- Cancel
57007
- </button>
57008
- </div>
57009
- </div>
57010
- }
57011
- </div>
56850
+ template: `
56851
+ <div class="space-y-8 pb-32">
56852
+ <div [ngClass]="sectionCardClasses()" class="rounded-2xl border shadow-lg p-8">
56853
+ <h2 [ngClass]="sectionTitleClasses()" class="text-2xl font-bold mb-6">
56854
+ Calculate Your Revenue Target
56855
+ </h2>
56856
+
56857
+ <div class="grid lg:grid-cols-2 gap-8">
56858
+ <div class="space-y-6">
56859
+ <div>
56860
+ <label [ngClass]="labelClasses()" class="block text-sm font-semibold mb-2">
56861
+ {{ currentYear() }} Revenue
56862
+ </label>
56863
+ <div class="space-y-1 mb-4">
56864
+ <p [ngClass]="priorYearLabelClasses()" class="text-xs">
56865
+ {{ priorYear() }} Revenue: {{ formatCurrency(priorYearRevenue()) }}
56866
+ </p>
56867
+ @if (currentPaceProjection() > 0) {
56868
+ <p [ngClass]="priorYearLabelClasses()" class="text-xs">
56869
+ Current Pace Projection: {{ formatCurrency(currentPaceProjection()) }}
56870
+ </p>
56871
+ }
56872
+ </div>
56873
+
56874
+ <div class="flex gap-2 mb-4">
56875
+ <button
56876
+ (click)="setInputMode('absolute')"
56877
+ [ngClass]="inputModeButtonClasses('absolute')"
56878
+ class="flex-1 py-2 px-4 rounded-lg text-sm font-semibold transition-all">
56879
+ Absolute Amount
56880
+ </button>
56881
+ <button
56882
+ (click)="setInputMode('percentage')"
56883
+ [ngClass]="inputModeButtonClasses('percentage')"
56884
+ class="flex-1 py-2 px-4 rounded-lg text-sm font-semibold transition-all">
56885
+ % Increase
56886
+ </button>
56887
+ </div>
56888
+
56889
+ @if (inputMode() === 'absolute') {
56890
+ <div class="relative">
56891
+ <span [ngClass]="inputPrefixClasses()" class="absolute left-4 top-1/2 -translate-y-1/2 text-xl font-bold">
56892
+ $
56893
+ </span>
56894
+ <input
56895
+ #absoluteInputRef
56896
+ type="number"
56897
+ [(ngModel)]="absoluteInput"
56898
+ (ngModelChange)="onAbsoluteInputChange()"
56899
+ [ngClass]="inputClasses()"
56900
+ class="w-full pl-10 pr-4 py-4 rounded-xl text-2xl font-bold border-2 transition-all"
56901
+ placeholder="0"
56902
+ min="0"
56903
+ step="1000">
56904
+ </div>
56905
+ } @else {
56906
+ <div class="relative">
56907
+ <input
56908
+ #percentageInputRef
56909
+ type="number"
56910
+ [(ngModel)]="percentageInput"
56911
+ (ngModelChange)="onPercentageInputChange()"
56912
+ [ngClass]="inputClasses()"
56913
+ class="w-full pr-10 pl-4 py-4 rounded-xl text-2xl font-bold border-2 transition-all"
56914
+ placeholder="0"
56915
+ min="0"
56916
+ max="1000"
56917
+ step="0.1">
56918
+ <span [ngClass]="inputSuffixClasses()" class="absolute right-4 top-1/2 -translate-y-1/2 text-xl font-bold">
56919
+ %
56920
+ </span>
56921
+ </div>
56922
+ }
56923
+ </div>
56924
+
56925
+ @if (calculatedRevenue() > 0) {
56926
+ <div [ngClass]="calculatedValuesCardClasses()" class="p-6 rounded-xl border-2">
56927
+ <div class="space-y-4">
56928
+ <div>
56929
+ <p [ngClass]="calculatedLabelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
56930
+ {{ currentYear() }} Revenue Target
56931
+ </p>
56932
+ <p [ngClass]="calculatedValueClasses()" class="text-3xl font-bold">
56933
+ {{ formatCurrency(calculatedRevenue()) }}
56934
+ </p>
56935
+ </div>
56936
+ <div class="grid grid-cols-2 gap-4 pt-4" [ngClass]="calculatedDividerClasses()">
56937
+ <div>
56938
+ <p [ngClass]="calculatedLabelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
56939
+ Increase Amount
56940
+ </p>
56941
+ <p [ngClass]="calculatedSecondaryClasses()" class="text-xl font-bold">
56942
+ {{ formatCurrency(calculatedRevenue() - priorYearRevenue()) }}
56943
+ </p>
56944
+ </div>
56945
+ <div>
56946
+ <p [ngClass]="calculatedLabelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
56947
+ % Growth
56948
+ </p>
56949
+ <p [ngClass]="calculatedSecondaryClasses()" class="text-xl font-bold">
56950
+ +{{ formatPercentage(percentageIncrease(), 1) }}
56951
+ </p>
56952
+ </div>
56953
+ </div>
56954
+ @if (currentPaceProjection() > 0 && gapToClose().amount !== 0) {
56955
+ <div class="grid grid-cols-2 gap-4 pt-4" [ngClass]="calculatedDividerClasses()">
56956
+ <div>
56957
+ <p [ngClass]="calculatedLabelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
56958
+ Gap to Close
56959
+ </p>
56960
+ <p [ngClass]="calculatedSecondaryClasses()" class="text-xl font-bold">
56961
+ {{ formatCurrency(absValue(gapToClose().amount)) }}
56962
+ </p>
56963
+ </div>
56964
+ <div>
56965
+ <p [ngClass]="calculatedLabelClasses()" class="text-xs font-medium uppercase tracking-wider mb-1">
56966
+ Additional Growth Needed
56967
+ </p>
56968
+ <p [ngClass]="calculatedSecondaryClasses()" class="text-xl font-bold">
56969
+ {{ gapToClose().amount > 0 ? '+' : '' }}{{ formatPercentage(gapToClose().percentage, 1) }}
56970
+ </p>
56971
+ </div>
56972
+ </div>
56973
+ }
56974
+ </div>
56975
+ </div>
56976
+ }
56977
+ </div>
56978
+
56979
+ <div>
56980
+ <p [ngClass]="chartTitleClasses()" class="text-sm font-semibold mb-3">
56981
+ Year-over-Year Revenue Trend
56982
+ </p>
56983
+ <div [ngClass]="chartContainerClasses()" class="rounded-xl border p-4">
56984
+ @if (revenueChartData()) {
56985
+ <symphiq-area-chart
56986
+ [chart]="revenueChartData()!"
56987
+ [showAxisLabels]="true"
56988
+ [viewMode]="viewMode()"
56989
+ [currencySymbol]="'$'"
56990
+ [height]="'320px'"
56991
+ />
56992
+ } @else {
56993
+ <div class="h-64 flex items-center justify-center">
56994
+ <p [ngClass]="noDataClasses()" class="text-sm">
56995
+ No revenue data available
56996
+ </p>
56997
+ </div>
56998
+ }
56999
+ </div>
57000
+ </div>
57001
+ </div>
57002
+ </div>
57003
+
57004
+ @if (showMetricsVisualization()) {
57005
+ <div [ngClass]="sectionCardClasses()" class="rounded-2xl border shadow-lg p-8">
57006
+ <div class="mb-6">
57007
+ <h2 [ngClass]="sectionTitleClasses()" class="text-2xl font-bold mb-2">
57008
+ Contributing Metrics
57009
+ </h2>
57010
+ <p [ngClass]="sectionDescriptionClasses()" class="text-sm">
57011
+ To achieve your revenue target of {{ formatCurrency(displayedTargetRevenue()) }}, the following metrics need to improve by these amounts. These improvements compound through your funnel to drive revenue growth.
57012
+ </p>
57013
+ </div>
57014
+
57015
+ <symphiq-funnel-metrics-visualization
57016
+ [viewMode]="viewMode()"
57017
+ [calculations]="displayedMetricCalculations()"
57018
+ [pacingMetrics]="pacingMetrics()"
57019
+ />
57020
+ </div>
57021
+ }
57022
+
57023
+ <symphiq-sticky-submit-bar
57024
+ [viewMode]="viewMode()"
57025
+ [isValid]="isValid()"
57026
+ [isSubmitting]="isCalculating()"
57027
+ [validationMessage]="validationMessage()"
57028
+ [buttonText]="submitButtonText()"
57029
+ (submitClick)="handleSubmitClick()"
57030
+ />
57031
+
57032
+ @if (calculationState() === 'results') {
57033
+ <div class="fixed bottom-24 left-0 right-0 z-40 pb-4 px-4">
57034
+ <div class="max-w-7xl mx-auto flex gap-4 justify-center">
57035
+ <button
57036
+ (click)="handleAdjustTarget()"
57037
+ [ngClass]="secondaryButtonClasses()"
57038
+ class="px-6 py-3 rounded-xl font-semibold transition-all shadow-lg">
57039
+ Adjust Revenue Target
57040
+ </button>
57041
+ </div>
57042
+ </div>
57043
+ }
57044
+
57045
+ @if (calculationState() === 'input' && hasStoredResponse()) {
57046
+ <div class="fixed bottom-32 left-0 right-0 z-40 pb-4 px-4">
57047
+ <div class="max-w-7xl mx-auto flex gap-4 justify-center">
57048
+ <button
57049
+ (click)="handleCancel()"
57050
+ [ngClass]="cancelButtonClasses()"
57051
+ class="px-6 py-3 rounded-xl font-semibold transition-all shadow-lg">
57052
+ Cancel
57053
+ </button>
57054
+ </div>
57055
+ </div>
57056
+ }
57057
+ </div>
57012
57058
  `
57013
57059
  }]
57014
57060
  }], () => [], { absoluteInputRef: [{
@@ -57018,7 +57064,7 @@ class InitialTargetSettingComponent {
57018
57064
  type: ViewChild,
57019
57065
  args: ['percentageInputRef']
57020
57066
  }], viewMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewMode", required: false }] }], funnelMetrics: [{ type: i0.Input, args: [{ isSignal: true, alias: "funnelMetrics", required: false }] }], mainUiData: [{ type: i0.Input, args: [{ isSignal: true, alias: "mainUiData", required: false }] }], trendUiData: [{ type: i0.Input, args: [{ isSignal: true, alias: "trendUiData", required: false }] }], shopId: [{ type: i0.Input, args: [{ isSignal: true, alias: "shopId", required: false }] }], pacingMetrics: [{ type: i0.Input, args: [{ isSignal: true, alias: "pacingMetrics", required: false }] }], dataResults: [{ type: i0.Input, args: [{ isSignal: true, alias: "dataResults", required: false }] }], reverseCalculationResponse: [{ type: i0.Input, args: [{ isSignal: true, alias: "reverseCalculationResponse", required: false }] }], targetsCreated: [{ type: i0.Output, args: ["targetsCreated"] }], calculateRevenueRequest: [{ type: i0.Output, args: ["calculateRevenueRequest"] }] }); })();
57021
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(InitialTargetSettingComponent, { className: "InitialTargetSettingComponent", filePath: "lib/components/revenue-calculator-dashboard/initial-target-setting.component.ts", lineNumber: 247 }); })();
57067
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(InitialTargetSettingComponent, { className: "InitialTargetSettingComponent", filePath: "lib/components/revenue-calculator-dashboard/initial-target-setting.component.ts", lineNumber: 259 }); })();
57022
57068
 
57023
57069
  function IndeterminateSpinnerComponent_For_5_Template(rf, ctx) { if (rf & 1) {
57024
57070
  i0.ɵɵelement(0, "div", 5);