@hulkapps/app-manager-vue 3.1.23 → 3.1.25

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hulkapps/app-manager-vue",
3
- "version": "3.1.23",
3
+ "version": "3.1.25",
4
4
  "description": "Vue SDK to render app manager contents",
5
5
  "main": "dist/app-manager-vue.ssr.js",
6
6
  "browser": "dist/app-manager-vue.esm.js",
@@ -17,6 +17,8 @@ import AppManagerSliderPlan from "./AppManagerSliderPlan";
17
17
  import Vue from "vue";
18
18
  import install from "@/entry.esm";
19
19
 
20
+ const APP_MANAGER_VUE_VERSION = "3.1.24";
21
+
20
22
  export default {
21
23
  name: "AppManagerPlan",
22
24
  components: {AppManagerSliderPlan},
@@ -77,6 +79,10 @@ export default {
77
79
  }
78
80
  install(Vue, config)
79
81
  }
82
+
83
+ console.info("[AppManagerPlan] mounted wrapper context", {
84
+ sdkVersion: APP_MANAGER_VUE_VERSION,
85
+ });
80
86
  }
81
87
  }
82
88
  </script>
@@ -196,6 +196,8 @@ import CustomizationModal from "@/components/PolarisNew/CustomizationModal.vue";
196
196
  import {calculatePlanPriceWithDiscounts} from "@/helpers";
197
197
  import PlanBanners from "@/components/Plans/PlanBanners.vue";
198
198
 
199
+ const APP_MANAGER_VUE_VERSION = "3.1.24";
200
+
199
201
  export default {
200
202
  name: "AppManagerSliderPlan",
201
203
  components: {
@@ -397,7 +399,7 @@ export default {
397
399
  if (this.discount_code !== null) {
398
400
  params['discount_code'] = this.discount_code;
399
401
  }
400
- params['frontend_sdk_version'] = "3.1.23"
402
+ params['frontend_sdk_version'] = APP_MANAGER_VUE_VERSION
401
403
  let {data} = await axios.get(`${this.app_manager_config.baseUrl}/api/app-manager/plans`, {params: params}).catch(error => {
402
404
  console.error(error)
403
405
  });
@@ -445,6 +447,10 @@ export default {
445
447
  if (data.bundle_details) {
446
448
  this.bundle_details = data.bundle_details;
447
449
  }
450
+
451
+ console.info("[AppManagerSliderPlan] plans loaded", {
452
+ sdkVersion: APP_MANAGER_VUE_VERSION,
453
+ });
448
454
  }
449
455
  },
450
456
  handlePlanBannerClose(payload) {
@@ -464,6 +470,9 @@ export default {
464
470
  },
465
471
  async mounted() {
466
472
  this.planLoading = true;
473
+ console.info("[AppManagerSliderPlan] mounting plan view", {
474
+ sdkVersion: APP_MANAGER_VUE_VERSION,
475
+ });
467
476
  await this.fetchFeatures();
468
477
  await this.fetchPlans();
469
478
  this.planLoading = false;
@@ -53,65 +53,37 @@ export default {
53
53
  before: 0,
54
54
  after: 0
55
55
  },
56
- anyMonthlyPlanHasDiscount: false,
57
- anyAnnuallyPlanHasDiscount: false,
58
- anyMonthlyPlanHasNote: false,
59
- anyAnnuallyPlanHasNote: false,
60
- anyMonthlyPlanHasDetail: false,
61
- anyAnnuallyPlanHasDetail: false,
62
56
  loadingPlanId: null
63
57
  };
64
58
  },
65
59
  computed: {
66
60
  monthlyPlans() {
67
- this.anyMonthlyPlanHasDiscount = false;
68
- this.anyMonthlyPlanHasNote = false;
69
- this.anyMonthlyPlanHasDetail = false;
70
-
71
61
  return this.plans
72
62
  .filter(plan => plan.interval === "EVERY_30_DAYS")
73
- .map(plan => {
74
- const planDetails = calculatePlanPriceWithDiscounts(plan, this.promotionalDiscount);
75
- if (planDetails.has_discount && !this.anyMonthlyPlanHasDiscount) {
76
- this.anyMonthlyPlanHasDiscount = true;
77
- }
78
- if (
79
- plan.store_base_plan
80
- && this.anyMonthlyPlanHasNote === false
81
- && isPlanNote(this.shopifyPlan, plan, this.currentPlan, this.hasActiveCharge)
82
- ) {
83
- this.anyMonthlyPlanHasNote = true;
84
- }
85
- if (this.getSortedPlanDetails(plan).length > 0 && this.anyMonthlyPlanHasDetail === false) {
86
- this.anyMonthlyPlanHasDetail = true;
87
- }
88
- return planDetails;
89
- });
63
+ .map(plan => calculatePlanPriceWithDiscounts(plan, this.promotionalDiscount));
90
64
  },
91
65
  annualPlans() {
92
- this.anyAnnuallyPlanHasDiscount = false;
93
- this.anyAnnuallyPlanHasNote = false;
94
- this.anyAnnuallyPlanHasDetail = false;
95
-
96
66
  return this.plans
97
67
  .filter(plan => plan.interval === "ANNUAL")
98
- .map(plan => {
99
- const planDetails = calculatePlanPriceWithDiscounts(plan, this.promotionalDiscount);
100
- if (planDetails.has_discount && !this.anyAnnuallyPlanHasDiscount) {
101
- this.anyAnnuallyPlanHasDiscount = true;
102
- }
103
- if (
104
- plan.store_base_plan
105
- && this.anyAnnuallyPlanHasNote === false
106
- && isPlanNote(this.shopifyPlan, plan, this.currentPlan, this.hasActiveCharge)
107
- ) {
108
- this.anyAnnuallyPlanHasNote = true;
109
- }
110
- if (this.getSortedPlanDetails(plan).length > 0 && this.anyAnnuallyPlanHasDetail === false) {
111
- this.anyAnnuallyPlanHasDetail = true;
112
- }
113
- return planDetails;
114
- });
68
+ .map(plan => calculatePlanPriceWithDiscounts(plan, this.promotionalDiscount));
69
+ },
70
+ anyMonthlyPlanHasDiscount() {
71
+ return this.monthlyPlans.some((plan) => plan.has_discount);
72
+ },
73
+ anyAnnuallyPlanHasDiscount() {
74
+ return this.annualPlans.some((plan) => plan.has_discount);
75
+ },
76
+ anyMonthlyPlanHasNote() {
77
+ return this.monthlyPlans.some((plan) => this.hasPlanNote(plan));
78
+ },
79
+ anyAnnuallyPlanHasNote() {
80
+ return this.annualPlans.some((plan) => this.hasPlanNote(plan));
81
+ },
82
+ anyMonthlyPlanHasDetail() {
83
+ return this.monthlyPlans.some((plan) => this.hasPlanDetail(plan));
84
+ },
85
+ anyAnnuallyPlanHasDetail() {
86
+ return this.annualPlans.some((plan) => this.hasPlanDetail(plan));
115
87
  },
116
88
  isMonthlyVisible() {
117
89
  return this.selectedInterval === "monthly";
@@ -130,9 +102,57 @@ export default {
130
102
  const normalized = Number(value);
131
103
  return Number.isNaN(normalized) ? fallback : normalized;
132
104
  },
105
+ normalizePlanDetailType(type) {
106
+ const normalized = String(type ?? "").trim().toLowerCase();
107
+
108
+ if (normalized === "details") {
109
+ return "detail";
110
+ }
111
+
112
+ if (normalized === "highlights") {
113
+ return "highlight";
114
+ }
115
+
116
+ return normalized;
117
+ },
118
+ hasPlanNote(plan) {
119
+ return isPlanNote(this.shopifyPlan, plan, this.currentPlan, this.hasActiveCharge);
120
+ },
121
+ hasPlanDetail(plan) {
122
+ return this.getSortedPlanDetails(plan).length > 0;
123
+ },
124
+ debugAnyPlanHasDetail(interval) {
125
+ const isMonthlyInterval = interval === "monthly";
126
+ const value = isMonthlyInterval ? this.anyMonthlyPlanHasDetail : this.anyAnnuallyPlanHasDetail;
127
+
128
+ console.info("[PlanCardsHighlights][render] detail-row gate", {
129
+ interval,
130
+ selectedInterval: this.selectedInterval,
131
+ anyMonthlyPlanHasDetail: this.anyMonthlyPlanHasDetail,
132
+ anyAnnuallyPlanHasDetail: this.anyAnnuallyPlanHasDetail,
133
+ value,
134
+ });
135
+
136
+ return value;
137
+ },
138
+ debugPlanDetailVisibility(plan, interval) {
139
+ const primaryDetail = this.getPrimaryPlanDetail(plan);
140
+ const isVisible = this.selectedInterval === interval && Boolean(primaryDetail);
141
+
142
+ console.info("[PlanCardsHighlights][render] detail-row visibility", {
143
+ interval,
144
+ selectedInterval: this.selectedInterval,
145
+ planId: plan?.id,
146
+ hasPrimaryDetail: Boolean(primaryDetail),
147
+ primaryDetail: primaryDetail?.name || null,
148
+ isVisible,
149
+ });
150
+
151
+ return isVisible;
152
+ },
133
153
  getSortedPlanHighlights(plan) {
134
154
  return Object.values(plan.details || {})
135
- .filter((highlight) => highlight.type === "highlight")
155
+ .filter((highlight) => this.normalizePlanDetailType(highlight.type) === "highlight")
136
156
  .sort((a, b) => this.normalizeSortOrder(a.sort_order) - this.normalizeSortOrder(b.sort_order))
137
157
  .map((highlight) => ({
138
158
  plan_id: highlight.plan_id,
@@ -147,7 +167,7 @@ export default {
147
167
  },
148
168
  getSortedPlanDetails(plan) {
149
169
  return Object.values(plan.details || {})
150
- .filter((detail) => detail.type === "detail")
170
+ .filter((detail) => this.normalizePlanDetailType(detail.type) === "detail")
151
171
  .sort((a, b) => this.normalizeSortOrder(a.sort_order) - this.normalizeSortOrder(b.sort_order))
152
172
  .map((detail) => ({
153
173
  plan_id: detail.plan_id,
@@ -577,10 +597,10 @@ export default {
577
597
  </p>
578
598
  <h6
579
599
  class="plan-detail"
580
- v-if="anyMonthlyPlanHasDetail"
600
+ v-if="debugAnyPlanHasDetail('monthly')"
581
601
  :style="{
582
602
  visibility:
583
- selectedInterval === 'monthly' && getPrimaryPlanDetail(plan)
603
+ debugPlanDetailVisibility(plan, 'monthly')
584
604
  ? 'visible'
585
605
  : 'hidden',
586
606
  }"
@@ -740,10 +760,10 @@ export default {
740
760
  </p>
741
761
  <h6
742
762
  class="plan-detail"
743
- v-if="anyAnnuallyPlanHasDetail"
763
+ v-if="debugAnyPlanHasDetail('annually')"
744
764
  :style="{
745
765
  visibility:
746
- selectedInterval === 'annually' && getPrimaryPlanDetail(plan)
766
+ debugPlanDetailVisibility(plan, 'annually')
747
767
  ? 'visible'
748
768
  : 'hidden',
749
769
  }"
@@ -848,6 +868,7 @@ export default {
848
868
  font-size: 16px;
849
869
  font-weight: 700;
850
870
  color: #1A1A1A;
871
+ text-align: center;
851
872
  }
852
873
 
853
874
  .card .price-wrapper {
@@ -900,7 +921,7 @@ export default {
900
921
  width: 100%;
901
922
  justify-content: center;
902
923
  border-top: 1px solid #cccccc;
903
- margin-top: 16px;
924
+ margin-top: auto;
904
925
  padding-top: 12px;
905
926
  }
906
927
 
@@ -986,6 +1007,7 @@ export default {
986
1007
 
987
1008
  .features {
988
1009
  margin-top: 19px;
1010
+ margin-bottom: 19px;
989
1011
  }
990
1012
 
991
1013
  .features ul {
@@ -582,7 +582,6 @@ export default {
582
582
  anyMonthlyPlanHasDiscount ? 'has-discount' : ''
583
583
  ]"
584
584
  >
585
- <h4 class="plan-name mobile-plan-name">{{ translateMe(plan.name) }}</h4>
586
585
  <template v-if="plan.strike_price">
587
586
  <h5>
588
587
  <span class="strike-price">${{ Number(plan.strike_price).toFixed(2) }}</span>
@@ -695,7 +694,6 @@ export default {
695
694
  anyAnnuallyPlanHasDiscount ? 'has-discount' : ''
696
695
  ]"
697
696
  >
698
- <h4 class="plan-name mobile-plan-name">{{ translateMe(plan.name) }}</h4>
699
697
  <template v-if="plan.strike_price">
700
698
  <h5>
701
699
  <span class="strike-price">${{ Number(plan.strike_price).toFixed(2) }}</span>
@@ -900,7 +898,7 @@ export default {
900
898
 
901
899
  .plan-header-wrapper .price-wrapper .main-price {
902
900
  display: flex;
903
- flex-direction: row;
901
+ flex-direction: column;
904
902
  gap: 8px;
905
903
  justify-content: center;
906
904
  align-items: center;
@@ -923,15 +921,6 @@ export default {
923
921
  line-height: 20px;
924
922
  font-weight: 700;
925
923
  color: #1A1A1A;
926
- width: max-content;
927
- }
928
-
929
- .plan-header-wrapper .price-wrapper h4.plan-name {
930
- width: 100%;
931
- }
932
-
933
- .plan-header-wrapper .price-wrapper .mobile-plan-name {
934
- display: none;
935
924
  }
936
925
 
937
926
  .plan-header-wrapper .price-wrapper h4 h6 {
@@ -1062,20 +1051,6 @@ export default {
1062
1051
  overscroll-behavior: none !important;
1063
1052
  }
1064
1053
 
1065
- @media (max-width: 1024px) {
1066
- .plan-header-wrapper .price-wrapper .mobile-plan-name {
1067
- display: inline-block;
1068
- }
1069
-
1070
- .plan-header-wrapper .price-wrapper .desktop-plan-name {
1071
- display: none;
1072
- }
1073
-
1074
- .plan-header-wrapper .price-wrapper .main-price {
1075
- flex-direction: column;
1076
- }
1077
- }
1078
-
1079
1054
  @media (max-width: 640px) {
1080
1055
  .swiper-plan-navigation {
1081
1056
  display: none !important;