cloudcommerce 0.0.96 → 0.0.98
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 +21 -0
- package/package.json +3 -3
- package/packages/api/package.json +1 -1
- package/packages/apps/correios/lib-mjs/correios-ws.mjs +2 -1
- package/packages/apps/correios/package.json +1 -1
- package/packages/apps/custom-shipping/package.json +1 -1
- package/packages/apps/discounts/package.json +1 -1
- package/packages/apps/frenet/package.json +1 -1
- package/packages/apps/tiny-erp/lib/event-to-tiny.js +94 -94
- package/packages/apps/tiny-erp/lib/index.js +1 -1
- package/packages/apps/tiny-erp/lib/integration/after-tiny-queue.js +74 -71
- package/packages/apps/tiny-erp/lib/integration/export-order-to-tiny.js +73 -70
- package/packages/apps/tiny-erp/lib/integration/export-product-to-tiny.js +53 -49
- package/packages/apps/tiny-erp/lib/integration/helpers/format-tiny-date.js +3 -3
- package/packages/apps/tiny-erp/lib/integration/import-order-from-tiny.js +75 -76
- package/packages/apps/tiny-erp/lib/integration/import-product-from-tiny.js +140 -137
- package/packages/apps/tiny-erp/lib/integration/parsers/order-from-tiny.js +39 -40
- package/packages/apps/tiny-erp/lib/integration/parsers/order-to-tiny.js +178 -173
- package/packages/apps/tiny-erp/lib/integration/parsers/product-from-tiny.js +171 -173
- package/packages/apps/tiny-erp/lib/integration/parsers/product-to-tiny.js +127 -123
- package/packages/apps/tiny-erp/lib/integration/parsers/status-from-tiny.js +32 -32
- package/packages/apps/tiny-erp/lib/integration/parsers/status-to-tiny.js +37 -37
- package/packages/apps/tiny-erp/lib/integration/post-tiny-erp.js +43 -42
- package/packages/apps/tiny-erp/lib/tiny-erp.js +6 -8
- package/packages/apps/tiny-erp/lib/tiny-webhook.js +73 -76
- package/packages/apps/tiny-erp/package.json +2 -2
- package/packages/cli/package.json +1 -1
- package/packages/config/package.json +1 -1
- package/packages/events/package.json +2 -2
- package/packages/firebase/package.json +3 -3
- package/packages/modules/lib/firebase/ajv.js +19 -24
- package/packages/modules/lib/firebase/call-app-module.js +116 -110
- package/packages/modules/lib/firebase/checkout.js +151 -152
- package/packages/modules/lib/firebase/functions-checkout/fix-items.js +194 -187
- package/packages/modules/lib/firebase/functions-checkout/get-custumerId.js +25 -26
- package/packages/modules/lib/firebase/functions-checkout/handle-order-transaction.js +110 -109
- package/packages/modules/lib/firebase/functions-checkout/new-order.js +177 -177
- package/packages/modules/lib/firebase/functions-checkout/request-to-module.js +59 -59
- package/packages/modules/lib/firebase/functions-checkout/utils.js +195 -197
- package/packages/modules/lib/firebase/handle-module.js +144 -146
- package/packages/modules/lib/firebase/proxy-apps.js +2 -1
- package/packages/modules/lib/firebase/serve-modules-api.js +52 -53
- package/packages/modules/lib/firebase.js +4 -6
- package/packages/modules/lib/index.js +12 -15
- package/packages/modules/package.json +2 -2
- package/packages/passport/package.json +2 -2
- package/packages/ssr/package.json +2 -2
- package/packages/storefront/.eslintrc.cjs +1 -0
- package/packages/storefront/astro.config.mjs +11 -1
- package/packages/storefront/dist/client/LoginOffcanvas.daf3f717.js +1 -0
- package/packages/storefront/dist/client/assets/_...522e6bf2.css +4 -0
- package/packages/storefront/dist/client/assets/{_...ee104f19.css → _...a48b75c7.css} +1 -1
- package/packages/storefront/dist/client/chunks/LoginForm.d9251274.js +1066 -0
- package/packages/storefront/dist/client/chunks/LoginOffcanvas.07fe6492.js +1 -0
- package/packages/storefront/dist/client/{hoisted.46e058d2.js → chunks/index.esm.84a649c7.js} +77 -17
- package/packages/storefront/dist/client/chunks/preload-helper.f15ab524.js +1 -0
- package/packages/storefront/dist/client/chunks/runtime-dom.esm-bundler.738639ee.js +1 -0
- package/packages/storefront/dist/client/client.b552d86a.js +1 -0
- package/packages/storefront/dist/client/hoisted.054c36ac.js +1 -0
- package/packages/storefront/dist/client/manifest.webmanifest +1 -1
- package/packages/storefront/dist/client/sw.js +1 -1
- package/packages/storefront/dist/server/entry.mjs +370 -180
- package/packages/storefront/dist/server/manifest.webmanifest +1 -1
- package/packages/storefront/package.json +6 -5
- package/packages/storefront/src/assets/pico.css +0 -1
- package/packages/storefront/src/env.d.ts +1 -1
- package/packages/storefront/src/lib/components/AOffcanvas.vue +98 -0
- package/packages/storefront/src/lib/components/LoginForm.vue +54 -0
- package/packages/storefront/src/lib/components/LoginOffcanvas.vue +41 -0
- package/packages/storefront/src/lib/components/TheHeader.vue +37 -3
- package/packages/storefront/src/lib/components/TopBar.vue +13 -21
- package/packages/storefront/src/lib/layouts/BaseBody.astro +41 -38
- package/packages/storefront/src/lib/layouts/BaseHead.astro +0 -5
- package/packages/storefront/src/lib/layouts/BaseStateJson.astro +12 -11
- package/packages/storefront/src/lib/layouts/PagesHeader.astro +29 -20
- package/packages/storefront/src/lib/scripts/firebase-app.ts +16 -0
- package/packages/storefront/src/lib/{helpers → ssr}/image.ts +1 -1
- package/packages/storefront/src/pages/app/account.astro +0 -0
- package/packages/storefront/storefront.config.mjs +1 -1
- package/packages/storefront/tsconfig.json +4 -1
- package/packages/types/package.json +1 -1
- package/packages/storefront/dist/client/assets/_...73e01db2.css +0 -4
- package/packages/storefront/dist/client/client.80baece3.js +0 -1
- package/packages/storefront/src/lib/components/LoginModal.vue +0 -82
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name":"My Shop","short_name":"MyShop","start_url":"/","display":"standalone","background_color":"#f5f6fa","lang":"en","scope":"/","description":"My PWA Shop","theme_color":"#
|
|
1
|
+
{"name":"My Shop","short_name":"MyShop","start_url":"/","display":"standalone","background_color":"#f5f6fa","lang":"en","scope":"/","description":"My PWA Shop","theme_color":"#137c5c","crossorigin":"use-credentials","icons":[{"src":"/img/icon.png","sizes":"192x192","type":"image/png"},{"src":"/img/large-icon.png","sizes":"512x512","type":"image/png"},{"src":"/img/large-icon.png","sizes":"512x512","type":"image/png","purpose":"any maskable"}]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudcommerce/storefront",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.98",
|
|
5
5
|
"description": "E-Com Plus Cloud Commerce storefront with Astro",
|
|
6
6
|
"main": "src/index.js",
|
|
7
7
|
"repository": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"homepage": "https://github.com/ecomplus/cloud-commerce/tree/main/packages/storefront#readme",
|
|
18
18
|
"scripts": {
|
|
19
19
|
"dev": "astro dev",
|
|
20
|
-
"start": "astro dev",
|
|
20
|
+
"start": "astro dev --host",
|
|
21
21
|
"build": "astro build",
|
|
22
22
|
"preview": "astro preview",
|
|
23
23
|
"astro": "astro",
|
|
@@ -32,12 +32,13 @@
|
|
|
32
32
|
"@astrojs/vue": "^1.0.2",
|
|
33
33
|
"@cloudcommerce/api": "workspace:*",
|
|
34
34
|
"@cloudcommerce/config": "workspace:*",
|
|
35
|
+
"@ecomplus/i18n": "^1.32.0",
|
|
35
36
|
"@ecomplus/utils": "^1.4.1",
|
|
36
37
|
"@iconify-json/bxl": "^1.1.4",
|
|
37
38
|
"@iconify-json/heroicons": "^1.1.4",
|
|
38
39
|
"@iconify-json/logos": "^1.1.16",
|
|
39
40
|
"@nanostores/vue": "^0.6.0",
|
|
40
|
-
"@unocss/preset-icons": "^0.45.
|
|
41
|
+
"@unocss/preset-icons": "^0.45.23",
|
|
41
42
|
"astro": "^1.3.0",
|
|
42
43
|
"color": "^4.2.3",
|
|
43
44
|
"dotenv": "^16.0.2",
|
|
@@ -45,9 +46,9 @@
|
|
|
45
46
|
"image-size": "^1.0.2",
|
|
46
47
|
"nanostores": "^0.7.0",
|
|
47
48
|
"rollup": "^2.79.1",
|
|
48
|
-
"unocss": "^0.45.
|
|
49
|
+
"unocss": "^0.45.23",
|
|
49
50
|
"vite": "^3.1.3",
|
|
50
|
-
"vite-plugin-pwa": "^0.
|
|
51
|
+
"vite-plugin-pwa": "^0.13.1",
|
|
51
52
|
"vue": "^3.2.39"
|
|
52
53
|
}
|
|
53
54
|
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import {
|
|
3
|
+
toRef,
|
|
4
|
+
ref,
|
|
5
|
+
computed,
|
|
6
|
+
watch,
|
|
7
|
+
} from 'vue';
|
|
8
|
+
import { i19close } from '@i18n';
|
|
9
|
+
|
|
10
|
+
export interface Props {
|
|
11
|
+
modelValue?: boolean;
|
|
12
|
+
placement?: 'start' | 'end';
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
16
|
+
modelValue: false,
|
|
17
|
+
placement: 'end',
|
|
18
|
+
});
|
|
19
|
+
const emit = defineEmits(['update:modelValue']);
|
|
20
|
+
const close = () => emit('update:modelValue', false);
|
|
21
|
+
const article = ref(null);
|
|
22
|
+
const outsideClickListener = (ev: MouseEvent) => {
|
|
23
|
+
if (!article.value?.contains(ev.target)) {
|
|
24
|
+
close();
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const escClickListener = (ev: KeyboardEvent) => {
|
|
28
|
+
if (ev.key === 'Escape') {
|
|
29
|
+
close();
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
watch(toRef(props, 'modelValue'), async (isOpen) => {
|
|
33
|
+
if (isOpen) {
|
|
34
|
+
document.body.style.maxWidth = `${document.body.offsetWidth}px`;
|
|
35
|
+
document.body.style.overflow = 'hidden';
|
|
36
|
+
setTimeout(() => {
|
|
37
|
+
document.addEventListener('click', outsideClickListener, { passive: true });
|
|
38
|
+
document.addEventListener('keydown', escClickListener, { passive: true });
|
|
39
|
+
}, 500);
|
|
40
|
+
} else {
|
|
41
|
+
document.removeEventListener('click', outsideClickListener);
|
|
42
|
+
document.removeEventListener('keydown', escClickListener);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
const transition3dTx = computed(() => {
|
|
46
|
+
return props.placement === 'end' ? '100%' : '-100%';
|
|
47
|
+
});
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
<template>
|
|
51
|
+
<Transition>
|
|
52
|
+
<dialog
|
|
53
|
+
v-if="modelValue"
|
|
54
|
+
class="offcanvas p-0"
|
|
55
|
+
:class="placement === 'end' ? 'justify-end' : 'justify-start'"
|
|
56
|
+
:open="modelValue"
|
|
57
|
+
>
|
|
58
|
+
<article
|
|
59
|
+
ref="article"
|
|
60
|
+
class="rounded-none h-full max-h-screen m-0"
|
|
61
|
+
>
|
|
62
|
+
<a
|
|
63
|
+
href="#close"
|
|
64
|
+
:aria-label="i19close"
|
|
65
|
+
class="close"
|
|
66
|
+
data-target="modal-example"
|
|
67
|
+
@click.prevent="close"
|
|
68
|
+
></a>
|
|
69
|
+
<slot />
|
|
70
|
+
</article>
|
|
71
|
+
</dialog>
|
|
72
|
+
</Transition>
|
|
73
|
+
</template>
|
|
74
|
+
|
|
75
|
+
<style>
|
|
76
|
+
.offcanvas.v-enter-active,
|
|
77
|
+
.offcanvas.v-leave-active {
|
|
78
|
+
transition: opacity 0.25s linear;
|
|
79
|
+
}
|
|
80
|
+
.offcanvas.v-enter-from,
|
|
81
|
+
.offcanvas.v-leave-to {
|
|
82
|
+
opacity: 0;
|
|
83
|
+
}
|
|
84
|
+
.offcanvas.v-enter-active article,
|
|
85
|
+
.offcanvas.v-leave-active article {
|
|
86
|
+
transition: transform 0.3s ease-out;
|
|
87
|
+
}
|
|
88
|
+
.offcanvas.v-enter-from article,
|
|
89
|
+
.offcanvas.v-leave-to article {
|
|
90
|
+
transform: translate3d(var(--transition-3d-tx), 0, 0);
|
|
91
|
+
}
|
|
92
|
+
</style>
|
|
93
|
+
|
|
94
|
+
<style scoped>
|
|
95
|
+
.offcanvas {
|
|
96
|
+
--transition-3d-tx: v-bind(transition3dTx);
|
|
97
|
+
}
|
|
98
|
+
</style>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { ref } from 'vue';
|
|
3
|
+
import {
|
|
4
|
+
i19login,
|
|
5
|
+
} from '@i18n';
|
|
6
|
+
import '../scripts/firebase-app';
|
|
7
|
+
// eslint-disable-next-line import/order
|
|
8
|
+
import {
|
|
9
|
+
getAuth,
|
|
10
|
+
signInWithEmailAndPassword,
|
|
11
|
+
// isSignInWithEmailLink,
|
|
12
|
+
// signInWithEmailLink,
|
|
13
|
+
} from 'firebase/auth';
|
|
14
|
+
|
|
15
|
+
const auth = getAuth();
|
|
16
|
+
const email = ref('');
|
|
17
|
+
const password = ref('');
|
|
18
|
+
const loginWithPassord = () => {
|
|
19
|
+
signInWithEmailAndPassword(auth, email.value, password.value)
|
|
20
|
+
.then((userCredential) => {
|
|
21
|
+
const { user } = userCredential;
|
|
22
|
+
console.log(user);
|
|
23
|
+
})
|
|
24
|
+
.catch((error) => {
|
|
25
|
+
console.warn(error.code);
|
|
26
|
+
console.error(error);
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
</script>
|
|
30
|
+
|
|
31
|
+
<template>
|
|
32
|
+
<form @submit.prevent="loginWithPassord">
|
|
33
|
+
<input
|
|
34
|
+
ref="input"
|
|
35
|
+
type="email"
|
|
36
|
+
placeholder="email@mail.com"
|
|
37
|
+
v-model="email"
|
|
38
|
+
required
|
|
39
|
+
>
|
|
40
|
+
<input
|
|
41
|
+
ref="input"
|
|
42
|
+
type="password"
|
|
43
|
+
placeholder="***"
|
|
44
|
+
v-model="password"
|
|
45
|
+
required
|
|
46
|
+
>
|
|
47
|
+
<button
|
|
48
|
+
type="submit"
|
|
49
|
+
class="btn btn-block btn-primary"
|
|
50
|
+
>
|
|
51
|
+
{{ i19login }}
|
|
52
|
+
</button>
|
|
53
|
+
</form>
|
|
54
|
+
</template>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { ref, defineAsyncComponent } from 'vue';
|
|
3
|
+
import { i19myAccountAndOrders } from '@i18n';
|
|
4
|
+
import AOffcanvas from './AOffcanvas.vue';
|
|
5
|
+
|
|
6
|
+
export interface Props {
|
|
7
|
+
accountUrl?: string;
|
|
8
|
+
accountIconClass?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
withDefaults(defineProps<Props>(), {
|
|
12
|
+
accountUrl: '/app/account',
|
|
13
|
+
accountIconClass: 'i-user-circle',
|
|
14
|
+
});
|
|
15
|
+
const isVisible = ref(false);
|
|
16
|
+
const loadingLoginForm = !import.meta.env.SSR
|
|
17
|
+
? import('./LoginForm.vue')
|
|
18
|
+
: Promise.resolve() as Promise<any>;
|
|
19
|
+
const LoginForm = defineAsyncComponent(() => loadingLoginForm);
|
|
20
|
+
const toggle = (ev: MouseEvent) => {
|
|
21
|
+
loadingLoginForm.then(() => {
|
|
22
|
+
isVisible.value = !isVisible.value;
|
|
23
|
+
ev.preventDefault();
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<template>
|
|
29
|
+
<div @click="toggle">
|
|
30
|
+
<slot name="toggle" v-bind="{ isVisible }">
|
|
31
|
+
<a :href="accountUrl" :title="i19myAccountAndOrders">
|
|
32
|
+
<div :class="accountIconClass"></div>
|
|
33
|
+
</a>
|
|
34
|
+
</slot>
|
|
35
|
+
</div>
|
|
36
|
+
<AOffcanvas v-model="isVisible" class="login-offcanvas">
|
|
37
|
+
<slot name="form">
|
|
38
|
+
<LoginForm class="max-w-xs" />
|
|
39
|
+
</slot>
|
|
40
|
+
</AOffcanvas>
|
|
41
|
+
</template>
|
|
@@ -1,15 +1,49 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
+
import { toRefs, ImgHTMLAttributes } from 'vue';
|
|
3
|
+
|
|
2
4
|
export interface Props {
|
|
5
|
+
logo?: ImgHTMLAttributes;
|
|
6
|
+
gridClass?: string;
|
|
7
|
+
actionsGridClass?: string;
|
|
3
8
|
}
|
|
9
|
+
|
|
10
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
11
|
+
gridClass: 'grid grid-flow-col auto-cols-max justify-between items-center',
|
|
12
|
+
actionsGridClass: 'grid items-center text-2xl',
|
|
13
|
+
});
|
|
14
|
+
const { logo } = toRefs(props);
|
|
4
15
|
</script>
|
|
5
16
|
|
|
6
17
|
<template>
|
|
7
18
|
<header class="header bg-surface bg-opacity-70 sticky py-1 sm:py-2">
|
|
8
19
|
<div class="container">
|
|
9
|
-
<div class="
|
|
10
|
-
<
|
|
11
|
-
|
|
20
|
+
<div :class="gridClass">
|
|
21
|
+
<slot name="aside">
|
|
22
|
+
<div class="header__aside md:hidden">
|
|
23
|
+
<div class="i-bars-3-bottom-left"></div>
|
|
24
|
+
</div>
|
|
25
|
+
</slot>
|
|
26
|
+
<slot name="logo" v-bind="{ logo }">
|
|
27
|
+
<a v-if="logo" href="/" class="header__logo">
|
|
28
|
+
<component :is="logo.alt ? 'h1' : 'span'" class="m-0">
|
|
29
|
+
<img v-bind="logo" />
|
|
30
|
+
</component>
|
|
31
|
+
</a>
|
|
32
|
+
</slot>
|
|
33
|
+
<slot name="actions-grid">
|
|
34
|
+
<div :class="actionsGridClass">
|
|
35
|
+
<slot name="nav" />
|
|
36
|
+
<slot name="search" />
|
|
37
|
+
<slot name="buttons" />
|
|
38
|
+
</div>
|
|
39
|
+
</slot>
|
|
12
40
|
</div>
|
|
13
41
|
</div>
|
|
14
42
|
</header>
|
|
15
43
|
</template>
|
|
44
|
+
|
|
45
|
+
<style>
|
|
46
|
+
.header a:not(:hover) {
|
|
47
|
+
color: var(--gray-accent);
|
|
48
|
+
}
|
|
49
|
+
</style>
|
|
@@ -10,10 +10,6 @@ export interface Props {
|
|
|
10
10
|
hasPhoneLinks?: boolean;
|
|
11
11
|
hasNetworkLinks?: boolean;
|
|
12
12
|
socialNetworks?: string[];
|
|
13
|
-
countdownClass?: string;
|
|
14
|
-
pageLinksClass?: string;
|
|
15
|
-
contactLinksClass?: string;
|
|
16
|
-
socialNetworksClass?: string;
|
|
17
13
|
}
|
|
18
14
|
|
|
19
15
|
withDefaults(defineProps<Props>(), {
|
|
@@ -28,23 +24,19 @@ withDefaults(defineProps<Props>(), {
|
|
|
28
24
|
|
|
29
25
|
<template>
|
|
30
26
|
<div class="top-bar w-full bg-surface">
|
|
31
|
-
<slot
|
|
32
|
-
name="countdown"
|
|
33
|
-
v-bind="{ marketingStripe, countdownClass }"
|
|
34
|
-
>
|
|
27
|
+
<slot name="countdown" v-bind="{ marketingStripe }">
|
|
35
28
|
<template v-if="marketingStripe && marketingStripe.text">
|
|
36
29
|
<component
|
|
37
30
|
:is="marketingStripe.link ? 'a' : 'div'"
|
|
38
31
|
class="top-bar__countdown block text-sm text-center p-1
|
|
39
32
|
whitespace-nowrap overflow-x-auto"
|
|
40
|
-
:class="
|
|
33
|
+
:class="marketingStripe.link ? 'primary' : 'secondary'"
|
|
41
34
|
:href="marketingStripe.link"
|
|
42
35
|
>
|
|
43
36
|
{{ marketingStripe.text }}
|
|
44
37
|
</component>
|
|
45
38
|
</template>
|
|
46
39
|
</slot>
|
|
47
|
-
|
|
48
40
|
<div
|
|
49
41
|
v-if="hasNavbar"
|
|
50
42
|
class="top-bar__nav hidden md:block py-2"
|
|
@@ -52,14 +44,10 @@ withDefaults(defineProps<Props>(), {
|
|
|
52
44
|
<div class="container">
|
|
53
45
|
<div class="flex items-center lg:px-2 xl:px-4">
|
|
54
46
|
<div class="grow text-xs">
|
|
55
|
-
<slot
|
|
56
|
-
name="contacts-container"
|
|
57
|
-
v-bind="{ pageLinks, pageLinksClass }"
|
|
58
|
-
>
|
|
47
|
+
<slot name="page-links" v-bind="{ pageLinks }">
|
|
59
48
|
<nav
|
|
60
49
|
v-if="pageLinks"
|
|
61
50
|
class="top-bar__page-links inline-block mr-4 font-semibold"
|
|
62
|
-
:class="pageLinksClass"
|
|
63
51
|
>
|
|
64
52
|
<a
|
|
65
53
|
v-for="({ link, title }, i) in pageLinks"
|
|
@@ -71,15 +59,13 @@ withDefaults(defineProps<Props>(), {
|
|
|
71
59
|
</a>
|
|
72
60
|
</nav>
|
|
73
61
|
</slot>
|
|
74
|
-
|
|
75
62
|
<slot
|
|
76
63
|
name="contact-links"
|
|
77
|
-
v-bind="{ contacts, hasPhoneLinks
|
|
64
|
+
v-bind="{ contacts, hasPhoneLinks }"
|
|
78
65
|
>
|
|
79
66
|
<div
|
|
80
67
|
v-if="hasPhoneLinks"
|
|
81
68
|
class="top-bar__contact-links inline-block"
|
|
82
|
-
:class="contactLinksClass"
|
|
83
69
|
>
|
|
84
70
|
<a
|
|
85
71
|
v-if="contacts.whatsapp"
|
|
@@ -93,7 +79,7 @@ withDefaults(defineProps<Props>(), {
|
|
|
93
79
|
{{ contacts.whatsapp }}
|
|
94
80
|
</a>
|
|
95
81
|
<a
|
|
96
|
-
v-if="contacts.phone"
|
|
82
|
+
v-if="contacts.phone && contacts.phone !== contacts.whatsapp"
|
|
97
83
|
:href="`tel:+${contacts.phone.replace(/\D/g, '')}`"
|
|
98
84
|
target="_blank"
|
|
99
85
|
rel="noopener"
|
|
@@ -105,10 +91,9 @@ withDefaults(defineProps<Props>(), {
|
|
|
105
91
|
</div>
|
|
106
92
|
</slot>
|
|
107
93
|
</div>
|
|
108
|
-
|
|
109
94
|
<slot
|
|
110
95
|
name="social-networks"
|
|
111
|
-
v-bind="{ contacts, hasNetworkLinks
|
|
96
|
+
v-bind="{ contacts, hasNetworkLinks }"
|
|
112
97
|
>
|
|
113
98
|
<div
|
|
114
99
|
v-if="hasNetworkLinks"
|
|
@@ -122,6 +107,7 @@ withDefaults(defineProps<Props>(), {
|
|
|
122
107
|
target="_blank"
|
|
123
108
|
rel="noopener"
|
|
124
109
|
class="ml-1"
|
|
110
|
+
:aria-label="`Follow on ${network}`"
|
|
125
111
|
>
|
|
126
112
|
<i v-if="network === 'facebook'" class="i-facebook"></i>
|
|
127
113
|
<i v-else-if="network === 'youtube'" class="i-youtube"></i>
|
|
@@ -139,3 +125,9 @@ withDefaults(defineProps<Props>(), {
|
|
|
139
125
|
</div>
|
|
140
126
|
</div>
|
|
141
127
|
</template>
|
|
128
|
+
|
|
129
|
+
<style>
|
|
130
|
+
.top-bar__nav a:not(:hover) {
|
|
131
|
+
color: var(--gray);
|
|
132
|
+
}
|
|
133
|
+
</style>
|
|
@@ -9,7 +9,6 @@ export interface Props {
|
|
|
9
9
|
|
|
10
10
|
const { pageContext } = Astro.props as Props;
|
|
11
11
|
const { primaryColor, secondaryColor } = pageContext;
|
|
12
|
-
|
|
13
12
|
const brandColors = {
|
|
14
13
|
primary: primaryColor,
|
|
15
14
|
secondary: secondaryColor,
|
|
@@ -65,44 +64,48 @@ Object.keys(brandColors).forEach((colorName) => {
|
|
|
65
64
|
</body>
|
|
66
65
|
|
|
67
66
|
<style is:global define:vars={colorCSSVars}>
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
67
|
+
:root {
|
|
68
|
+
--content-max-width: 80rem;
|
|
69
|
+
--white: #fff;
|
|
70
|
+
--gray-50: #f9fafb;
|
|
71
|
+
--gray-200: #e5e7eb;
|
|
72
|
+
--gray-400: #94a3b8;
|
|
73
|
+
--gray-600: #4b5563;
|
|
74
|
+
--gray-700: #374151;
|
|
75
|
+
--gray-800: #1f2937;
|
|
76
|
+
--gray-900: #111827;
|
|
77
|
+
--gray: var(--gray-600);
|
|
78
|
+
--gray-accent: var(--gray-800);
|
|
79
|
+
--surface-color: var(--gray-50);
|
|
80
|
+
--surface-border-color: var(--gray-200);
|
|
81
|
+
--yiq-text-light: var(--white);
|
|
82
|
+
--yiq-text-dark: var(--gray-900);
|
|
83
|
+
}
|
|
84
|
+
body {
|
|
85
|
+
--primary: var(--primary-500);
|
|
86
|
+
--primary-hover: var(--primary-700);
|
|
87
|
+
--primary-focus: rgba(var(--primary-200-rgb), 0.2);
|
|
88
|
+
--primary-inverse: var(--primary-500-yiq);
|
|
89
|
+
--secondary: var(--secondary-500);
|
|
90
|
+
--secondary-hover: var(--secondary-700);
|
|
91
|
+
--secondary-focus: rgba(var(--secondary-200-rgb), 0.2);
|
|
92
|
+
--secondary-inverse: var(--secondary-500-yiq);
|
|
93
|
+
}
|
|
94
|
+
@media only screen and (prefers-color-scheme: dark) {
|
|
95
|
+
:root:not([data-theme=light]) {
|
|
96
|
+
--gray: var(--gray-400);
|
|
97
|
+
--gray-accent: var(--gray-200);
|
|
98
|
+
--surface-color: var(--gray-800);
|
|
99
|
+
--surface-border-color: var(--gray-700);
|
|
80
100
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
body [data-theme=dark] {
|
|
84
|
-
--primary: var(--primary-500);
|
|
85
|
-
--primary-hover: var(--primary-700);
|
|
86
|
-
--primary-focus: rgba(var(--primary-200-rgb), 0.2);
|
|
87
|
-
--primary-inverse: var(--primary-500-yiq);
|
|
88
|
-
--secondary: var(--secondary-500);
|
|
89
|
-
--secondary-hover: var(--secondary-700);
|
|
90
|
-
--secondary-focus: rgba(var(--secondary-200-rgb), 0.2);
|
|
91
|
-
--secondary-inverse: var(--secondary-500-yiq);
|
|
101
|
+
:root:not([data-theme=light]) a:not([role=button]) {
|
|
102
|
+
--color: var(--primary-100);
|
|
92
103
|
}
|
|
93
|
-
|
|
94
|
-
:
|
|
95
|
-
--surface-color: var(--gray-800);
|
|
96
|
-
--surface-border-color: var(--gray-700);
|
|
97
|
-
}
|
|
98
|
-
:root:not([data-theme=light]) a {
|
|
99
|
-
--color: var(--primary-200);
|
|
100
|
-
}
|
|
101
|
-
:root:not([data-theme=light]) a:is([aria-current], :hover, :active, :focus) {
|
|
102
|
-
--color: var(--primary-400);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
body {
|
|
106
|
-
overflow-x: hidden;
|
|
104
|
+
:root:not([data-theme=light]) a:not([role=button]):is([aria-current], :hover, :active, :focus) {
|
|
105
|
+
--color: var(--primary-300);
|
|
107
106
|
}
|
|
107
|
+
}
|
|
108
|
+
body {
|
|
109
|
+
overflow-x: hidden;
|
|
110
|
+
}
|
|
108
111
|
</style>
|
|
@@ -21,7 +21,6 @@ const {
|
|
|
21
21
|
const state = apiDoc || cmsContent || {};
|
|
22
22
|
const title = state.meta_title || state.name || state.title || Astro.props.title || settings.name;
|
|
23
23
|
const description = state.meta_description || state.short_description || settings.description;
|
|
24
|
-
|
|
25
24
|
const canonicalUrl = new URL(Astro.url.pathname, Astro.site || `https://${domain}`);
|
|
26
25
|
const cmsSocial = cms('social') as CmsSocial;
|
|
27
26
|
const ogLocale = lang.length === 2 ? lang : lang.substring(0, 2) + lang.slice(3).toUpperCase();
|
|
@@ -53,7 +52,6 @@ if (!ogImage) {
|
|
|
53
52
|
<link rel="apple-touch-icon" href={settings.icon} />
|
|
54
53
|
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
55
54
|
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
|
56
|
-
|
|
57
55
|
<meta property="og:site_name" content={settings.name}>
|
|
58
56
|
<meta property="og:url" content={canonicalUrl}>
|
|
59
57
|
<meta property="og:title" content={title}>
|
|
@@ -64,7 +62,4 @@ if (!ogImage) {
|
|
|
64
62
|
{cmsSocial.fb_app_id && <meta property="fb:app_id" content={cmsSocial.fb_app_id} />}
|
|
65
63
|
<meta name="twitter:card" content="summary">
|
|
66
64
|
{cmsSocial.twitter_username && <meta name="twitter:site" content={cmsSocial.twitter_username} />}
|
|
67
|
-
|
|
68
|
-
<link rel="preconnect" href="https://ecomplus.io/" crossorigin />
|
|
69
|
-
<link rel="dns-prefetch" href="https://ecomplus.io/" />
|
|
70
65
|
<meta name="ecom-store-id" content={String(storeId)}>
|
|
@@ -6,18 +6,19 @@ export interface Props {
|
|
|
6
6
|
pageContext: PageContext;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
const { pageContext } = Astro.props as Props;
|
|
10
9
|
const {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
10
|
+
pageContext: {
|
|
11
|
+
storeId,
|
|
12
|
+
apiResource,
|
|
13
|
+
apiDoc,
|
|
14
|
+
lang,
|
|
15
|
+
countryCode,
|
|
16
|
+
currency,
|
|
17
|
+
currencySymbol,
|
|
18
|
+
domain,
|
|
19
|
+
settings,
|
|
20
|
+
},
|
|
21
|
+
} = Astro.props as Props;
|
|
21
22
|
|
|
22
23
|
let inlineClientJS = `
|
|
23
24
|
window.storefront = ${JSON.stringify({
|
|
@@ -3,22 +3,16 @@ import type { Categories } from '@cloudcommerce/api/types';
|
|
|
3
3
|
import type CmsHeader from '../../types/cms-header';
|
|
4
4
|
import type CmsContacts from '../../types/cms-contacts';
|
|
5
5
|
import type { PageContext } from '../ssr-context';
|
|
6
|
-
import { getImageAttrs } from '../
|
|
6
|
+
import { getImageAttrs } from '../ssr/image';
|
|
7
7
|
import TopBar, { Props as TopBarProps } from '../components/TopBar.vue';
|
|
8
|
-
import TheHeader from '../components/TheHeader.vue';
|
|
8
|
+
import TheHeader, { Props as TheHeaderProps } from '../components/TheHeader.vue';
|
|
9
|
+
import LoginOffcanvas, { Props as LoginOffcanvasProps } from '../components/LoginOffcanvas.vue';
|
|
9
10
|
|
|
10
11
|
export interface Props {
|
|
11
12
|
pageContext: PageContext;
|
|
12
13
|
topBarProps?: Partial<TopBarProps>;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
height?: number;
|
|
16
|
-
quality?: number;
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
declare global {
|
|
21
|
-
var TopBarProps: TopBarProps;
|
|
14
|
+
theHeaderProps?: Partial<TheHeaderProps>;
|
|
15
|
+
loginOffcanvasProps?: Partial<LoginOffcanvasProps>;
|
|
22
16
|
}
|
|
23
17
|
|
|
24
18
|
const {
|
|
@@ -28,12 +22,12 @@ const {
|
|
|
28
22
|
cms,
|
|
29
23
|
},
|
|
30
24
|
topBarProps,
|
|
31
|
-
|
|
25
|
+
theHeaderProps,
|
|
26
|
+
loginOffcanvasProps,
|
|
32
27
|
} = Astro.props as Props;
|
|
33
28
|
const header = cms('header') as CmsHeader;
|
|
34
29
|
const contacts = cms('contacts') as CmsContacts;
|
|
35
30
|
const customThemeName = settings.theme.custom || '';
|
|
36
|
-
|
|
37
31
|
let headerCategories: Array<{ slug: string, name: string }> = [];
|
|
38
32
|
let isCategoriesNavFull: boolean | undefined;
|
|
39
33
|
if (header.categories_list) {
|
|
@@ -64,6 +58,11 @@ const hasMegamenu: boolean | undefined = header.desktop_megamenu;
|
|
|
64
58
|
const isAlphabeticalOrderSubmenu: boolean | undefined = header.alphabetical_order_submenu;
|
|
65
59
|
const isFullWidthSubmenu: boolean | undefined = header.full_width_submenu;
|
|
66
60
|
|
|
61
|
+
declare global {
|
|
62
|
+
var TopBarProps: TopBarProps;
|
|
63
|
+
var TheHeaderProps: TheHeaderProps;
|
|
64
|
+
var LoginOffcanvasProps: LoginOffcanvasProps;
|
|
65
|
+
}
|
|
67
66
|
globalThis.TopBarProps = {
|
|
68
67
|
marketingStripe: header.marketing_stripe,
|
|
69
68
|
pageLinks: header.contacts_stripe.pages,
|
|
@@ -72,18 +71,28 @@ globalThis.TopBarProps = {
|
|
|
72
71
|
contacts,
|
|
73
72
|
...topBarProps,
|
|
74
73
|
};
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
74
|
+
globalThis.TheHeaderProps = {
|
|
75
|
+
logo: {
|
|
76
|
+
...getImageAttrs({
|
|
77
|
+
src: settings.logo,
|
|
78
|
+
width: 150,
|
|
79
|
+
}),
|
|
80
|
+
alt: settings.name,
|
|
81
|
+
},
|
|
82
|
+
...theHeaderProps,
|
|
83
|
+
};
|
|
84
|
+
globalThis.LoginOffcanvasProps = {
|
|
85
|
+
...loginOffcanvasProps,
|
|
86
|
+
};
|
|
80
87
|
---
|
|
81
88
|
|
|
82
89
|
<slot name="top-bar">
|
|
83
90
|
<TopBar {...globalThis.TopBarProps} />
|
|
84
91
|
</slot>
|
|
85
92
|
<slot name="header">
|
|
86
|
-
<TheHeader>
|
|
87
|
-
<
|
|
93
|
+
<TheHeader {...globalThis.TheHeaderProps}>
|
|
94
|
+
<Fragment slot="buttons">
|
|
95
|
+
<LoginOffcanvas client:idle {...globalThis.LoginOffcanvasProps} />
|
|
96
|
+
</Fragment>
|
|
88
97
|
</TheHeader>
|
|
89
98
|
</slot>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { initializeApp } from 'firebase/app';
|
|
2
|
+
|
|
3
|
+
const firebaseConfig = window.firebaseConfig || {
|
|
4
|
+
apiKey: 'AIzaSyCrVzemDgpyp9i6ni7Yc5ZuEVfXYwl-4J0',
|
|
5
|
+
authDomain: 'ecom2-002.firebaseapp.com',
|
|
6
|
+
projectId: 'ecom2-002',
|
|
7
|
+
storageBucket: 'ecom2-002.appspot.com',
|
|
8
|
+
messagingSenderId: '402807248219',
|
|
9
|
+
appId: '1:402807248219:web:cf7d57759751e74776367e',
|
|
10
|
+
measurementId: 'G-SC592CE0GB',
|
|
11
|
+
};
|
|
12
|
+
const app = initializeApp(firebaseConfig);
|
|
13
|
+
|
|
14
|
+
export default app;
|
|
15
|
+
|
|
16
|
+
export const firebaseApp = app;
|