PluginProbe ʕ •ᴥ•ʔ
Booking for Appointments and Events Calendar – Amelia / 2.4.6
Booking for Appointments and Events Calendar – Amelia v2.4.6
2.4.8 2.4.7 2.4.6 2.4.5 2.4.4 2.4.3 2.4.2 2.4.1 2.4 trunk 1.2.1 1.2.10 1.2.11 1.2.12 1.2.13 1.2.14 1.2.15 1.2.16 1.2.17 1.2.18 1.2.19 1.2.2 1.2.20 1.2.21 1.2.22 1.2.23 1.2.24 1.2.25 1.2.26 1.2.27 1.2.28 1.2.29 1.2.3 1.2.30 1.2.31 1.2.32 1.2.33 1.2.34 1.2.35 1.2.36 1.2.37 1.2.38 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 2.0 2.0.1 2.0.2 2.1 2.1.1 2.1.2 2.1.3 2.2 2.2.1 2.3
ameliabooking / v3 / src / views / admin / customize / steps / CategoryPackage.vue
ameliabooking / v3 / src / views / admin / customize / steps Last commit date
Cabinet 1 month ago Events 1 month ago StepForm 1 month ago common 1 month ago parts 1 month ago BringingAnyone.vue 1 month ago CategoriesList.vue 1 month ago CategoryItemsList.vue 1 month ago CategoryPackage.vue 1 month ago CategoryService.vue 1 month ago Extras.vue 1 month ago PackageAppointmentsListStep.vue 1 month ago PackageAppointmentsStep.vue 1 month ago PackageInfoStep.vue 1 month ago PackageStep.vue 1 month ago RecurringStep.vue 1 month ago RecurringSummary.vue 1 month ago
CategoryPackage.vue
1376 lines
1 <template>
2 <Content
3 ref="contentRef"
4 wrapper-class="am-fcip"
5 form-class="am-fcip__form"
6 heading-class="am-fcip__header"
7 :content-class="`am-fcip__content ${customizeOptions.pageScroll.visibility ? '' : 'no-scroll'}`"
8 :style="cssVars"
9 >
10 <template #header>
11 <Header
12 :btn-string="labelsDisplay('back_btn')"
13 :btn-type="customizeOptions.backBtn.buttonType"
14 ></Header>
15 </template>
16 <template #heading>
17 <div
18 class="am-fcip__header-top"
19 :class="[{ 'am-tablet': pageWidth <= 678 }, { 'am-mobile': pageWidth < 450 }]"
20 >
21 <div class="am-fcip__header-text">
22 <span class="am-fcip__header-name">
23 <span>
24 {{ pack.name }}
25 </span>
26 </span>
27 <div v-if="customizeOptions.packageBadge.visibility" class="am-fcip__badge am-package">
28 <span class="am-icon-shipment"></span>
29 <span>
30 {{ labelsDisplay('package') }}
31 </span>
32 </div>
33 </div>
34 <div class="am-fcip__header-action">
35 <span
36 v-if="pack.discount && customizeOptions.packagePrice.visibility"
37 class="am-fcip__header-discount"
38 >
39 {{ `${labelsDisplay('save')} ${pack.discount}%` }}
40 </span>
41 <span v-if="customizeOptions.packagePrice.visibility" class="am-fcip__header-price">
42 {{ pack.price ? useFormattedPrice(usePackageAmount(pack)) : amLabels.free }}
43 </span>
44 <span class="am-fcip__header-btn">
45 <AmButton :type="customizeOptions.bookingBtn.buttonType">
46 {{ labelsDisplay('book_now') }}
47 </AmButton>
48 </span>
49 </div>
50 </div>
51 <div
52 v-if="
53 customizeOptions.packageCategory.visibility ||
54 customizeOptions.packageDuration.visibility ||
55 customizeOptions.packageCapacity.visibility ||
56 customizeOptions.packageLocation.visibility
57 "
58 class="am-fcip__header-bottom"
59 >
60 <div class="am-fcip__mini-info">
61 <div v-if="customizeOptions.packageCategory.visibility" class="am-fcip__mini-info__inner">
62 <span class="am-icon-folder"></span>
63 <span>Category 1</span>
64 </div>
65 <div v-if="customizeOptions.packageDuration.visibility" class="am-fcip__mini-info__inner">
66 <span class="am-icon-clock"></span>
67 <span v-if="pack.endDate">
68 {{ `${labelsDisplay('expires_at')} ${pack.endDate.split(' ')[0]}` }}
69 </span>
70 <span v-else-if="pack.durationCount">
71 {{
72 `${labelsDisplay('expires_after')} ${
73 pack.durationCount
74 } ${durationTypeLabel(pack.durationCount, pack.durationType)}`
75 }}
76 </span>
77 <span v-else>
78 {{ labelsDisplay('without_expiration') }}
79 </span>
80 </div>
81 <div v-if="customizeOptions.packageCapacity.visibility" class="am-fcip__mini-info__inner">
82 <span class="am-icon-user"></span>
83 <span>1/1</span>
84 </div>
85 <div v-if="customizeOptions.packageLocation.visibility" class="am-fcip__mini-info__inner">
86 <span class="am-icon-locations"></span>
87 <span>
88 {{ labelsDisplay('multiple_locations') }}
89 </span>
90 </div>
91 </div>
92 </div>
93 </template>
94 <template #content>
95 <!-- Package Gallery -->
96 <div v-if="pack.gallery.length" class="am-fcip__gallery">
97 <div
98 class="am-fcip__gallery-hero"
99 :class="[{ w100: pack.gallery.length === 1 }, { 'am-mobile w100': pageWidth < 678 }]"
100 :style="{
101 backgroundImage: `url(${pack.gallery[0].pictureFullPath})`,
102 }"
103 ></div>
104 <div
105 v-if="packageThumbsGallery.length && pageWidth > 677"
106 class="am-fcip__gallery-thumb__wrapper"
107 >
108 <div
109 v-for="(img, index) in packageThumbsGallery"
110 :key="index"
111 class="am-fcip__gallery-thumb"
112 :class="{ 'am-one-thumb': packageThumbsGallery.length === 1 }"
113 :style="{ backgroundImage: `url(${img.pictureFullPath})` }"
114 ></div>
115 <AmButton
116 :custom-class="`am-fcip__gallery-btn${pageWidth < 678 ? ' am-mobile' : ''}`"
117 category="secondary"
118 type="filled"
119 @click="() => (galleryDialog = true)"
120 >
121 <span class="am-icon-gallery"></span>
122 <span>
123 {{ labelsDisplay('view_all_photos') }}
124 </span>
125 </AmButton>
126 </div>
127 </div>
128 <!-- Service Gallery -->
129
130 <!-- Gallery Images -->
131 <AmDialog
132 v-model="galleryDialog"
133 :modal-class="'amelia-v2-booking amelia-v2-gdp'"
134 :append-to-body="true"
135 :center="true"
136 :lock-scroll="false"
137 >
138 <div class="am-gd" :style="cssGalleryDialogVars">
139 <div class="am-gd__display-wrapper">
140 <div class="am-gd__arrows" style="display: flex; justify-content: space-between">
141 <span
142 class="am-icon-arrow-left"
143 @click="
144 () => (activeImage = activeImage <= 0 ? pack.gallery.length - 1 : activeImage - 1)
145 "
146 ></span>
147 <span
148 class="am-icon-arrow-right"
149 @click="
150 () =>
151 (activeImage = pack.gallery.length - 1 === activeImage ? 0 : activeImage + 1)
152 "
153 ></span>
154 </div>
155 <div
156 v-for="(img, index) in pack.gallery"
157 :key="index"
158 class="am-gd__display"
159 :style="{ display: index === activeImage ? 'flex' : 'none' }"
160 @click="
161 () => (activeImage = pack.gallery.length - 1 === activeImage ? 0 : activeImage + 1)
162 "
163 >
164 <img :src="img.pictureFullPath" :alt="index" />
165 </div>
166 </div>
167 <div class="am-gd__selection">
168 {{ `${activeImage + 1}/${pack.gallery.length}` }}
169 </div>
170 <div class="am-gd__thumb-wrapper">
171 <div
172 v-for="(img, index) in pack.gallery"
173 :key="index"
174 class="am-gd__thumb"
175 :class="{ 'am-active': index === activeImage }"
176 :style="{ backgroundImage: `url(${img.pictureFullPath})` }"
177 @click="() => (activeImage = index)"
178 ></div>
179 </div>
180 </div>
181 </AmDialog>
182 <!-- /Gallery Images -->
183
184 <!-- Package Info - (description, employees) -->
185 <div
186 v-if="
187 customizeOptions.packageDescription.visibility ||
188 customizeOptions.packageEmployees.visibility
189 "
190 class="am-fcip__info"
191 >
192 <div class="am-fcip__info-tab__wrapper">
193 <div
194 v-if="pack.description && customizeOptions.packageDescription.visibility"
195 class="am-fcip__info-tab"
196 :class="{ 'am-active': tabsActive === 'description' }"
197 @click="() => (tabsActive = 'description')"
198 >
199 {{ labelsDisplay('about_package') }}
200 </div>
201 <div
202 v-if="customizeOptions.packageEmployees.visibility"
203 :class="{ 'am-active': tabsActive === 'employees' }"
204 class="am-fcip__info-tab"
205 @click="() => (tabsActive = 'employees')"
206 >
207 {{ labelsDisplay('tab_employees') }}
208 </div>
209 </div>
210 <div class="am-fcip__info-content__wrapper">
211 <!-- Description -->
212 <div
213 v-if="pack.description && customizeOptions.packageDescription.visibility"
214 v-show="tabsActive === 'description'"
215 class="am-fcip__info-content"
216 >
217 <div class="am-fcip__info-service__desc" v-html="pack.description"></div>
218 </div>
219 <!-- /Description -->
220
221 <!-- Employees -->
222 <div
223 v-if="customizeOptions.packageEmployees.visibility"
224 v-show="tabsActive === 'employees'"
225 class="am-fcip__info-content"
226 >
227 <AmCollapse>
228 <AmCollapseItem v-for="employee in packageEmployees" :key="employee.id" side>
229 <template #heading>
230 <div class="am-fcip__info-employee">
231 <div class="am-fcip__info-employee__hero">
232 <div
233 class="am-fcip__info-employee__img"
234 :style="{ ...employeeImage(employee) }"
235 >
236 {{ employeeSign(employee) }}
237 </div>
238 <div class="am-fcip__info-employee__name">
239 {{ employee.firstName }} {{ employee.lastName }}
240 </div>
241 </div>
242 </div>
243 </template>
244 <template #default></template>
245 </AmCollapseItem>
246 </AmCollapse>
247 </div>
248 <!-- /Employees -->
249 </div>
250 </div>
251
252 <!-- Available Service in Packages -->
253 <div v-if="customizeOptions.packageServices.visibility" class="am-fcip__include-wrapper">
254 <div class="am-fcip__include-heading">
255 <span class="am-fcip__include-heading__text">
256 {{ `${labelsDisplay('package_includes')}:` }}
257 </span>
258 </div>
259 <AmCollapse>
260 <AmCollapseItem v-for="book in pack.services" :key="book.id" :side="true">
261 <template #heading>
262 <div class="am-fcip__include-service">
263 <div class="am-fcip__include-service__img" :style="{ ...cardImage(book) }">
264 {{ cardSign(book) }}
265 </div>
266 {{ book.name + (!pack.sharedCapacity ? ' x ' + book.quantity : '') }}
267 </div>
268 </template>
269 <template #default>
270 <div class="am-fcip__include-service__info">
271 <span>{{ `${labelsDisplay('tab_employees')}:` }}</span>
272 <template v-for="employee in packageEmployees" :key="employee.id">
273 <div
274 class="am-fcip__include-service__employee"
275 :style="{ ...cardImage(employee) }"
276 >
277 {{ cardSign(employee) }}
278 </div>
279 </template>
280 <span v-if="packageEmployees.length > 6">
281 + {{ packageEmployees.length - 6 }}
282 </span>
283 <template v-if="book.description">
284 <p v-html="book.description"></p>
285 </template>
286 </div>
287 </template>
288 </AmCollapseItem>
289 </AmCollapse>
290 <div class="am-fcip__include-footer">
291 <span class="am-fcip__include-footer__text">
292 {{ labelsDisplay('package_book_service') }}
293 </span>
294 </div>
295 </div>
296 <!-- /Available Package in Service -->
297 </template>
298 </Content>
299 </template>
300
301 <script setup>
302 // * Components
303 import Content from '../../../common/CatalogFormConstruction/Content/Content.vue'
304 import Header from '../../../common/CatalogFormConstruction/Header/Header.vue'
305 import AmButton from '../../../_components/button/AmButton.vue'
306 import AmDialog from '../../../_components/dialog/AmDialog.vue'
307 import AmCollapse from '../../../_components/collapse/AmCollapse.vue'
308 import AmCollapseItem from '../../../_components/collapse/AmCollapseItem.vue'
309
310 // * Vue
311 import { ref, inject, computed, onMounted, watchEffect, onBeforeUnmount } from 'vue'
312
313 // * Composables
314 import { useFormattedPrice } from '../../../../assets/js/common/formatting.js'
315 import {
316 amCardColors,
317 useColorTransparency,
318 } from '../../../../assets/js/common/colorManipulation.js'
319 import { usePackageAmount } from '../../../../assets/js/public/package.js'
320 import { useReactiveCustomize } from '../../../../assets/js/admin/useReactiveCustomize.js'
321
322 // * Customize
323 const { amCustomize } = useReactiveCustomize()
324
325 // * Page Width
326 let contentRef = ref()
327 let pageWidth = inject('containerWidth')
328
329 // * Customize Options
330 let customizeOptions = computed(() => {
331 return amCustomize.value.cbf.categoryPackage.options
332 })
333
334 // * Base URLs
335 const baseUrls = inject('baseUrls')
336
337 // * Selected service
338 let pack = ref({
339 id: 1,
340 name: 'Package 1',
341 color: '#689BCA',
342 calculatedPrice: false,
343 deposit: 50,
344 discount: 10,
345 price: 500,
346 depositPayment: 'percentage',
347 description:
348 "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
349 durationCount: 2,
350 durationType: 'week',
351 endDate: null,
352 gallery: [
353 {
354 pictureFullPath: `${baseUrls.value.wpAmeliaPluginURL}v3/src/assets/img/admin/customize/img_gallery_placeholder.svg`,
355 pictureThumbPath: `${baseUrls.value.wpAmeliaPluginURL}v3/src/assets/img/admin/customize/img_holder1.svg`,
356 },
357 {
358 pictureFullPath: `${baseUrls.value.wpAmeliaPluginURL}v3/src/assets/img/admin/customize/img_holder1.svg`,
359 pictureThumbPath: `${baseUrls.value.wpAmeliaPluginURL}v3/src/assets/img/admin/customize/img_holder1.svg`,
360 },
361 {
362 pictureFullPath: `${baseUrls.value.wpAmeliaPluginURL}v3/src/assets/img/admin/customize/img_holder1.svg`,
363 pictureThumbPath: `${baseUrls.value.wpAmeliaPluginURL}v3/src/assets/img/admin/customize/img_holder1.svg`,
364 },
365 {
366 pictureFullPath: `${baseUrls.value.wpAmeliaPluginURL}v3/src/assets/img/admin/customize/img_holder1.svg`,
367 pictureThumbPath: `${baseUrls.value.wpAmeliaPluginURL}v3/src/assets/img/admin/customize/img_holder1.svg`,
368 },
369 ],
370 pictureFullPath: `${baseUrls.value.wpAmeliaPluginURL}v3/src/assets/img/admin/customize/img_holder1.svg`,
371 pictureThumbPath: `${baseUrls.value.wpAmeliaPluginURL}v3/src/assets/img/admin/customize/img_holder1.svg`,
372 locations: ['Location 1, Location 2'],
373 services: [
374 {
375 id: 1,
376 name: 'Service 1',
377 description:
378 "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
379 quantity: 5,
380 },
381 {
382 id: 2,
383 name: 'Service 2',
384 description:
385 "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
386 quantity: 5,
387 },
388 {
389 id: 3,
390 name: 'Service 3',
391 description:
392 "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
393 quantity: 5,
394 },
395 {
396 id: 4,
397 name: 'Service 4',
398 description:
399 "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
400 quantity: 5,
401 },
402 {
403 id: 5,
404 name: 'Service 5',
405 description:
406 "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.",
407 quantity: 5,
408 },
409 ],
410 })
411
412 // * Package info tabs
413 let tabsActive = ref('description')
414
415 watchEffect(() => {
416 if (!customizeOptions.value.packageDescription.visibility) tabsActive.value = 'employees'
417 if (!customizeOptions.value.packageEmployees.visibility) tabsActive.value = 'description'
418 })
419
420 onBeforeUnmount(() => {
421 watchEffect(() => {})
422 })
423
424 let packageEmployees = ref([
425 {
426 id: 1,
427 firstName: 'Herman',
428 lastName: 'Small',
429 pictureFullPath: null,
430 pictureThumbPath: null,
431 price: 20,
432 },
433 {
434 id: 2,
435 firstName: 'Abbie',
436 lastName: 'William',
437 pictureFullPath: null,
438 pictureThumbPath: null,
439 price: 150,
440 },
441 {
442 id: 3,
443 firstName: 'Miya',
444 lastName: 'Burrows',
445 pictureFullPath: null,
446 pictureThumbPath: null,
447 price: 80,
448 },
449 {
450 id: 4,
451 firstName: 'Derrick',
452 lastName: 'Cardenas',
453 pictureFullPath: null,
454 pictureThumbPath: null,
455 price: 120,
456 },
457 {
458 id: 5,
459 firstName: 'Zeynep',
460 lastName: 'Whittington',
461 pictureFullPath: null,
462 pictureThumbPath: null,
463 price: 45,
464 },
465 ])
466
467 function employeeImage(employee) {
468 if (employee.pictureFullPath) return { backgroundImage: `url(${employee.pictureFullPath})` }
469
470 return {
471 backgroundColor: `${amCardColors.value[Math.floor(Math.random() * amCardColors.value.length)]}`,
472 }
473 }
474
475 function employeeSign(employee) {
476 if (!employee.pictureFullPath) {
477 let firstName = employee.firstName.charAt(0)
478 let lastName = employee.lastName.charAt(0)
479 return `${firstName}${lastName}`
480 }
481 return ''
482 }
483
484 onMounted(() => {
485 tabsActive.value = pack.value.description ? 'description' : 'employees'
486 })
487
488 // * Gallery
489 let activeImage = ref(0)
490 let galleryDialog = ref(false)
491
492 let packageThumbsGallery = computed(() => {
493 let thumbs = pack.value.gallery.length ? JSON.parse(JSON.stringify(pack.value.gallery)) : []
494 if (pack.value.gallery.length === 1) return []
495 thumbs.shift()
496 if (thumbs.length > 2) thumbs.splice(2, thumbs.length - 2)
497 return thumbs
498 })
499
500 function cardImage(info) {
501 if (info.pictureFullPath) return { backgroundImage: `url(${info.pictureFullPath})` }
502
503 return {
504 backgroundColor: `${amCardColors.value[Math.floor(Math.random() * amCardColors.value.length)]}`,
505 }
506 }
507
508 function cardSign(info) {
509 if (!info.pictureFullPath) {
510 let name = 'firstName' in info ? `${info.firstName} ${info.lastName}` : info.name
511 return name
512 .split(' ')
513 .map((s) => s.charAt(0))
514 .join('')
515 .toUpperCase()
516 .substring(0, 3)
517 .replace(/[^\w\s]/g, '')
518 }
519 return ''
520 }
521
522 // * Labels
523 let langKey = inject('langKey')
524 let amLabels = inject('labels')
525
526 function labelsDisplay(label) {
527 let computedLabel = computed(() => {
528 let translations = amCustomize.value.cbf.categoryPackage.translations
529 return translations && translations[label] && translations[label][langKey.value]
530 ? translations[label][langKey.value]
531 : amLabels[label]
532 })
533
534 return computedLabel.value
535 }
536
537 function durationTypeLabel(duration, type) {
538 let string = ''
539 if (duration > 1) {
540 if (type === 'day') string = labelsDisplay('expires_days')
541 if (type === 'week') string = labelsDisplay('expires_weeks')
542 if (type === 'month') string = labelsDisplay('expires_months')
543 } else {
544 if (type === 'day') string = labelsDisplay('expires_day')
545 if (type === 'week') string = labelsDisplay('expires_week')
546 if (type === 'month') string = labelsDisplay('expires_month')
547 }
548 return string
549 }
550
551 // * Fonts
552 let amFonts = inject('amFonts')
553
554 // * Colors
555 let amColors = inject('amColors')
556
557 let cssVars = computed(() => {
558 return {
559 '--am-c-fcip-success-op20': useColorTransparency(amColors.value.colorSuccess, 0.2),
560 '--am-c-fcip-primary-op20': useColorTransparency(amColors.value.colorPrimary, 0.2),
561 '--am-c-fcip-text-op80': useColorTransparency(amColors.value.colorMainText, 0.8),
562 '--am-c-fcip-text-op60': useColorTransparency(amColors.value.colorMainText, 0.6),
563 '--am-c-fcip-text-op03': useColorTransparency(amColors.value.colorMainText, 0.03),
564 '--am-c-fcip-btn-op50': useColorTransparency(amColors.value.colorBtnSec, 0.5),
565 }
566 })
567
568 let cssGalleryDialogVars = computed(() => {
569 return {
570 '--am-c-fcip-bgr': amColors.value.colorMainBgr,
571 '--am-c-fcip-text': amColors.value.colorMainText,
572 '--am-c-fcip-success': amColors.value.colorSuccess,
573 '--am-c-fcip-primary': amColors.value.colorPrimary,
574 '--am-c-scroll-op30': useColorTransparency(amColors.value.colorPrimary, 0.3),
575 '--am-c-scroll-op10': useColorTransparency(amColors.value.colorPrimary, 0.1),
576 '--am-font-family': amFonts.fontFamily,
577 }
578 })
579 </script>
580
581 <script>
582 export default {
583 name: 'CategoryPackage',
584 key: 'categoryPackage',
585 }
586 </script>
587
588 <style lang="scss">
589 @import '../../../../../src/assets/scss/common/quill/_quill-mixin.scss';
590
591 #amelia-app-backend-new {
592 // am- amelia
593 // -c- color
594 // -fcip- form category item package
595 // -bgr background
596 #amelia-container {
597 .am-fcip {
598 --am-c-fcip-header-text: var(--am-c-main-heading-text);
599 --am-c-fcip-bgr: var(--am-c-main-bgr);
600 --am-c-fcip-text: var(--am-c-main-text);
601 --am-c-fcip-success: var(--am-c-success);
602 --am-c-fcip-primary: var(--am-c-primary);
603 width: 100%;
604 padding: 24px;
605 border-radius: 10px;
606
607 &__form {
608 padding-top: 24px;
609 }
610
611 &__header {
612 &-top {
613 display: flex;
614 align-items: center;
615 justify-content: space-between;
616 padding: 0 0 16px;
617
618 &.am-tablet {
619 flex-wrap: wrap;
620
621 .am-fcip__header-text {
622 width: 100%;
623 justify-content: space-between;
624 margin-bottom: 12px;
625 }
626
627 .am-fcip__header-action {
628 width: 100%;
629 justify-content: space-between;
630 }
631
632 &.am-mobile {
633 .am-fcip__header {
634 &-text {
635 flex-wrap: wrap;
636 }
637
638 &-name {
639 width: 100%;
640 }
641
642 &-action {
643 flex-wrap: wrap;
644 }
645
646 &-discount,
647 &-price,
648 &-tax {
649 margin-bottom: 6px;
650 }
651
652 &-btn {
653 width: 100%;
654 .am-button {
655 width: 100%;
656 margin-top: 6px;
657 }
658 }
659 }
660
661 .am-fcip__badge {
662 margin-left: 0;
663 }
664 }
665 }
666 }
667
668 &-text {
669 display: flex;
670 padding-right: 12px;
671 align-items: center;
672 }
673
674 &-name {
675 display: inline-flex;
676
677 span {
678 display: -webkit-box;
679 font-size: 28px;
680 font-weight: 500;
681 line-height: 1.2;
682 color: var(--am-c-fcip-header-text);
683 -webkit-line-clamp: 3;
684 -webkit-box-orient: vertical;
685 overflow: hidden;
686 text-overflow: ellipsis;
687 }
688 }
689
690 &-action {
691 display: flex;
692 align-items: center;
693 justify-content: flex-end;
694 flex: 0 0 auto;
695 }
696
697 &-discount {
698 display: inline-flex;
699 align-items: center;
700 height: 28px;
701 padding: 0 12px 0;
702 border-radius: 14px;
703 font-size: 18px;
704 font-weight: 500;
705 margin: 0 12px 0 0;
706 color: var(--am-c-fcip-success);
707 background-color: var(--am-c-fcip-success-op20);
708 }
709
710 &-price {
711 font-size: 18px;
712 font-weight: 500;
713 margin-right: 20px;
714 color: var(--am-c-fcip-primary);
715 }
716
717 &-tax {
718 display: inline-flex;
719 align-items: center;
720 height: 28px;
721 padding: 0 12px 0;
722 border-radius: 14px;
723 font-size: 18px;
724 font-weight: 500;
725 margin: 0 12px 0 0;
726 color: var(--am-c-fcip-primary);
727 background-color: var(--am-c-fcip-primary-op20);
728 }
729
730 &-bottom {
731 padding: 0 0 16px;
732 }
733 }
734
735 &__content {
736 &.no-scroll {
737 max-height: unset;
738 overflow-x: unset;
739 }
740 }
741
742 &__badge {
743 display: inline-flex;
744 flex: 0 0 auto;
745 align-items: center;
746 height: 28px;
747 padding: 0 12px 0 8px;
748 border-radius: 14px;
749 margin-left: 10px;
750
751 &.am-package {
752 background: linear-gradient(
753 95.75deg,
754 var(--am-c-fcip-bgr) -110.8%,
755 var(--am-c-warning) 114.33%
756 );
757 span {
758 color: var(--am-c-fcip-bgr);
759 }
760 }
761
762 span {
763 display: block;
764 font-size: 18px;
765 font-weight: 400;
766 line-height: 1;
767
768 &[class*='am-icon']*='am-icon'] {
769 font-size: 24px;
770 }
771 }
772 }
773
774 &__mini-info {
775 display: flex;
776 flex-wrap: wrap;
777 align-items: center;
778
779 &__inner {
780 display: inline-flex;
781 align-items: center;
782 max-width: 100%;
783 padding: 0 8px 0 0;
784 margin: 0 0 8px;
785
786 &:last-child {
787 padding: 0;
788 }
789
790 span {
791 font-size: 18px;
792 font-weight: 400;
793 color: var(--am-c-fcip-text-op80);
794 line-height: 1.2;
795 text-overflow: ellipsis;
796 white-space: nowrap;
797 overflow: hidden;
798
799 &[class*='am-icon']*='am-icon'] {
800 flex: 0 0 auto;
801 font-size: 24px;
802 color: var(--am-c-fcip-primary);
803 }
804 }
805 }
806 }
807
808 &__gallery {
809 display: flex;
810 position: relative;
811 transition: all 0.3s ease-in-out;
812 margin: 0 0 32px;
813 padding: 0 12px;
814
815 &-hero {
816 width: calc(100% - 264px);
817 border-top-left-radius: 8px;
818 border-bottom-left-radius: 8px;
819 margin: 0;
820 background-size: cover;
821 background-repeat: no-repeat;
822 background-position: center;
823 transition: all 0.3s ease-in-out;
824 overflow: hidden;
825
826 &.w100 {
827 width: 100%;
828 padding-top: 25%;
829 border-radius: 8px;
830 margin-bottom: 0;
831
832 &.am-mobile {
833 padding-top: 150px;
834 }
835 }
836 }
837
838 &-thumb {
839 position: relative;
840 display: inline-block;
841 width: calc(100% - 16px);
842 padding-top: calc(50% - 16px);
843 margin: 0 0 16px 16px;
844 background-size: cover;
845 background-repeat: no-repeat;
846 background-position: center;
847 overflow: hidden;
848 //cursor: pointer;
849 float: left;
850
851 &:first-child {
852 border-top-right-radius: 8px;
853 }
854
855 &:last-of-type {
856 border-bottom-right-radius: 8px;
857 margin-bottom: 0;
858 }
859
860 &__wrapper {
861 width: 100%;
862 max-width: 264px;
863 position: relative;
864
865 &:after,
866 &:before {
867 content: '';
868 display: block;
869 clear: both;
870 }
871 }
872
873 &.am-one-thumb {
874 padding-top: calc(100% - 16px);
875 }
876 }
877
878 &-btn {
879 position: absolute;
880 bottom: 12px;
881 right: 24px;
882 display: flex;
883 align-items: center;
884 justify-content: center;
885 width: calc(264px - 40px);
886
887 &.am-mobile {
888 width: calc(100% - 48px);
889 }
890
891 &.am-button.am-button--filled {
892 --am-c-btn-bgr: var(--am-c-btn-second);
893 --am-c-btn-text: var(--am-c-btn-first);
894 --am-c-btn-border: var(--am-c-fcip-btn-op50);
895
896 &:not(.is-disabled) {
897 &:hover {
898 --am-c-btn-bgr: var(--am-c-btn-second);
899 --am-c-btn-text: var(--am-c-btn-first);
900 --am-c-btn-border: var(--am-c-fcip-btn-op50);
901 }
902 }
903 }
904
905 .am-icon-gallery {
906 font-size: 24px;
907 margin-right: 4px;
908 }
909 }
910 }
911
912 &__info {
913 padding: 0 12px;
914 margin: 0 0 32px;
915
916 &-tab {
917 font-size: 14px;
918 font-weight: 500;
919 color: var(--am-c-fcip-text);
920 padding: 12px 16px;
921 cursor: pointer;
922
923 &:hover {
924 color: var(--am-c-fcip-primary);
925 }
926
927 &.am-active {
928 color: var(--am-c-fcip-primary);
929 border-bottom: 3px solid var(--am-c-fcip-primary);
930 padding-bottom: 9px;
931 }
932
933 &__wrapper {
934 display: flex;
935 align-items: center;
936 justify-content: flex-start;
937 position: relative;
938 }
939 }
940
941 &-content {
942 padding: 24px 0;
943
944 .am-collapse-item {
945 background-color: var(--am-c-fcip-bgr);
946
947 $count: 100;
948 @for $i from 0 through $count {
949 &:nth-child(#{$i + 1}) {
950 animation: 600ms
951 cubic-bezier(0.45, 1, 0.4, 1.2)
952 #{$i *
953 100}ms
954 am-animation-slide-up;
955 animation-fill-mode: both;
956 }
957 }
958
959 &__heading {
960 padding: 12px;
961 transition-delay: 0.5s;
962
963 &-side {
964 transition-delay: 0s;
965 }
966 }
967 }
968 }
969
970 &-service {
971 &__desc {
972 font-size: 15px;
973 line-height: 2;
974 word-break: break-word;
975 white-space: break-spaces;
976 color: var(--am-c-fcip-text-op80);
977
978 * {
979 font-size: 15px;
980 line-height: 2;
981 word-break: break-word;
982 white-space: break-spaces;
983 color: var(--am-c-fcip-text-op80);
984 }
985
986 a {
987 color: var(--am-c-fcip-primary);
988 }
989
990 &.ql-description {
991 @include quill-styles;
992 }
993 }
994 }
995
996 &-employee {
997 display: flex;
998 flex-wrap: wrap;
999 align-items: center;
1000 justify-content: space-between;
1001
1002 &:last-child {
1003 margin: 0;
1004 }
1005
1006 &__hero {
1007 display: flex;
1008 align-items: center;
1009 justify-content: center;
1010 }
1011
1012 &__img {
1013 width: 54px;
1014 height: 54px;
1015 display: flex;
1016 flex: 0 0 auto;
1017 align-items: center;
1018 justify-content: center;
1019 background-position: center;
1020 background-size: cover;
1021 border-radius: 4px;
1022 border: 1px solid var(--am-c-inp-border);
1023 color: var(--am-c-fcip-bgr);
1024 font-size: 18px;
1025 font-weight: 500;
1026 }
1027
1028 &__name {
1029 font-size: 15px;
1030 font-weight: 500;
1031 color: var(--am-c-fcip-text);
1032 margin: 0 0 0 12px;
1033 }
1034
1035 &__badge {
1036 color: #fff;
1037 border-radius: 4px;
1038 padding: 0 4px;
1039 font-size: 13px;
1040 line-height: 19px;
1041 }
1042
1043 &__price {
1044 display: flex;
1045 align-items: center;
1046 justify-content: center;
1047 height: 24px;
1048 font-size: 14px;
1049 line-height: 1;
1050 color: var(--am-c-fcip-primary);
1051 background-color: var(--am-c-fcip-primary-op20);
1052 padding: 0 8px;
1053 border-radius: 12px;
1054 }
1055
1056 &__description {
1057 color: var(--am-c-fcis-text);
1058
1059 &.ql-description {
1060 @include quill-styles;
1061 }
1062 }
1063 }
1064 }
1065
1066 &__include {
1067 &-wrapper {
1068 padding: 12px;
1069 background-color: var(--am-c-fcip-text-op03);
1070 border-radius: 8px;
1071
1072 .am-collapse-item {
1073 background-color: var(--am-c-fcip-bgr);
1074
1075 $count: 100;
1076 @for $i from 0 through $count {
1077 &:nth-child(#{$i + 1}) {
1078 animation: 600ms
1079 cubic-bezier(0.45, 1, 0.4, 1.2)
1080 #{$i *
1081 100}ms
1082 am-animation-slide-up;
1083 animation-fill-mode: both;
1084 }
1085 }
1086
1087 &__heading {
1088 padding: 8px;
1089 transition-delay: 0.5s;
1090
1091 &-side {
1092 transition-delay: 0s;
1093 }
1094 }
1095 }
1096 }
1097
1098 &-heading {
1099 display: flex;
1100 align-items: center;
1101
1102 &__text {
1103 display: inline-flex;
1104 font-size: 14px;
1105 font-weight: 500;
1106 color: var(--am-c-fcip-text);
1107 }
1108 }
1109
1110 &-footer {
1111 display: flex;
1112 align-items: center;
1113
1114 &__text {
1115 display: inline-flex;
1116 font-size: 13px;
1117 font-weight: 400;
1118 color: var(--am-c-fcip-text-op60);
1119 }
1120 }
1121
1122 &-service {
1123 display: flex;
1124 align-items: center;
1125 font-size: 15px;
1126 font-weight: 500;
1127 line-height: 1.6;
1128 /* $shade-900 */
1129 color: var(--am-c-fcip-text);
1130
1131 &__img {
1132 display: inline-flex;
1133 flex: 0 0 auto;
1134 align-items: center;
1135 justify-content: center;
1136 width: 54px;
1137 height: 54px;
1138 color: var(--am-c-fcip-bgr);
1139 font-size: 18px;
1140 font-weight: 500;
1141 line-height: 1;
1142 border-radius: 4px;
1143 background-size: cover;
1144 background-position: center;
1145 background-repeat: no-repeat;
1146 margin: 0 8px 0 0;
1147 }
1148
1149 &__employee {
1150 display: inline-flex;
1151 align-items: center;
1152 justify-content: center;
1153 width: 36px;
1154 height: 36px;
1155 color: var(--am-c-fcip-bgr);
1156 font-size: 12px;
1157 font-weight: 500;
1158 line-height: 1;
1159 border-radius: 50%;
1160 border: 3px solid var(--am-c-fcip-bgr);
1161 margin: 0 -12px 0 0;
1162 }
1163
1164 &__info {
1165 & > span:first-child {
1166 font-size: 13px;
1167 font-weight: 400;
1168 line-height: 1.384615;
1169 /* $shade-700 */
1170 color: var(--am-c-fcip-text-op80);
1171 margin-right: 20px;
1172 }
1173
1174 & > .am-fcip__include-service__info-name {
1175 display: inline-flex;
1176 align-items: center;
1177 justify-content: center;
1178 width: 36px;
1179 height: 36px;
1180 vertical-align: middle;
1181 font-size: 13px;
1182 font-weight: 500;
1183 color: var(--am-c-fcip-bgr);
1184 margin-left: -10px;
1185 border-radius: 50%;
1186 border: 2px solid var(--am-c-fcip-bgr);
1187 background-color: var(--am-c-fcip-bgr);
1188 background-size: cover;
1189 background-position: center;
1190 background-repeat: no-repeat;
1191 }
1192
1193 & > p {
1194 font-size: 15px;
1195 font-weight: 400;
1196 line-height: 1.6;
1197 /* $shade-700 */
1198 color: var(--am-c-fcip-text-op80);
1199 margin: 16px 0 0;
1200
1201 & * {
1202 color: var(--am-c-fcip-text-op80);
1203 }
1204 }
1205
1206 & .am-fcip__include-service__info-description {
1207 &.ql-description {
1208 @include quill-styles;
1209 }
1210 }
1211 }
1212 }
1213 }
1214 }
1215 }
1216
1217 &.amelia-v2-booking-dialog {
1218 --am-c-fcip-header-text: var(--am-c-main-heading-text);
1219 --am-c-fcip-bgr: var(--am-c-main-bgr);
1220 --am-c-fcip-text: var(--am-c-main-text);
1221 --am-c-fcip-success: var(--am-c-success);
1222 --am-c-fcip-primary: var(--am-c-primary);
1223
1224 .el-overlay-dialog {
1225 background-color: rgba(26, 44, 55, 0.5);
1226 }
1227
1228 .el-dialog {
1229 max-width: var(--el-dialog-width);
1230 width: 100%;
1231 border-radius: 8px;
1232
1233 &__footer {
1234 display: none;
1235 }
1236 }
1237 }
1238 }
1239
1240 // - gdp - gallery dialog package
1241 .amelia-v2-booking.amelia-v2-gdp {
1242 .el-overlay-dialog {
1243 background-color: rgba(26, 44, 55, 0.5);
1244 }
1245
1246 .el-dialog {
1247 max-width: var(--el-dialog-width);
1248 width: 100%;
1249 border-radius: 8px;
1250 background-color: transparent;
1251 margin-top: var(--el-dialog-margin-top);
1252 }
1253
1254 .am-gd {
1255 border-radius: 8px;
1256 background-color: var(--am-c-fcip-bgr);
1257 padding: 0 0 8px;
1258
1259 * {
1260 font-family: var(--am-font-family);
1261 }
1262
1263 &__display {
1264 display: flex;
1265 align-items: center;
1266 justify-content: center;
1267
1268 img {
1269 width: 100%;
1270 border-radius: 8px;
1271 }
1272
1273 &-wrapper {
1274 position: relative;
1275 padding: 24px 60px 12px;
1276 }
1277 }
1278
1279 &__arrows {
1280 width: 100%;
1281 height: 100%;
1282 position: absolute;
1283 top: 0;
1284 left: 0;
1285 z-index: 100;
1286
1287 span {
1288 position: absolute;
1289 width: 60px;
1290 height: 100%;
1291 font-size: 38px;
1292 color: var(--am-c-fcip-text);
1293 cursor: pointer;
1294
1295 &::before {
1296 position: absolute;
1297 top: 50%;
1298 left: 50%;
1299 transform: translate(-50%, -50%);
1300 }
1301
1302 &:first-child {
1303 left: 0;
1304 }
1305
1306 &:last-child {
1307 right: 0;
1308 }
1309 }
1310 }
1311
1312 &__selection {
1313 display: flex;
1314 align-items: center;
1315 justify-content: center;
1316 font-size: 14px;
1317 line-height: 1.42857;
1318 color: var(--am-c-fcip-text);
1319 }
1320
1321 &__thumb {
1322 position: relative;
1323 width: 100px;
1324 height: 100px;
1325 flex: 0 0 auto;
1326 cursor: pointer;
1327 margin: 0 8px 8px 0;
1328 background-size: cover;
1329 background-repeat: no-repeat;
1330 background-position: center;
1331
1332 &:last-child {
1333 margin-right: 0;
1334 }
1335
1336 &.am-active {
1337 &:before {
1338 content: '';
1339 position: absolute;
1340 bottom: -8px;
1341 left: 0;
1342 width: 100%;
1343 height: 4px;
1344 background-color: var(--am-c-fcip-primary);
1345 }
1346 }
1347
1348 &-wrapper {
1349 display: flex;
1350 max-width: calc(100% - 48px);
1351 width: calc(100% - 48px);
1352 white-space: nowrap;
1353 margin: 0 24px;
1354 overflow-y: hidden;
1355 padding-bottom: 8px;
1356
1357 // Main Scroll styles
1358 &::-webkit-scrollbar {
1359 height: 6px;
1360 }
1361
1362 &::-webkit-scrollbar-thumb {
1363 border-radius: 6px;
1364 background: var(--am-c-scroll-op30);
1365 }
1366
1367 &::-webkit-scrollbar-track {
1368 border-radius: 6px;
1369 background: var(--am-c-scroll-op10);
1370 }
1371 }
1372 }
1373 }
1374 }
1375 </style>
1376