cloudcommerce 0.36.2 → 0.37.1

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 (174) hide show
  1. package/.github/workflows/test-apps.yml +2 -2
  2. package/.gitmodules +0 -3
  3. package/.vscode/settings.json +0 -1
  4. package/CHANGELOG.md +38 -0
  5. package/action.yml +2 -2
  6. package/ecomplus-stores/barra-doce/functions/many/package.json +3 -3
  7. package/ecomplus-stores/barra-doce/functions/ssr/package.json +6 -6
  8. package/ecomplus-stores/barra-doce/functions/with-apps/package.json +3 -3
  9. package/ecomplus-stores/barra-doce/package.json +2 -2
  10. package/package.json +5 -5
  11. package/packages/api/package.json +1 -1
  12. package/packages/apps/affilate-program/package.json +1 -1
  13. package/packages/apps/correios/package.json +1 -1
  14. package/packages/apps/custom-payment/package.json +1 -1
  15. package/packages/apps/custom-shipping/package.json +1 -1
  16. package/packages/apps/datafrete/package.json +1 -1
  17. package/packages/apps/discounts/package.json +1 -1
  18. package/packages/apps/emails/package.json +1 -1
  19. package/packages/apps/fb-conversions/package.json +2 -2
  20. package/packages/apps/flash-courier/package.json +1 -1
  21. package/packages/apps/frenet/package.json +1 -1
  22. package/packages/apps/galaxpay/package.json +1 -1
  23. package/packages/apps/google-analytics/package.json +1 -1
  24. package/packages/apps/jadlog/package.json +1 -1
  25. package/packages/apps/loyalty-points/package.json +1 -1
  26. package/packages/apps/mandae/package.json +1 -1
  27. package/packages/apps/melhor-envio/package.json +1 -1
  28. package/packages/apps/mercadopago/package.json +1 -1
  29. package/packages/apps/pagarme/package.json +1 -1
  30. package/packages/apps/pagarme-v5/package.json +1 -1
  31. package/packages/apps/paghiper/package.json +1 -1
  32. package/packages/apps/pix/package.json +1 -1
  33. package/packages/apps/tiny-erp/package.json +1 -1
  34. package/packages/apps/webhooks/package.json +1 -1
  35. package/packages/cli/package.json +1 -1
  36. package/packages/config/package.json +1 -1
  37. package/packages/emails/package.json +1 -1
  38. package/packages/eslint/package.json +5 -5
  39. package/packages/events/package.json +1 -1
  40. package/packages/feeds/package.json +1 -1
  41. package/packages/firebase/package.json +1 -1
  42. package/packages/i18n/package.json +1 -1
  43. package/packages/modules/package.json +1 -1
  44. package/packages/passport/package.json +1 -1
  45. package/packages/ssr/package.json +4 -4
  46. package/packages/storefront/package.json +11 -10
  47. package/packages/storefront/src/helpers/sf-utils.ts +8 -5
  48. package/packages/storefront/src/lib/components/CarouselControl.vue +1 -1
  49. package/packages/storefront/src/lib/composables/use-search-modal.ts +90 -0
  50. package/packages/storefront/src/lib/composables/use-shop-header.ts +69 -1
  51. package/packages/storefront/src/lib/state/search-engine.ts +39 -13
  52. package/packages/storefront/src/lib/state/shopping-cart.ts +2 -1
  53. package/packages/storefront/src/lib/state/use-analytics.ts +27 -11
  54. package/packages/test-base/package.json +1 -1
  55. package/packages/types/package.json +1 -1
  56. package/ecomplus-stores/monocard/.devcontainer/devcontainer.json +0 -30
  57. package/ecomplus-stores/monocard/.editorconfig +0 -13
  58. package/ecomplus-stores/monocard/.eslintrc.cjs +0 -3
  59. package/ecomplus-stores/monocard/.firebaserc +0 -5
  60. package/ecomplus-stores/monocard/.github/build-and-deploy +0 -1
  61. package/ecomplus-stores/monocard/.github/renovate.json +0 -5
  62. package/ecomplus-stores/monocard/.github/workflows/build-and-deploy.yml +0 -37
  63. package/ecomplus-stores/monocard/.github/workflows/calibreapp-image-actions.yml +0 -23
  64. package/ecomplus-stores/monocard/.gitpod.yml +0 -12
  65. package/ecomplus-stores/monocard/.idx/dev.nix +0 -24
  66. package/ecomplus-stores/monocard/.nvmrc +0 -1
  67. package/ecomplus-stores/monocard/.vscode/extensions.json +0 -8
  68. package/ecomplus-stores/monocard/.vscode/launch.json +0 -11
  69. package/ecomplus-stores/monocard/.vscode/settings.json +0 -13
  70. package/ecomplus-stores/monocard/LICENSE.md +0 -230
  71. package/ecomplus-stores/monocard/README.md +0 -31
  72. package/ecomplus-stores/monocard/SETUP.md +0 -129
  73. package/ecomplus-stores/monocard/SETUP.pt-BR.md +0 -129
  74. package/ecomplus-stores/monocard/functions/config.json +0 -3
  75. package/ecomplus-stores/monocard/functions/example.env +0 -10
  76. package/ecomplus-stores/monocard/functions/many/index.js +0 -14
  77. package/ecomplus-stores/monocard/functions/many/package.json +0 -22
  78. package/ecomplus-stores/monocard/functions/ssr/.eslintrc.cjs +0 -6
  79. package/ecomplus-stores/monocard/functions/ssr/astro.config.mjs +0 -4
  80. package/ecomplus-stores/monocard/functions/ssr/content/blog/.gitkeep +0 -0
  81. package/ecomplus-stores/monocard/functions/ssr/content/extra-pages/terms.json +0 -11
  82. package/ecomplus-stores/monocard/functions/ssr/content/extra-pages/trocas.json +0 -11
  83. package/ecomplus-stores/monocard/functions/ssr/content/layout.json +0 -52
  84. package/ecomplus-stores/monocard/functions/ssr/content/pages/home.json +0 -20
  85. package/ecomplus-stores/monocard/functions/ssr/content/pages/products.json +0 -18
  86. package/ecomplus-stores/monocard/functions/ssr/content/settings.json +0 -78
  87. package/ecomplus-stores/monocard/functions/ssr/index.js +0 -18
  88. package/ecomplus-stores/monocard/functions/ssr/package.json +0 -36
  89. package/ecomplus-stores/monocard/functions/ssr/public/admin/.gitkeep +0 -0
  90. package/ecomplus-stores/monocard/functions/ssr/public/assets/lotties/img_1.png +0 -0
  91. package/ecomplus-stores/monocard/functions/ssr/public/assets/lotties/img_1.webp +0 -0
  92. package/ecomplus-stores/monocard/functions/ssr/public/assets/lotties/phone-nfc.json +0 -1
  93. package/ecomplus-stores/monocard/functions/ssr/public/img/icon.png +0 -0
  94. package/ecomplus-stores/monocard/functions/ssr/public/img/large-icon.png +0 -0
  95. package/ecomplus-stores/monocard/functions/ssr/public/img/uploads/card-phone.png +0 -0
  96. package/ecomplus-stores/monocard/functions/ssr/public/img/uploads/devices.jpg +0 -0
  97. package/ecomplus-stores/monocard/functions/ssr/public/img/uploads/ecom-icon.png +0 -0
  98. package/ecomplus-stores/monocard/functions/ssr/public/img/uploads/edit-suit.jpg +0 -0
  99. package/ecomplus-stores/monocard/functions/ssr/public/img/uploads/favicon.png +0 -0
  100. package/ecomplus-stores/monocard/functions/ssr/public/img/uploads/icon.png +0 -0
  101. package/ecomplus-stores/monocard/functions/ssr/public/img/uploads/large-icon.png +0 -0
  102. package/ecomplus-stores/monocard/functions/ssr/public/img/uploads/logo-arcelor-mittal.webp +0 -0
  103. package/ecomplus-stores/monocard/functions/ssr/public/img/uploads/logo-azul.webp +0 -0
  104. package/ecomplus-stores/monocard/functions/ssr/public/img/uploads/logo-banco-pan.webp +0 -0
  105. package/ecomplus-stores/monocard/functions/ssr/public/img/uploads/logo-brinks.webp +0 -0
  106. package/ecomplus-stores/monocard/functions/ssr/public/img/uploads/logo-mastercard.webp +0 -0
  107. package/ecomplus-stores/monocard/functions/ssr/public/img/uploads/logo-pfizer.webp +0 -0
  108. package/ecomplus-stores/monocard/functions/ssr/public/img/uploads/logo-prudential.webp +0 -0
  109. package/ecomplus-stores/monocard/functions/ssr/public/img/uploads/logo-unimed.webp +0 -0
  110. package/ecomplus-stores/monocard/functions/ssr/public/img/uploads/logo.webp +0 -0
  111. package/ecomplus-stores/monocard/functions/ssr/public/img/uploads/mockup-editar.png +0 -0
  112. package/ecomplus-stores/monocard/functions/ssr/public/img/uploads/og-image.png +0 -0
  113. package/ecomplus-stores/monocard/functions/ssr/public/img/uploads/padronagem-tilada.png +0 -0
  114. package/ecomplus-stores/monocard/functions/ssr/public/img/uploads/qrcode-camera.png +0 -0
  115. package/ecomplus-stores/monocard/functions/ssr/public/img/uploads/sua-logo-aqui.png +0 -0
  116. package/ecomplus-stores/monocard/functions/ssr/public/robots.txt +0 -6
  117. package/ecomplus-stores/monocard/functions/ssr/scripts/build.sh +0 -14
  118. package/ecomplus-stores/monocard/functions/ssr/src/assets/card.css +0 -99
  119. package/ecomplus-stores/monocard/functions/ssr/src/assets/style.css +0 -79
  120. package/ecomplus-stores/monocard/functions/ssr/src/components/AccountMenu.vue +0 -97
  121. package/ecomplus-stores/monocard/functions/ssr/src/components/AccountPage.vue +0 -62
  122. package/ecomplus-stores/monocard/functions/ssr/src/components/Banner.vue +0 -59
  123. package/ecomplus-stores/monocard/functions/ssr/src/components/BannersGrid.astro +0 -25
  124. package/ecomplus-stores/monocard/functions/ssr/src/components/Breadcrumbs.astro +0 -44
  125. package/ecomplus-stores/monocard/functions/ssr/src/components/CartItem.vue +0 -64
  126. package/ecomplus-stores/monocard/functions/ssr/src/components/CartSidebar.vue +0 -69
  127. package/ecomplus-stores/monocard/functions/ssr/src/components/CasesGrid.astro +0 -49
  128. package/ecomplus-stores/monocard/functions/ssr/src/components/CheckoutPage.vue +0 -33
  129. package/ecomplus-stores/monocard/functions/ssr/src/components/Collapse.vue +0 -19
  130. package/ecomplus-stores/monocard/functions/ssr/src/components/DemoVideo.vue +0 -10
  131. package/ecomplus-stores/monocard/functions/ssr/src/components/DocDescription.vue +0 -28
  132. package/ecomplus-stores/monocard/functions/ssr/src/components/FeatureTabs.vue +0 -286
  133. package/ecomplus-stores/monocard/functions/ssr/src/components/FeaturesSection.astro +0 -28
  134. package/ecomplus-stores/monocard/functions/ssr/src/components/FooterStamps.vue +0 -63
  135. package/ecomplus-stores/monocard/functions/ssr/src/components/ImagesGallery.vue +0 -154
  136. package/ecomplus-stores/monocard/functions/ssr/src/components/LoginForm.vue +0 -107
  137. package/ecomplus-stores/monocard/functions/ssr/src/components/LottiePhoneNFC.vue +0 -20
  138. package/ecomplus-stores/monocard/functions/ssr/src/components/MonocardCustomizer.vue +0 -261
  139. package/ecomplus-stores/monocard/functions/ssr/src/components/PitchBar.vue +0 -61
  140. package/ecomplus-stores/monocard/functions/ssr/src/components/Prices.vue +0 -95
  141. package/ecomplus-stores/monocard/functions/ssr/src/components/ProductCard.vue +0 -117
  142. package/ecomplus-stores/monocard/functions/ssr/src/components/ProductDetails.vue +0 -122
  143. package/ecomplus-stores/monocard/functions/ssr/src/components/ProductShelf.vue +0 -57
  144. package/ecomplus-stores/monocard/functions/ssr/src/components/ProductSpecifications.vue +0 -42
  145. package/ecomplus-stores/monocard/functions/ssr/src/components/SearchModal.vue +0 -6
  146. package/ecomplus-stores/monocard/functions/ssr/src/components/ShopFooter.vue +0 -71
  147. package/ecomplus-stores/monocard/functions/ssr/src/components/ShopHeader.vue +0 -137
  148. package/ecomplus-stores/monocard/functions/ssr/src/components/ShopHeaderMenu.vue +0 -92
  149. package/ecomplus-stores/monocard/functions/ssr/src/components/ShopSidenav.vue +0 -64
  150. package/ecomplus-stores/monocard/functions/ssr/src/components/ShopSidenavCategory.vue +0 -77
  151. package/ecomplus-stores/monocard/functions/ssr/src/components/SkuSelector.vue +0 -58
  152. package/ecomplus-stores/monocard/functions/ssr/src/env.d.ts +0 -13
  153. package/ecomplus-stores/monocard/functions/ssr/src/layouts/Base.astro +0 -15
  154. package/ecomplus-stores/monocard/functions/ssr/src/layouts/PageFooter.astro +0 -53
  155. package/ecomplus-stores/monocard/functions/ssr/src/layouts/PageHeader.astro +0 -35
  156. package/ecomplus-stores/monocard/functions/ssr/src/main/Fallback.astro +0 -10
  157. package/ecomplus-stores/monocard/functions/ssr/src/main/Home.astro +0 -95
  158. package/ecomplus-stores/monocard/functions/ssr/src/main/Sections.astro +0 -52
  159. package/ecomplus-stores/monocard/functions/ssr/src/main/Wildcard.astro +0 -18
  160. package/ecomplus-stores/monocard/functions/ssr/src/pages/[...slug].astro +0 -42
  161. package/ecomplus-stores/monocard/functions/ssr/src/pages/_vue.ts +0 -10
  162. package/ecomplus-stores/monocard/functions/ssr/src/pages/app/account.astro +0 -34
  163. package/ecomplus-stores/monocard/functions/ssr/src/pages/app/index.astro +0 -62
  164. package/ecomplus-stores/monocard/functions/ssr/src/pages/comprar/index.astro +0 -52
  165. package/ecomplus-stores/monocard/functions/ssr/src/pages/index.astro +0 -32
  166. package/ecomplus-stores/monocard/functions/ssr/src/pages/~fallback.astro +0 -23
  167. package/ecomplus-stores/monocard/functions/ssr/src/scripts/InlineScripts.astro +0 -10
  168. package/ecomplus-stores/monocard/functions/ssr/tailwind.config.cjs +0 -18
  169. package/ecomplus-stores/monocard/functions/ssr/tsconfig.json +0 -12
  170. package/ecomplus-stores/monocard/functions/ssr/uno.config.cjs +0 -5
  171. package/ecomplus-stores/monocard/functions/with-apps/index.js +0 -12
  172. package/ecomplus-stores/monocard/functions/with-apps/package.json +0 -22
  173. package/ecomplus-stores/monocard/package.json +0 -31
  174. package/ecomplus-stores/monocard/scripts/install.sh +0 -24
@@ -1,261 +0,0 @@
1
- <script lang="ts" setup>
2
- import type { Products } from '@cloudcommerce/api/types';
3
- import ecomUtils from '@ecomplus/utils';
4
-
5
- export interface Props {
6
- monocard: Partial<Products>;
7
- monocardWithLogo?: Partial<Products>;
8
- }
9
-
10
- const { price: getPrice, formatMoney } = ecomUtils;
11
- // eslint-disable-next-line vue/no-setup-props-destructure
12
- const {
13
- monocard,
14
- monocardWithLogo,
15
- } = withDefaults(defineProps<Props>(), {
16
- monocard: typeof window === 'object'
17
- ? (window as any).monocard
18
- : {},
19
- monocardWithLogo: typeof window === 'object'
20
- ? (window as any).monocardWithLogo
21
- : {},
22
- });
23
- const cardVariants: Array<{ bgColor: string, textColor: string }> = [];
24
- monocard.variations?.forEach(({ specifications: { colors } }) => {
25
- if (colors && colors.length) {
26
- const { value: bgColor } = colors[0];
27
- if (
28
- !cardVariants.find((cardVariant) => cardVariant.bgColor === bgColor)
29
- && colors[1]?.value !== bgColor
30
- ) {
31
- cardVariants.push({
32
- bgColor,
33
- textColor: colors[1]?.value || (bgColor.startsWith('#f') ? '#000' : '#fff'),
34
- });
35
- }
36
- }
37
- });
38
- const cardBgColor = ref(cardVariants[0]?.bgColor || '#000');
39
- const cardTextColor = ref(cardVariants[0]?.textColor || '#fff');
40
- const selectCardVariant = ({ bgColor, textColor }: typeof cardVariants[0]) => {
41
- cardBgColor.value = bgColor;
42
- cardTextColor.value = textColor;
43
- };
44
- const isLogoEnabled = ref(typeof window === 'object'
45
- && /[?&]logomarca(&|$)/.test(window.location.search));
46
- const enablingLogoTimer = ref(null);
47
- watch(isLogoEnabled, (_isLogoEnabled) => {
48
- if (_isLogoEnabled) {
49
- clearTimeout(enablingLogoTimer.value);
50
- enablingLogoTimer.value = setTimeout(() => {
51
- enablingLogoTimer.value = null;
52
- }, 3000);
53
- } else {
54
- enablingLogoTimer.value = null;
55
- }
56
- });
57
- const customLogoUrl = ref('');
58
- const isLoadingLogo = ref(false);
59
- const upload = (ev) => {
60
- isLoadingLogo.value = true;
61
- const image = ev.target.files[0];
62
- const reader = new FileReader();
63
- reader.readAsDataURL(image);
64
- reader.onload = (loadEv) => {
65
- customLogoUrl.value = loadEv.target.result.toString();
66
- setTimeout(() => {
67
- isLoadingLogo.value = false;
68
- }, 3000);
69
- };
70
- };
71
- const isLogoInputFocus = ref(false);
72
- const isNameInputFocus = ref(false);
73
- const cardAnimationClass = computed(() => {
74
- if (!isLogoEnabled.value) {
75
- return 'card--no-back';
76
- }
77
- return !isNameInputFocus.value
78
- && (isLoadingLogo.value || enablingLogoTimer.value || isLogoInputFocus.value)
79
- ? 'card--show-back' : null;
80
- });
81
- const logoInput = ref(null);
82
- const cardsBag = ref([{
83
- holderName: '',
84
- quantity: 1,
85
- }]);
86
- const focusedCard = ref(0);
87
- const holderName = computed(() => {
88
- return cardsBag.value[focusedCard.value].holderName;
89
- });
90
- const removeCard = (index: number) => {
91
- cardsBag.value.splice(index, 1);
92
- if (focusedCard.value === index) {
93
- focusedCard.value = 0;
94
- }
95
- };
96
- const totalQuantity = computed(() => {
97
- return cardsBag.value.reduce((acc, { quantity }) => (acc + quantity), 0);
98
- });
99
- const price = computed(() => {
100
- if (isLogoEnabled.value && customLogoUrl.value && monocardWithLogo) {
101
- return getPrice(monocardWithLogo) as number;
102
- }
103
- return getPrice(monocard) as number;
104
- });
105
- const logoAdditionalPrice = monocardWithLogo
106
- ? getPrice(monocardWithLogo) - getPrice(monocard) as number : 30;
107
- </script>
108
-
109
- <template>
110
- <div class="container">
111
- <article class="mx-auto max-w-4xl gap-5 lg:flex">
112
- <div class="order-2 mb-10 basis-1/2 lg:mb-0">
113
- <div class="mb-3 mr-5 inline-block">
114
- <i class="i-checkbox-circle-fill bg-primary mr-1"></i> Frete grátis
115
- </div>
116
- <div class="mb-3 inline-block">
117
- <i class="i-checkbox-circle-fill bg-primary mr-1"></i> Sem mensalidade
118
- </div>
119
- <a name="comprar"></a>
120
- <h1 class="mb-3">Seu cartão de visitas eletrônico personalizado</h1>
121
- <h4 class="mb-10 text-sm">
122
- <a href="#como-funciona">
123
- <i class="i-play-circle-line mr-1"></i>Como o Monocard funciona?
124
- </a>
125
- </h4>
126
- <form>
127
- <div
128
- v-for="(card, i) in cardsBag"
129
- :key="i"
130
- class="mb-3 flex gap-2"
131
- >
132
- <input
133
- id="login-form-email"
134
- type="text"
135
- class="mb-0 uppercase"
136
- placeholder="Nome no cartão"
137
- @focus="focusedCard = i"
138
- @focusin="isNameInputFocus = true"
139
- @focusout="isNameInputFocus = false"
140
- v-model="card.holderName"
141
- required
142
- >
143
- <div class="flex basis-1/3 items-center">
144
- <input
145
- class="mb-0"
146
- type="number"
147
- min="1"
148
- v-model="card.quantity"
149
- @change="ev => (ev as any).target.value <= 0 ? card.quantity = 1 : null"
150
- required
151
- >
152
- <div v-if="cardsBag.length > 1" class="flex-auto">
153
- <div
154
- class="i-close-fill ml-1 bg-red-400 text-xl"
155
- role="button"
156
- :aria-label="`Remover cartão ${(i + 1)}`"
157
- @click="removeCard(i)"
158
- ></div>
159
- </div>
160
- </div>
161
- </div>
162
- <div class="gap-8 lg:flex">
163
- <div class="order-last flex-none">
164
- <button
165
- class="secondary inline-block w-auto flex-none text-sm leading-none"
166
- type="button"
167
- @click="cardsBag.push({ holderName: '', quantity: 1 })"
168
- >
169
- <i class="i-add-circle-fill mr-1"></i>
170
- Adicionar cartão
171
- </button>
172
- </div>
173
- <div class="grow">
174
- <div class="mb-5 mt-6">
175
- <strong class="block text-4xl">
176
- {{ formatMoney(price * totalQuantity) }}
177
- </strong>
178
- <span v-if="totalQuantity > 1">{{ formatMoney(price) }} /cartão</span>
179
- </div>
180
- <button class="rounded-full text-xl font-bold uppercase" type="submit">
181
- Comprar
182
- </button>
183
- </div>
184
- </div>
185
- </form>
186
- </div>
187
- <div class="order-1 basis-1/2">
188
- <div
189
- class="card mb-5 mt-2"
190
- :class="cardAnimationClass"
191
- :style="{
192
- '--background-color': cardBgColor,
193
- '--color': cardTextColor,
194
- }"
195
- >
196
- <div class="card__front card__part">
197
- <div class="card__front-square card__square">
198
- <div class="i-qr-code-line text-5xl"></div>
199
- </div>
200
- <div class="card__front-logo card__logo">
201
- <div class="text-sm font-bold">monocard</div>
202
- </div>
203
- <div class="card__space-75">
204
- <p class="card__info">{{ holderName || 'Seu nome aqui' }}</p>
205
- </div>
206
- <div class="card__space-25">
207
- <p class="card__info">
208
- <i class="i-wifi-fill rotate-90 text-lg"></i>
209
- </p>
210
- </div>
211
- </div>
212
- <div class="card__back card__part">
213
- <img
214
- :src="(isLogoEnabled && customLogoUrl) || '/img/uploads/sua-logo-aqui.png'"
215
- class="cursor-pointer"
216
- @click="logoInput.click()"
217
- >
218
- </div>
219
- </div>
220
- <button
221
- v-for="{ bgColor, textColor } in cardVariants"
222
- :key="bgColor"
223
- class="border-1 border-gray relative mr-2 inline-block h-5
224
- w-5 rounded-full p-0 shadow drop-shadow"
225
- :style="{ background: bgColor }"
226
- @click="selectCardVariant({ bgColor, textColor })"
227
- >
228
- <i
229
- v-if="cardBgColor === bgColor"
230
- class="i-checkbox-fill absolute bg-green-300 text-xs"
231
- ></i>
232
- </button>
233
- <div class="mt-5">
234
- <label for="switch-logo" class="inline-block">
235
- <input
236
- id="switch-logo"
237
- type="checkbox"
238
- name="switch"
239
- role="switch"
240
- v-model="isLogoEnabled"
241
- >
242
- Imagem no verso
243
- <small class="mb-2 text-sm" v-if="logoAdditionalPrice">
244
- <br>+ {{ formatMoney(logoAdditionalPrice) }} por cartão
245
- </small>
246
- </label>
247
- </div>
248
- <input
249
- v-if="isLogoEnabled"
250
- type="file"
251
- class="w-auto"
252
- accept="image/*"
253
- ref="logoInput"
254
- @change="upload"
255
- @mouseenter="isLogoInputFocus = true"
256
- @mouseout="isLogoInputFocus = false"
257
- >
258
- </div>
259
- </article>
260
- </div>
261
- </template>
@@ -1,61 +0,0 @@
1
- <template>
2
- <div class="relative z-20 bg-black uppercase">
3
- <div class="bg-primary/20">
4
- <div class="container mx-auto px-3 py-1 md:w-2/3">
5
- <Carousel :autoplay="countValidSlides > 1 ? 7000 : undefined">
6
- <li
7
- v-for="(slide, i) in slides"
8
- :key="i"
9
- class="h-full shrink-0 basis-full text-center"
10
- >
11
- <component
12
- :is="slide.href ? 'ALink' : 'span'"
13
- :href="slide.href"
14
- :target="slide.target"
15
- class="inline-block px-8"
16
- :class="slide.href ? 'hover:underline' : null"
17
- >
18
- <span
19
- v-if="parsedContents[i]"
20
- v-html="parsedContents[i]"
21
- class="prose text-primary-100 text-sm"
22
- ></span>
23
- </component>
24
- </li>
25
- <template #controls>
26
- <div
27
- v-show="countValidSlides > 1"
28
- class="text-primary-400 text-xl leading-none"
29
- >
30
- <CarouselControl
31
- :direction="-1"
32
- class="hover:text-primary-200 pr-2"
33
- />
34
- <CarouselControl class="hover:text-primary-200 pl-2" />
35
- </div>
36
- </template>
37
- </Carousel>
38
- </div>
39
- </div>
40
- </div>
41
- </template>
42
-
43
- <script setup lang="ts">
44
- import usePitchBar from '@@sf/composables/use-pitch-bar';
45
- import Carousel from '@@sf/components/Carousel.vue';
46
- import CarouselControl from '@@sf/components/CarouselControl.vue';
47
-
48
- export interface Props {
49
- slides: Array<{
50
- href?: string;
51
- target?: string;
52
- html: string;
53
- }>;
54
- }
55
-
56
- const props = defineProps<Props>();
57
- const {
58
- parsedContents,
59
- countValidSlides,
60
- } = usePitchBar(props);
61
- </script>
@@ -1,95 +0,0 @@
1
- <template>
2
- <div
3
- class="text-base-600
4
- [&>div]:[font-size:90%] [&_small]:lowercase [&_small]:[font-size:92%]"
5
- :class="isBig ? 'text-lg' : null"
6
- >
7
- <span v-if="comparePrice" class="text-base-500 mr-1 text-[87%]">
8
- <small v-if="isLiteral">
9
- {{ `${$t.i19from} ` }}
10
- </small>
11
- <s>{{ $money(comparePrice) }}</s>
12
- <small v-if="isLiteral">
13
- {{ ` ${$t.i19to}` }}
14
- </small>
15
- </span>
16
- <strong
17
- class="text-base-800"
18
- :class="isBig ? 'text-4xl block' : 'inline-block'"
19
- >
20
- <small v-if="hasVariedPrices">
21
- {{ `${$t.i19asOf} ` }}
22
- </small>
23
- {{ $money(salePrice) }}
24
- </strong>
25
- <Fade slide="down">
26
- <div v-if="cashbackValue && hasCashback" class="relative z-10">
27
- <span :data-tooltip="$t.i19get$1back
28
- .replace('$1', $percentage(cashbackPercentage))">
29
- <i class="i-arrow-go-back-fill mr-1"></i>
30
- <span class="font-medium">
31
- {{ $money(cashbackValue) }}
32
- </span>
33
- <small> cashback</small>
34
- </span>
35
- </div>
36
- </Fade>
37
- <Fade slide="down">
38
- <div v-if="installmentValue && hasPriceOptions">
39
- <small v-if="isLiteral">
40
- {{ `${$t.i19upTo} ` }}
41
- </small>
42
- {{ installmentsNumber }}x
43
- <small v-if="isLiteral">
44
- {{ ` ${$t.i19of} ` }}
45
- </small>
46
- <span>{{ $money(installmentValue) }}</span>
47
- <small v-if="!monthlyInterest && isLiteral">
48
- {{ ` ${$t.i19interestFree}` }}
49
- </small>
50
- </div>
51
- </Fade>
52
- <Fade slide="down">
53
- <div v-if="priceWithDiscount < salePrice && hasPriceOptions">
54
- <small v-if="!discountLabel">
55
- {{ `${$t.i19asOf} ` }}
56
- </small>
57
- <span>{{ $money(priceWithDiscount) }}</span>
58
- <small v-if="discountLabel">
59
- {{ ` ${discountLabel}` }}
60
- </small>
61
- </div>
62
- </Fade>
63
- </div>
64
- </template>
65
-
66
- <script setup lang="ts">
67
- import {
68
- type Props as UsePricesProps,
69
- usePrices,
70
- } from '@@sf/composables/use-prices';
71
-
72
- export interface Props extends UsePricesProps {
73
- isBig?: boolean;
74
- isLiteral?: boolean;
75
- hasCashback?: boolean;
76
- hasPriceOptions?: boolean;
77
- }
78
-
79
- const props = withDefaults(defineProps<Props>(), {
80
- hasCashback: true,
81
- hasPriceOptions: true,
82
- });
83
- const {
84
- hasVariedPrices,
85
- salePrice,
86
- comparePrice,
87
- cashbackPercentage,
88
- cashbackValue,
89
- installmentsNumber,
90
- monthlyInterest,
91
- installmentValue,
92
- priceWithDiscount,
93
- discountLabel,
94
- } = usePrices(props);
95
- </script>
@@ -1,117 +0,0 @@
1
- <template>
2
- <article
3
- ref="card"
4
- :data-sku="product.sku"
5
- class="group relative mx-auto h-full max-w-[350px] py-3"
6
- >
7
- <ALink
8
- :href="link"
9
- class="flex h-full flex-col overflow-hidden rounded
10
- ring-black/5 group-hover:shadow group-hover:ring-1"
11
- >
12
- <div class="aspect-square p-2
13
- transition-transform motion-safe:group-hover:scale-110">
14
- <div class="relative h-full w-full overflow-hidden rounded bg-white
15
- group-hover:rounded-none">
16
- <span v-if="images?.length" class="text-xs text-opacity-70">
17
- <AImg
18
- :picture="images[0]"
19
- :alt="title"
20
- class="absolute left-0 top-0 block h-full w-full object-cover"
21
- />
22
- <AImg
23
- v-if="images[1] && wasHoveredOnce"
24
- :picture="images[1]"
25
- :alt="title"
26
- class="absolute left-0 top-0 z-10 block h-full w-full
27
- object-cover text-transparent opacity-0
28
- transition-opacity group-hover:opacity-100 motion-safe:duration-300"
29
- />
30
- </span>
31
- <div
32
- v-else
33
- class="from-base-50/20 to-base-100 h-full w-full bg-gradient-to-br"
34
- />
35
- </div>
36
- </div>
37
- <span
38
- v-if="discountPercentage"
39
- class=":uno: bg-secondary/70 text-on-secondary absolute
40
- right-2 top-9 py-0.5
41
- pl-3 pr-1.5 text-xs
42
- transition-transform [clip-path:polygon(20%_0,100%_0,100%_100%,0_100%)]
43
- group-hover:translate-x-2 group-hover:scale-110"
44
- >
45
- -<strong>{{ discountPercentage }}</strong>%
46
- </span>
47
- <div class="relative z-10 flex grow flex-col justify-between
48
- bg-white/40 p-4 group-hover:backdrop-blur-md">
49
- <component
50
- :is="headingTag"
51
- class="ui-link line-clamp-2 no-underline"
52
- :class="[
53
- isActive ? 'text-base-700' : 'text-base-500',
54
- link ? 'group-hover:text-primary group-hover:underline' : null,
55
- ]"
56
- >
57
- {{ title }}
58
- </component>
59
- <div class="pt-2">
60
- <div v-if="isActive">
61
- <Prices :product="product" />
62
- </div>
63
- <span v-else class="ui-badge bg-warning-100 text-warning-700">
64
- {{ !isInStock ? $t.i19outOfStock : $t.i19inactive }}
65
- </span>
66
- </div>
67
- <button
68
- v-if="isActive && !hasVariations"
69
- class=":uno: ui-btn-sm ui-btn-primary absolute -top-6
70
- left-0 -z-10 hidden w-full rounded-none
71
- opacity-0 transition group-hover:z-10 group-hover:opacity-100 md:block"
72
- @click.prevent="addProductToCart(product)"
73
- >
74
- <span class="bg-on-primary text-primary mr-1 inline-block h-4 w-4
75
- rounded-full text-center text-base leading-none opacity-80">
76
- &plus;
77
- </span>
78
- {{ $t.i19addToCart }}
79
- </button>
80
- </div>
81
- </ALink>
82
- </article>
83
- </template>
84
-
85
- <script setup lang="ts">
86
- import { watchOnce, useElementHover } from '@vueuse/core';
87
- import { addProductToCart } from '@@sf/state/shopping-cart';
88
- import {
89
- type Props as UseProductCardProps,
90
- useProductCard,
91
- } from '@@sf/composables/use-product-card';
92
- import Prices from '~/components/Prices.vue';
93
-
94
- export type Props = UseProductCardProps & {
95
- headingTag?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6';
96
- };
97
-
98
- const props = withDefaults(defineProps<Props>(), {
99
- headingTag: 'h3',
100
- });
101
- const {
102
- product,
103
- title,
104
- link,
105
- images,
106
- isInStock,
107
- isActive,
108
- discountPercentage,
109
- hasVariations,
110
- } = useProductCard(props as UseProductCardProps);
111
- const card = ref<HTMLElement | null>(null);
112
- const isHovered = useElementHover(card);
113
- const wasHoveredOnce = ref(false);
114
- watchOnce(isHovered, () => {
115
- wasHoveredOnce.value = true;
116
- });
117
- </script>
@@ -1,122 +0,0 @@
1
- <template>
2
- <section class="ui-section relative grid grid-cols-1 items-start
3
- gap-5 md:gap-4 lg:grid-cols-4 2xl:gap-6">
4
- <div class="w-full lg:col-span-3">
5
- <template v-if="product.pictures?.length">
6
- <ImagesGallery :pictures="product.pictures" />
7
- </template>
8
- </div>
9
- <div class="top-0 py-4 lg:sticky">
10
- <h1 class="ui-text-brand text-base-700 text-xl">
11
- {{ title }}
12
- </h1>
13
- <div v-if="isActive" class="mt-5">
14
- <Prices :product="product" is-big is-literal />
15
- <SkuSelector
16
- v-if="product.variations"
17
- :variations="product.variations"
18
- v-model:variation-id="variationId"
19
- class="my-4"
20
- />
21
- <Fade slide="down">
22
- <div v-if="hasSkuSelectionAlert" class="ui-alert inline-block">
23
- {{ $t.i19selectVariationMsg }}
24
- <i class="i-arrow-right ml-1 -rotate-90"></i>
25
- </div>
26
- </Fade>
27
- <div class="mt-5 flex flex-wrap items-center gap-x-4 gap-y-2
28
- overflow-hidden md:flex-nowrap lg:mt-4 lg:flex-wrap">
29
- <QuantitySelector
30
- v-model="quantity"
31
- :min="product.min_quantity"
32
- :max="product.quantity"
33
- class="border-base-100 rounded md:mr-5
34
- lg:mb-2 lg:mr-auto lg:border-2"
35
- />
36
- <CheckoutLink
37
- class="ui-btn-lg ui-btn-primary grow text-center"
38
- to="checkout"
39
- :cart-item="{
40
- product_id: product._id,
41
- quantity,
42
- variation_id: variationId || undefined,
43
- }"
44
- :data-tooltip="!isSkuSelected ? $t.i19chooseProductDetailsToBuy : null"
45
- @click="checkVariation"
46
- >
47
- <i class="i-chevron-double-right mr-1"></i>
48
- {{ $t.i19buy }}
49
- </CheckoutLink>
50
- <button
51
- class="ui-btn-lg ui-btn-contrast grow"
52
- @click.prevent="addToCart"
53
- :data-tooltip="!isSkuSelected ? $t.i19chooseProductDetailsToBuy : null"
54
- >
55
- {{ $t.i19addToCart }}
56
- </button>
57
- </div>
58
- </div>
59
- </div>
60
- <div class="w-full lg:col-span-3">
61
- <slot name="description" />
62
- </div>
63
- </section>
64
- </template>
65
-
66
- <script setup lang="ts">
67
- import type { ResourceId, Products } from '@cloudcommerce/api/types';
68
- import { useUrlSearchParams } from '@vueuse/core';
69
- import { addProductToCart } from '@@sf/state/shopping-cart';
70
- import { useProductCard } from '@@sf/composables/use-product-card';
71
- import CheckoutLink from '@@sf/components/CheckoutLink.vue';
72
- import QuantitySelector from '@@sf/components/QuantitySelector.vue';
73
- import Prices from '~/components/Prices.vue';
74
- import ImagesGallery from '~/components/ImagesGallery.vue';
75
- import SkuSelector from '~/components/SkuSelector.vue';
76
-
77
- export interface Props {
78
- product?: Products;
79
- }
80
-
81
- const props = withDefaults(defineProps<Props>(), {
82
- product: () => globalThis.$storefront.apiContext?.doc as Products,
83
- });
84
- const {
85
- product,
86
- title,
87
- isActive,
88
- } = useProductCard<Products>(props);
89
- const quantity = ref(product.min_quantity || 1);
90
- const params = useUrlSearchParams('history');
91
- const hasSkuSelectionAlert = ref(false);
92
- const variationId = ref<ResourceId | null>(null);
93
- watch(variationId, (_variationId) => {
94
- if (_variationId) {
95
- params.var = _variationId;
96
- hasSkuSelectionAlert.value = false;
97
- }
98
- });
99
- onMounted(() => {
100
- watch(params, ({ var: variation }) => {
101
- if (typeof variation === 'string' && variation) {
102
- variationId.value = variation as ResourceId;
103
- }
104
- }, { immediate: true });
105
- });
106
- const isSkuSelected = computed(() => {
107
- return Boolean(!product.variations?.length || variationId.value);
108
- });
109
- const checkVariation = (ev?: Event) => {
110
- if (!isSkuSelected.value) {
111
- if (ev) ev.preventDefault();
112
- hasSkuSelectionAlert.value = true;
113
- } else {
114
- hasSkuSelectionAlert.value = false;
115
- }
116
- return !hasSkuSelectionAlert.value;
117
- };
118
- const addToCart = () => {
119
- if (!checkVariation()) return;
120
- addProductToCart(product, variationId.value ? variationId.value : undefined);
121
- };
122
- </script>