@total_onion/onion-library 2.0.66 → 2.0.70

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.
Files changed (129) hide show
  1. package/.github/workflows/npm-publish.yml +2 -2
  2. package/components/block-accent-image-v3/accent-image-v3.twig +2 -2
  3. package/components/block-accordion-v3/accordion-v3.twig +23 -24
  4. package/components/block-betterreviews-display-v3/betterreviews-display-v3.twig +2 -3
  5. package/components/block-block-interactions-v3/block-interactions-v3.twig +7 -9
  6. package/components/block-carousel-multi-layout-v3/carousel-multi-layout-v3.twig +5 -3
  7. package/components/block-cover-link-v3/cover-link-v3.twig +1 -1
  8. package/components/block-divider-v3/divider-v3.twig +1 -1
  9. package/components/block-featured-image-gallery-v3/featured-image-gallery-v3.twig +2 -2
  10. package/components/block-featured-image-gallery-v3/group_5f91897095b42.json +162 -7
  11. package/components/block-form-selection-v3/form-selection-v3.twig +16 -1
  12. package/components/block-gradient-layer-v3/gradient-layer-v3.twig +2 -2
  13. package/components/block-group-container-v3/group-container-v3.twig +5 -4
  14. package/components/block-group-container-v3/group_6865578ada499.json +364 -38
  15. package/components/block-lottie-content-v3/lottie-content-v3.twig +5 -7
  16. package/components/block-market-selector-v3/market-selector-v3.twig +1 -1
  17. package/components/block-modal-form-v3/modal-form-v3.twig +12 -12
  18. package/components/block-nav-menu-container-v3/group_687e00b45e9a3.json +96 -66
  19. package/components/block-nav-menu-container-v3/nav-menu-container-v3.twig +9 -8
  20. package/components/block-post-type-filter-grid-v3/group_64690c62487bc.json +3674 -0
  21. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/better-reviews-widget.vue +15 -0
  22. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/buy-now-widget.vue +72 -0
  23. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/cocktail-category.vue +40 -0
  24. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/cocktail-tasting-notes.vue +15 -0
  25. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/divider-widget.vue +11 -0
  26. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/drink-tastes.vue +26 -0
  27. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/featured-post-component.vue +62 -0
  28. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/global-image-widget.vue +23 -0
  29. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/media-widget.vue +23 -0
  30. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/person-email-widget.vue +20 -0
  31. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/person-name-widget.vue +15 -0
  32. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/person-questionaire-widget.vue +17 -0
  33. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/person-rating-widget.vue +25 -0
  34. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-author-widget.vue +15 -0
  35. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-category-widget.vue +20 -0
  36. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-component.vue +130 -0
  37. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-headline-widget.vue +16 -0
  38. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-image-widget.vue +60 -0
  39. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-info-description.vue +14 -0
  40. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-info-subtitle.vue +14 -0
  41. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-link-widget.vue +44 -0
  42. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-publish-widget.vue +44 -0
  43. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-tags-widget.vue +19 -0
  44. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-text-alternative-style.vue +18 -0
  45. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/post-title-widget.vue +20 -0
  46. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/pre-render-posts-html.twig +17 -0
  47. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/product-abv.vue +18 -0
  48. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/product-age-statement.vue +17 -0
  49. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/product-bazaarvoice.vue +15 -0
  50. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/product-brand.vue +16 -0
  51. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/product-cask-type.vue +16 -0
  52. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/product-country.vue +14 -0
  53. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/product-description.vue +15 -0
  54. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/product-details-name.vue +18 -0
  55. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/product-details-price.vue +15 -0
  56. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/product-finish.vue +15 -0
  57. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/product-history.vue +16 -0
  58. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/product-link.vue +15 -0
  59. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/product-logo-widget.vue +22 -0
  60. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/product-name.vue +17 -0
  61. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/product-nose.vue +16 -0
  62. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/product-price.vue +15 -0
  63. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/product-slug.vue +14 -0
  64. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/product-taste.vue +16 -0
  65. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/product-whisky-type.vue +25 -0
  66. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/ptfg-posts.twig +474 -0
  67. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/ptfg-utils.vue +38 -0
  68. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/shopify-add-to-cart.vue +31 -0
  69. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/social-media-item.vue +58 -0
  70. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/spacer-widget.vue +13 -0
  71. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3/text-search.vue +10 -0
  72. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3.js +14 -0
  73. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3.php +48 -0
  74. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3.scss +1084 -0
  75. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3.twig +157 -0
  76. package/components/block-post-type-filter-grid-v3/post-type-filter-grid-v3.vue +938 -0
  77. package/components/block-product-info-v3/product-info-v3.twig +2 -1
  78. package/components/block-scrolling-banner-v3/group_68e67fca1ec80.json +1 -56
  79. package/components/block-scrolling-banner-v3/scrolling-banner-v3.twig +7 -4
  80. package/components/block-section-separator-v3/section-separator-v3.twig +2 -2
  81. package/components/block-single-column-container-v3/single-column-container-v3.twig +1 -1
  82. package/components/block-single-responsive-image-v3/group_6867bcf24c2fc.json +5 -11
  83. package/components/block-single-responsive-image-v3/single-responsive-image-v3.twig +2 -2
  84. package/components/block-site-copyright-notice-v3/site-copyright-notice-v3.php +1 -1
  85. package/components/block-site-logo-container-v3/group_687e3b887b508.json +53 -5
  86. package/components/block-site-logo-container-v3/site-logo-container-v3.twig +4 -2
  87. package/components/block-site-title-and-tagline-v3/site-title-and-tagline-v3.twig +2 -2
  88. package/components/block-smash-balloon-social-media-v3/smash-balloon-social-media-v3.twig +2 -2
  89. package/components/block-social-networks-v3/social-networks-v3.twig +5 -6
  90. package/components/block-standard-content-v3/standard-content-v3.twig +2 -3
  91. package/components/block-sticky-buy-cta-v3/sticky-buy-cta-v3.twig +59 -59
  92. package/components/block-sub-group-container-v3/group_686ceba7d6066.json +197 -56
  93. package/components/block-sub-group-container-v3/sub-group-container-v3.twig +3 -4
  94. package/components/block-video-content-v3/group_687190b8d26df.json +175 -167
  95. package/components/block-video-content-v3/video-content-v3.twig +1 -1
  96. package/components/component-accent-image-v3/group_686cd5547efd2.json +5 -5
  97. package/components/component-athena-body-close-v3/athena-body-close-v3.twig +2 -2
  98. package/components/component-athena-head-v3/athena-head-v3.twig +11 -11
  99. package/components/component-block-settings-v3/group_689f649af2ac4.json +22 -1
  100. package/components/component-child-block-video-fields/group_6852a4f384204.json +351 -349
  101. package/components/component-content-box-settings-v3/group_686e6ec702acc.json +1727 -1937
  102. package/components/component-content-box-v3/group_686b8a4f1fe5d.json +50 -1
  103. package/components/component-core-body-close-v3/core-body-close-v3.twig +2 -0
  104. package/components/component-core-body-open-v3/core-body-open-v3.twig +32 -0
  105. package/components/component-core-head-v3/core-head-v3.twig +63 -0
  106. package/components/component-cta-selection-v3/cta-selection-v3.twig +1 -2
  107. package/components/component-responsive-image-v3/group_6867bc53f1da8.json +4 -31
  108. package/components/component-text-editor-settings-variables-v3/text-editor-settings-variables-v3.twig +1 -1
  109. package/components/component-video-component-v3/video-component-v3.twig +1 -1
  110. package/components/component-video-trigger-button-v3/video-trigger-button-v3.twig +1 -1
  111. package/components/entrypoint-entry-point-html-v3/entry-point-html-v3.twig +4 -7
  112. package/components/entrypoint-entry-point-style-v3/entry-point-style-v3.twig +2 -5
  113. package/components/fields-block-editor-assets-v3/block-editor-assets-v3.php +5 -7
  114. package/components/{fields-core-athena-block-render-function-v3/core-athena-block-render-function-v3.php → fields-core-block-render-function-v3/core-block-render-function-v3.php} +1 -1
  115. package/components/fields-drink-responsibly-notice-v3/group_68751257883ad.json +2 -1
  116. package/components/fields-dynamic-critical-css-v3/group_65abcd463e8d0.json +1 -1
  117. package/components/fields-image-management-service-v3/group_677813165b633.json +149 -0
  118. package/components/fields-modal-popup-content-v3/group_689876f1ee3fc.json +403 -0
  119. package/components/{component-modal-popup-content-v3 → fields-modal-popup-content-v3}/modal-popup-content-v3.twig +1 -1
  120. package/package.json +3 -2
  121. package/components/block-smash-balloon-social-media-v3/group_6890a2ab0e0a9.json +0 -143
  122. package/components/component-modal-popup-content/modal-popup-content.twig +0 -18
  123. package/components/fields-buy-now-button/group_658432636bde2.json +0 -340
  124. package/components/fields-cta-icons-v3/group_677ed96c3c64f.json +0 -822
  125. package/components/fields-design-system-v3/group_6870e9e74a347.json +0 -743
  126. package/components/fields-modal-popup-content/group_689876f1ee3fc.json +0 -390
  127. package/components/fields-modal-popup-content/modal-popup-content.twig +0 -18
  128. package/components/fields-site-logos-v3/group_6877b1697bf9f.json +0 -149
  129. package/components/fields-typography-settings-v3/group_6876149264002.json +0 -5636
@@ -0,0 +1,938 @@
1
+ <template>
2
+ <div id="app" :class="`${blockClassName}__main-container ${blockClassName}__main-container ${!showFilters && 'post-type-filter-grid-v3__main-container--hide-filters'
3
+ }`" :data-layout="filterLayout">
4
+ <TextSearch v-if="enableTextSearch" v-model="textSearchInput" ref="textSearchInput"
5
+ :placeholder="textSearchInputPlaceholder" />
6
+ <div ref="filterBlock" v-if="showFilters" :class="`${blockClassName}__filter`" :data-layout="filterLayout">
7
+ <button :class="`${blockClassName}__open-filter-toggle cmpl-cta-style-${toggleFilterButtonStyle}`">
8
+ {{ modalOpen ? closeFilterText : openFilterText }}
9
+ </button>
10
+ <div :class="`${blockClassName}__filter-container ${modalOpen ? 'post-type-filter-grid-v3__filter-container--open' : ''
11
+ }`" :data-layout="filterLayout">
12
+ <button v-if="fields.enable_show_all_button"
13
+ :class="`${blockClassName}__show-all cmpl-cta-style-${showAllButtonStyle}`"
14
+ v-on:click.prevent="clearAllFilters()" :data-layout="filterLayout">
15
+ {{ showAllText }}
16
+ </button>
17
+ <div v-if="
18
+ filterLayout == 1 ||
19
+ filterLayout == 2 ||
20
+ filterLayout == 4 ||
21
+ filterLayout == 5
22
+ " :class="`${blockClassName}__filter-categories`" :data-layout="filterLayout">
23
+ <div v-if="filterLayout == 4" :class="`${blockClassName}__filter-categories-label`">
24
+ {{ categoriesTitleText }}
25
+ <button @click="modalOpen = !modalOpen"></button>
26
+ </div>
27
+ <div v-for="(topCategory, index) in computedCategories.topLevelCategories" :class="`${blockClassName}__filter-category ${blockClassName}__cta cmpl-cta-style-${showTopLevelFilters ? topLevelCategoryButtonStyle : 'none'
28
+ }`" v-bind:key="index" :data-layout="filterLayout">
29
+ <h6 v-if="showTopLevelFilters" :class="`${blockClassName}__filter-top-level-category-name`"
30
+ :data-layout="filterLayout">
31
+ {{ topCategory.name }}
32
+ </h6>
33
+ <ul :class="`${blockClassName}__filter-subcategory-list`" :data-layout="filterLayout"
34
+ :style="`${subFilterOverflowStyles}`">
35
+ <li v-for="(subCategory, index) in computedCategories.subCategories[
36
+ topCategory.term_id
37
+ ]" :key="index" :data-categoryid="subCategory.term_id"
38
+ :class="`${blockClassName}__filter-subcategory-list-item`" :data-layout="filterLayout">
39
+ <button :class="`${blockClassName}__filter-subcategory-button ${updateCategoryButtonActiveStatus(
40
+ subCategory.term_id
41
+ )} ${blockClassName}__cta cmpl-cta-style-${categoryButtonStyle} cmpl-cta-style-${categoryButtonStyle}--${updateActiveCategoryButtonStyle(subCategory.term_id) ? 'selected' : ''
42
+ }`" :data-categoryid="subCategory.term_id" @click="addOrRemoveIdFromActiveFilters(subCategory.term_id)"
43
+ :disabled="updateDisabledStatus(subCategory.term_id)">
44
+ <span v-html="subCategory.name"></span>
45
+ <img v-if="enableFilterIcon" :src="ctaIcons.cta_filter_icon"
46
+ :class="`${blockClassName}__filter-subcategory-button-icon`" />
47
+ </button>
48
+ </li>
49
+ </ul>
50
+ </div>
51
+ <div :class="`${blockClassName}__filter-update-button`" v-if="filterLayout == 4">
52
+ <button @click="modalOpen = false">{{ updateFilterText }}</button>
53
+ </div>
54
+ </div>
55
+ <div v-if="filterLayout == 3" :class="`${blockClassName}__filter-categories`"
56
+ :data-layout="filterLayout">
57
+ <div :class="`${blockClassName}__filter-categories-container`">
58
+ <ul v-if="showTopLevelFilters" @click="toggleTopLevelContainerStatus" :class="`${blockClassName}__filter-top-level-categories ${blockClassName}__filter-top-level-category-container ${topLevelContainerStatus ? 'open' : ''
59
+ }`" :data-layout="filterLayout">
60
+ <li :class="`${blockClassName}__filter-top-level-category ${placeholderFilterStatus ? 'currently-selected' : ''
61
+ }`" @click="toggleActiveTopLevelCategory('placeholder')" v-if="enablePlaceholderFilter"
62
+ data-categoryid="placeholder">
63
+ <button :class="`${blockClassName}__cta cmpl-cta-style-${showTopLevelFilters ? topLevelCategoryButtonStyle : 'none'
64
+ } `">
65
+ <span>{{ placeholderFilterText }}</span><img v-if="enableTopLevelFilterIcon"
66
+ :src="ctaIcons.cta_filter_icon"
67
+ :class="`${blockClassName}__filter-top-level-category-button-icon style-svg`" />
68
+ </button>
69
+ </li>
70
+ <li v-for="(topCategory, index) in computedCategories?.topLevelCategories"
71
+ v-bind:key="index" :class="`${blockClassName}__filter-top-level-category ${topLevelCategoryActiveStatus(topCategory.term_id)
72
+ ? 'currently-selected'
73
+ : ''
74
+ }`" :data-categoryid="topCategory.term_id" :data-layout="filterLayout"
75
+ @click="toggleActiveTopLevelCategory(topCategory.term_id)">
76
+ <button :class="`${blockClassName}__cta ${topLevelCategoryActiveStatus(topCategory.term_id)
77
+ ? blockClassName +
78
+ '__cta-style-' +
79
+ topLevelCategoryButtonStyle +
80
+ '--selected'
81
+ : ''
82
+ } cmpl-cta-style-${showTopLevelFilters ? topLevelCategoryButtonStyle : 'none'
83
+ } `">
84
+ <span v-html="topCategory?.name"></span><img v-if="enableTopLevelFilterIcon"
85
+ :src="ctaIcons.cta_filter_icon"
86
+ :class="`${blockClassName}__filter-top-level-category-button-icon style-svg`" />
87
+ </button>
88
+ </li>
89
+ </ul>
90
+ </div>
91
+ <div :class="`${blockClassName}__filter-subcategories-container`">
92
+ <!-- <ul v-if="enablePlaceholderFilter">
93
+ <li :class="`${blockClassName}__filter-subcategory-list-item ${placeholderFilterActiveStatus ? 'active' : ''}`"
94
+ v-if="enablePlaceholderFilter" data-categoryid="placeholder">
95
+ <button
96
+ :class="`${blockClassName}__filter-subcategory-button ${placeholderFilterActiveStatus ? 'active' : ''} cmpl-cta-style-${categoryButtonStyle}`">
97
+ Choose country <img v-if="enableFilterIcon" :src="ctaIcons.cta_filter_icon"
98
+ :class="`${blockClassName}__filter-subcategory-button-icon style-svg`">
99
+ </button>
100
+
101
+ </li>
102
+ </ul>-->
103
+ <ul v-for="(topCategory, index) in computedCategories?.topLevelCategories" v-bind:key="index"
104
+ @click="toggleSubcategoryListContainer(topCategory?.term_id)" :class="`${blockClassName}__filter-subcategory-list ${topLevelCategoryActiveStatus(topCategory?.term_id)
105
+ ? blockClassName + '__filter-subcategory-list--active'
106
+ : ''
107
+ } ${subCategoryListOpenStatus(topCategory?.term_id) ? 'open' : ''}`" :data-layout="filterLayout"
108
+ :data-topcategoryid="topCategory?.term_id" :style="`${subFilterOverflowStyles}`">
109
+ <li v-for="(subCategory, index) in computedCategories.subCategories[
110
+ topCategory?.term_id
111
+ ]" :key="index" :data-categoryid="subCategory.term_id" :class="`${blockClassName}__filter-subcategory-list-item ${updateCategoryButtonActiveStatus(
112
+ subCategory.term_id
113
+ )}`" :data-layout="filterLayout">
114
+ <button :class="`${blockClassName}__filter-subcategory-button ${updateCategoryButtonActiveStatus(
115
+ subCategory.term_id
116
+ )} ${blockClassName}__cta cmpl-cta-style-${categoryButtonStyle} cmpl-cta-style-${categoryButtonStyle}--${updateActiveCategoryButtonStyle(subCategory.term_id) ? 'selected' : ''
117
+ }`" :data-categoryid="subCategory.term_id" @click="addOrRemoveIdFromActiveFilters(subCategory.term_id)"
118
+ :disabled="updateDisabledStatus(subCategory.term_id)">
119
+ <span v-html="subCategory.name"></span>
120
+ <img v-if="enableFilterIcon" :src="ctaIcons.cta_filter_icon"
121
+ :class="`${blockClassName}__filter-subcategory-button-icon style-svg`" />
122
+ </button>
123
+ </li>
124
+ </ul>
125
+ </div>
126
+ </div>
127
+ </div>
128
+ </div>
129
+
130
+ <div :class="`${blockClassName}__featured-post`" v-if="enableFeaturedPost && activeFilterCategories.length < 1"
131
+ :style="featuredPostBackgroundColour">
132
+ <TransitionGroup>
133
+ <div :class="`${blockClassName}__featured-post-container`" v-if="featuredPost">
134
+ <FeaturedPostComponent :featuredpost="featuredPost" :fields="fields" :options="options"
135
+ :mappedIcons="mappedIcons" :ctaStyles="ctaStyles" :ctaIcons="ctaIcons">
136
+ </FeaturedPostComponent>
137
+ </div>
138
+ </TransitionGroup>
139
+ </div>
140
+
141
+ <div :class="`${blockClassName}__market-toggle`" v-if="showMarketToggle">
142
+ <div :class="`${blockClassName}__switch`">
143
+ <span :class="`${blockClassName}__switch-text`">All Products</span>
144
+ <label :class="`${blockClassName}__switch-toggle`">
145
+ <input type="checkbox" v-model="showAllMarkets" @change="onMarketToggle" />
146
+ <span class="switch-slider"></span>
147
+ </label>
148
+ <span :class="`${blockClassName}__switch-text`">Local Products</span>
149
+ </div>
150
+ </div>
151
+
152
+ <div :class="`${blockClassName}__grid`">
153
+ <TransitionGroup :name="fields.filter_results_transition">
154
+ <div :class="`${blockClassName}__post-container`" :style="`
155
+ --post-container-background-colour: ${postContainerBackgroundColour(
156
+ post
157
+ )}; --post-container-grid-gap-mobile: ${fields.post_container_grid_gap_mobile
158
+ }; --post-container-grid-gap-portrait: ${fields.post_container_grid_gap_portrait
159
+ }; --post-container-grid-gap-desktop: ${fields.post_container_grid_gap_desktop
160
+ }; --post-container-grid-auto-rows: ${fields.post_container_grid_auto_rows?.slice(
161
+ 2
162
+ )}; --post-container-grid-auto-columns: ${fields.post_container_grid_auto_columns?.slice(
163
+ 2
164
+ )}; --post-container-grid-template-rows: ${fields.post_container_grid_template_rows
165
+ }; --post-container-grid-template-columns: ${fields.post_container_grid_template_columns
166
+ };`" v-for="post in pagedPosts" :key="post.slug">
167
+ <PostComponent :postDataConfig="postDataConfig" :post="post" :fields="fields" :options="options"
168
+ :mappedIcons="mappedIcons" :ctaStyles="ctaStyles" :globalImages="globalImages"
169
+ :imageSizesAttribute="imageSizesAttribute"
170
+ :gradientOverlayColour="postContainerGradientOverlayColour(post)">
171
+ </PostComponent>
172
+ </div>
173
+ </TransitionGroup>
174
+ </div>
175
+
176
+ <div :class="`${blockClassName}__load-more-container`" ref="loadMore" role="button" tab-index="0"
177
+ :aria-label="loadMoreText" :title="loadMoreText" v-if="computedLoadMore && enableLoadMoreButton">
178
+ <a :href="`${nextPage}`" ref="loadButton" @click.prevent="
179
+ page = page + 1;
180
+ incrementLoadMoreStatus(); loadMorePosts();
181
+ " :class="`${blockClassName}__load-more-button ${blockClassName}__cta cmpl-cta-style-${loadMoreButtonStyle} cmpl-cta-animation-style-${loadMoreAnimationStyle}`">
182
+ <span :class="`cmpl-cta-span ${isLoading ? 'hide-text' : ''}`">{{ loadMoreText }}</span> <span
183
+ :class="`loader ${isLoading ? 'show-spinner' : ''}`"></span>
184
+ <span :class="`${blockClassName}__cta-icon cmpl-cta-icon`" v-if="enableLoadMoreIcon"
185
+ v-html="loadmoreIconImage"></span>
186
+ </a>
187
+ </div>
188
+
189
+ </div>
190
+ </template>
191
+
192
+ <script setup>
193
+ import { ref, reactive, onMounted, useAttrs, computed, watch } from "vue";
194
+ // import likes from "WpPlugins/cbl-better-reviews/public/src/modules/likes.js";
195
+ // import reviews from "WpPlugins/cbl-better-reviews/public/src/modules/reviews.js";
196
+ // import shop from "Assets/js/modules/library-modules/shopify/shop.js";
197
+ // import reviewModal from "WpPlugins/cbl-better-reviews/public/src/modules/review-modal.js";
198
+ // import reservebarPopup from "Assets/js/modules/library-modules/reservebar-popup/reservebar-popup.js";
199
+ // import { isWpAdmin, ctbCTAClickHandler } from "@pernod-ricard-global-cms/jsutils";
200
+ import PostComponent from "./post-type-filter-grid-v3/post-component.vue";
201
+ import FeaturedPostComponent from "./post-type-filter-grid-v3/featured-post-component.vue";
202
+ import TextSearch from "./post-type-filter-grid-v3/text-search.vue";
203
+
204
+ // get content data from window
205
+ const attrs = useAttrs();
206
+ const ptfgData = window["ptfgData" + attrs.blockid];
207
+ // if (!ptfgData) {
208
+ // console.log('No ptfgData found');
209
+ // return;
210
+ // }
211
+
212
+ // defining refs
213
+ let page = ref(0);
214
+ let loadMoreStatus = ref(1);
215
+ let topLevelContainerStatus = ref(false);
216
+ let activeTopLevelCategories = ref([]);
217
+ let placeholderFilterStatus = ref(true);
218
+
219
+ let activeFilterCategories = ref([]);
220
+ let openSubCategoryListContainers = ref([]);
221
+ let enableCategoryDisabledStatus = ref(false);
222
+
223
+ // ref dom elements
224
+ const textSearchInput = ref(null);
225
+ const filterBlock = ref(null);
226
+
227
+ // defining constant variables
228
+ const blockClassName = "post-type-filter-grid-v3";
229
+ const fields = ptfgData.fields;
230
+ let modalOpen = ref(false);
231
+
232
+ const sortText = "Sort";
233
+ const sortByText = fields.sort_by_text;
234
+
235
+ const openFilterText = fields.mobile_filter_label
236
+ ? fields.mobile_filter_label
237
+ : "Open Filter";
238
+ const closeFilterText = "Close Filter";
239
+ const updateFilterText = fields.mobile_filter_update_label
240
+ ? fields.mobile_filter_update_label
241
+ : "Update Filter";
242
+
243
+ const ajaxUrl = ptfgData.ajaxUrl;
244
+ const isLoading = ref(false);
245
+ const options = ptfgData.options;
246
+ const allPosts = reactive({ items: ptfgData.posts });
247
+ const allProducts = ptfgData.allProducts;
248
+ const postDataConfig = ptfgData.postDataConfig;
249
+ const allCategories = ptfgData.taxonomies;
250
+ const featuredPost = ptfgData.featuredPost;
251
+ const mappedIcons = ptfgData.mappedIcons;
252
+ const ctaStyles = ptfgData.ctaStyles;
253
+ const totalPosts = ptfgData.total;
254
+
255
+ const ctaIcons = ptfgData.theme_cta_icons;
256
+ const globalImages = ptfgData.global_images;
257
+ const gridColumnsDesktop = fields.columns_desktop;
258
+ const gridColumnsPortrait = fields.columns_tablet_portrait;
259
+ const gridColumnsMobile = fields.columns_mobile;
260
+ const containerWidth = 100;
261
+ const defaultImageSizes = `(min-width: 1440px) ${containerWidth / gridColumnsDesktop}vw, (min-width: 1024px) ${containerWidth / gridColumnsDesktop}vw, (min-width: 768px) ${containerWidth / gridColumnsPortrait}vw, (min-width: 500px) ${containerWidth / gridColumnsMobile}vw, ${containerWidth / gridColumnsMobile}vw`;
262
+ const customSizesAttribute = fields.custom_image_sizes;
263
+ const imageSizesAttribute = customSizesAttribute ? customSizesAttribute : defaultImageSizes;
264
+ const postType = fields.post_type?.replace("__", "");
265
+ const sorting = fields.sorting?.replace("__", "");
266
+ const filterLayout = fields.filter_layout?.toString().replace("__", "");
267
+ const topLevelCategoryButtonStyle = fields.top_level_category_button_style
268
+ ?.toString()
269
+ .replace("__", "");
270
+ const categoryButtonStyle = fields.category_button_style?.toString().replace("__", "");
271
+ const loadMoreButtonStyle = fields.load_more_button_style?.toString().replace("__", "");
272
+ // const loadMoreAnimationStyle =
273
+ // ctaStyles[parseInt(loadMoreButtonStyle) - 1]?.cta_settings
274
+ // ?.cta_animation_style;
275
+ const loadMoreAnimationStyle = 1;
276
+ const toggleFilterButtonStyle = fields.toggle_filter_button_style
277
+ ?.toString()
278
+ .replace("__", "");
279
+ const showAllButtonStyle = fields.show_all_button_style?.toString().replace("__", "");
280
+ const enableLoadMoreButton = fields.enable_load_more_button;
281
+ const showFilters = fields.show_filters;
282
+ const showMarketToggle = fields.show_market_toggle;
283
+ const showTopLevelFilters = fields.show_top_level_filters;
284
+ const topLevelFiltersActiveOnLoad = fields.top_level_filters_active_on_load;
285
+ const singleActiveTopLevelCategory = fields.single_active_top_level_category;
286
+ const singleActiveFilter = ref(fields.single_active_filter);
287
+ const limitPostsToCategories = fields.limit_posts_to_selected_categories;
288
+ const categoriesTitleText = fields.categories_title_text;
289
+ const loadMoreText = fields.load_more_button_text;
290
+ const showAllText = fields.show_all_button_text;
291
+ const showAllPosts = fields.show_all_posts;
292
+ const postContainerBackgroundColourStyle = fields.post_container_background_style?.replace(
293
+ "__",
294
+ ""
295
+ );
296
+ let loadmoreIconImage = '';
297
+ if (mappedIcons['cta_link_icon']) {
298
+ loadmoreIconImage = mappedIcons['cta_link_icon']['type'] == 'image/svg+xml' ? mappedIcons['cta_link_icon']['image'] : '<img src="' + mappedIcons['cta_link_icon']['image'] + '">';
299
+ }
300
+ const enableLoadMoreIcon = ctaStyles[parseInt(loadMoreButtonStyle) - 1]?.cta_settings?.include_cta_icon;
301
+ const enableTextSearch = fields.enable_text_search;
302
+ const textSearchInputPlaceholder = fields.text_filter_placeholder;
303
+ const enableFilterIcon = fields.enable_filter_icon;
304
+ const enableTopLevelFilterIcon = fields.enable_top_level_filter_icon;
305
+ const enableStartingFilter = fields.enable_starting_filter;
306
+ const enablePlaceholderFilter = fields.enable_placeholder_filter;
307
+ const enableShopify = JSON.parse(localStorage.getItem("enableShopify"));
308
+ const placeholderFilterText = fields.placeholder_filter_text;
309
+ const enableFeaturedPost = fields.enable_featured_post;
310
+ const featuredPostBackgroundColour = `--featured-post-background-colour: ${fields.featured_post_background_colour}`;
311
+ const initialPostsPerPageDesktop = fields.initial_posts_per_page_desktop;
312
+ const initialPostsPerPageTablet = fields.initial_posts_per_page_portrait;
313
+ const initialPostsPerPageMobile = fields.initial_posts_per_page_mobile;
314
+ const postsPerPageDesktop = showAllPosts ? 999999 : Number(fields.posts_per_page_desktop);
315
+ const postsPerPageTablet = showAllPosts ? 999999 : Number(fields.posts_per_page_tablet);
316
+ const postsPerPageMobile = showAllPosts ? 999999 : Number(fields.posts_per_page_mobile);
317
+ const loadedCategories = [];
318
+ const subFilterOverflowMobileValue = fields.sub_filter_overflow ? fields.sub_filter_overflow.mobile_overflow.toString().replace("__", "") : 'scroll';
319
+ const subFilterOverflowTabletValue = fields.sub_filter_overflow ? fields.sub_filter_overflow.tablet_overflow.toString().replace("__", "") : 'scroll';
320
+ const subFilterOverflowDesktopValue = fields.sub_filter_overflow ? fields.sub_filter_overflow.desktop_overflow.toString().replace("__", "") : 'scroll';
321
+ const subFilterOverflowMobile = `--sub-filter-overflow-mobile: ${subFilterOverflowMobileValue};`;
322
+ const subFilterOverflowTablet = `--sub-filter-overflow-tablet: ${subFilterOverflowTabletValue};`;
323
+ const subFilterOverflowDesktop = `--sub-filter-overflow-desktop: ${subFilterOverflowDesktopValue};`;
324
+ const subFilterOverflowCenterMobile = `--sub-filter-overflow-center-mobile: ${subFilterOverflowMobileValue === 'wrap' ? 'center' : ''};`;
325
+ const subFilterOverflowCenterTablet = `--sub-filter-overflow-center-tablet: ${subFilterOverflowTabletValue === 'wrap' ? 'center' : ''};`;
326
+ const subFilterOverflowCenterDesktop = `--sub-filter-overflow-center-desktop: ${subFilterOverflowDesktopValue === 'wrap' ? 'center' : ''};`;
327
+ const subFilterOverflowStyles = subFilterOverflowMobile + subFilterOverflowTablet + subFilterOverflowDesktop + subFilterOverflowCenterMobile + subFilterOverflowCenterTablet + subFilterOverflowCenterDesktop
328
+
329
+ let devicePostsPerPage = postsPerPageDesktop;
330
+ let deviceInitialPostsPerPage = initialPostsPerPageDesktop;
331
+ if (window.innerWidth < 1024) {
332
+ devicePostsPerPage = postsPerPageTablet;
333
+ deviceInitialPostsPerPage = initialPostsPerPageTablet;
334
+ }
335
+ if (window.innerWidth < 768) {
336
+ devicePostsPerPage = postsPerPageMobile;
337
+ deviceInitialPostsPerPage = initialPostsPerPageMobile;
338
+ }
339
+ watch(
340
+ () => modalOpen.value,
341
+ () => {
342
+ if (modalOpen.value) {
343
+ document.body.classList.add("mobile-menu-active");
344
+ } else {
345
+ document.body.classList.remove("mobile-menu-active");
346
+ }
347
+ }
348
+ );
349
+
350
+
351
+ // computed variables
352
+ const computedAllPosts = computed(() => {
353
+ if (limitPostsToCategories) {
354
+ const allSubcategories = [];
355
+ const allParentIds = Object.keys(computedCategories.value.subCategories);
356
+ allParentIds.forEach((id) => {
357
+ computedCategories.value.subCategories[id].forEach((category) => {
358
+ allSubcategories.push(category.term_id);
359
+ });
360
+ });
361
+ return filterPosts(allPosts.items, allSubcategories);
362
+ } else {
363
+ return allPosts.items;
364
+ }
365
+ });
366
+ const computedFilteredPosts = computed(() => {
367
+ let computedPosts = computedAllPosts.value;
368
+ if (enableFeaturedPost) {
369
+ computedPosts = computedAllPosts.value.filter(
370
+ (post) => post.post_data.ID != fields.featured_post
371
+ );
372
+ }
373
+ const posts = filterPosts(computedPosts, activeFilterCategories.value);
374
+ return sortPosts(posts);
375
+ });
376
+
377
+ const computedLoadMore = computed(() => {
378
+ if (showAllPosts) {
379
+ return false;
380
+ }
381
+ let postsPerPage = devicePostsPerPage;
382
+ if (page.value == 1) {
383
+ postsPerPage = deviceInitialPostsPerPage;
384
+ }
385
+ if (activeFilterCategories.value.length) {
386
+ if (computedFilteredPosts.value.length <= (page.value * postsPerPage)) {
387
+ return false;
388
+ }
389
+ }
390
+ if (
391
+ page.value * postsPerPage < totalPosts
392
+ ) {
393
+ return true;
394
+ }
395
+ return false;
396
+ });
397
+
398
+ const nextPage = computed(() => {
399
+ const path = `https://${window.location.host}${window.location.pathname}`;
400
+ return `${path}?pages=${page.value + 1}`;
401
+ });
402
+
403
+ const resetPage = () => {
404
+ const path = `https://${window.location.host}${window.location.pathname}${window.location.search}`;
405
+ page.value = 1;
406
+ window.history.pushState({}, "", path);
407
+ };
408
+
409
+ const computedFeaturedPost = computed(() => {
410
+ const featuredPost = computedAllPosts.value.filter(
411
+ (post) => post.id == fields.featured_post
412
+ );
413
+ const [post] = featuredPost;
414
+ return post;
415
+ });
416
+
417
+ const computedProducts = computed(() => {
418
+ // const updatedProducts = [];
419
+ // allProducts.forEach((product) => {
420
+ // product.slug = product["post_name"];
421
+ // product.name = product["post_title"];
422
+ // product.taxonomy = "products";
423
+ // updatedProducts.push(product);
424
+ // });
425
+ // return updatedProducts;
426
+ });
427
+
428
+ const pagedPosts = computed(() => {
429
+ if (showAllPosts) {
430
+ return computedFilteredPosts.value;
431
+ } else {
432
+ return computedFilteredPosts.value.slice(
433
+ 0,
434
+ page.value == 1
435
+ ? Number(deviceInitialPostsPerPage)
436
+ : Number(deviceInitialPostsPerPage) +
437
+ Number(page.value - 1) * Number(devicePostsPerPage)
438
+ );
439
+ }
440
+ });
441
+
442
+ const computedCategories = computed(() => {
443
+ let topLevelCategories = [];
444
+ const subCategories = {};
445
+ allCategories.forEach((taxonomy) => {
446
+ if (taxonomy.parent === 0) {
447
+ topLevelCategories.push(taxonomy);
448
+ } else {
449
+ if (subCategories[taxonomy.parent]) {
450
+ subCategories[taxonomy.parent].push(taxonomy);
451
+ } else {
452
+ subCategories[taxonomy.parent] = [];
453
+ subCategories[taxonomy.parent].push(taxonomy);
454
+ }
455
+ }
456
+ });
457
+ return {
458
+ topLevelCategories: topLevelCategories,
459
+ subCategories: subCategories,
460
+ };
461
+ });
462
+
463
+ // functions
464
+
465
+ const addOrRemoveIdFromActiveFilters = async (categoryId) => {
466
+ if (singleActiveFilter.value) {
467
+ activeFilterCategories.value = [];
468
+ activeFilterCategories.value.push(categoryId);
469
+
470
+ return;
471
+ }
472
+ if (!activeFilterCategories.value.find((element) => Number(element) === Number(categoryId))
473
+ ) {
474
+ activeFilterCategories.value.push(categoryId);
475
+ } else {
476
+ activeFilterCategories.value = activeFilterCategories.value.filter(
477
+ (element) => element !== categoryId
478
+ );
479
+ }
480
+ };
481
+
482
+ const filterPosts = (posts, filterCategoryIds = activeFilterCategories.value) => {
483
+ let filteredPosts = [];
484
+ if (filterCategoryIds.length === 0) {
485
+ filteredPosts = posts;
486
+ } else {
487
+ filteredPosts = posts.filter((post) => {
488
+ const postSubCategories = post.categories.filter(
489
+ (category) => category.parent != 0
490
+ );
491
+ let categoryMatch = false;
492
+ filterCategoryIds.forEach((categoryId) => {
493
+ if (
494
+ postSubCategories.find(
495
+ (subCategory) => Number(subCategory.term_id) == Number(categoryId)
496
+ )
497
+ ) {
498
+ categoryMatch = true;
499
+ return;
500
+ }
501
+ });
502
+ return categoryMatch;
503
+ });
504
+ }
505
+
506
+ //filter by text
507
+
508
+ //Split the search term by , to get 'or' functionality then trim the spaces and filter empty search terms
509
+ let searchTerm = textSearchInput.value ? textSearchInput.value : null;
510
+ if (searchTerm) {
511
+ const searchTerm = searchTerm
512
+ .toLowerCase()
513
+ .split(",")
514
+ .map((term) => term.trim())
515
+ .filter((term) => term != "");
516
+
517
+ //Filter drinks based on the search terms
518
+ const textFilteredPosts = filteredPosts.filter((post) => {
519
+ return searchTerm.some((item) =>
520
+ post.post_data.post_title.toLowerCase().includes(item)
521
+ );
522
+ });
523
+ }
524
+ filteredPosts = searchTerm == null ? filteredPosts : textFilteredPosts;
525
+ setTimeout(() => {
526
+ const gridContainer = document.querySelector(".post-type-filter-grid-v3__grid");
527
+ ctbCTAClickHandler(gridContainer);
528
+ reservebarPopup();
529
+ if (enableShopify) {
530
+ refreshShopifyBuyButtons();
531
+ }
532
+ }, 50);
533
+
534
+ return filteredPosts;
535
+ };
536
+
537
+ const sortPosts = (posts) => {
538
+ switch (fields.sorting?.replace("__", "")) {
539
+ case "menu-order":
540
+ return posts.sort((a, b) => a.menu_order - b.menu_order); // Sort by menu order (ascending)
541
+ case "date-desc":
542
+ return posts.sort((a, b) => new Date(b.post_data.post_date) - new Date(a.post_data.post_date)); // Newest first
543
+ case "date-asc":
544
+ return posts.sort((a, b) => new Date(a.post_data.post_date) - new Date(b.post_data.post_date)); // Oldest first
545
+ case "postorder":
546
+ return posts; // Respect post type order plugin
547
+ default:
548
+ return posts;
549
+ }
550
+ };
551
+
552
+ const incrementLoadMoreStatus = () => {
553
+ const url = new URL(window.location);
554
+ loadMoreStatus.value = Number(loadMoreStatus.value) + 1;
555
+ url.searchParams.set("pages", loadMoreStatus.value);
556
+ setTimeout(() => {
557
+ reviews.init();
558
+ if (enableShopify) {
559
+ refreshShopifyBuyButtons();
560
+ }
561
+ }, 0);
562
+ if (!isWpAdmin()) {
563
+ window.history.pushState({}, "", url);
564
+ }
565
+ };
566
+
567
+ const postContainerBackgroundColour = (post) => {
568
+ switch (postContainerBackgroundColourStyle) {
569
+ case "none":
570
+ return "none";
571
+ break;
572
+
573
+ case "colour-palette":
574
+ return fields.post_container_background_colour;
575
+ break;
576
+
577
+ case "post-colour":
578
+ return post.post_data.post_colour;
579
+ break;
580
+ case "post-colour-secondary":
581
+ return post.post_data.post_colour_secondary;
582
+ break;
583
+
584
+ default:
585
+ break;
586
+ }
587
+ };
588
+
589
+ const postContainerGradientOverlayColour = (post) => {
590
+ switch (fields.gradient_overlay_colour_type?.slice(2)) {
591
+ case "colour-palette":
592
+ return fields.gradient_overlay_colour;
593
+ break;
594
+
595
+ case "post-colour":
596
+ return post.post_data.post_colour;
597
+ break;
598
+ case "post-colour-secondary":
599
+ return post.post_data.post_colour_secondary;
600
+ break;
601
+
602
+ default:
603
+ break;
604
+ }
605
+ };
606
+
607
+ const getLoadMoreStatusParam = async () => {
608
+ const urlParams = new URLSearchParams(window.location.search);
609
+ const loadMore = urlParams.get("pages");
610
+ if (loadMore) {
611
+ loadMoreStatus.value = Number(loadMore);
612
+ page.value += loadMoreStatus.value;
613
+
614
+ let demandedPosts = Number(initialPostsPerPageDesktop) + (Number(page.value - 1) * Number(postsPerPageDesktop));
615
+ let actualMaxPages = Math.ceil(Number((Number(totalPosts.value) - Number(initialPostsPerPageDesktop)) / Number(postsPerPageDesktop)));
616
+ let retrievedPosts = Number(initialPostsPerPageDesktop);
617
+
618
+ for (let i = 2; i <= loadMore; i++) {
619
+ if (retrievedPosts <= totalPosts.value) {
620
+ retrievedPosts += Number(postsPerPageDesktop);
621
+ page.value = i;
622
+ }
623
+ }
624
+
625
+ if (demandedPosts > totalPosts.value) {
626
+ page.value = actualMaxPages;
627
+ window.history.pushState({}, "?pages=" + page.value);
628
+ }
629
+ loadMoreStatus.value = loadMore;
630
+ } else {
631
+ resetPage();
632
+ }
633
+ };
634
+
635
+ const setupFilterLayout = () => {
636
+ if (!showFilters) {
637
+ return;
638
+ }
639
+ if (filterLayout == 1 || filterLayout == 2 || filterLayout == 4 || filterLayout == 5) {
640
+ const topLevelCategories = filterBlock.value.querySelectorAll(
641
+ ".post-type-filter-grid-v3__filter-category"
642
+ );
643
+ const primaryCategoryNames = filterBlock.value.querySelectorAll(
644
+ ".post-type-filter-grid-v3__filter-top-level-category-name"
645
+ );
646
+ if (topLevelFiltersActiveOnLoad) {
647
+ if (singleActiveTopLevelCategory) {
648
+ topLevelCategories[0].classList.add("active");
649
+ } else {
650
+ topLevelCategories.forEach((topLevelCategory) =>
651
+ topLevelCategory.classList.add("active")
652
+ );
653
+ }
654
+ }
655
+ primaryCategoryNames.forEach((name) => {
656
+ name.addEventListener("click", () => {
657
+ name.parentElement.classList.toggle("active");
658
+ });
659
+ });
660
+ if (enableStartingFilter) {
661
+ let categoryObject;
662
+
663
+ switch (postType) {
664
+ case "product":
665
+ categoryObject = fields.starting_product_filter_category;
666
+ break;
667
+ case "person":
668
+ categoryObject = fields.starting_person_filter_category;
669
+ break;
670
+
671
+ default:
672
+ break;
673
+ }
674
+ activeTopLevelCategories.value.push(categoryObject.parent);
675
+ activeFilterCategories.value.push(categoryObject.term_id);
676
+ }
677
+ }
678
+ if (filterLayout == 3) {
679
+ if (topLevelFiltersActiveOnLoad) {
680
+ if (singleActiveTopLevelCategory) {
681
+ toggleActiveTopLevelCategory(
682
+ computedCategories.value.topLevelCategories[0].term_id
683
+ );
684
+ } else {
685
+ computedCategories.value.topLevelCategories.forEach((topLevelCategory) =>
686
+ toggleActiveTopLevelCategory(topLevelCategory.term_id)
687
+ );
688
+ }
689
+ }
690
+ }
691
+
692
+ if (showFilters) {
693
+ filterBlock.value
694
+ .querySelector(".post-type-filter-grid-v3__open-filter-toggle")
695
+ .addEventListener("click", () => {
696
+ modalOpen.value = !modalOpen.value;
697
+ });
698
+ }
699
+ };
700
+
701
+ const toggleTopLevelContainerStatus = () => {
702
+ topLevelContainerStatus.value = !topLevelContainerStatus.value;
703
+ };
704
+
705
+ const topLevelCategoryActiveStatus = (id) => {
706
+ return activeTopLevelCategories.value.find((catId) => catId == id);
707
+ };
708
+ const placeholderFilterActiveStatus = () => {
709
+ return placeholderFilterStatus.value ? true : false;
710
+ };
711
+
712
+ const toggleSubcategoryListContainer = (id) => {
713
+ if (id == "placeholder") {
714
+ activeTopLevelCategories.value = [];
715
+ activeFilterCategories.value = [];
716
+ return;
717
+ }
718
+ if (openSubCategoryListContainers.value.find((categoryId) => categoryId == id)) {
719
+ openSubCategoryListContainers.value = openSubCategoryListContainers.value.filter(
720
+ (categoryId) => categoryId != id
721
+ );
722
+ } else {
723
+ openSubCategoryListContainers.value.push(id);
724
+ }
725
+ };
726
+
727
+ const subCategoryListOpenStatus = (id) => {
728
+ return openSubCategoryListContainers.value.find((catId) => catId == id);
729
+ };
730
+ const updateCategoryButtonActiveStatus = (categoryId) => {
731
+ if (
732
+ activeFilterCategories.value.find(
733
+ (filterCategory) => Number(filterCategory) === Number(categoryId)
734
+ )
735
+ ) {
736
+ return "active";
737
+ } else {
738
+ return "";
739
+ }
740
+ };
741
+
742
+ const updateActiveCategoryButtonStyle = (categoryId) => {
743
+ if (
744
+ activeFilterCategories.value.find(
745
+ (filterCategory) => Number(filterCategory) === Number(categoryId)
746
+ )
747
+ ) {
748
+ return true;
749
+ } else {
750
+ return false;
751
+ }
752
+ };
753
+
754
+ const updateDisabledStatus = (categoryId) => {
755
+ if (!enableCategoryDisabledStatus.value) {
756
+ return false;
757
+ }
758
+ if (activeFilterCategories.value.length === 0) {
759
+ return false;
760
+ }
761
+ if (
762
+ activeFilterCategories.value.find(
763
+ (filterCategory) => Number(filterCategory) === Number(categoryId)
764
+ )
765
+ ) {
766
+ return false;
767
+ }
768
+ const testCategories = [...activeFilterCategories.value];
769
+ testCategories.push(categoryId);
770
+ const testFilterPosts = filterPosts(allPosts.items, testCategories);
771
+ if (testFilterPosts.length <= computedFilteredPosts.value.length) {
772
+ return true;
773
+ }
774
+ };
775
+ const getPostSubcategories = (post) => {
776
+ return post.categories.filter((category) => category.parent != 0);
777
+ };
778
+ const clearAllFilters = () => {
779
+ activeFilterCategories.value = [];
780
+ };
781
+ const getCategoryIds = () => {
782
+ let allCategoryIds = [];
783
+ allCategories.forEach((cat) => {
784
+ allCategoryIds.push(cat.term_id);
785
+ });
786
+ // return JSON.stringify(all_cats);
787
+ return allCategoryIds;
788
+ };
789
+
790
+ const loadMorePosts = async (currentCategoryId = null, { replace = false } = {}) => {
791
+
792
+ if (currentCategoryId && loadedCategories.includes(currentCategoryId)) {
793
+ console.log('category already loaded');
794
+ return;
795
+ }
796
+
797
+ isLoading.value = true;
798
+ let form_data = new FormData();
799
+ form_data.append("action", "ptfg_next_page");
800
+ form_data.append("pageNum", page.value);
801
+ form_data.append("postType", postType);
802
+ form_data.append("sorting", sorting);
803
+ form_data.append("initialPostsPerPage", initialPostsPerPageDesktop);
804
+ form_data.append("desktopPostsPerPage", postsPerPageDesktop);
805
+ form_data.append("includeReviews", ptfgData.includeReviews);
806
+ form_data.append("reviewDisplayOptions", ptfgData.reviewDisplayOptions);
807
+ form_data.append("limitPostsToSelectedCategories", fields.limit_posts_to_selected_categories);
808
+ form_data.append("currentMarket", showAllMarkets.value ? "en" : ptfgData.currentMarket);
809
+
810
+ form_data.append(
811
+ "categoryIds",
812
+ activeFilterCategories.value.length > 0 ? activeFilterCategories.value : getCategoryIds()
813
+ );
814
+
815
+
816
+ form_data.append("initialPostsPerPage", 99999);
817
+ if (currentCategoryId && !loadedCategories.includes(currentCategoryId)) {
818
+ console.log('category was not yet loaded... getting posts now');
819
+ form_data.append("categoryIds", currentCategoryId);
820
+ loadedCategories.push(currentCategoryId);
821
+ console.log(currentCategoryId, '... added to loaded categories');
822
+ }
823
+ try {
824
+ const response = await fetch(ajaxUrl, {
825
+ method: "POST",
826
+ body: form_data,
827
+ credentials: "same-origin",
828
+ });
829
+
830
+ if (response.ok) {
831
+ const markup = await response.text();
832
+ const postData = JSON.parse(markup);
833
+ if (replace) {
834
+ allPosts.items = sortPosts(postData.posts); // Replace all posts
835
+ } else {
836
+ const mergedArray = [
837
+ ...allPosts.items,
838
+ ...postData.posts.filter(item2 => !allPosts.items.some(item1 => item1.id === item2.id)),
839
+ ];
840
+ allPosts.items = sortPosts(mergedArray); // Merge as usual
841
+ }
842
+ setTimeout(() => {
843
+ reviews.init();
844
+ if (enableShopify) {
845
+ refreshShopifyBuyButtons();
846
+ }
847
+ }, 0);
848
+ isLoading.value = false;
849
+ }
850
+ } catch (e) {
851
+ console.error("Get listing error:", e);
852
+ }
853
+ };
854
+
855
+ const toggleActiveTopLevelCategory = async (id) => {
856
+ if (id == "placeholder") {
857
+ placeholderFilterStatus.value = true;
858
+ activeTopLevelCategories.value = [];
859
+ activeFilterCategories.value = [];
860
+ return;
861
+ }
862
+ if (filterLayout == 3) {
863
+ if (activeTopLevelCategories.value.find((categoryId) => categoryId == id)) {
864
+ activeTopLevelCategories.value = activeTopLevelCategories.value.filter(
865
+ (categoryId) => categoryId != id
866
+ );
867
+ } else {
868
+ if (singleActiveTopLevelCategory == 1) {
869
+ scrollBackToStart();
870
+ activeTopLevelCategories.value = [];
871
+ activeTopLevelCategories.value.push(id);
872
+ } else {
873
+ activeTopLevelCategories.value.push(id);
874
+ }
875
+ }
876
+ }
877
+ if (filterLayout == 4 && topLevelContainerStatus.value) {
878
+ placeholderFilterStatus.value = false;
879
+ activeTopLevelCategories.value = [];
880
+ activeTopLevelCategories.value.push(id);
881
+ activeFilterCategories.value = [];
882
+ activeFilterCategories.value.push(computedCategories.value.subCategories[id][0].term_id);
883
+ }
884
+ };
885
+
886
+ const scrollBackToStart = () => {
887
+ const subCategoriesContainer = filterBlock.value.querySelector(
888
+ ".post-type-filter-grid-v3__filter-subcategories-container"
889
+ );
890
+ if (subCategoriesContainer) {
891
+ subCategoriesContainer.scrollTo({ left: 0 })
892
+ }
893
+ }
894
+
895
+ const refreshShopifyBuyButtons = () => {
896
+ postDataConfig.forEach((item) => {
897
+ if (item.acf_fc_layout === "shopify_add_to_cart") {
898
+ document.dispatchEvent(
899
+ new Event('shop-refresh')
900
+ )
901
+ }
902
+ })
903
+ }
904
+
905
+ const showAllMarkets = ref(false);
906
+ const onMarketToggle = async () => {
907
+ isLoading.value = true;
908
+ page.value = 1;
909
+ resetPage();
910
+ const previousPosts = [...allPosts.items];
911
+ try {
912
+ await loadMorePosts(null, { replace: true });
913
+ isLoading.value = false;
914
+ } catch (e) {
915
+ console.error("Market toggle failed:", e);
916
+ allPosts.items = previousPosts;
917
+ isLoading.value = false;
918
+ }
919
+ };
920
+
921
+ onMounted(() => {
922
+ getLoadMoreStatusParam();
923
+ setupFilterLayout();
924
+ reservebarPopup();
925
+
926
+
927
+ setTimeout(() => {
928
+ reviews.init();
929
+ if (enableShopify) {
930
+ shop.loadShops();
931
+ refreshShopifyBuyButtons();
932
+ }
933
+ if (!allPosts.items.length) {
934
+ loadMorePosts();
935
+ }
936
+ }, 500);
937
+ });
938
+ </script>