cloudcommerce 0.0.96 → 0.0.97

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 (96) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/package.json +3 -3
  3. package/packages/api/package.json +1 -1
  4. package/packages/apps/correios/lib-mjs/correios-ws.mjs +2 -1
  5. package/packages/apps/correios/package.json +1 -1
  6. package/packages/apps/custom-shipping/package.json +1 -1
  7. package/packages/apps/discounts/package.json +1 -1
  8. package/packages/apps/frenet/package.json +1 -1
  9. package/packages/apps/tiny-erp/package.json +2 -2
  10. package/packages/cli/package.json +1 -1
  11. package/packages/config/package.json +1 -1
  12. package/packages/events/package.json +2 -2
  13. package/packages/firebase/lib/config.js +25 -27
  14. package/packages/firebase/lib/const.js +2 -3
  15. package/packages/firebase/lib/env.js +1 -2
  16. package/packages/firebase/lib/handlers/check-store-events.js +145 -146
  17. package/packages/firebase/lib/helpers/pubsub.js +18 -20
  18. package/packages/firebase/lib/helpers/update-app-data.js +38 -38
  19. package/packages/firebase/lib/index.js +7 -9
  20. package/packages/firebase/lib/init.js +1 -2
  21. package/packages/firebase/package.json +3 -3
  22. package/packages/modules/package.json +2 -2
  23. package/packages/passport/package.json +2 -2
  24. package/packages/ssr/package.json +2 -2
  25. package/packages/storefront/.eslintrc.cjs +1 -0
  26. package/packages/storefront/astro.config.mjs +11 -1
  27. package/packages/storefront/package.json +6 -5
  28. package/packages/storefront/src/assets/pico.css +0 -1
  29. package/packages/storefront/src/env.d.ts +1 -1
  30. package/packages/storefront/src/lib/components/AOffcanvas.vue +98 -0
  31. package/packages/storefront/src/lib/components/LoginForm.vue +54 -0
  32. package/packages/storefront/src/lib/components/LoginOffcanvas.vue +41 -0
  33. package/packages/storefront/src/lib/components/TheHeader.vue +37 -3
  34. package/packages/storefront/src/lib/components/TopBar.vue +13 -21
  35. package/packages/storefront/src/lib/layouts/BaseBody.astro +41 -38
  36. package/packages/storefront/src/lib/layouts/BaseHead.astro +0 -5
  37. package/packages/storefront/src/lib/layouts/BaseStateJson.astro +12 -11
  38. package/packages/storefront/src/lib/layouts/PagesHeader.astro +28 -20
  39. package/packages/storefront/src/lib/scripts/firebase-app.ts +16 -0
  40. package/packages/storefront/src/lib/{helpers → ssr}/image.ts +1 -1
  41. package/packages/storefront/src/pages/app/account.astro +0 -0
  42. package/packages/storefront/storefront.config.mjs +1 -1
  43. package/packages/storefront/tsconfig.json +4 -1
  44. package/packages/types/package.json +1 -1
  45. package/packages/storefront/dist/client/admin/config.json +0 -1
  46. package/packages/storefront/dist/client/assets/_...73e01db2.css +0 -4
  47. package/packages/storefront/dist/client/assets/_...ee104f19.css +0 -1
  48. package/packages/storefront/dist/client/assets/cms-preview.css +0 -274
  49. package/packages/storefront/dist/client/assets/cms.css +0 -114
  50. package/packages/storefront/dist/client/assets/cvv.png +0 -0
  51. package/packages/storefront/dist/client/assets/icons/bootstrap-icons/font/storefront-icons.woff2 +0 -0
  52. package/packages/storefront/dist/client/assets/icons/feather-icons/font/storefront-icons.woff2 +0 -0
  53. package/packages/storefront/dist/client/assets/icons/font-awesome/font/storefront-icons.woff2 +0 -0
  54. package/packages/storefront/dist/client/assets/icons/line-awesome/font/storefront-icons.woff2 +0 -0
  55. package/packages/storefront/dist/client/assets/icons/tabler-icons/font/storefront-icons.woff2 +0 -0
  56. package/packages/storefront/dist/client/assets/img-placeholder.png +0 -0
  57. package/packages/storefront/dist/client/assets/payments.png +0 -0
  58. package/packages/storefront/dist/client/assets/ssl-safe.png +0 -0
  59. package/packages/storefront/dist/client/chunks/workbox-window.prod.es5.4b654ae6.js +0 -2
  60. package/packages/storefront/dist/client/client.80baece3.js +0 -1
  61. package/packages/storefront/dist/client/hoisted.46e058d2.js +0 -271
  62. package/packages/storefront/dist/client/img/icon.png +0 -0
  63. package/packages/storefront/dist/client/img/large-icon.png +0 -0
  64. package/packages/storefront/dist/client/img/uploads/banner1.png +0 -0
  65. package/packages/storefront/dist/client/img/uploads/banner2.png +0 -0
  66. package/packages/storefront/dist/client/img/uploads/banner2.webp +0 -0
  67. package/packages/storefront/dist/client/img/uploads/favicon.png +0 -0
  68. package/packages/storefront/dist/client/img/uploads/headless.png +0 -0
  69. package/packages/storefront/dist/client/img/uploads/headphone.png +0 -0
  70. package/packages/storefront/dist/client/img/uploads/headphone.webp +0 -0
  71. package/packages/storefront/dist/client/img/uploads/icon.png +0 -0
  72. package/packages/storefront/dist/client/img/uploads/large-icon.png +0 -0
  73. package/packages/storefront/dist/client/img/uploads/logo.png +0 -0
  74. package/packages/storefront/dist/client/img/uploads/logo.webp +0 -0
  75. package/packages/storefront/dist/client/img/uploads/og-image.png +0 -0
  76. package/packages/storefront/dist/client/img/uploads/passion.png +0 -0
  77. package/packages/storefront/dist/client/img/uploads/passion.webp +0 -0
  78. package/packages/storefront/dist/client/img/uploads/pwa-reliable.png +0 -0
  79. package/packages/storefront/dist/client/img/uploads/rect8589.png +0 -0
  80. package/packages/storefront/dist/client/img/uploads/rect859.png +0 -0
  81. package/packages/storefront/dist/client/img/uploads/rect89.png +0 -0
  82. package/packages/storefront/dist/client/img/uploads/rect89.webp +0 -0
  83. package/packages/storefront/dist/client/img/uploads/ssl-safe.png +0 -0
  84. package/packages/storefront/dist/client/manifest.webmanifest +0 -1
  85. package/packages/storefront/dist/client/page.3aa82516.js +0 -1
  86. package/packages/storefront/dist/client/robots.txt +0 -8
  87. package/packages/storefront/dist/client/sw.js +0 -1
  88. package/packages/storefront/dist/client/workbox-6f0d1f78.js +0 -1
  89. package/packages/storefront/dist/client/~partytown/partytown-atomics.js +0 -2
  90. package/packages/storefront/dist/client/~partytown/partytown-media.js +0 -2
  91. package/packages/storefront/dist/client/~partytown/partytown-sw.js +0 -2
  92. package/packages/storefront/dist/client/~partytown/partytown.js +0 -2
  93. package/packages/storefront/dist/server/entry.mjs +0 -2662
  94. package/packages/storefront/dist/server/manifest.webmanifest +0 -1
  95. package/packages/storefront/dist/server/registerSW.js +0 -1
  96. package/packages/storefront/src/lib/components/LoginModal.vue +0 -82
@@ -2,44 +2,44 @@ import { PubSub } from '@google-cloud/pubsub';
2
2
  import logger from 'firebase-functions/lib/logger';
3
3
  import api from '@cloudcommerce/api';
4
4
  import { EVENT_SKIP_FLAG, GET_PUBSUB_TOPIC } from '../const.js';
5
-
6
5
  export default async (application, data, { isHiddenData = false, canSendPubSub = true } = {}) => {
7
- const applicationId = typeof application === 'string'
8
- ? application : application._id;
9
- const subresource = isHiddenData ? 'hidden_data' : 'data';
10
- if (application && typeof application === 'object' && canSendPubSub) {
11
- // eslint-disable-next-line no-param-reassign
12
- application[subresource] = data;
13
- const json = {
14
- evName: 'applications-dataSet',
15
- apiEvent: {
16
- timestamp: new Date().toISOString(),
17
- resource_id: applicationId,
18
- action: 'update',
19
- modified_fields: [subresource],
20
- authentication_id: null,
21
- },
22
- apiDoc: application,
23
- app: {
24
- _id: applicationId,
25
- app_id: application.app_id,
26
- data: application.data,
27
- hidden_data: application.hidden_data,
28
- },
29
- isInternal: true,
30
- };
31
- try {
32
- await new PubSub()
33
- .topic(GET_PUBSUB_TOPIC(application.app_id))
34
- .publishMessage({ json });
35
- } catch (err) {
36
- logger.error(err);
6
+ const applicationId = typeof application === 'string'
7
+ ? application : application._id;
8
+ const subresource = isHiddenData ? 'hidden_data' : 'data';
9
+ if (application && typeof application === 'object' && canSendPubSub) {
10
+ // eslint-disable-next-line no-param-reassign
11
+ application[subresource] = data;
12
+ const json = {
13
+ evName: 'applications-dataSet',
14
+ apiEvent: {
15
+ timestamp: new Date().toISOString(),
16
+ resource_id: applicationId,
17
+ action: 'update',
18
+ modified_fields: [subresource],
19
+ authentication_id: null,
20
+ },
21
+ apiDoc: application,
22
+ app: {
23
+ _id: applicationId,
24
+ app_id: application.app_id,
25
+ data: application.data,
26
+ hidden_data: application.hidden_data,
27
+ },
28
+ isInternal: true,
29
+ };
30
+ try {
31
+ await new PubSub()
32
+ .topic(GET_PUBSUB_TOPIC(application.app_id))
33
+ .publishMessage({ json });
34
+ }
35
+ catch (err) {
36
+ logger.error(err);
37
+ }
37
38
  }
38
- }
39
- return api.patch(`applications/${applicationId}/${subresource}`, data, {
40
- headers: {
41
- 'X-Event-Flag': EVENT_SKIP_FLAG,
42
- },
43
- });
39
+ return api.patch(`applications/${applicationId}/${subresource}`, data, {
40
+ headers: {
41
+ 'X-Event-Flag': EVENT_SKIP_FLAG,
42
+ },
43
+ });
44
44
  };
45
- // # sourceMappingURL=update-app-data.js.map
45
+ //# sourceMappingURL=update-app-data.js.map
@@ -3,18 +3,16 @@ import './init.js';
3
3
  import functions from 'firebase-functions';
4
4
  import config from './config.js';
5
5
  import checkStoreEvents from './handlers/check-store-events.js';
6
-
7
6
  const { httpsFunctionOptions: { region } } = config.get();
8
7
  const functionBuilder = functions
9
- .region(region)
10
- .runWith({
8
+ .region(region)
9
+ .runWith({
11
10
  timeoutSeconds: 300,
12
11
  memory: '128MB',
13
- });
14
-
12
+ });
15
13
  export const cronStoreEvents = functionBuilder.pubsub
16
- .schedule('* * * * *')
17
- .onRun(() => {
14
+ .schedule('* * * * *')
15
+ .onRun(() => {
18
16
  return checkStoreEvents();
19
- });
20
- // # sourceMappingURL=index.js.map
17
+ });
18
+ //# sourceMappingURL=index.js.map
@@ -4,6 +4,5 @@ import '@cloudcommerce/api/fetch-polyfill';
4
4
  // https://github.com/import-js/eslint-plugin-import/issues/1810
5
5
  // eslint-disable-next-line import/no-unresolved
6
6
  import { initializeApp } from 'firebase-admin/app';
7
-
8
7
  initializeApp();
9
- // # sourceMappingURL=init.js.map
8
+ //# sourceMappingURL=init.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/firebase",
3
3
  "type": "module",
4
- "version": "0.0.96",
4
+ "version": "0.0.97",
5
5
  "description": "E-Com Plus Cloud Commerce on Firebase",
6
6
  "main": "lib/index.js",
7
7
  "types": "lib/index.d.ts",
@@ -31,9 +31,9 @@
31
31
  "dependencies": {
32
32
  "@cloudcommerce/api": "workspace:*",
33
33
  "@cloudcommerce/config": "workspace:*",
34
- "@google-cloud/pubsub": "^3.1.1",
34
+ "@google-cloud/pubsub": "^3.2.0",
35
35
  "firebase-admin": "^11.0.1",
36
- "firebase-functions": "^3.23.0",
36
+ "firebase-functions": "^3.24.0",
37
37
  "node-fetch": "^3.2.10",
38
38
  "source-map-support": "^0.5.21"
39
39
  },
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/modules",
3
3
  "type": "module",
4
- "version": "0.0.96",
4
+ "version": "0.0.97",
5
5
  "description": "E-Com Plus Cloud Commerce modules API",
6
6
  "main": "lib/index.cjs",
7
7
  "exports": {
@@ -34,7 +34,7 @@
34
34
  "ajv-formats": "^2.1.1",
35
35
  "axios": "^0.27.2",
36
36
  "firebase-admin": "^11.0.1",
37
- "firebase-functions": "^3.23.0",
37
+ "firebase-functions": "^3.24.0",
38
38
  "source-map-support": "^0.5.21"
39
39
  },
40
40
  "devDependencies": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/passport",
3
3
  "type": "module",
4
- "version": "0.0.96",
4
+ "version": "0.0.97",
5
5
  "description": "E-Com Plus Cloud Commerce customers authentication (passport) API",
6
6
  "main": "lib/index.js",
7
7
  "exports": {
@@ -26,7 +26,7 @@
26
26
  "@cloudcommerce/api": "workspace:*",
27
27
  "@cloudcommerce/firebase": "workspace:*",
28
28
  "firebase-admin": "^11.0.1",
29
- "firebase-functions": "^3.23.0",
29
+ "firebase-functions": "^3.24.0",
30
30
  "source-map-support": "^0.5.21"
31
31
  },
32
32
  "devDependencies": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/ssr",
3
3
  "type": "module",
4
- "version": "0.0.96",
4
+ "version": "0.0.97",
5
5
  "description": "E-Com Plus Cloud Commerce storefront SSR",
6
6
  "main": "lib/index.js",
7
7
  "exports": {
@@ -30,7 +30,7 @@
30
30
  "color": "^4.2.3",
31
31
  "compression": "^1.7.4",
32
32
  "firebase-admin": "^11.0.1",
33
- "firebase-functions": "^3.23.0",
33
+ "firebase-functions": "^3.24.0",
34
34
  "html-escaper": "^3.0.3",
35
35
  "image-size": "^1.0.2",
36
36
  "kleur": "^4.1.5",
@@ -2,5 +2,6 @@ module.exports = {
2
2
  extends: '../../.eslintrc.cjs',
3
3
  rules: {
4
4
  'no-console': 'off',
5
+ 'import/no-unresolved': 'off',
5
6
  },
6
7
  };
@@ -13,7 +13,12 @@ import getConfig from './storefront.config.mjs';
13
13
 
14
14
  dotenv.config();
15
15
 
16
- const { domain, primaryColor, settings } = getConfig();
16
+ const {
17
+ lang,
18
+ domain,
19
+ primaryColor,
20
+ settings,
21
+ } = getConfig();
17
22
 
18
23
  const _vitePWAOptions = {
19
24
  manifest: {
@@ -136,6 +141,11 @@ const genAstroConfig = ({
136
141
  plugins: [
137
142
  VitePWA(vitePWAOptions),
138
143
  ],
144
+ resolve: {
145
+ alias: {
146
+ '@i18n': `@ecomplus/i18n/src/${lang}/index.js`,
147
+ },
148
+ },
139
149
  },
140
150
  });
141
151
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@cloudcommerce/storefront",
3
3
  "type": "module",
4
- "version": "0.0.96",
4
+ "version": "0.0.97",
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.22",
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.22",
49
+ "unocss": "^0.45.23",
49
50
  "vite": "^3.1.3",
50
- "vite-plugin-pwa": "^0.12.8",
51
+ "vite-plugin-pwa": "^0.13.1",
51
52
  "vue": "^3.2.39"
52
53
  }
53
54
  }
@@ -558,7 +558,6 @@ a:is([aria-current], :hover, :active, :focus),
558
558
  --color: var(--primary-hover);
559
559
  --text-decoration: underline;
560
560
  }
561
- a:focus,
562
561
  [role=link]:focus {
563
562
  --background-color: var(--primary-focus);
564
563
  }
@@ -1,3 +1,3 @@
1
- /// <reference types="@astrojs/image/client" />
1
+ /// <reference types="astro/client" />
2
2
  /// <reference types="vite-plugin-pwa/client" />
3
3
  /// <reference types="../client" />
@@ -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="grid items-center">
10
- <div class="i-bars-3-bottom-left md:hidden"></div>
11
- <slot name="logo"></slot>
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="[countdownClass, marketingStripe.link ? 'primary' : 'secondary']"
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, contactLinksClass }"
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, socialNetworksClass }"
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>