@hulkapps/app-manager-vue 2.5.12 → 3.0.3

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.
@@ -0,0 +1,153 @@
1
+ <script>
2
+ import VariantButton from "./VariantButton";
3
+
4
+ export default {
5
+ name: "BundlePlanCard",
6
+ components: {
7
+ VariantButton,
8
+ },
9
+ props: {
10
+ plan: {
11
+ type: Object,
12
+ required: true,
13
+ },
14
+ plan_details: {
15
+ type: Array,
16
+ required: true,
17
+ },
18
+ },
19
+ methods: {
20
+ handlePlanClick(plan) {
21
+ this.$emit("plan-clicked", 'bundle');
22
+ },
23
+ translateMe(message) {
24
+ return this.$translations.hasOwnProperty(message)
25
+ ? this.$translations[message]
26
+ : message;
27
+ },
28
+ },
29
+ computed: {
30
+ allApps() {
31
+ return this.plan_details.flatMap((category) => category.apps_relation);
32
+ },
33
+ totalAppsCount() {
34
+ return this.allApps.length;
35
+ },
36
+ },
37
+ // computed: {
38
+ // isSlotEmpty() {
39
+ // return !this.$slots.default;
40
+ // },
41
+ // },
42
+ };
43
+ </script>
44
+
45
+ <template>
46
+ <div class="block">
47
+ <div class="bundle-header">
48
+ <h3>{{ translateMe("Bundle") }}</h3>
49
+ <h2>${{ plan.price - plan.discount }}</h2>
50
+ <span class="mo-label">{{ translateMe("/mo") }}</span>
51
+ <h4>${{ plan.price }}</h4>
52
+ <span class="apps-count">{{ allApps.length }} {{ translateMe("Apps") }}</span>
53
+ </div>
54
+ <div class="apps-list">
55
+ <div v-for="(app, index) in allApps" :key="app.id + '_' + index" class="app">
56
+ <template v-if="index <= 10">
57
+ <img
58
+ :src="app.app_logo_url"
59
+ :alt="`${app.app_name} Logo`"
60
+ width="24"
61
+ height="24"
62
+ />
63
+ <h5>{{ app.app_name }}</h5>
64
+ </template>
65
+ <template v-else-if="index === 11">
66
+ <h5 class="more-apps-label">+ {{ allApps.length - 11 }} {{ translateMe('More Apps') }}</h5>
67
+ </template>
68
+ </div>
69
+ </div>
70
+ <VariantButton @click="handlePlanClick('bundle')" variant="primary" class="button">{{
71
+ translateMe("Start Saving Now")
72
+ }}</VariantButton>
73
+ </div>
74
+ </template>
75
+
76
+ <style scoped>
77
+ .block {
78
+ display: flex;
79
+ flex-direction: column;
80
+ justify-content: space-between;
81
+ width: 100%;
82
+ gap: 16px;
83
+ padding: 20px;
84
+ background-color: white;
85
+ border-radius: 16px;
86
+ box-shadow: 0px 4px 6px -1px #0000001a;
87
+ border: 1px solid #e5e5e5;
88
+ }
89
+ .button {
90
+ /* width: 261px !important; */
91
+ width: 100% !important;
92
+ display: flex !important;
93
+ height: fit-content !important;
94
+ justify-content: center !important;
95
+ }
96
+ .bundle-header {
97
+ display: flex;
98
+ gap: 8px;
99
+ border-bottom: 1px solid #e3e3e3;
100
+ padding-bottom: 12px;
101
+ }
102
+ .bundle-header h3 {
103
+ font-size: 18px;
104
+ font-weight: 700;
105
+ color: black;
106
+ }
107
+ .bundle-header h2 {
108
+ font-size: 30px;
109
+ font-weight: 700;
110
+ color: black;
111
+ }
112
+ .bundle-header .mo-label {
113
+ font-size: 13px;
114
+ font-weight: 400;
115
+ color: #00000080;
116
+ }
117
+ .bundle-header h4 {
118
+ font-size: 13.5px;
119
+ font-weight: 700;
120
+ color: #616161;
121
+ text-decoration: line-through;
122
+ }
123
+ .bundle-header .apps-count {
124
+ background-color: #91d0ff;
125
+ border-radius: 8px;
126
+ padding: 2px 8px;
127
+ font-size: 12px;
128
+ line-height: 16px;
129
+ font-weight: 550;
130
+ color: #00527c;
131
+ }
132
+ .apps-list {
133
+ display: flex;
134
+ flex-wrap: wrap;
135
+ gap: 8px;
136
+ }
137
+ .apps-list .app {
138
+ display: flex;
139
+ flex-basis: calc(33% - 8px);
140
+ align-items: center;
141
+ gap: 8px;
142
+ }
143
+ .more-apps-label {
144
+ font-size: 13px;
145
+ font-weight: 700;
146
+ color: black;
147
+ }
148
+ @media (max-width: 640px) {
149
+ .apps-list .app {
150
+ flex-basis: calc(50% - 8px);
151
+ }
152
+ }
153
+ </style>
@@ -0,0 +1,297 @@
1
+ <template>
2
+ <transition name="modal-fade">
3
+ <div v-if="visible" class="customization-modal modal-overlay" @click.self="onCancel">
4
+ <div class="modal-container" tabindex="0" @keydown.esc="onCancel">
5
+ <div class="modal-header">
6
+ <h2 class="modal-title">{{ title }}</h2>
7
+ <button class="close-button" @click="onCancel">
8
+ <svg width="24" height="24" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
9
+ <path d="M12 4L4 12" stroke="currentColor" stroke-width="1" />
10
+ <path d="M4 4L12 12" stroke="currentColor" stroke-width="1" />
11
+ </svg>
12
+ </button>
13
+ </div>
14
+ <div class="modal-body">
15
+ <div class="grid">
16
+ <div
17
+ v-for="(item, index) in items"
18
+ :key="index"
19
+ class="card"
20
+ :class="{ selected: selectedIndex === index }"
21
+ @click="selectItem(index)"
22
+ >
23
+ <div v-if="item.icon" class="icon">
24
+ <svg width="51" height="52" viewBox="0 0 51 52" fill="none" xmlns="http://www.w3.org/2000/svg">
25
+ <g clip-path="url(#clip0_840_1701)">
26
+ <path d="M10.625 9H19.125L23.375 19.625L18.0625 22.8125C20.3383 27.427 24.073 31.1617 28.6875 33.4375L31.875 28.125L42.5 32.375V40.875C42.5 42.0022 42.0522 43.0832 41.2552 43.8802C40.4582 44.6772 39.3772 45.125 38.25 45.125C29.9609 44.6213 22.1428 41.1013 16.2708 35.2292C10.3987 29.3572 6.87873 21.5391 6.375 13.25C6.375 12.1228 6.82277 11.0418 7.6198 10.2448C8.41683 9.44777 9.49783 9 10.625 9Z" stroke="#303030" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
27
+ <path d="M31.875 15.375C33.0022 15.375 34.0832 15.8228 34.8802 16.6198C35.6772 17.4168 36.125 18.4978 36.125 19.625" stroke="#303030" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
28
+ <path d="M31.875 6.875C35.2565 6.875 38.4995 8.2183 40.8906 10.6094C43.2817 13.0005 44.625 16.2435 44.625 19.625" stroke="#303030" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
29
+ </g>
30
+ <defs>
31
+ <clipPath id="clip0_840_1701">
32
+ <rect width="51" height="51" fill="white" transform="translate(0 0.5)"/>
33
+ </clipPath>
34
+ </defs>
35
+ </svg>
36
+ </div>
37
+ <strong>{{ item.title }}</strong>
38
+ <div v-if="item.price" class="price">${{ item.price }}</div>
39
+ <p class="description">{{ item.description }}</p>
40
+ <a v-if="item.demo" :href="item.demo" class="demo-link" target="_blank">View demo</a>
41
+ <VariantButton variant="secondary" :full-width="true">
42
+ {{ item.buttonText || (item.price ? "Select" : "Schedule a Call") }}
43
+ </VariantButton>
44
+ </div>
45
+ </div>
46
+ </div>
47
+
48
+ <div class="modal-footer">
49
+ <span class="total">
50
+ <span>Total:</span> ${{ total }}
51
+ </span>
52
+ <VariantButton variant="primary">Submit</VariantButton>
53
+ </div>
54
+ </div>
55
+ </div>
56
+ </transition>
57
+ </template>
58
+
59
+ <script>
60
+ import VariantButton from "@/components/PolarisNew/VariantButton.vue";
61
+
62
+ export default {
63
+ name: "CustomizationModal",
64
+ components: {VariantButton},
65
+ props: {
66
+ visible: Boolean,
67
+ title: {
68
+ type: String,
69
+ default: "Book A Call",
70
+ },
71
+ },
72
+ data() {
73
+ return {
74
+ selectedIndex: null,
75
+ items: [
76
+ {
77
+ title: "Options Block on Collection Page",
78
+ price: 199,
79
+ description: "Lorem ipsum description for section",
80
+ demo: "#",
81
+ },
82
+ {
83
+ title: "Accordion Setup",
84
+ price: 79,
85
+ description: "Lorem ipsum description for section",
86
+ demo: "#",
87
+ },
88
+ {
89
+ title: "Step-by-Step Product Form",
90
+ price: 129,
91
+ description: "Lorem ipsum description for section",
92
+ demo: "#",
93
+ },
94
+ {
95
+ title: "Swatches with Drawer",
96
+ price: 199,
97
+ description: "Lorem ipsum description for section",
98
+ demo: "#",
99
+ },
100
+ {
101
+ title: "Options Block Customization",
102
+ price: 79,
103
+ description: "Lorem ipsum description for section",
104
+ demo: "#",
105
+ },
106
+ {
107
+ title: "Font Preview Block",
108
+ price: 99,
109
+ description: "Lorem ipsum description for section",
110
+ demo: "#",
111
+ },
112
+ {
113
+ title: "Didn't Find What You're Looking For?",
114
+ description: "Discuss with our experts!",
115
+ icon: true,
116
+ buttonText: "Schedule a Call",
117
+ },
118
+ ],
119
+ };
120
+ },
121
+ computed: {
122
+ total() {
123
+ const selected = this.items[this.selectedIndex];
124
+ return selected && selected.price ? selected.price : 0;
125
+ },
126
+ },
127
+ methods: {
128
+ selectItem(index) {
129
+ this.selectedIndex = index;
130
+ },
131
+ onCancel() {
132
+ this.$emit("cancel");
133
+ },
134
+ onSubmit() {
135
+ this.$emit("submit", this.items[this.selectedIndex] || null);
136
+ },
137
+ },
138
+ };
139
+ </script>
140
+
141
+ <style scoped>
142
+ .modal-fade-enter-active,
143
+ .modal-fade-leave-active {
144
+ transition: opacity 0.2s ease;
145
+ }
146
+
147
+ .modal-fade-enter,
148
+ .modal-fade-leave-to {
149
+ opacity: 0;
150
+ }
151
+
152
+ .customization-modal.modal-overlay {
153
+ position: fixed;
154
+ inset: 0;
155
+ background: rgba(0, 0, 0, 0.6);
156
+ z-index: 1000;
157
+ display: flex;
158
+ align-items: center;
159
+ justify-content: center;
160
+ }
161
+
162
+ .customization-modal .modal-container {
163
+ background: #fff;
164
+ width: 90%;
165
+ max-width: 960px;
166
+ border-radius: 10px;
167
+ overflow: hidden;
168
+ outline: none;
169
+ max-height: 90vh;
170
+ display: flex;
171
+ flex-direction: column;
172
+ }
173
+
174
+ .customization-modal .modal-header {
175
+ padding: 12px 16px;
176
+ background: #F3F3F3;
177
+ border-bottom: 1px solid #E3E3E3;
178
+ display: flex;
179
+ justify-content: space-between;
180
+ align-items: center;
181
+ position: relative;
182
+ }
183
+
184
+ .customization-modal .modal-title {
185
+ margin: 0;
186
+ font-size: 13px;
187
+ line-height: 20px;
188
+ font-weight: 600;
189
+ }
190
+
191
+ .customization-modal .close-button {
192
+ border: none;
193
+ cursor: pointer;
194
+ position: absolute;
195
+ top: calc(50% + 2px);
196
+ transform: translateY(-50%);
197
+ right: 10px;
198
+ background: #F3F3F3;
199
+ }
200
+
201
+ .customization-modal .modal-body {
202
+ padding: 20px;
203
+ overflow-y: auto;
204
+ flex: 1;
205
+ }
206
+
207
+ .customization-modal .grid {
208
+ display: grid;
209
+ grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
210
+ gap: 32px 44px;
211
+ }
212
+
213
+ .customization-modal .card {
214
+ border: 1px solid #dcdcdc;
215
+ border-radius: 12px;
216
+ padding: 16px;
217
+ text-align: center;
218
+ transition: border 0.2s;
219
+ background: #fff;
220
+ display: flex;
221
+ flex-direction: column;
222
+ justify-content: space-between;
223
+ gap: 6px;
224
+ }
225
+
226
+ .customization-modal .card.selected,
227
+ .card:hover {
228
+ box-shadow:
229
+ #e3e3e3 0 1px 0 0 inset,
230
+ #e3e3e3 1px 0 0 0 inset,
231
+ #e3e3e3 -1px 0 0 0 inset,
232
+ #b5b5b5 0 -1px 0 0 inset;
233
+ }
234
+
235
+ .customization-modal .card .price {
236
+ font-weight: 500;
237
+ font-size: 20px;
238
+ line-height: 28px;
239
+ letter-spacing: 0;
240
+ }
241
+
242
+ .customization-modal .card .description {
243
+ font-weight: 400;
244
+ font-size: 13px;
245
+ line-height: 20px;
246
+ letter-spacing: 0;
247
+ text-align: center;
248
+ }
249
+
250
+ .customization-modal .card .demo-link {
251
+ font-weight: 400;
252
+ font-size: 13px;
253
+ line-height: 20px;
254
+ letter-spacing: 0;
255
+ text-align: center;
256
+ color: #0094D5;
257
+ text-decoration: none;
258
+ }
259
+
260
+ .customization-modal .card .action-btn {
261
+ margin-top: auto;
262
+ border: 1px solid #dcdcdc;
263
+ background: #fff;
264
+ border-radius: 6px;
265
+ padding: 8px;
266
+ cursor: pointer;
267
+ }
268
+
269
+ .customization-modal .icon img {
270
+ height: 36px;
271
+ margin-bottom: 8px;
272
+ }
273
+
274
+ .customization-modal .modal-footer {
275
+ border-top: 1px solid #E3E3E3;
276
+ padding: 12px 16px;
277
+ display: flex;
278
+ gap: 8px;
279
+ justify-content: right;
280
+ align-items: center;
281
+ }
282
+
283
+ .customization-modal .total {
284
+ font-weight: 500;
285
+ font-size: 13px;
286
+ line-height: 20px;
287
+ letter-spacing: 0;
288
+ text-align: center;
289
+ color: #00000080;
290
+ }
291
+
292
+ .customization-modal .total span {
293
+ font-weight: 700;
294
+ color: #000000;
295
+ }
296
+
297
+ </style>
@@ -0,0 +1,93 @@
1
+ <script>
2
+ import VariantButton from "./VariantButton.vue";
3
+
4
+ export default {
5
+ name: "GetCustomBlock",
6
+ components: {
7
+ VariantButton
8
+ },
9
+ props: {
10
+ title: {
11
+ type: String,
12
+ required: false,
13
+ },
14
+ description: {
15
+ type: String,
16
+ required: false,
17
+ },
18
+ buttonText: {
19
+ type: String,
20
+ required: false,
21
+ },
22
+ },
23
+ methods: {
24
+ handleClick() {
25
+ event.preventDefault();
26
+ this.$emit("click", event);
27
+ },
28
+ translateMe(message) {
29
+ return this.$translations.hasOwnProperty(message)
30
+ ? this.$translations[message]
31
+ : message;
32
+ },
33
+ handleCustomizePlan(){
34
+ this.$emit('handleCustomizePlan')
35
+ }
36
+ },
37
+ };
38
+ </script>
39
+
40
+ <template>
41
+ <div class="block">
42
+ <img
43
+ src="../../assets/cogsettings.svg"
44
+ alt="Settings"
45
+ width="76"
46
+ height="78"
47
+ />
48
+ <h3>{{ title }}</h3>
49
+ <h6>{{ description }}</h6>
50
+ <VariantButton @click="handleClick" variant="primary" class="button">{{
51
+ buttonText
52
+ }}</VariantButton>
53
+ </div>
54
+ </template>
55
+
56
+ <style scoped>
57
+ .block {
58
+ display: flex;
59
+ flex-direction: column;
60
+ justify-content: center;
61
+ align-items: center;
62
+ width: 100%;
63
+ gap: 16px;
64
+ padding: 20px;
65
+ background-color: white;
66
+ border-radius: 16px;
67
+ box-shadow: 0px 4px 6px -1px #0000001a;
68
+ border: 1px solid #e5e5e5;
69
+ }
70
+ .block img {
71
+ width: auto;
72
+ height: auto;
73
+ }
74
+ .block h3 {
75
+ font-size: 16px;
76
+ font-weight: 700;
77
+ color: black;
78
+ }
79
+ .block h6 {
80
+ font-size: 13px;
81
+ font-weight: 400;
82
+ color: #00000080;
83
+ max-width: 186px;
84
+ text-align: center;
85
+ }
86
+ .button {
87
+ /* width: 261px !important; */
88
+ width: 100% !important;
89
+ display: flex !important;
90
+ height: fit-content !important;
91
+ justify-content: center !important;
92
+ }
93
+ </style>