cloudcommerce 0.1.6 → 0.2.0

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 (190) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/action.yml +4 -0
  3. package/ecomplus-stores/monocard/functions/core/package.json +1 -1
  4. package/ecomplus-stores/monocard/functions/events/package.json +2 -2
  5. package/ecomplus-stores/monocard/functions/modules/package.json +2 -2
  6. package/ecomplus-stores/monocard/functions/passport/package.json +2 -2
  7. package/ecomplus-stores/monocard/functions/ssr/package.json +9 -6
  8. package/ecomplus-stores/monocard/package.json +1 -1
  9. package/ecomplus-stores/tia-sonia/functions/core/package.json +1 -1
  10. package/ecomplus-stores/tia-sonia/functions/events/package.json +2 -2
  11. package/ecomplus-stores/tia-sonia/functions/modules/package.json +2 -2
  12. package/ecomplus-stores/tia-sonia/functions/passport/package.json +2 -2
  13. package/ecomplus-stores/tia-sonia/functions/ssr/package.json +11 -7
  14. package/ecomplus-stores/tia-sonia/functions/ssr/public/img/uploads/categoria-acucares.webp +0 -0
  15. package/ecomplus-stores/tia-sonia/functions/ssr/public/img/uploads/categoria-barras.webp +0 -0
  16. package/ecomplus-stores/tia-sonia/functions/ssr/public/img/uploads/categoria-bebidas-em-po.webp +0 -0
  17. package/ecomplus-stores/tia-sonia/functions/ssr/public/img/uploads/categoria-cookies.webp +0 -0
  18. package/ecomplus-stores/tia-sonia/functions/ssr/public/img/uploads/categoria-granola-tia-sonia.webp +0 -0
  19. package/ecomplus-stores/tia-sonia/functions/ssr/public/img/uploads/categoria-integrais.webp +0 -0
  20. package/ecomplus-stores/tia-sonia/functions/ssr/public/img/uploads/categoria-naturais.webp +0 -0
  21. package/ecomplus-stores/tia-sonia/functions/ssr/public/img/uploads/categoria-pastas-tia-sonia.webp +0 -0
  22. package/ecomplus-stores/tia-sonia/functions/ssr/public/img/uploads/categoria-snacks.webp +0 -0
  23. package/ecomplus-stores/tia-sonia/functions/ssr/public/img/uploads/categoria-ultrabar.webp +0 -0
  24. package/ecomplus-stores/tia-sonia/functions/ssr/public/img/uploads/daniel-cady.webp +0 -0
  25. package/ecomplus-stores/tia-sonia/functions/ssr/public/img/uploads/granola-tradicional-lata-verso.webp +0 -0
  26. package/ecomplus-stores/tia-sonia/functions/ssr/public/img/uploads/granola-tradicional-lata.webp +0 -0
  27. package/ecomplus-stores/tia-sonia/functions/ssr/public/img/uploads/{acai-com-granola.jpg → hero-acai-granola.jpg} +0 -0
  28. package/ecomplus-stores/tia-sonia/functions/ssr/public/img/uploads/{cafe-com-tapioca-e-aveia.jpg → hero-cafe-tapioca-aveia.jpg} +0 -0
  29. package/ecomplus-stores/tia-sonia/functions/ssr/public/img/uploads/hero-piquenique-snack-cookies.jpg +0 -0
  30. package/ecomplus-stores/tia-sonia/functions/ssr/public/img/uploads/machu-picchu-1500.jpg +0 -0
  31. package/ecomplus-stores/tia-sonia/functions/ssr/public/img/uploads/selo-ibd-120-80.webp +0 -0
  32. package/ecomplus-stores/tia-sonia/functions/ssr/public/img/uploads/selo-organico-120-80.webp +0 -0
  33. package/ecomplus-stores/tia-sonia/functions/ssr/public/img/uploads/selo-usda-120-80.webp +0 -0
  34. package/ecomplus-stores/tia-sonia/functions/ssr/public/img/uploads/selo-vegano-120-80.webp +0 -0
  35. package/ecomplus-stores/tia-sonia/functions/ssr/public/img/uploads/tia-sonia-real.png +0 -0
  36. package/ecomplus-stores/tia-sonia/functions/ssr/public/img/uploads/trustvox.png +0 -0
  37. package/ecomplus-stores/tia-sonia/functions/ssr/src/assets/prices.css +3 -0
  38. package/ecomplus-stores/tia-sonia/functions/ssr/src/components/AboutUs.astro +77 -0
  39. package/ecomplus-stores/tia-sonia/functions/ssr/src/components/BrandTestimonials.vue +134 -0
  40. package/ecomplus-stores/tia-sonia/functions/ssr/src/components/CategoriesGrid.vue +32 -0
  41. package/ecomplus-stores/tia-sonia/functions/ssr/src/components/CategoriesSlider.vue +117 -0
  42. package/ecomplus-stores/tia-sonia/functions/ssr/src/components/HeroBanner.vue +112 -0
  43. package/ecomplus-stores/tia-sonia/functions/ssr/src/components/PitchBar.vue +48 -16
  44. package/ecomplus-stores/tia-sonia/functions/ssr/src/components/TheHeader.vue +39 -19
  45. package/ecomplus-stores/tia-sonia/functions/ssr/src/components/header/HeaderNav.vue +4 -0
  46. package/ecomplus-stores/tia-sonia/functions/ssr/src/layouts/Base.astro +10 -4
  47. package/ecomplus-stores/tia-sonia/functions/ssr/src/layouts/Pages.astro +1 -1
  48. package/ecomplus-stores/tia-sonia/functions/ssr/src/main/Home.astro +158 -31
  49. package/ecomplus-stores/tia-sonia/functions/ssr/src/scripts/head-scripts.ts +15 -0
  50. package/ecomplus-stores/tia-sonia/functions/ssr/src/scripts/modules-info-preset.ts +27 -0
  51. package/ecomplus-stores/tia-sonia/package.json +1 -1
  52. package/package.json +13 -13
  53. package/packages/api/package.json +1 -1
  54. package/packages/apps/correios/package.json +2 -2
  55. package/packages/apps/custom-payment/package.json +1 -1
  56. package/packages/apps/custom-shipping/package.json +1 -1
  57. package/packages/apps/datafrete/CHANGELOG.md +1 -0
  58. package/packages/apps/datafrete/README.md +1 -0
  59. package/packages/apps/datafrete/lib/datafrete-webhook.d.ts +4 -0
  60. package/packages/apps/datafrete/lib/datafrete-webhook.js +108 -0
  61. package/packages/apps/datafrete/lib/datafrete-webhook.js.map +1 -0
  62. package/packages/apps/datafrete/lib/datafrete.d.ts +2 -0
  63. package/packages/apps/datafrete/lib/datafrete.js +6 -0
  64. package/packages/apps/datafrete/lib/datafrete.js.map +1 -0
  65. package/packages/apps/datafrete/lib/index.d.ts +1 -0
  66. package/packages/apps/datafrete/lib/index.js +2 -0
  67. package/packages/apps/datafrete/lib/index.js.map +1 -0
  68. package/packages/apps/datafrete/lib-mjs/calculate-datafrete.mjs +277 -0
  69. package/packages/apps/datafrete/package.json +37 -0
  70. package/packages/apps/datafrete/src/datafrete-webhook.ts +131 -0
  71. package/packages/apps/datafrete/src/datafrete.ts +7 -0
  72. package/packages/apps/datafrete/src/index.ts +1 -0
  73. package/packages/apps/datafrete/tsconfig.json +6 -0
  74. package/packages/apps/datafrete/webhook.js +1 -0
  75. package/packages/apps/discounts/package.json +1 -1
  76. package/packages/apps/emails/package.json +1 -1
  77. package/packages/apps/fb-conversions/package.json +2 -2
  78. package/packages/apps/frenet/package.json +3 -3
  79. package/packages/apps/galaxpay/lib/functions-lib/galaxpay/webhook.js +3 -2
  80. package/packages/apps/galaxpay/lib/functions-lib/galaxpay/webhook.js.map +1 -1
  81. package/packages/apps/galaxpay/package.json +2 -2
  82. package/packages/apps/galaxpay/src/functions-lib/galaxpay/webhook.ts +3 -2
  83. package/packages/apps/google-analytics/CHANGELOG.md +1 -0
  84. package/packages/apps/google-analytics/README.md +1 -0
  85. package/packages/apps/google-analytics/lib/google-analytics-events.js +113 -0
  86. package/packages/apps/google-analytics/lib/google-analytics-events.js.map +1 -0
  87. package/packages/apps/google-analytics/lib/index.js +2 -0
  88. package/packages/apps/google-analytics/lib/index.js.map +1 -0
  89. package/packages/apps/google-analytics/package.json +32 -0
  90. package/packages/apps/google-analytics/src/google-analytics-events.ts +151 -0
  91. package/packages/apps/google-analytics/src/index.ts +1 -0
  92. package/packages/apps/google-analytics/tsconfig.json +3 -0
  93. package/packages/apps/google-analytics/types.d.ts +43 -0
  94. package/packages/apps/infinitepay/package.json +2 -2
  95. package/packages/apps/jadlog/package.json +2 -2
  96. package/packages/apps/loyalty-points/package.json +1 -1
  97. package/packages/apps/mercadopago/lib/mp-create-transaction.js +1 -1
  98. package/packages/apps/mercadopago/lib/mp-create-transaction.js.map +1 -1
  99. package/packages/apps/mercadopago/lib/mp-webhook.js +2 -7
  100. package/packages/apps/mercadopago/lib/mp-webhook.js.map +1 -1
  101. package/packages/apps/mercadopago/package.json +2 -2
  102. package/packages/apps/mercadopago/src/mp-create-transaction.ts +1 -1
  103. package/packages/apps/mercadopago/src/mp-webhook.ts +3 -8
  104. package/packages/apps/pagarme/lib/pagarme-webhook.js +1 -1
  105. package/packages/apps/pagarme/lib/pagarme-webhook.js.map +1 -1
  106. package/packages/apps/pagarme/package.json +2 -2
  107. package/packages/apps/pagarme/src/pagarme-webhook.ts +1 -1
  108. package/packages/apps/pix/package.json +2 -2
  109. package/packages/apps/tiny-erp/package.json +2 -2
  110. package/packages/cli/package.json +1 -1
  111. package/packages/config/package.json +1 -1
  112. package/packages/emails/package.json +3 -3
  113. package/packages/events/lib/firebase.js +4 -0
  114. package/packages/events/lib/firebase.js.map +1 -1
  115. package/packages/events/package.json +3 -1
  116. package/packages/events/src/firebase.ts +4 -0
  117. package/packages/firebase/lib/config.d.ts +7 -0
  118. package/packages/firebase/lib/config.js +10 -0
  119. package/packages/firebase/lib/config.js.map +1 -1
  120. package/packages/firebase/package.json +1 -1
  121. package/packages/firebase/src/config.ts +11 -0
  122. package/packages/i18n/package.json +1 -1
  123. package/packages/modules/lib/firebase/call-app-module.js +5 -0
  124. package/packages/modules/lib/firebase/call-app-module.js.map +1 -1
  125. package/packages/modules/package.json +4 -3
  126. package/packages/modules/src/firebase/call-app-module.ts +5 -0
  127. package/packages/passport/package.json +1 -1
  128. package/packages/ssr/package.json +4 -3
  129. package/packages/storefront/.eslintrc.cjs +5 -1
  130. package/packages/storefront/astro.config.mjs +9 -24
  131. package/packages/storefront/client.d.ts +7 -8
  132. package/packages/storefront/dist/client/PitchBar.afe7ff5c.js +1 -0
  133. package/packages/storefront/dist/client/Prices.eaf8a32c.js +1 -0
  134. package/packages/storefront/dist/client/ProductCard.1106b153.js +1 -0
  135. package/packages/storefront/dist/client/assets/_...slug_.fea84512.css +1 -0
  136. package/packages/storefront/dist/client/assets/index.90df622b.css +1 -0
  137. package/packages/storefront/dist/client/chunks/Prices.vue_vue_type_script_setup_true_lang.781b6501.js +1 -0
  138. package/packages/storefront/dist/client/chunks/ecom-utils.63984324.js +1 -0
  139. package/packages/storefront/dist/client/chunks/runtime-core.esm-bundler.fa6cdb60.js +1 -0
  140. package/packages/storefront/dist/client/client.367a6497.js +1 -0
  141. package/packages/storefront/dist/client/hoisted.4671ed15.js +1 -0
  142. package/packages/storefront/dist/client/sw.js +1 -1
  143. package/packages/storefront/dist/client/workbox-e2ee76b5.js +1 -0
  144. package/packages/storefront/dist/server/entry.mjs +571 -737
  145. package/packages/storefront/package.json +11 -10
  146. package/packages/storefront/src/env.d.ts +9 -0
  147. package/packages/storefront/src/lib/assets/tooltip.css +6 -5
  148. package/packages/storefront/src/lib/components/Carousel.vue +259 -0
  149. package/packages/storefront/src/lib/components/CarouselControl.vue +29 -0
  150. package/packages/storefront/src/lib/components/LoginDrawer.vue +1 -1
  151. package/packages/storefront/src/lib/components/PitchBar.vue +44 -0
  152. package/packages/storefront/src/lib/components/Prices.vue +116 -105
  153. package/packages/storefront/src/lib/components/ProductCard.vue +1 -1
  154. package/packages/storefront/src/lib/components/_injection-keys.ts +9 -0
  155. package/packages/storefront/src/lib/components/globals/ALink.vue +26 -0
  156. package/packages/storefront/src/lib/composables/use-prices.ts +19 -12
  157. package/packages/storefront/src/lib/layouts/BaseBody.astro +1 -5
  158. package/packages/storefront/src/lib/layouts/BaseHead.astro +7 -2
  159. package/packages/storefront/src/lib/layouts/PagesHeader.astro +38 -0
  160. package/packages/storefront/src/lib/pages/_vue.ts +3 -2
  161. package/packages/storefront/src/lib/ssr/image.ts +3 -2
  162. package/packages/storefront/src/lib/ssr-context.ts +6 -0
  163. package/packages/storefront/src/lib/state/modules-info.ts +10 -4
  164. package/packages/storefront/src/vue-globals.d.ts +5 -5
  165. package/packages/storefront/tailwind.config.cjs +12 -6
  166. package/packages/storefront/tsconfig.json +2 -2
  167. package/packages/storefront/uno.config.cjs +4 -4
  168. package/packages/types/package.json +1 -1
  169. package/ecomplus-stores/tia-sonia/functions/ssr/src/scripts/InlineScripts.astro +0 -10
  170. package/packages/storefront/dist/client/HeaderButtons.300c19e5.js +0 -1
  171. package/packages/storefront/dist/client/Prices.6c44a513.js +0 -1
  172. package/packages/storefront/dist/client/ProductCard.69bba7fc.js +0 -1
  173. package/packages/storefront/dist/client/assets/_...slug_.15bda576.css +0 -1
  174. package/packages/storefront/dist/client/assets/index.e6a09532.css +0 -1
  175. package/packages/storefront/dist/client/chunks/HeaderButtons.1abd5bf4.js +0 -1
  176. package/packages/storefront/dist/client/chunks/LoginForm.7e7d6137.js +0 -1441
  177. package/packages/storefront/dist/client/chunks/Prices.vue_vue_type_script_setup_true_lang.e4525076.js +0 -1
  178. package/packages/storefront/dist/client/chunks/_plugin-vue_export-helper.fc452b02.js +0 -1
  179. package/packages/storefront/dist/client/chunks/ecom-utils.b0a26608.js +0 -1
  180. package/packages/storefront/dist/client/chunks/preload-helper.1de719f8.js +0 -1
  181. package/packages/storefront/dist/client/chunks/price.ecf7fed4.js +0 -1
  182. package/packages/storefront/dist/client/chunks/runtime-core.esm-bundler.b4556b35.js +0 -1
  183. package/packages/storefront/dist/client/client.2a3e5a58.js +0 -1
  184. package/packages/storefront/dist/client/hoisted.f6ee2883.js +0 -1
  185. package/packages/storefront/dist/client/page.5a6f3db5.js +0 -1
  186. package/packages/storefront/dist/client/workbox-abdc68aa.js +0 -1
  187. package/packages/storefront/dist/client/~partytown/partytown-atomics.js +0 -2
  188. package/packages/storefront/dist/client/~partytown/partytown-media.js +0 -2
  189. package/packages/storefront/dist/client/~partytown/partytown-sw.js +0 -2
  190. package/packages/storefront/dist/client/~partytown/partytown.js +0 -2
@@ -0,0 +1,117 @@
1
+ <script setup lang="ts">
2
+ import type { Categories } from '@cloudcommerce/types';
3
+ import { ref } from 'vue';
4
+ import { useElementVisibility } from '@vueuse/core';
5
+
6
+ export interface Props {
7
+ categories: Partial<Categories>[],
8
+ }
9
+
10
+ defineProps<Props>();
11
+ const list = ref<HTMLUListElement | null>(null);
12
+ const move = (isNext = true) => {
13
+ const factor = isNext ? 1 : -1;
14
+ list.value.scrollLeft += (factor * list.value.offsetWidth);
15
+ };
16
+ const next = () => move();
17
+ const prev = () => move(false);
18
+ const listStart = ref<HTMLLIElement | null>(null);
19
+ const listEnd = ref<HTMLLIElement | null>(null);
20
+ const isStartVisible = useElementVisibility(listStart, { scrollTarget: list });
21
+ const isEndVisible = useElementVisibility(listEnd, { scrollTarget: list });
22
+ </script>
23
+
24
+ <template>
25
+ <div class="CategoriesSlider px-4 py-3">
26
+ <nav>
27
+ <ul
28
+ role="list"
29
+ class="flex items-center overflow-hidden snap-x snap-mandatory scroll-smooth"
30
+ ref="list"
31
+ >
32
+ <li ref="listStart"></li>
33
+ <li
34
+ v-for="(category, i) in categories"
35
+ :key="i"
36
+ class="text-center font-brand text-lg"
37
+ :class="{
38
+ 'snap-start snap-always sm:snap-align-none sm:snap-normal': !(i % 2),
39
+ 'md:snap-start md:snap-always': !(i % 4),
40
+ 'xl:snap-start xl:snap-always': !(i % 6),
41
+ }"
42
+ >
43
+ <a
44
+ :href="category.slug"
45
+ class="block p-3 rounded-lg text-primary-700
46
+ hover:text-primary-900 hover:bg-gradient-to-t from-white/70"
47
+ >
48
+ <img
49
+ v-if="category.icon"
50
+ :src="category.icon.url"
51
+ :alt="category.icon.alt || category.name"
52
+ loading="lazy"
53
+ width="430"
54
+ height="286"
55
+ />
56
+ <h3>{{ category.name }}</h3>
57
+ </a>
58
+ </li>
59
+ <li ref="listEnd"></li>
60
+ </ul>
61
+ </nav>
62
+ <div class="mt-3 lg:mt-4 text-4xl text-base-700
63
+ flex gap-2 justify-center items-center">
64
+ <div class="basis-1/3 flex justify-end items-center mr-4">
65
+ <a
66
+ href="/busca"
67
+ class="inline-block font-bold uppercase text-sm px-3 py-2
68
+ bg-base-200 opacity-80 hover:opacity-100 rounded"
69
+ >
70
+ Todos os produtos
71
+ </a>
72
+ </div>
73
+ <button
74
+ class="px-3"
75
+ :class="!isStartVisible ? 'opacity-70 hover:opacity-100' : 'opacity-40'"
76
+ @click="prev"
77
+ :disabled="isStartVisible"
78
+ >
79
+ <i class="i-arrow-left-circle"></i>
80
+ </button>
81
+ <button
82
+ class="px-3"
83
+ :class="!isEndVisible ? 'opacity-70 hover:opacity-100' : 'opacity-40'"
84
+ @click="next"
85
+ :disabled="isEndVisible"
86
+ >
87
+ <i class="i-arrow-right-circle"></i>
88
+ </button>
89
+ <div class="basis-1/3 flex items-center ml-4">
90
+ <a
91
+ href="/blog/c/receitas"
92
+ class="inline-block font-bold uppercase text-sm p-2
93
+ opacity-80 hover:opacity-100"
94
+ >
95
+ <i class="i-chevron-right"></i>
96
+ Receitas
97
+ </a>
98
+ </div>
99
+ </div>
100
+ </div>
101
+ </template>
102
+
103
+ <style scoped>
104
+ li {
105
+ min-width: 50%;
106
+ }
107
+ @screen md {
108
+ li {
109
+ min-width: 25%;
110
+ }
111
+ }
112
+ @screen xl {
113
+ li {
114
+ min-width: 16.6667%;
115
+ }
116
+ }
117
+ </style>
@@ -0,0 +1,112 @@
1
+ <script setup lang="ts">
2
+ import type { Products } from '@cloudcommerce/types';
3
+ import { ref } from 'vue';
4
+ import { useElementHover } from '@vueuse/core';
5
+ import { Popover, PopoverButton, PopoverPanel } from '@headlessui/vue';
6
+ import Prices from '@@components/Prices.vue';
7
+
8
+ export interface Props {
9
+ pointers?: Array<{
10
+ product: Partial<Products> & { price: number },
11
+ position: {
12
+ x: number,
13
+ y: number,
14
+ },
15
+ }>,
16
+ blogPost?: {
17
+ title: string,
18
+ link: string,
19
+ description: string,
20
+ }
21
+ }
22
+
23
+ defineProps<Props>();
24
+ const postLink = ref<HTMLElement>(null);
25
+ const isPostLinkHovered = useElementHover(postLink);
26
+ </script>
27
+
28
+ <template>
29
+ <div class="HeroBanner relative">
30
+ <slot />
31
+ <Popover
32
+ v-for="{ product, position } in pointers"
33
+ :key="product.sku" class="z-20"
34
+ v-slot="{ open }"
35
+ >
36
+ <PopoverButton
37
+ class="absolute outline-none"
38
+ :style="{
39
+ top: `${position.y}%`,
40
+ left: `${position.x}%`,
41
+ }"
42
+ >
43
+ <span class="flex h-4 w-4">
44
+ <span
45
+ v-if="!open"
46
+ class="animate-ping absolute inline-flex h-full w-full
47
+ bg-primary opacity-75 rounded-full motion-reduce:hidden"
48
+ ></span>
49
+ <span
50
+ class="relative inline-flex h-4 w-4 rounded-full"
51
+ :class="open ? 'bg-primary/90' : 'bg-primary/50'"
52
+ ></span>
53
+ <Fade>
54
+ <PopoverPanel
55
+ class="absolute top-5 z-30"
56
+ :class="position.x > 55 ? 'right-0 text-right' : 'left-0 text-left'"
57
+ >
58
+ <article class="bg-white/80 rounded-sm w-60 py-2 px-3 leading-snug">
59
+ <div class="truncate text-sm mb-1">
60
+ <a
61
+ :href="product.slug"
62
+ :title="product.name"
63
+ class="underline decoration-dashed"
64
+ >
65
+ {{ product.name }}
66
+ </a>
67
+ </div>
68
+ <Prices :product="product"/>
69
+ <button class="bg-success-600 text-white hover:bg-success-700
70
+ rounded px-2 py-1 mt-1 mr-2 text-sm uppercase font-bold">
71
+ <i class="i-shopping-cart-plus"></i>
72
+ Comprar
73
+ </button>
74
+ <button class="bg-success-500 text-white hover:bg-success-700
75
+ rounded px-2 py-1 mt-1 text-sm uppercase font-bold">
76
+ <span class="text-xs">kit com</span> 3
77
+ <span class="bg-success-100 text-success-800
78
+ text-xs px-1 ml-1 rounded-full">
79
+ -5%
80
+ </span>
81
+ </button>
82
+ </article>
83
+ </PopoverPanel>
84
+ </Fade>
85
+ </span>
86
+ </PopoverButton>
87
+ </Popover>
88
+ <a
89
+ v-if="blogPost"
90
+ class="absolute bottom-0 left-0 w-full pb-3 px-7 z-10
91
+ hover:bg-white/70 transition-colors"
92
+ :href="blogPost.link"
93
+ ref="postLink"
94
+ >
95
+ <article class="prose">
96
+ <h3
97
+ class="font-brand font-normal mb-1 bg-secondary/90 rounded-sm text-white
98
+ inline-block px-3 py-2"
99
+ style="--un-prose-links: var(--c-primary)"
100
+ v-html="blogPost.title"
101
+ ></h3>
102
+ <p
103
+ class="text-secondary text-lg"
104
+ :class="isPostLinkHovered
105
+ ? 'my-3 xl:text-xl'
106
+ : 'my-1 underline decoration-2 truncate'"
107
+ v-html="blogPost.description"
108
+ ></p>
109
+ </article>
110
+ </a>
111
+ </div>
112
+ </template>
@@ -1,5 +1,6 @@
1
1
  <script setup lang="ts">
2
- import { ref, computed } from 'vue';
2
+ import { ref, computed, watch } from 'vue';
3
+ import { useTimeout, useSwipe } from '@vueuse/core';
3
4
 
4
5
  type Slide = {
5
6
  icon?: 'shipping' | 'credit-card' | 'discount' | 'cashback',
@@ -28,27 +29,55 @@ const slideIndex = ref(0);
28
29
  const slide = computed(() => {
29
30
  return slides.value[slideIndex.value];
30
31
  });
32
+ const { ready, start } = useTimeout(150, { controls: true, immediate: false });
33
+ const isToPrev = ref(false);
31
34
  const prev = () => {
32
- if (slideIndex.value) {
33
- slideIndex.value -= 1;
34
- } else {
35
- slideIndex.value = slides.value.length - 1;
36
- }
35
+ isToPrev.value = true;
36
+ start();
37
37
  };
38
38
  const next = () => {
39
- if (slideIndex.value < slides.value.length - 1) {
40
- slideIndex.value += 1;
41
- } else {
42
- slideIndex.value = 0;
43
- }
39
+ isToPrev.value = false;
40
+ start();
44
41
  };
42
+ watch(ready, (isReady) => {
43
+ if (isReady) {
44
+ if (isToPrev.value) {
45
+ if (slideIndex.value) {
46
+ slideIndex.value -= 1;
47
+ } else {
48
+ slideIndex.value = slides.value.length - 1;
49
+ }
50
+ } else if (slideIndex.value < slides.value.length - 1) {
51
+ slideIndex.value += 1;
52
+ } else {
53
+ slideIndex.value = 0;
54
+ }
55
+ }
56
+ });
57
+ const slider = ref<HTMLElement>(null);
58
+ useSwipe(slider, {
59
+ onSwipeEnd(e, direction) {
60
+ if (direction === 'LEFT') next();
61
+ else if (direction === 'RIGHT') prev();
62
+ },
63
+ });
45
64
  </script>
46
65
 
47
66
  <template>
48
- <div class="PitchBar w-full p-2 bg-white/60 leading-snug">
49
- <div class="flex justify-between items-center max-w-4xl m-auto">
50
- <button class="i-chevron-left text-2xl text-base-600" @click="prev"></button>
51
- <div class="flex items-center gap-2 lg:gap-3 text-base-800">
67
+ <div class="PitchBar w-full px-2 py-1 bg-white/70 leading-snug">
68
+ <div class="flex justify-between items-center max-w-4xl m-auto" ref="slider">
69
+ <button
70
+ class="i-chevron-left text-2xl p-4 text-base-600 hover:text-base-800"
71
+ @click="prev"
72
+ ></button>
73
+ <div
74
+ class="flex items-center gap-2 lg:gap-3 text-base-800
75
+ transition-transform duration-300"
76
+ :class="ready ? null : {
77
+ 'motion-safe:translate-x-1/3': !isToPrev,
78
+ 'motion-safe:-translate-x-1/3': isToPrev,
79
+ }"
80
+ >
52
81
  <span v-if="slide.icon" class="text-2xl">
53
82
  <i v-if="slide.icon === 'shipping'" class="i-truck-delivery"></i>
54
83
  <i v-else-if="slide.icon === 'credit-card'" class="i-credit-card"></i>
@@ -59,7 +88,10 @@ const next = () => {
59
88
  <strong v-if="slide.title" v-html="slide.title" class="uppercase"></strong>
60
89
  <span v-html="slide.html"></span>
61
90
  </div>
62
- <button class="i-chevron-right text-2xl text-base-600" @click="next"></button>
91
+ <button
92
+ class="i-chevron-right text-2xl p-4 text-base-600 hover:text-base-800"
93
+ @click="next"
94
+ ></button>
63
95
  </div>
64
96
  </div>
65
97
  </template>
@@ -7,7 +7,7 @@ import {
7
7
  toRefs,
8
8
  onMounted,
9
9
  } from 'vue';
10
- import { useWindowScroll } from '@vueuse/core';
10
+ import { promiseTimeout, useTimeout, useWindowScroll } from '@vueuse/core';
11
11
 
12
12
  export interface Props {
13
13
  logo?: ImgHTMLAttributes;
@@ -18,30 +18,51 @@ const props = withDefaults(defineProps<Props>(), {
18
18
  logoAltHeading: 'h2',
19
19
  });
20
20
  const { logo } = toRefs(props);
21
- const { y } = useWindowScroll();
22
21
  const header = ref<HTMLElement | null>(null);
23
- const logoImg = ref<HTMLElement | null>(null);
24
- let height: number = (Number(logo.value.height) || 0) + 20;
25
- onMounted(() => {
26
- logoImg.value.onload = () => {
27
- height = header.value.offsetHeight;
28
- };
22
+ const logoImg = ref<HTMLImageElement | null>(null);
23
+ const { ready, start } = useTimeout(100, { controls: true, immediate: false });
24
+ const height = ref(0);
25
+ if (!import.meta.env.SSR) {
26
+ onMounted(() => {
27
+ const fixHeight = () => {
28
+ height.value = header.value.offsetHeight;
29
+ start();
30
+ };
31
+ if (logoImg.value.complete && logoImg.value.naturalHeight !== 0) {
32
+ fixHeight();
33
+ } else {
34
+ logoImg.value.onload = fixHeight;
35
+ }
36
+ window.addEventListener('resize', fixHeight);
37
+ });
38
+ }
39
+ const { y } = useWindowScroll();
40
+ const isSticky = computed(() => ready.value && y.value > height.value * 1.5);
41
+ const transition = ref('none');
42
+ watch(isSticky, async (isSetSticky) => {
43
+ if (!isSetSticky) {
44
+ start();
45
+ transition.value = 'none';
46
+ } else {
47
+ await promiseTimeout(300);
48
+ transition.value = 'opacity var(--transition-slow), transform var(--transition)';
49
+ }
29
50
  });
30
- const isHidden = ref(false);
31
- const isSticky = computed(() => y.value > height);
51
+ const isScrollDown = ref(false);
32
52
  watch(y, (newY, oldY) => {
33
- isHidden.value = newY > 0 && newY > oldY;
53
+ isScrollDown.value = newY > 0 && newY < oldY;
34
54
  });
35
55
  </script>
36
56
 
37
57
  <template>
58
+ <div :style="isSticky ? `height: ${height}px` : null"></div>
38
59
  <header
39
- class="TheHeader z-50 sticky top-0"
40
- :class="[
41
- isHidden ? 'opacity-0 -translate-y-full' : null,
42
- isSticky ? 'bg-white/80 backdrop-blur-md shadow' : null,
43
- ]"
44
- style="transition: opacity var(--transition-slow), transform var(--transition)"
60
+ class="TheHeader z-50 top-0 overflow-auto will-change-transform"
61
+ :class="{
62
+ 'sticky bg-white/80 backdrop-blur-md shadow': isSticky,
63
+ 'opacity-0 -translate-y-full': isSticky && !isScrollDown,
64
+ }"
65
+ :style="{ transition }"
45
66
  ref="header"
46
67
  >
47
68
  <div
@@ -125,8 +146,7 @@ watch(y, (newY, oldY) => {
125
146
  <ul class="flex items-center gap-2 md:gap-3 text-sm">
126
147
  <li>
127
148
  <a
128
- class="text-on-primary font-bold uppercase rounded px-4 py-2"
129
- :class="isSticky ? 'bg-primary' : 'bg-primary/80'"
149
+ class="primary hover:bg-primary-300 font-bold uppercase rounded px-4 py-2"
130
150
  href="#"
131
151
  >
132
152
  <i class="i-chevron-down mr-1"></i> Produtos
@@ -5,6 +5,10 @@
5
5
  </a>
6
6
  <a href="#" class="text-primary-800 hover:text-primary-900">
7
7
  Promoções
8
+ <span class="relative rounded px-2 py-1 ml-1
9
+ bg-primary border-3 border-primary-bold">
10
+ Leve 5 pague 4
11
+ </span>
8
12
  </a>
9
13
  </nav>
10
14
  </template>
@@ -6,7 +6,7 @@ import '@fontsource/roboto-condensed';
6
6
  import '@fontsource/roboto-condensed/400-italic.css';
7
7
  import '@fontsource/roboto-condensed/700.css';
8
8
  import '@fontsource/roboto-condensed/700-italic.css';
9
- import InlineScripts from '~/scripts/InlineScripts.astro';
9
+ import '../assets/prices.css';
10
10
 
11
11
  export interface Props {
12
12
  pageContext: PageContext;
@@ -17,7 +17,9 @@ const { pageContext, title } = Astro.props as Props;
17
17
  ---
18
18
 
19
19
  <Base pageContext={pageContext} title={title}>
20
- <InlineScripts slot="before-head-end" />
20
+ <Fragment slot="before-head-end">
21
+ <script src="../scripts/head-scripts.ts"></script>
22
+ </Fragment>
21
23
  <slot />
22
24
  </Base>
23
25
 
@@ -37,7 +39,11 @@ body {
37
39
  overflow-x: hidden;
38
40
  background-color: var(--c-brand-light-blue);
39
41
  }
40
- a {
41
- transition: color var(--transition), background-color var(--transition);
42
+ a, button {
43
+ transition: color var(--transition), background-color var(--transition),
44
+ opacity var(--transition);
45
+ }
46
+ .prose {
47
+ max-width: 80ch;
42
48
  }
43
49
  </style>
@@ -16,7 +16,7 @@ const { pageContext, title } = Astro.props as Props;
16
16
  <slot name="header">
17
17
  <Header pageContext={pageContext} />
18
18
  </slot>
19
- <main class="container mx-auto">
19
+ <main class="container mx-auto shadow-md">
20
20
  <slot />
21
21
  </main>
22
22
  <Image
@@ -1,45 +1,172 @@
1
1
  ---
2
2
  import type { PageContext } from '@@sf/ssr-context';
3
+ import { existsSync } from 'node:fs';
4
+ import { join as joinPath } from 'node:path';
3
5
  import api from '@cloudcommerce/api';
4
- import { Image } from '@astrojs/image/components';
6
+ import { Picture } from '@astrojs/image/components';
5
7
  import PitchBar from '@@components/PitchBar.vue';
8
+ import HeroBanner from '@@components/HeroBanner.vue';
9
+ import CategoriesGrid from '@@components/CategoriesGrid.vue';
10
+ import CategoriesSlider from '@@components/CategoriesSlider.vue';
11
+ import BrandTestimonials from '@@components/BrandTestimonials.vue';
12
+ import AboutUs from '@@components/AboutUs.astro';
6
13
 
7
14
  export interface Props {
8
15
  pageContext: PageContext;
9
16
  }
10
17
 
11
- const products = (await api.get('products')).data.result;
18
+ const { pageContext: { apiState } } = Astro.props as Props;
19
+
20
+ const products = (await api.get('products?fields=name,slug,sku,price,base_price'))
21
+ .data.result;
22
+ const heroBanners = [{
23
+ src: '/img/uploads/hero-acai-granola.jpg',
24
+ alt: 'Açaí com morango, banana, manga e granola Tia Sônia',
25
+ pointers: [{
26
+ product: products.find(({ sku }) => sku === 'PA285'),
27
+ position: { x: 20, y: 35 },
28
+ }],
29
+ blogPost: {
30
+ title: 'Granola: 10 Benefícios para sua Saúde',
31
+ link: '/posts/10-beneficios-da-granola-para-a-sua-saude-2020-05-22',
32
+ description: `A granola é uma opção na alimentação saudável que acompanha a dieta
33
+ de pessoas ao redor de todo o mundo, saiba mais sobre o assunto em nosso blog!`,
34
+ }
35
+ }, {
36
+ src: '/img/uploads/hero-piquenique-snack-cookies.jpg',
37
+ alt: 'Piquenique com frutas, pães com pasta de amendoim, snacks e cookies Tia Sônia',
38
+ pointers: [{
39
+ product: products.find(({ sku }) => sku === 'PA588'),
40
+ position: { x: 21, y: 50 },
41
+ }, {
42
+ product: products.find(({ sku }) => sku === 'PA358'),
43
+ position: { x: 24, y: 80 },
44
+ }, {
45
+ product: products.find(({ sku }) => sku === 'PA352'),
46
+ position: { x: 84, y: 20 },
47
+ }, {
48
+ product: products.find(({ sku }) => sku === 'PA291'),
49
+ position: { x: 74, y: 46 },
50
+ }],
51
+ }];
52
+
53
+ const categoriesOnGrid = apiState.categories.filter(({ parent }) => {
54
+ return parent?.slug?.includes('estilos');
55
+ });
56
+ const mainCategories = apiState.categories
57
+ .filter(({ slug, parent }) => {
58
+ return slug && !parent && !/(todos|kits|parceir|estilos)/.test(slug);
59
+ })
60
+ .map((category) => {
61
+ const localIconSrc = `/img/uploads/categoria-${category.slug}.webp`;
62
+ if (existsSync(joinPath(process.env.STOREFRONT_BASE_DIR, 'public', localIconSrc))) {
63
+ if (!category.icon) {
64
+ category.icon = { url: localIconSrc };
65
+ } else {
66
+ category.icon.url = localIconSrc;
67
+ }
68
+ }
69
+ return category;
70
+ });
12
71
  ---
13
72
 
14
- <section class="relative">
15
- <PitchBar class="absolute top-0 left-0" client:idle />
16
- <div class="grid grid-cols-2">
17
- <Image
18
- src="/img/uploads/acai-com-granola.jpg"
19
- alt="Açaí com morango, banana, manga e granola Tia Sônia"
20
- format={'webp'}
21
- quality={75}
22
- width={1080}
23
- height={1080}
24
- />
25
- <Image
26
- src="/img/uploads/cafe-com-tapioca-e-aveia.jpg"
27
- alt="Açaí com morango, banana, manga e granola Tia Sônia"
28
- format={'webp'}
73
+ <section id="hero" class="relative">
74
+ <PitchBar class="absolute top-0 left-0 z-10" client:load />
75
+ <div class="bg-white grid grid-cols-2">
76
+ {heroBanners.map(({ src, alt, pointers, blogPost }, i) => (
77
+ <HeroBanner client:visible {pointers} {blogPost}>
78
+ <Picture
79
+ src={src}
80
+ alt={alt}
81
+ widths={[600, 1080]}
82
+ sizes="(max-width: 599.98px) 600px, 1080px"
83
+ aspectRatio={1}
84
+ quality={75}
85
+ formats={['webp']}
86
+ fetchpriority={i === 0 ? 'high' : 'auto'}
87
+ />
88
+ </HeroBanner>
89
+ ))}
90
+ </div>
91
+ </section>
92
+ <section id="categories" class="bg-base-50 p-7">
93
+ <h4 class="text-center uppercase font-bold text-base text-primary-800 mb-3">
94
+ Para seu estilo de alimentação
95
+ </h4>
96
+ <CategoriesGrid categories={categoriesOnGrid} />
97
+ <CategoriesSlider categories={mainCategories} client:visible />
98
+ </section>
99
+ <section
100
+ id="product"
101
+ style="background-color: var(--c-brand-light-blue);"
102
+ class="py-8 lg:py-14"
103
+ >
104
+ <article class="grid md:grid-cols-2 gap-4 px-8 py-4">
105
+ <Picture
106
+ src="/img/uploads/granola-tradicional-lata.webp"
107
+ alt="Granola Tradicional Tia Sônia - Lata edição especial"
108
+ widths={[600, 1000]}
109
+ sizes="(max-width: 599.98px) 600px, 1000px"
110
+ aspectRatio={1}
29
111
  quality={75}
30
- width={1080}
31
- height={1080}
112
+ formats={['webp']}
32
113
  />
33
- </div>
114
+ <div class="md:pt-5 lg:pt-8 prose">
115
+ <div class="flex">
116
+ <img
117
+ src="/img/uploads/selo-organico-120-80.webp"
118
+ width="80"
119
+ height="53.333"
120
+ loading="lazy"
121
+ class="mr-4"
122
+ />
123
+ <img
124
+ src="/img/uploads/selo-vegano-120-80.webp"
125
+ width="80"
126
+ height="53.333"
127
+ loading="lazy"
128
+ />
129
+ <img
130
+ src="/img/uploads/selo-usda-120-80.webp"
131
+ width="80"
132
+ height="53.333"
133
+ loading="lazy"
134
+ />
135
+ </div>
136
+ <h3 class="font-brand font-normal text-2xl md:text-4xl text-base-100 mb-8">
137
+ Granola Tradicional
138
+ </h3>
139
+ <p class="grid grid-cols-2 gap-3 whitespace-nowrap
140
+ uppercase font-bold text-sm text-base-300">
141
+ <span><i class="i-square-rounded-check"></i> Saúde e muito sabor</span>
142
+ <span><i class="i-health-recognition"></i> Produto vegano</span>
143
+ <span><i class="i-leaf"></i> Cultivado organicamente</span>
144
+ <span><i class="i-checklist"></i> Ingredientes selecionados</span>
145
+ </p>
146
+ <ul class="grid grid-cols-2 gap-x-3 list-none p-0 text-white">
147
+ <li>Flocos de aveia</li>
148
+ <li>Rapadura</li>
149
+ <li>Coco</li>
150
+ <li>Tapioca</li>
151
+ <li>Uva-passa</li>
152
+ <li>Castanha de caju</li>
153
+ <li>Gérmen de trigo</li>
154
+ <li>Melaço de cana</li>
155
+ <li>Manteiga</li>
156
+ <li>Gergelim</li>
157
+ <li>Sal do Himalaia</li>
158
+ </ul>
159
+ <button class="bg-primary text-secondary hover:secondary
160
+ rounded uppercase font-bold text-lg px-6 py-3 mt-4">
161
+ <i class="i-shopping-cart-plus mr-2"></i>
162
+ Comprar
163
+ </button>
164
+ </div>
165
+ </article>
166
+ </section>
167
+ <section id="testimonials" class="bg-white py-9">
168
+ <BrandTestimonials client:visible />
169
+ </section>
170
+ <section id="about">
171
+ <AboutUs />
34
172
  </section>
35
- <article class="bg-white p-6">
36
- <h1 class="font-brand">
37
- Welcome to
38
- <span class="text-secondary font-sans font-bold">FEITO NA BAHIA</span>
39
- </h1>
40
- <ul role="list" class="mt-3 fs-20">
41
- {products.map((product) => <li>
42
- <a href={`/${product.slug}`}>{product.sku}</a>
43
- </li>)}
44
- </ul>
45
- </article>
@@ -0,0 +1,15 @@
1
+ import modulesInfoPreset from './modules-info-preset';
2
+
3
+ if (window.storefront) {
4
+ window.storefront.modulesInfoPreset = modulesInfoPreset;
5
+ }
6
+
7
+ /* eslint-disable quotes, comma-dangle */
8
+ window.firebaseConfig = {
9
+ apiKey: "AIzaSyDZ5QPJaLZM1bxEJyGbyK1weoBZ1TiLgFc",
10
+ authDomain: "ecom2-tiasonia.firebaseapp.com",
11
+ projectId: "ecom2-tiasonia",
12
+ storageBucket: "ecom2-tiasonia.appspot.com",
13
+ messagingSenderId: "895718193792",
14
+ appId: "1:895718193792:web:1d4fd74466248202994465"
15
+ };