cloudcommerce 0.22.4 → 0.23.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.
- package/CHANGELOG.md +43 -0
- package/ecomplus-stores/barra-doce/.eslintrc.cjs +1 -1
- package/ecomplus-stores/barra-doce/functions/many/package.json +3 -3
- package/ecomplus-stores/barra-doce/functions/ssr/.eslintrc.cjs +1 -1
- package/ecomplus-stores/barra-doce/functions/ssr/package.json +6 -6
- package/ecomplus-stores/barra-doce/functions/ssr/src/components/AccountMenu.vue +1 -1
- package/ecomplus-stores/barra-doce/functions/ssr/src/components/ProductCard.vue +1 -4
- package/ecomplus-stores/barra-doce/functions/ssr/src/components/ShopSidenav.vue +1 -1
- package/ecomplus-stores/barra-doce/functions/ssr/src/main/Home.astro +18 -10
- package/ecomplus-stores/barra-doce/functions/with-apps/package.json +3 -3
- package/ecomplus-stores/barra-doce/package.json +4 -1
- package/ecomplus-stores/iluminim/.ecomplus.cd.json +3 -3
- package/ecomplus-stores/iluminim/.eslintrc.cjs +1 -1
- package/ecomplus-stores/iluminim/functions/many/package.json +3 -3
- package/ecomplus-stores/iluminim/functions/ssr/.eslintrc.cjs +1 -1
- package/ecomplus-stores/iluminim/functions/ssr/package.json +6 -6
- package/ecomplus-stores/iluminim/functions/ssr/src/components/AccountMenu.vue +1 -1
- package/ecomplus-stores/iluminim/functions/ssr/src/components/ProductCard.vue +5 -5
- package/ecomplus-stores/iluminim/functions/ssr/src/components/ShopSidenav.vue +1 -1
- package/ecomplus-stores/iluminim/functions/with-apps/package.json +3 -3
- package/ecomplus-stores/iluminim/package.json +4 -1
- package/package.json +4 -4
- package/packages/api/package.json +1 -1
- package/packages/api/types/carts.d.ts +8 -0
- package/packages/api/types/orders.d.ts +8 -0
- package/packages/apps/affilate-program/package.json +1 -1
- package/packages/apps/correios/package.json +1 -1
- package/packages/apps/custom-payment/package.json +1 -1
- package/packages/apps/custom-shipping/package.json +1 -1
- package/packages/apps/datafrete/package.json +1 -1
- package/packages/apps/discounts/package.json +1 -1
- package/packages/apps/emails/package.json +1 -1
- package/packages/apps/fb-conversions/package.json +1 -1
- package/packages/apps/flash-courier/package.json +1 -1
- package/packages/apps/frenet/package.json +1 -1
- package/packages/apps/galaxpay/package.json +1 -1
- package/packages/apps/google-analytics/package.json +1 -1
- package/packages/apps/jadlog/package.json +1 -1
- package/packages/apps/loyalty-points/package.json +1 -1
- package/packages/apps/melhor-envio/package.json +1 -1
- package/packages/apps/mercadopago/package.json +1 -1
- package/packages/apps/pagarme/package.json +1 -1
- package/packages/apps/paghiper/package.json +1 -1
- package/packages/apps/pix/package.json +1 -1
- package/packages/apps/tiny-erp/package.json +1 -1
- package/packages/apps/webhooks/package.json +1 -1
- package/packages/cli/lib/build.js +1 -1
- package/packages/cli/package.json +1 -1
- package/packages/cli/src/build.ts +1 -1
- package/packages/config/package.json +1 -1
- package/packages/emails/package.json +1 -1
- package/packages/eslint/package.json +3 -3
- package/packages/events/package.json +1 -1
- package/packages/feeds/package.json +1 -1
- package/packages/firebase/package.json +1 -1
- package/packages/i18n/lib/en_us/i19minus.txt +1 -0
- package/packages/i18n/lib/en_us/i19plus.txt +1 -0
- package/packages/i18n/lib/en_us.d.ts +2 -0
- package/packages/i18n/lib/en_us.js +2 -0
- package/packages/i18n/lib/en_us.js.map +1 -1
- package/packages/i18n/lib/pt_br/i19minus.txt +1 -0
- package/packages/i18n/lib/pt_br/i19plus.txt +1 -0
- package/packages/i18n/lib/pt_br.d.ts +2 -0
- package/packages/i18n/lib/pt_br.js +2 -0
- package/packages/i18n/lib/pt_br.js.map +1 -1
- package/packages/i18n/package.json +1 -1
- package/packages/i18n/src/en_us.ts +2 -0
- package/packages/i18n/src/pt_br.ts +2 -0
- package/packages/modules/package.json +1 -1
- package/packages/passport/package.json +1 -1
- package/packages/ssr/cloudflare/README.md +3 -0
- package/packages/ssr/cloudflare/swr-worker.js +102 -0
- package/packages/ssr/lib/firebase/serve-storefront.js +0 -1
- package/packages/ssr/lib/firebase/serve-storefront.js.map +1 -1
- package/packages/ssr/package.json +6 -4
- package/packages/ssr/src/cloudflare/swr-worker.ts +120 -0
- package/packages/ssr/src/cloudflare/tsconfig.json +8 -0
- package/packages/ssr/src/firebase/serve-storefront.ts +0 -1
- package/packages/ssr/tsconfig.json +2 -1
- package/packages/storefront/config/storefront.cms.js +1 -1
- package/packages/storefront/config/storefront.tailwind.cjs +1 -0
- package/packages/storefront/dist/client/_astro/Carousel.63d511ab.js +1 -0
- package/packages/storefront/dist/client/_astro/{HeroSlider.8a040a33.js → HeroSlider.8d2ea532.js} +1 -1
- package/packages/storefront/dist/client/_astro/{PitchBar.ab0c501e.js → PitchBar.c2a2ad79.js} +1 -1
- package/packages/storefront/dist/client/_astro/Prices.8572765c.js +1 -0
- package/packages/storefront/dist/client/_astro/ProductShelf.4a105932.js +1 -0
- package/packages/storefront/dist/client/_astro/ShopHeader.7ecb7597.js +4 -0
- package/packages/storefront/dist/client/_astro/{_...slug_.c13e0486.css → _...slug_.07c1fa58.css} +1 -1
- package/packages/storefront/dist/client/_astro/_plugin-vue_export-helper.48e557ba.js +1 -0
- package/packages/storefront/dist/client/_astro/client.9dbf6b61.js +1 -0
- package/packages/storefront/dist/client/_astro/{img.abbe849f.js → img.7def76a1.js} +1 -1
- package/packages/storefront/dist/client/_astro/index.c0c35ead.js +1 -0
- package/packages/storefront/dist/client/sw.js +1 -1
- package/packages/storefront/dist/server/chunks/{_...1b951f6c.mjs → _...d3f15170.mjs} +3 -3
- package/packages/storefront/dist/server/chunks/{account@_@astro.f6aec583.mjs → account@_@astro.38a725e7.mjs} +3 -3
- package/packages/storefront/dist/server/chunks/{astro.b875de26.mjs → astro.6adaff02.mjs} +296 -1146
- package/packages/storefront/dist/server/chunks/{endpoint@_@js.5834ad4e.mjs → endpoint@_@js.a92a4584.mjs} +3 -3
- package/packages/storefront/dist/server/chunks/{fallback@_@astro.069ddb54.mjs → fallback@_@astro.4e98328e.mjs} +3 -3
- package/packages/storefront/dist/server/chunks/{index@_@astro.37e61ebe.mjs → index@_@astro.2dda826c.mjs} +3 -3
- package/packages/storefront/dist/server/chunks/{index@_@astro.485287a1.mjs → index@_@astro.db07fb09.mjs} +3 -3
- package/packages/storefront/dist/server/chunks/pages/{_...slug_.astro.95bf4c3b.mjs → _...slug_.astro.88866aae.mjs} +812 -150
- package/packages/storefront/dist/server/chunks/pages/{account.astro.4b8c2471.mjs → account.astro.53400a42.mjs} +1 -1
- package/packages/storefront/dist/server/chunks/pages/{endpoint.js.bd1232b7.mjs → endpoint.js.a11da4ad.mjs} +1 -1
- package/packages/storefront/dist/server/chunks/pages/{fallback.astro.b52164bc.mjs → fallback.astro.c1fd06ab.mjs} +2 -2
- package/packages/storefront/dist/server/chunks/pages/{index.astro.98167846.mjs → index.astro.c45cc893.mjs} +18 -344
- package/packages/storefront/dist/server/entry.mjs +31 -23
- package/packages/storefront/dist/server/renderers.mjs +2 -2
- package/packages/storefront/package.json +10 -10
- package/packages/storefront/src/helpers/sf-utils.ts +12 -0
- package/packages/storefront/src/lib/components/Carousel.vue +17 -8
- package/packages/storefront/src/lib/components/CarouselControl.vue +1 -1
- package/packages/storefront/src/lib/components/CheckoutLink.vue +23 -0
- package/packages/storefront/src/lib/components/Drawer.vue +1 -1
- package/packages/storefront/src/lib/components/QuantitySelector.vue +107 -0
- package/packages/storefront/src/lib/components/QuantitySelectorControl.vue +35 -0
- package/packages/storefront/src/lib/components/SocialNetworkIcon.vue +1 -1
- package/packages/storefront/src/lib/components/SocialNetworkLink.vue +1 -3
- package/packages/storefront/src/lib/composables/use-cart-item.ts +52 -0
- package/packages/storefront/src/lib/composables/use-sticky-header.ts +14 -2
- package/packages/storefront/src/lib/sf-lib.ts +7 -0
- package/packages/storefront/src/lib/state/customer-session.ts +2 -2
- package/packages/storefront/src/lib/state/modules-info.ts +1 -1
- package/packages/storefront/src/lib/state/shopping-cart/parse-product.ts +23 -21
- package/packages/storefront/src/lib/state/shopping-cart.ts +13 -4
- package/packages/types/package.json +1 -1
- package/packages/storefront/dist/client/_astro/Carousel.8af656b5.js +0 -1
- package/packages/storefront/dist/client/_astro/ProductShelf.6351b57b.js +0 -1
- package/packages/storefront/dist/client/_astro/ShopHeader.cfab20c7.js +0 -4
- package/packages/storefront/dist/client/_astro/_plugin-vue_export-helper.4cb7dd76.js +0 -1
- package/packages/storefront/dist/client/_astro/api.4984c5be.js +0 -1
- package/packages/storefront/dist/client/_astro/client.0fb6b44e.js +0 -1
- package/packages/storefront/dist/client/_astro/index.7eac5494.js +0 -1
- package/packages/storefront/src/helpers/idle-callback.ts +0 -9
- package/packages/storefront/src/lib/components/_injection-keys.ts +0 -11
- /package/packages/storefront/src/{lib → helpers}/browser-env.ts +0 -0
- /package/packages/storefront/src/{lib → helpers}/server-data.ts +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudcommerce/storefront",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.23.1",
|
|
5
5
|
"description": "E-Com Plus Cloud Commerce storefront with Astro",
|
|
6
6
|
"bin": {
|
|
7
7
|
"storefront": "./scripts/build-prod.sh"
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"prepare-monorepo": "bash scripts/prepare-monorepo.sh"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@astrojs/image": "0.17.
|
|
33
|
-
"@astrojs/node": "5.3.
|
|
32
|
+
"@astrojs/image": "0.17.3",
|
|
33
|
+
"@astrojs/node": "5.3.2",
|
|
34
34
|
"@astrojs/vue": "2.2.1",
|
|
35
35
|
"@cloudcommerce/api": "workspace:*",
|
|
36
36
|
"@cloudcommerce/config": "workspace:*",
|
|
@@ -38,12 +38,12 @@
|
|
|
38
38
|
"@ecomplus/utils": "1.5.0-rc.5",
|
|
39
39
|
"@fastify/deepmerge": "^1.3.0",
|
|
40
40
|
"@headlessui/vue": "^1.7.15",
|
|
41
|
-
"@iconify-json/fa6-brands": "^1.1.
|
|
42
|
-
"@iconify-json/heroicons": "^1.1.
|
|
43
|
-
"@iconify-json/logos": "^1.1.
|
|
41
|
+
"@iconify-json/fa6-brands": "^1.1.13",
|
|
42
|
+
"@iconify-json/heroicons": "^1.1.12",
|
|
43
|
+
"@iconify-json/logos": "^1.1.34",
|
|
44
44
|
"@vite-pwa/astro": "^0.1.1",
|
|
45
45
|
"@vueuse/core": "10.3.0",
|
|
46
|
-
"astro": "2.
|
|
46
|
+
"astro": "2.10.2",
|
|
47
47
|
"chroma-js": "^2.4.2",
|
|
48
48
|
"dotenv": "^16.3.1",
|
|
49
49
|
"firebase": "^10.1.0",
|
|
@@ -52,13 +52,13 @@
|
|
|
52
52
|
"semver": "^7.5.4",
|
|
53
53
|
"sharp": "^0.32.4",
|
|
54
54
|
"tailwindcss": "^3.3.3",
|
|
55
|
-
"unocss": "^0.54.
|
|
56
|
-
"vite": "^4.4.
|
|
55
|
+
"unocss": "^0.54.2",
|
|
56
|
+
"vite": "^4.4.9",
|
|
57
57
|
"vite-plugin-pwa": "^0.16.4",
|
|
58
58
|
"vue": "^3.3.4"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
|
-
"@cloudcommerce/eslint": "workspace
|
|
61
|
+
"@cloudcommerce/eslint": "workspace:*",
|
|
62
62
|
"@cloudcommerce/types": "workspace:*"
|
|
63
63
|
}
|
|
64
64
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
let id = -1;
|
|
2
|
+
|
|
3
|
+
/* eslint-disable-next-line no-plusplus */
|
|
4
|
+
export const useId = () => String(++id);
|
|
5
|
+
|
|
6
|
+
export const requestIdleCallback = (fn: (...args: any[]) => any, fallbackMs = 300) => {
|
|
7
|
+
if (typeof window.requestIdleCallback === 'function') {
|
|
8
|
+
window.requestIdleCallback(fn);
|
|
9
|
+
} else {
|
|
10
|
+
setTimeout(fn, fallbackMs);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
<script
|
|
2
|
-
/* REFERENCE: https://github.com/bartdominiak/vue-snap */
|
|
1
|
+
<script lang="ts">
|
|
3
2
|
import {
|
|
3
|
+
type Ref,
|
|
4
|
+
type InjectionKey,
|
|
4
5
|
onMounted,
|
|
5
6
|
onBeforeUnmount,
|
|
6
7
|
ref,
|
|
@@ -11,9 +12,20 @@ import {
|
|
|
11
12
|
provide,
|
|
12
13
|
} from 'vue';
|
|
13
14
|
import { useDebounceFn, useElementHover, useScroll } from '@vueuse/core';
|
|
14
|
-
import { carouselKey } from '@@sf/components/_injection-keys';
|
|
15
15
|
import CarouselControl from '@@sf/components/CarouselControl.vue';
|
|
16
16
|
|
|
17
|
+
export type CarouselInject = {
|
|
18
|
+
autoplay: Ref<number | undefined>,
|
|
19
|
+
changeSlide: (direction: number, isPageScroll?: boolean) => void,
|
|
20
|
+
isBoundLeft: Ref<boolean>,
|
|
21
|
+
isBoundRight: Ref<boolean>,
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export const carouselKey = Symbol('carousel') as InjectionKey<CarouselInject>;
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<script setup lang="ts">
|
|
28
|
+
/* REFERENCE: https://github.com/bartdominiak/vue-snap */
|
|
17
29
|
export interface Props {
|
|
18
30
|
as?: string;
|
|
19
31
|
modelValue?: number;
|
|
@@ -27,10 +39,10 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
27
39
|
const emit = defineEmits([
|
|
28
40
|
'update:modelValue',
|
|
29
41
|
]);
|
|
30
|
-
const currentIndex = ref(
|
|
42
|
+
const currentIndex = ref(0);
|
|
31
43
|
watch(toRef(props, 'modelValue'), (modelValue) => {
|
|
32
44
|
currentIndex.value = modelValue - 1;
|
|
33
|
-
});
|
|
45
|
+
}, { immediate: true });
|
|
34
46
|
watch(currentIndex, (current, previous) => {
|
|
35
47
|
if (current !== previous) {
|
|
36
48
|
emit('update:modelValue', current + 1);
|
|
@@ -119,9 +131,6 @@ const changeSlide = (direction: number, isPageScroll: boolean = true) => {
|
|
|
119
131
|
direction = direction > 0 ? pageStep : -pageStep;
|
|
120
132
|
}
|
|
121
133
|
}
|
|
122
|
-
if (!props.autoplay) {
|
|
123
|
-
console.log({ direction }, currentIndex.value, slidesWidth.value.length);
|
|
124
|
-
}
|
|
125
134
|
const nextOffsetLeft = calcNextOffsetLeft(direction);
|
|
126
135
|
wrapper.value?.scrollTo({ left: nextOffsetLeft, behavior: 'smooth' });
|
|
127
136
|
restartAutoplay();
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { inject } from 'vue';
|
|
3
|
-
import { type CarouselInject, carouselKey } from '@@sf/components/
|
|
3
|
+
import { type CarouselInject, carouselKey } from '@@sf/components/Carousel.vue';
|
|
4
4
|
|
|
5
5
|
export interface Props {
|
|
6
6
|
isPrev?: boolean;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed } from 'vue';
|
|
3
|
+
|
|
4
|
+
export interface Props {
|
|
5
|
+
to?: 'cart' | 'checkout';
|
|
6
|
+
cartUrl?: string;
|
|
7
|
+
checkoutUrl?: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
11
|
+
to: 'cart',
|
|
12
|
+
cartUrl: globalThis.$storefront.settings.cart_url || '/app/#/cart',
|
|
13
|
+
checkoutUrl: globalThis.$storefront.settings.checkout_url || '/app/#/checkout',
|
|
14
|
+
});
|
|
15
|
+
const href = computed(() => {
|
|
16
|
+
if (props.to === 'cart') return props.cartUrl;
|
|
17
|
+
return props.checkoutUrl;
|
|
18
|
+
});
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<template>
|
|
22
|
+
<a :href="href"><slot /></a>
|
|
23
|
+
</template>
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import {
|
|
3
|
+
type Ref,
|
|
4
|
+
type WritableComputedRef,
|
|
5
|
+
type InjectionKey,
|
|
6
|
+
ref,
|
|
7
|
+
computed,
|
|
8
|
+
provide,
|
|
9
|
+
} from 'vue';
|
|
10
|
+
import { useId } from '@@sf/sf-lib';
|
|
11
|
+
import QuantitySelectorControl from '@@sf/components/QuantitySelectorControl.vue';
|
|
12
|
+
|
|
13
|
+
export type QuantitySelectorInject = {
|
|
14
|
+
value: WritableComputedRef<number>,
|
|
15
|
+
isBoundMin: Ref<boolean>,
|
|
16
|
+
isBoundMax: Ref<boolean>,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const quantitySelectorKey = Symbol('quantitySelector') as
|
|
20
|
+
InjectionKey<QuantitySelectorInject>;
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<script setup lang="ts">
|
|
24
|
+
export interface Props {
|
|
25
|
+
modelValue?: number;
|
|
26
|
+
min?: number;
|
|
27
|
+
max?: number;
|
|
28
|
+
step?: number;
|
|
29
|
+
disabled?: boolean;
|
|
30
|
+
readonly?: boolean;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
34
|
+
modelValue: 1,
|
|
35
|
+
min: 1,
|
|
36
|
+
});
|
|
37
|
+
const emit = defineEmits<{
|
|
38
|
+
'update:modelValue': [value: number]
|
|
39
|
+
}>();
|
|
40
|
+
const input = ref<HTMLInputElement | null>(null);
|
|
41
|
+
const inputId = `NInput${useId()}`;
|
|
42
|
+
const value = computed({
|
|
43
|
+
get() {
|
|
44
|
+
return props.modelValue;
|
|
45
|
+
},
|
|
46
|
+
set(_value) {
|
|
47
|
+
if (_value < props.min) {
|
|
48
|
+
_value = props.min;
|
|
49
|
+
(input.value as HTMLInputElement).value = `${_value}`;
|
|
50
|
+
}
|
|
51
|
+
if (props.max && _value > props.max) {
|
|
52
|
+
_value = props.max;
|
|
53
|
+
(input.value as HTMLInputElement).value = `${_value}`;
|
|
54
|
+
}
|
|
55
|
+
emit('update:modelValue', _value);
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
const isBoundMin = computed(() => {
|
|
59
|
+
return props.min >= value.value;
|
|
60
|
+
});
|
|
61
|
+
const isBoundMax = computed(() => {
|
|
62
|
+
return (props.max as number) <= value.value;
|
|
63
|
+
});
|
|
64
|
+
provide(quantitySelectorKey, {
|
|
65
|
+
value,
|
|
66
|
+
isBoundMin,
|
|
67
|
+
isBoundMax,
|
|
68
|
+
});
|
|
69
|
+
</script>
|
|
70
|
+
|
|
71
|
+
<template>
|
|
72
|
+
<div data-quantity-selector>
|
|
73
|
+
<slot name="label" v-bind="{ inputId, value }">
|
|
74
|
+
<label :for="inputId" class="sr-only">
|
|
75
|
+
{{ $t.i19quantity }}
|
|
76
|
+
</label>
|
|
77
|
+
</slot>
|
|
78
|
+
<div class="flex items-center">
|
|
79
|
+
<input
|
|
80
|
+
ref="input"
|
|
81
|
+
type="number"
|
|
82
|
+
:id="inputId"
|
|
83
|
+
v-model="value"
|
|
84
|
+
:min="min"
|
|
85
|
+
:max="max"
|
|
86
|
+
:step="step"
|
|
87
|
+
:disabled="disabled"
|
|
88
|
+
:readonly="readonly"
|
|
89
|
+
class="h-12 w-14 px-2 text-lg border-transparent text-center
|
|
90
|
+
[-moz-appearance:_textfield] [&::-webkit-outer-spin-button]:m-0
|
|
91
|
+
[&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:m-0
|
|
92
|
+
[&::-webkit-inner-spin-button]:appearance-none"
|
|
93
|
+
/>
|
|
94
|
+
<slot
|
|
95
|
+
name="controls"
|
|
96
|
+
v-bind="{ value, isBoundMin, isBoundMax }"
|
|
97
|
+
>
|
|
98
|
+
<QuantitySelectorControl is-minus class="order-first">
|
|
99
|
+
<slot name="minus" />
|
|
100
|
+
</QuantitySelectorControl>
|
|
101
|
+
<QuantitySelectorControl class="order-last">
|
|
102
|
+
<slot name="plus" />
|
|
103
|
+
</QuantitySelectorControl>
|
|
104
|
+
</slot>
|
|
105
|
+
</div>
|
|
106
|
+
</div>
|
|
107
|
+
</template>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { inject } from 'vue';
|
|
3
|
+
import {
|
|
4
|
+
type QuantitySelectorInject,
|
|
5
|
+
quantitySelectorKey,
|
|
6
|
+
} from '@@sf/components/QuantitySelector.vue';
|
|
7
|
+
|
|
8
|
+
export interface Props {
|
|
9
|
+
isMinus?: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
defineProps<Props>();
|
|
13
|
+
const {
|
|
14
|
+
value,
|
|
15
|
+
isBoundMin,
|
|
16
|
+
isBoundMax,
|
|
17
|
+
} = inject(quantitySelectorKey) as QuantitySelectorInject;
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<template>
|
|
21
|
+
<button
|
|
22
|
+
type="button"
|
|
23
|
+
class="w-10 h-12 text-xl leading-12 enabled:text-primary
|
|
24
|
+
enabled:hover:bg-primary-100/70 disabled:opacity-40"
|
|
25
|
+
:data-quantity-selector-control="isMinus ? 'minus' : 'plus'"
|
|
26
|
+
:aria-label="isMinus ? $t.i19minus : $t.i19plus"
|
|
27
|
+
:disabled="isMinus ? isBoundMin : isBoundMax"
|
|
28
|
+
@click.prevent="value += (isMinus ? -1 : 1)"
|
|
29
|
+
>
|
|
30
|
+
<slot>
|
|
31
|
+
<template v-if="isMinus">−</template>
|
|
32
|
+
<template v-else>+</template>
|
|
33
|
+
</slot>
|
|
34
|
+
</button>
|
|
35
|
+
</template>
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import type
|
|
2
|
+
import { type NetworkName, isMobile, socialNetworks } from '@@sf/sf-lib';
|
|
3
3
|
import { computed } from 'vue';
|
|
4
|
-
import { isMobile } from '@@sf/browser-env';
|
|
5
|
-
import { socialNetworks } from '@@sf/server-data';
|
|
6
4
|
import SocialNetworkIcon from '@@sf/components/SocialNetworkIcon.vue';
|
|
7
5
|
|
|
8
6
|
export interface Props {
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Carts } from '@cloudcommerce/api/types';
|
|
2
|
+
import type { ProductItem } from '@@sf/composables/use-product-card';
|
|
3
|
+
import { computed } from 'vue';
|
|
4
|
+
import { name as getName, img as getImg } from '@ecomplus/utils';
|
|
5
|
+
import { parseProduct } from '@@sf/state/shopping-cart';
|
|
6
|
+
|
|
7
|
+
export type CartItem = Carts['items'][0];
|
|
8
|
+
|
|
9
|
+
export type Props = {
|
|
10
|
+
item?: CartItem;
|
|
11
|
+
product?: ProductItem;
|
|
12
|
+
pictureSize?: string;
|
|
13
|
+
} & ({ item: CartItem } | { product: ProductItem });
|
|
14
|
+
|
|
15
|
+
export const useCartItem = (props: Props) => {
|
|
16
|
+
const parsedItem = computed(() => {
|
|
17
|
+
return !props.item && props.product
|
|
18
|
+
? parseProduct(props.product)
|
|
19
|
+
: null;
|
|
20
|
+
});
|
|
21
|
+
const cartItem = computed(() => {
|
|
22
|
+
return (props.item || parsedItem.value) as CartItem;
|
|
23
|
+
});
|
|
24
|
+
const title = computed(() => {
|
|
25
|
+
return getName(cartItem.value);
|
|
26
|
+
});
|
|
27
|
+
const link = computed(() => {
|
|
28
|
+
const { slug } = cartItem.value;
|
|
29
|
+
if (typeof slug === 'string') {
|
|
30
|
+
return `/${slug}`;
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
});
|
|
34
|
+
const image = computed(() => {
|
|
35
|
+
if (cartItem.value.picture) {
|
|
36
|
+
return getImg(cartItem.value.picture, undefined, props.pictureSize || 'small');
|
|
37
|
+
}
|
|
38
|
+
return undefined;
|
|
39
|
+
});
|
|
40
|
+
const finalPrice = computed(() => {
|
|
41
|
+
return cartItem.value.final_price || cartItem.value.price;
|
|
42
|
+
});
|
|
43
|
+
return {
|
|
44
|
+
cartItem,
|
|
45
|
+
title,
|
|
46
|
+
link,
|
|
47
|
+
image,
|
|
48
|
+
finalPrice,
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export default useCartItem;
|
|
@@ -10,7 +10,9 @@ import {
|
|
|
10
10
|
useTimeout,
|
|
11
11
|
useDebounceFn,
|
|
12
12
|
useScroll,
|
|
13
|
+
watchDebounced,
|
|
13
14
|
} from '@vueuse/core';
|
|
15
|
+
import { isMobile } from '@@sf/sf-lib';
|
|
14
16
|
|
|
15
17
|
export interface Props {
|
|
16
18
|
header: Ref<HTMLElement | null>;
|
|
@@ -34,12 +36,20 @@ const useStickyHeader = (props: Props) => {
|
|
|
34
36
|
const staticHeight = ref(0);
|
|
35
37
|
const staticY = ref(0);
|
|
36
38
|
let heightDiv: HTMLElement | undefined;
|
|
37
|
-
const { y } = !import.meta.env.SSR ? useScroll(document) : { y: ref(0) };
|
|
39
|
+
const { y: _y } = !import.meta.env.SSR ? useScroll(document) : { y: ref(0) };
|
|
40
|
+
const y = ref(0);
|
|
41
|
+
watchDebounced(_y, (nextY) => {
|
|
42
|
+
y.value = nextY;
|
|
43
|
+
}, {
|
|
44
|
+
debounce: isMobile ? 150 : 50,
|
|
45
|
+
maxWait: 600,
|
|
46
|
+
});
|
|
38
47
|
const isSticky = computed(() => ready.value && y.value > staticY.value * 1.2);
|
|
39
48
|
const transition = ref('none');
|
|
40
49
|
watch(isSticky, async (_isSticky) => {
|
|
41
50
|
if (canSetStyles && header.value) {
|
|
42
|
-
header.value.style.position = _isSticky ? '
|
|
51
|
+
header.value.style.position = _isSticky ? 'fixed' : '';
|
|
52
|
+
header.value.style.width = _isSticky ? '100vw' : '';
|
|
43
53
|
}
|
|
44
54
|
if (heightDiv) {
|
|
45
55
|
heightDiv.style.height = _isSticky ? `${staticHeight.value}px` : '';
|
|
@@ -56,6 +66,7 @@ const useStickyHeader = (props: Props) => {
|
|
|
56
66
|
watch(y, (newY, oldY) => {
|
|
57
67
|
isScrollUp.value = newY > 0 && newY < oldY;
|
|
58
68
|
});
|
|
69
|
+
|
|
59
70
|
if (!import.meta.env.SSR) {
|
|
60
71
|
onMounted(() => {
|
|
61
72
|
if (!header.value) throw new Error('<header> (props.header) not set');
|
|
@@ -102,6 +113,7 @@ const useStickyHeader = (props: Props) => {
|
|
|
102
113
|
}
|
|
103
114
|
});
|
|
104
115
|
}
|
|
116
|
+
|
|
105
117
|
return {
|
|
106
118
|
staticHeight,
|
|
107
119
|
staticY,
|
|
@@ -3,8 +3,8 @@ import type { Auth } from 'firebase/auth';
|
|
|
3
3
|
import api from '@cloudcommerce/api';
|
|
4
4
|
import { nickname as getNickname } from '@ecomplus/utils';
|
|
5
5
|
import { computed } from 'vue';
|
|
6
|
-
import requestIdleCallback from '
|
|
7
|
-
import useStorage from '
|
|
6
|
+
import { requestIdleCallback } from '@@sf/sf-lib';
|
|
7
|
+
import useStorage from '@@sf/state/use-storage';
|
|
8
8
|
|
|
9
9
|
const storageKey = 'ecomSession';
|
|
10
10
|
const emptySession = {
|
|
@@ -7,8 +7,8 @@ import { reactive, computed } from 'vue';
|
|
|
7
7
|
import { formatMoney } from '@ecomplus/utils';
|
|
8
8
|
import loadingGlobalInfoPreset from '@@sf/scripts/modules-info-preset';
|
|
9
9
|
import utm from '@@sf/scripts/session-utm';
|
|
10
|
+
import { requestIdleCallback } from '@@sf/sf-lib';
|
|
10
11
|
import afetch from '../../helpers/afetch';
|
|
11
|
-
import requestIdleCallback from '../../helpers/idle-callback';
|
|
12
12
|
|
|
13
13
|
const emptyInfo = {
|
|
14
14
|
list_payments: {},
|
|
@@ -11,29 +11,31 @@ export default (
|
|
|
11
11
|
if (typeof quantity !== 'number' || Number.isNaN(quantity)) {
|
|
12
12
|
quantity = product.min_quantity || 1;
|
|
13
13
|
}
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
14
|
+
const minQuantity = product.min_quantity || 0;
|
|
15
|
+
const variation = variationId && product.variations
|
|
16
|
+
? product.variations.find(({ _id }) => _id === variationId)
|
|
17
|
+
: undefined;
|
|
18
|
+
const item: CartItem = {
|
|
19
|
+
product_id: product._id,
|
|
20
|
+
variation_id: variationId,
|
|
21
|
+
sku: variation?.sku || product.sku,
|
|
22
|
+
name: variation?.name || product.name,
|
|
23
|
+
slug: product.slug,
|
|
24
|
+
production_time: variation?.production_time || product.production_time,
|
|
25
|
+
currency_id: product.currency_id,
|
|
26
|
+
currency_symbol: product.currency_symbol,
|
|
27
|
+
base_price: variation?.base_price || product.base_price,
|
|
28
|
+
max_quantity: product.quantity,
|
|
29
|
+
quantity: minQuantity > 0 ? Math.max(minQuantity, quantity) : quantity,
|
|
30
|
+
price: getPrice(product),
|
|
31
|
+
};
|
|
32
|
+
if (variation?.picture_id && product.pictures) {
|
|
33
|
+
item.picture = product.pictures.find((_picture) => {
|
|
34
|
+
return _picture._id === variation.picture_id;
|
|
35
|
+
});
|
|
30
36
|
}
|
|
31
37
|
if (!item.picture && product.pictures) {
|
|
32
38
|
[item.picture] = product.pictures;
|
|
33
39
|
}
|
|
34
|
-
|
|
35
|
-
const minQuantity = item.min_quantity || product.min_quantity;
|
|
36
|
-
item.quantity = minQuantity > 0 ? Math.max(minQuantity, quantity) : quantity;
|
|
37
|
-
item.price = getPrice(item) || getPrice(product);
|
|
38
|
-
return item as CartItem;
|
|
40
|
+
return item;
|
|
39
41
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { Products, CartSet, SearchItem } from '@cloudcommerce/api/types';
|
|
2
2
|
import { computed } from 'vue';
|
|
3
|
-
import useStorage from '
|
|
4
|
-
import addItem from '
|
|
5
|
-
import parseProduct from '
|
|
3
|
+
import useStorage from '@@sf/state/use-storage';
|
|
4
|
+
import addItem from '@@sf/state/shopping-cart/add-cart-item';
|
|
5
|
+
import parseProduct from '@@sf/state/shopping-cart/parse-product';
|
|
6
6
|
|
|
7
7
|
const storageKey = 'ecomShoppingCart';
|
|
8
8
|
const emptyCart = {
|
|
@@ -72,7 +72,15 @@ const addCartItem = (newItem: CartSet['items'][0]) => {
|
|
|
72
72
|
shoppingCart.value.items = cartObj.items;
|
|
73
73
|
}
|
|
74
74
|
};
|
|
75
|
-
|
|
75
|
+
const removeCartItem = (itemId: string) => {
|
|
76
|
+
for (let i = 0; i < shoppingCart.value.items.length; i++) {
|
|
77
|
+
const item = shoppingCart.value.items[i];
|
|
78
|
+
if (item._id === itemId) {
|
|
79
|
+
shoppingCart.value.items.splice(i, 1);
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
};
|
|
76
84
|
const addProductToCart = (
|
|
77
85
|
product: (Partial<Products> | Partial<SearchItem>) & { _id: Products['_id'] },
|
|
78
86
|
variationId?: Products['_id'],
|
|
@@ -85,6 +93,7 @@ export {
|
|
|
85
93
|
totalItems,
|
|
86
94
|
shoppingCart,
|
|
87
95
|
addCartItem,
|
|
96
|
+
removeCartItem,
|
|
88
97
|
parseProduct,
|
|
89
98
|
addProductToCart,
|
|
90
99
|
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a as q,h as G,c as J}from"./index.7eac5494.js";import{_ as M,d as K,B as X,o as B,a as Q,u as v,b as Y,n as H,j as c,k as h,t as $,c as D,l as Z,E as ee,Q as te,C as ae,g as oe,w as P,h as le,e as F,H as se,I as re}from"./_plugin-vue_export-helper.4cb7dd76.js";const U=Symbol("carousel"),ne=K({__name:"CarouselControl",props:{isPrev:{type:Boolean,default:!1}},setup(r,{expose:u}){u();const{changeSlide:l}=X(U),t={changeSlide:l};return Object.defineProperty(t,"__isScriptSetup",{enumerable:!1,value:!0}),t}}),ue=["aria-label","data-carousel-control"];function ie(r,u,l,t,n,o){return B(),Q("button",{type:"button","aria-label":l.isPrev?"Anterior":"Próximo",onClick:u[0]||(u[0]=m=>t.changeSlide(l.isPrev?-1:1)),class:H(["group absolute top-0 z-1",l.isPrev?"left-0":"right-0"]),"data-carousel-control":l.isPrev?"previous":"next"},[v(r.$slots,"default",{},()=>[Y("i",{class:H(["m-0",l.isPrev?"i-chevron-left group-active:-translate-x-1":"i-chevron-right group-active:translate-x-1"])},null,2)])],10,ue)}const ce=M(ne,[["render",ie]]),de=K({__name:"Carousel",props:{as:{default:"ul"},modelValue:{default:1},autoplay:{}},emits:["update:modelValue"],setup(r,{expose:u,emit:l}){u();const t=r,n=c(t.modelValue-1);h($(t,"modelValue"),e=>{n.value=e-1}),h(n,(e,a)=>{e!==a&&l("update:modelValue",e+1)});const o=c(null),{x:m,isScrolling:L,arrivedState:_}=q(o),T=D(()=>_.left),W=D(()=>_.right),s=c([]),g=c(0),p=c(0),I=c(0),k=()=>{o.value&&(g.value=o.value.scrollWidth,p.value=o.value.offsetWidth)},V=()=>{if(!o.value)return;let e=[...o.value.children];e.length===1&&e[0].tagName.endsWith("SLOT")&&(e=[...e[0].children]),s.value=e.map(a=>({offsetLeft:a.offsetLeft,width:a.offsetWidth}))},z=e=>{let a=n.value+e;if(a>=s.value.length)return 0;a<0&&(a=s.value.length+a);const{offsetLeft:b,width:d}=s.value[a]||{};return d?b:0},x=()=>{const e=s.value.findIndex(a=>Math.abs(a.offsetLeft-m.value)<=5);e>-1&&(n.value=e||0)},E=()=>{const e=g.value-p.value;I.value=s.value.findIndex(({offsetLeft:a})=>a>=e-5)};let i;const f=()=>{t.autoplay&&(clearTimeout(i),i=setTimeout(()=>{C(1)},t.autoplay))},C=(e,a=!0)=>{if(s.value.length<2)return;if(a&&(e===1||e===-1)){let d=0,j=0;for(let S=n.value;S<s.value.length;S++){const{width:A}=s.value[S]||{};if(A&&(d+=1,j+=A,j>=p.value))break}d&&(e=e>0?d:-d)}t.autoplay||console.log({direction:e},n.value,s.value.length);const b=z(e);o.value?.scrollTo({left:b,behavior:"smooth"}),f()};h(L,e=>{e?clearTimeout(i):(x(),f())});const O=c(null),R=G(O);h(R,e=>{e?clearTimeout(i):f()});const w=()=>{o.value&&(k(),V(),x(),E())},y=J(()=>{o.value&&(o.value.scrollLeft=0,w())},400);Z(()=>{w(),ee(()=>{o.value&&[...o.value.children].forEach(e=>{e.setAttribute("tabindex","0")})}),f(),window.addEventListener("resize",y)}),te(()=>{window.removeEventListener("resize",y),clearTimeout(i)}),ae(U,{autoplay:$(t,"autoplay"),changeSlide:C,isBoundLeft:T,isBoundRight:W});const N={props:t,emit:l,currentIndex:n,wrapper:o,currentPos:m,isScrolling:L,arrivedState:_,isBoundLeft:T,isBoundRight:W,slidesWidth:s,wrapperScrollWidth:g,wrapperVisibleWidth:p,indexCount:I,calcWrapperWidth:k,calcSlidesWidth:V,calcNextOffsetLeft:z,calcCurrentIndex:x,calcIndexCount:E,get autoplayTimer(){return i},set autoplayTimer(e){i=e},restartAutoplay:f,changeSlide:C,carousel:O,isHovered:R,calcOnInit:w,onResize:y,CarouselControl:ce};return Object.defineProperty(N,"__isScriptSetup",{enumerable:!1,value:!0}),N}}),fe={ref:"carousel",class:"relative","data-carousel":""};function ve(r,u,l,t,n,o){return B(),Q("div",fe,[(B(),oe(le(l.as),{ref:"wrapper",class:"flex overflow-x-scroll overflow-y-hidden list-none m-0 p-0 snap-x snap-mandatory scroll-smooth [&>*]:snap-start [&>*]:outline-none",style:{"scrollbar-width":"none","-webkit-overflow-scrolling":"touch","-ms-overflow-style":"none"},"data-carousel-wrapper":""},{default:P(()=>[v(r.$slots,"default")]),_:3},512)),v(r.$slots,"controls",se(re({changeSlide:t.changeSlide,isBoundLeft:t.isBoundLeft,isBoundRight:t.isBoundRight,currentPage:t.currentIndex+1,pageCount:t.indexCount+1})),()=>[F(t.CarouselControl,{"is-prev":""},{default:P(()=>[v(r.$slots,"previous")]),_:3}),F(t.CarouselControl,null,{default:P(()=>[v(r.$slots,"next")]),_:3})])],512)}const me=M(de,[["render",ve]]);export{me as C,ce as a};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{L as R,j as O,M as q,N as A,c as d,O as F,_ as N,d as E,m as M,o as i,a as c,x as h,i as f,b as g,y as S,n as B,e as x,w as I,g as j,F as Q,h as T,q as G,f as J,v as K,r as U}from"./_plugin-vue_export-helper.4cb7dd76.js";import{a as D,b as X}from"./api.4984c5be.js";import{C as Y,a as Z}from"./Carousel.8af656b5.js";import{d as $,e as ee,g as te,l as ne,h as ae,w as re}from"./index.7eac5494.js";import{i as se,g as oe}from"./img.abbe849f.js";import"./session-utm.744b0db3.js";const ie=(t,n=R.get("lang"))=>n&&t.i18n&&t.i18n[n]?t.i18n[n]:t.name||t.title||se(t.i18n,n)||"",le=ie,ce=t=>t&&t.min_quantity||1,ue=ce,de=t=>!t.hasOwnProperty("quantity")||t.quantity>=ue(t),W=de,me=t=>{const n=O(t.title||""),r=O(t.titleLink||""),e=O(!1);let m=null;const s=O(null),u=q(t.products||[]);return t.products||(e.value=!0,m=(async()=>{let _=t.searchQuery||"",b;if(t.collectionId){try{const{data:a}=await D.get(`collections/${t.collectionId}`);b=a}catch(a){console.error(a),s.value=a}const l=b?.products;Array.isArray(l)&&l.length&&(_+=`&_id=${l.slice(0,60).join(",")}`),!n.value&&n.value!==null&&b?.name&&(n.value=b?.name)}const v=t.limit||24;let p=`offset=${t.page?(t.page-1)*v:0}&limit=${v}`;t.sort&&(p+=`&sort=${t.sort}`),p+=_;try{const{data:l}=await D.get(`search/v1?${p}`);if(t.isShuffle){let a=l.result.filter(P=>P.available&&W(P)).length,k,C;for(;a;)C=Math.floor(Math.random()*a--),k=l.result[a],l.result[a]=l.result[C],l.result[C]=k}l.result.forEach(a=>u.push(a))}catch(l){console.error(l),s.value=l}e.value=!1})()),{title:n,titleLink:r,isFetching:e,fetching:m,fetchError:s,products:u}},he=t=>{const n=O(!1);let r=null;const e=O(null),{productId:m}=t,s=q({...t.product,_id:t.product?._id||m,price:A(t.product||{})});!t.product&&m&&(n.value=!0,r=(async()=>{try{const{data:a}=await D.get(`products/${m}`);Object.assign(s,a)}catch(a){console.error(a),e.value=a}n.value=!1})());const u=d(()=>le(s)),_=d(()=>{const{slug:a}=s;return typeof a=="string"?`/${a}`:null}),b=d(()=>{const{pictures:a}=s,k=[];return a&&a.forEach(C=>{const P=oe(C);P&&k.push(P)}),k}),v=d(()=>W(s)),w=d(()=>v.value&&s.available&&s.visible),p=d(()=>{if(F(s)){const a=s.base_price;return Math.round((a-A(s))*100/a)}return 0}),l=d(()=>s.has_variations?!0:!!s.variations?.length);return{isFetching:n,fetching:r,fetchError:e,product:s,title:u,link:_,images:b,isInStock:v,isActive:w,discountPercentage:p,hasVariations:l}},z=(t,n)=>{const{type:r,value:e}=n;let m;return e?(r==="percentage"?m=t*((100-e)/100):m=t-e,m>0?m:0):t},_e=t=>{const n=d(()=>t.product||{price:t.price||0,base_price:t.basePrice}),r=d(()=>{const{variations:o}=n.value;if(o){const y=A(n.value);for(let L=0;L<o.length;L++)if(A({...n.value,...o[L]})>y)return!0}return!1}),e=d(()=>{const o=A(n.value),y=$.value;return y&&(!y.min_amount||o>y.min_amount)?z(o,y):o}),m=d(()=>{if(F(n.value))return n.value.base_price;const o=A(n.value);return o>e.value?o:0}),s=d(()=>t.installmentsOption||ee.value||{max_number:1}),u=d(()=>{if(s.value.max_number<=1)return 1;const o=s.value.min_installment||5,y=Math.floor(e.value/o);return Math.min(y,s.value.max_number)}),_=d(()=>s.value.monthly_interest||0),b=d(()=>{if(u.value>=2){if(!_.value)return e.value/u.value;const o=_.value/100;return e.value*o/(1-(1+o)**-u.value)}return 0}),v=d(()=>{const o=t.discountOption||te.value;return o&&(!o.min_amount||o.min_amount<=e.value)&&(!t.isAmountTotal||o.apply_at==="total")?o:{}}),w=d(()=>{const{label:o}=v.value;return o?o.includes(" ")?o:`via ${o}`:""}),p=d(()=>z(e.value,v.value)),l=d(()=>{if(t.loyaltyPointsProgram)return t.loyaltyPointsProgram;const o=ne.value;if(o){const y=Object.keys(o);for(let L=0;L<y.length;L++){const V=o[y[L]];if(V?.earn_percentage&&V.earn_percentage>0)return V}}return{ratio:0}}),a=d(()=>l.value.min_subtotal_to_earn||0),k=d(()=>l.value.name||""),C=d(()=>l.value.earn_percentage||0),P=d(()=>C.value*l.value.ratio),H=d(()=>P.value>=1?e.value*(P.value/100):0);return{hasVariedPrices:r,salePrice:e,comparePrice:m,installmentsObject:s,installmentsNumber:u,monthlyInterest:_,installmentValue:b,discountObject:v,discountLabel:w,priceWithDiscount:p,pointsProgramObject:l,pointsMinPrice:a,pointsProgramName:k,earnPointsPercentage:C,cashbackPercentage:P,cashbackValue:H}},fe=E({__name:"Prices",props:{isBig:{type:Boolean},isLiteral:{type:Boolean},hasCashback:{type:Boolean,default:!0},hasPriceOptions:{type:Boolean,default:!0},product:{},price:{},basePrice:{},isAmountTotal:{type:Boolean},installmentsOption:{},discountOption:{},loyaltyPointsProgram:{}},setup(t,{expose:n}){n();const r=t,{hasVariedPrices:e,salePrice:m,comparePrice:s,cashbackPercentage:u,cashbackValue:_,installmentsNumber:b,monthlyInterest:v,installmentValue:w,priceWithDiscount:p,discountLabel:l}=_e(r),a={props:r,hasVariedPrices:e,salePrice:m,comparePrice:s,cashbackPercentage:u,cashbackValue:_,installmentsNumber:b,monthlyInterest:v,installmentValue:w,priceWithDiscount:p,discountLabel:l};return Object.defineProperty(a,"__isScriptSetup",{enumerable:!1,value:!0}),a}}),ge={key:0,class:"text-base-500 mr-1 [font-size:87%]"},ve={key:0},be={key:1},pe={key:0},ye={key:0,class:"relative z-10"},ke=["data-tooltip"],Pe=g("i",{class:"i-arrow-uturn-left mr-1"},null,-1),xe={class:"font-medium"},we=g("small",null," cashback",-1),Ce={key:0},Oe={key:0},Ie={key:1},Le={key:2},Se={key:0},Ae={key:0},Ve={key:1};function je(t,n,r,e,m,s){const u=M("Fade");return i(),c("div",{class:B(["text-base-600 [&>div]:[font-size:90%] [&_small]:lowercase [&_small]:[font-size:92%]",r.isBig?"text-lg":null]),"data-prices":""},[e.comparePrice?(i(),c("span",ge,[r.isLiteral?(i(),c("small",ve,h("De "))):f("",!0),g("s",null,h(t.$money(e.comparePrice)),1),r.isLiteral?(i(),c("small",be,h(" Por"))):f("",!0)])):f("",!0),g("strong",{class:B(["inline-block text-base-800",r.isBig?"text-5xl block":null])},[e.hasVariedPrices?(i(),c("small",pe,h("A partir de "))):f("",!0),S(" "+h(t.$money(e.salePrice)),1)],2),x(u,{slide:"down"},{default:I(()=>[e.cashbackValue&&r.hasCashback?(i(),c("div",ye,[g("span",{"data-tooltip":"Receba $1 de volta".replace("$1",t.$percentage(e.cashbackPercentage))},[Pe,g("span",xe,h(t.$money(e.cashbackValue)),1),we],8,ke)])):f("",!0)]),_:1}),x(u,{slide:"down"},{default:I(()=>[e.installmentValue&&r.hasPriceOptions?(i(),c("div",Ce,[r.isLiteral?(i(),c("small",Oe,h("Até "))):f("",!0),S(" "+h(e.installmentsNumber)+"x ",1),r.isLiteral?(i(),c("small",Ie,h(" De "))):f("",!0),g("span",null,h(t.$money(e.installmentValue)),1),!e.monthlyInterest&&r.isLiteral?(i(),c("small",Le,h("Sem juros"))):f("",!0)])):f("",!0)]),_:1}),x(u,{slide:"down"},{default:I(()=>[e.priceWithDiscount<e.salePrice&&r.hasPriceOptions?(i(),c("div",Se,[e.discountLabel?f("",!0):(i(),c("small",Ae,h("A partir de "))),g("span",null,h(t.$money(e.priceWithDiscount)),1),e.discountLabel?(i(),c("small",Ve,h(` ${e.discountLabel}`),1)):f("",!0)])):f("",!0)]),_:1})],2)}const Be=N(fe,[["render",je]]),De=E({__name:"ProductCard",props:{product:{},productId:{},headingTag:{default:"h3"}},setup(t,{expose:n}){n();const r=t,{product:e,title:m,link:s,images:u,isInStock:_,isActive:b,discountPercentage:v,hasVariations:w}=he({product:r.product,productId:r.productId}),p=O(null),l=ae(p),a=O(!1);re(l,()=>{a.value=!0});const k={props:r,product:e,title:m,link:s,images:u,isInStock:_,isActive:b,discountPercentage:v,hasVariations:w,card:p,isHovered:l,wasHoveredOnce:a,get addProductToCart(){return X},Prices:Be};return Object.defineProperty(k,"__isScriptSetup",{enumerable:!1,value:!0}),k}}),Ne=["data-sku"],Ee={class:"aspect-square p-2 motion-safe:group-hover:scale-110 transition-transform"},Me={class:"relative w-full h-full bg-white rounded overflow-hidden group-hover:rounded-none"},Te={key:1,class:"w-full h-full bg-gradient-to-br from-base-50/20 to-base-100"},ze={key:0,class:"uno-bm03rg"},qe={class:"relative flex flex-col grow justify-between p-4 group-hover:backdrop-blur-md bg-white/40 z-10"},Fe={class:"pt-2"},Qe={key:0},We={key:1,class:"ui-badge bg-warning-100 text-warning-700"},He=g("i",{class:"i-plus-20-solid mr-0.5"},null,-1);function Re(t,n,r,e,m,s){const u=M("AImg");return i(),c("article",{ref:"card","data-sku":e.product.sku,class:"relative h-full max-w-[350px] mx-auto py-3 group"},[(i(),j(T(e.link?"ALink":"span"),{href:e.link,class:"flex flex-col h-full rounded overflow-hidden group-hover:shadow group-hover:ring-1 ring-black/5"},{default:I(()=>[g("div",Ee,[g("div",Me,[e.images?.length?(i(),c(Q,{key:0},[x(u,{picture:e.images[0],alt:e.title,class:"absolute top-0 left-0 block w-full h-full object-cover"},null,8,["picture","alt"]),e.images[1]&&e.wasHoveredOnce?(i(),j(u,{key:0,picture:e.images[1],alt:e.title,class:"absolute top-0 left-0 block w-full h-full object-cover opacity-0 group-hover:opacity-100 transition-opacity motion-safe:duration-300 text-transparent z-10"},null,8,["picture","alt"])):f("",!0)],64)):(i(),c("div",Te))])]),e.discountPercentage?(i(),c("span",ze,[S(" -"),g("strong",null,h(e.discountPercentage),1),S("% ")])):f("",!0),g("div",qe,[(i(),j(T(r.headingTag),{class:B(["ui-link no-underline line-clamp-2",[e.isActive?"text-base-700":"text-base-500",e.link?"group-hover:underline group-hover:text-primary":null]])},{default:I(()=>[S(h(e.title),1)]),_:1},8,["class"])),g("div",Fe,[e.isActive?(i(),c("div",Qe,[x(e.Prices,{product:e.product},null,8,["product"])])):(i(),c("span",We,h(e.isInStock?"Inativo":"Sem estoque"),1))]),e.isActive&&!e.hasVariations?(i(),c("button",{key:0,class:"uno-3suct9 ui-btn-sm ui-btn-primary",onClick:n[0]||(n[0]=G(_=>e.addProductToCart(e.product),["prevent"]))},[He,S(" "+h("Adicionar ao carrinho"))])):f("",!0)])]),_:1},8,["href"]))],8,Ne)}const Ge=N(De,[["render",Re]]),Je=E({__name:"ProductShelf",props:{collectionId:{},searchQuery:{},sort:{},title:{},titleLink:{},isShuffle:{type:Boolean},limit:{},page:{},products:{}},async setup(t,{expose:n}){n();const r=t,{title:e,titleLink:m,fetching:s,products:u}=me(r),_={props:r,title:e,titleLink:m,fetching:s,products:u,Carousel:Y,CarouselControl:Z,ProductCard:Ge};return Object.defineProperty(_,"__isScriptSetup",{enumerable:!1,value:!0}),_}}),Ke={class:"ui-section"},Ue={key:0,class:"max-w-prose mx-auto text-center mb-2"},Xe={class:"ui-text-brand text-3xl"},Ye={key:1,class:"text-base-700"},Ze={class:"text-3xl lg:text-2xl leading-none text-primary lg:opacity-0 group-hover/shelf:opacity-90 transition-opacity"};function $e(t,n,r,e,m,s){const u=M("ALink");return i(),c("section",Ke,[e.title?(i(),c("div",Ue,[g("h2",Xe,[e.titleLink?(i(),j(u,{key:0,href:e.titleLink,class:"ui-link"},{default:I(()=>[S(h(e.title),1)]),_:1},8,["href"])):(i(),c("span",Ye,h(e.title),1))])])):f("",!0),x(e.Carousel,{class:"group/shelf"},{controls:I(()=>[J(g("div",Ze,[x(e.CarouselControl,{class:"!top-1/2 !-left-4 w-12 h-12 bg-transparent lg:bg-white/80 lg:hover:bg-primary-300/60 rounded-full lg:shadow-sm lg:ring-1 ring-black/5","is-prev":""}),x(e.CarouselControl,{class:"!top-1/2 !-right-4 w-12 h-12 bg-transparent lg:bg-white/80 lg:hover:bg-primary-300/60 rounded-full lg:shadow-sm lg:ring-1 ring-black/5"})],512),[[K,e.products.length>2]])]),default:I(()=>[(i(!0),c(Q,null,U(e.products,_=>(i(),c("li",{key:_._id,class:"basis-1/2 md:basis-1/3 lg:basis-1/4 shrink-0"},[x(e.ProductCard,{product:_},null,8,["product"])]))),128))]),_:1})])}const ot=N(Je,[["render",$e]]);export{ot as default};
|