cja-phoenix 0.7.2 → 0.7.4

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.
@@ -2,24 +2,13 @@
2
2
  <header
3
3
  class="main-header-container"
4
4
  :class="{
5
- 'sidebar-active':
6
- sidebarActive || (callModal?.active && activeViewport.md),
5
+ 'overlay-active': callModal?.active && activeViewport.md,
7
6
  }"
8
7
  id="page-header"
9
8
  ref="headerEl"
10
9
  >
11
10
  <FixedContainer :active="activeViewport.lg" :size="{ width: '100%' }">
12
- <div
13
- class="main-header"
14
- :class="{ 'has-categories': categories?.length }"
15
- >
16
- <div class="btn-sidebar-container" v-if="categories?.length">
17
- <button
18
- class="btn-sidebar m-cgg-icon--tlist"
19
- @click="sidebarActive = !sidebarActive"
20
- ></button>
21
- </div>
22
-
11
+ <div class="main-header">
23
12
  <div class="logo-container">
24
13
  <component
25
14
  :is="homeNavigationEnabled ? 'a' : 'div'"
@@ -39,38 +28,10 @@
39
28
  :stepList="macroStepList"
40
29
  v-if="activeViewport.lg && macroStepList"
41
30
  />
42
-
43
- <nav class="categories-container" v-else-if="categories?.length">
44
- <div class="menu-category" v-for="category in categories">
45
- <component
46
- :is="category.link ? 'a' : 'div'"
47
- class="category-label"
48
- :href="category.link ? getStoryblokUrl(category.link) : ''"
49
- >
50
- {{ category.text }}
51
- <span
52
- v-if="category.subLinks"
53
- class="m-cgg-icon--chevron-down"
54
- ></span>
55
- </component>
56
- <Transition name="fade">
57
- <div class="category-links-container" v-if="category.subLinks">
58
- <ul>
59
- <li v-for="menuLink in category.subLinks">
60
- <a :href="getStoryblokUrl(menuLink.link)">
61
- {{ menuLink.text }}
62
- </a>
63
- </li>
64
- </ul>
65
- </div>
66
- </Transition>
67
- </div>
68
- </nav>
69
-
70
31
  <slot name="content" v-else-if="$slots.content"></slot>
71
32
  </div>
72
33
 
73
- <div class="side-info" v-if="hasSideInfo">
34
+ <div class="side-info" v-if="$slots.side || hasContact">
74
35
  <slot name="side"></slot>
75
36
  <button
76
37
  class="contact m-cgg-icon--phone"
@@ -114,75 +75,25 @@
114
75
  </div>
115
76
  </template>
116
77
  </Modal>
117
-
118
- <Teleport to="body" v-if="categories?.length">
119
- <Transition name="slide">
120
- <nav class="categories-sidebar" v-if="sidebarActive">
121
- <div class="menu-category" v-for="category in categories">
122
- <CollapseContainer v-if="category.subLinks">
123
- <template #header>
124
- <div class="menu-category-link">
125
- {{ category.text }}
126
- </div>
127
- </template>
128
- <template #content>
129
- <ul class="category-links-container" v-if="category.subLinks">
130
- <li v-if="category.link">
131
- <a class="menu-link" :href="getStoryblokUrl(category.link)">
132
- {{ category.text }}
133
- </a>
134
- </li>
135
- <li v-for="menuLink in category.subLinks">
136
- <a class="menu-link" :href="getStoryblokUrl(menuLink.link)">
137
- {{ menuLink.text }}
138
- </a>
139
- </li>
140
- </ul>
141
- </template>
142
- </CollapseContainer>
143
- <a
144
- class="menu-category-link menu-link"
145
- :href="getStoryblokUrl(category.link)"
146
- v-else-if="category.link"
147
- >
148
- {{ category.text }}
149
- </a>
150
- </div>
151
- </nav>
152
- </Transition>
153
- <Transition name="fade">
154
- <div
155
- class="categories-backdrop"
156
- @click="sidebarActive = false"
157
- v-if="sidebarActive"
158
- ></div>
159
- </Transition>
160
- </Teleport>
161
78
  </template>
162
79
 
163
80
  <script lang="ts" setup>
164
81
  import FixedContainer from "../structural/FixedContainer.vue";
165
- import CollapseContainer from "../structural/CollapseContainer.vue";
166
82
  import CjaButton from "../structural/CjaButton.vue";
167
- import { MacroStep, MenuCategory } from "../../types";
83
+ import { MacroStep } from "../../types";
168
84
  import JourneyMacroSteps from "./JourneyMacroSteps.vue";
169
85
  import Modal from "../structural/Modal.vue";
170
86
  import { ref } from "vue";
171
- import { getStoryblokUrl } from "../../utils";
172
- import { watch } from "vue";
173
87
  import { useViewportDetector, useGlobalProperties } from "../../utils";
174
88
 
175
89
  withDefaults(
176
90
  defineProps<{
177
91
  homeNavigationEnabled?: boolean;
178
- hasSideInfo?: boolean;
179
92
  macroStepList?: MacroStep[];
180
- categories?: MenuCategory[];
181
93
  hasContact?: boolean;
182
94
  }>(),
183
95
  {
184
96
  homeNavigationEnabled: true,
185
- hasSideInfo: true,
186
97
  hasContact: true,
187
98
  }
188
99
  );
@@ -190,29 +101,10 @@ withDefaults(
190
101
  const { activeViewport } = useViewportDetector();
191
102
  const { imageURL } = useGlobalProperties();
192
103
  const callModal = ref();
193
- const sidebarActive = ref(false);
194
104
 
195
105
  const callContact = () => {
196
106
  window.open("tel:211165765", "_self");
197
107
  };
198
-
199
- watch(
200
- () => sidebarActive.value,
201
- (newVal) => {
202
- if (newVal && callModal.value.active) {
203
- callModal.value.closeModal();
204
- }
205
- }
206
- );
207
-
208
- watch(
209
- () => callModal.value?.active,
210
- (newVal) => {
211
- if (callModal.value && newVal && sidebarActive.value) {
212
- sidebarActive.value = false;
213
- }
214
- }
215
- );
216
108
  </script>
217
109
 
218
110
  <style lang="scss" scoped>
@@ -225,7 +117,7 @@ header.main-header-container {
225
117
  z-index: 100;
226
118
  transition: z-index 0s linear 0.4s;
227
119
 
228
- &.sidebar-active {
120
+ &.overlay-active {
229
121
  z-index: 1002;
230
122
  transition: z-index 0s linear;
231
123
  }
@@ -251,12 +143,6 @@ header.main-header-container {
251
143
  gap: 24px;
252
144
  }
253
145
 
254
- &.has-categories {
255
- @media screen and (max-width: $break-md-max) {
256
- grid-template-columns: auto auto 1fr auto;
257
- }
258
- }
259
-
260
146
  .logo-container {
261
147
  user-select: none;
262
148
 
@@ -359,185 +245,4 @@ header.main-header-container {
359
245
  }
360
246
  }
361
247
  }
362
-
363
- .categories-container {
364
- display: none;
365
-
366
- @media screen and (min-width: $break-lg-min) {
367
- display: flex;
368
- flex-direction: row;
369
- justify-content: flex-end;
370
- gap: 16px;
371
- }
372
-
373
- .menu-category {
374
- position: relative;
375
- padding-bottom: 28px;
376
- margin-bottom: -28px;
377
-
378
- .category-label {
379
- display: flex;
380
- flex-direction: row;
381
- align-items: center;
382
- gap: 5px;
383
- font-size: 12px;
384
- line-height: 18px;
385
- font-weight: 700;
386
-
387
- @media screen and (min-width: $break-xl-min) {
388
- font-size: 16px;
389
- }
390
- }
391
-
392
- a.category-label {
393
- color: inherit;
394
- text-decoration: none;
395
- transition: all 0.3s ease-in-out;
396
-
397
- &:hover {
398
- color: #076b9c;
399
- }
400
- }
401
-
402
- .category-links-container {
403
- position: absolute;
404
- opacity: 0;
405
- transition: opacity 0.3s ease-in-out, transform 0s linear 0.3s;
406
- top: 100%;
407
- left: 50%;
408
- transform: scale(0);
409
- padding: 16px;
410
- background: #fff;
411
- box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.1);
412
- border-bottom-left-radius: 4px;
413
- border-bottom-right-radius: 4px;
414
-
415
- ul {
416
- display: flex;
417
- flex-direction: column;
418
- gap: 16px;
419
- list-style: none;
420
- margin: 0;
421
- padding: 0;
422
-
423
- a {
424
- font-size: 16px;
425
- line-height: 18px;
426
- font-weight: 700;
427
- color: inherit;
428
- text-decoration: none;
429
- transition: all 0.3s ease-in-out;
430
- white-space: nowrap;
431
-
432
- &:hover {
433
- color: #076b9c;
434
- }
435
- }
436
- }
437
- }
438
-
439
- &:hover {
440
- .category-links-container {
441
- opacity: 1;
442
- transform: translateX(-50%);
443
- transition: opacity 0.3s ease-in-out, transform 0s linear;
444
- }
445
- }
446
- }
447
- }
448
-
449
- .btn-sidebar-container {
450
- @media screen and (min-width: $break-lg-min) {
451
- display: none;
452
- }
453
-
454
- .btn-sidebar {
455
- display: block;
456
- background: none;
457
- border: none;
458
- padding: 0;
459
- width: 25px;
460
- height: 25px;
461
- font-size: 25px;
462
- line-height: 25px;
463
- }
464
- }
465
-
466
- .categories-sidebar {
467
- position: fixed;
468
- left: 0;
469
- bottom: 0;
470
- height: calc(100% - 60px);
471
- overflow-y: auto;
472
- display: flex;
473
- flex-direction: column;
474
- gap: 16px;
475
- width: 100%;
476
- background: #fff;
477
- z-index: 1001;
478
- padding: 16px 24px;
479
-
480
- @media screen and (min-width: $break-sm-min) {
481
- width: 300px;
482
- }
483
-
484
- &.slide-enter-active,
485
- &.slide-leave-active {
486
- transition: all 0.4s ease-in-out;
487
- }
488
-
489
- &.slide-enter-from,
490
- &.slide-leave-to {
491
- transform: translateX(-100%);
492
- }
493
-
494
- &.slide-enter-to,
495
- &.slide-leave-from {
496
- transform: translateX(0);
497
- }
498
-
499
- .category-links-container {
500
- display: flex;
501
- flex-direction: column;
502
- gap: 16px;
503
- list-style: none;
504
- margin: 0;
505
- padding: 0 0 16px;
506
- font-size: 16px;
507
- line-height: 18px;
508
- }
509
-
510
- .menu-link {
511
- color: inherit;
512
-
513
- &:hover {
514
- text-decoration: none;
515
- }
516
- }
517
-
518
- .menu-category-link {
519
- font-weight: 700;
520
- font-size: 16px;
521
- line-height: 18px;
522
- }
523
- }
524
-
525
- .categories-backdrop {
526
- @include backdrop;
527
-
528
- &.fade-enter-active,
529
- &.fade-leave-active {
530
- transition: all 0.4s ease-in-out;
531
- }
532
-
533
- &.fade-enter-from,
534
- &.fade-leave-to {
535
- opacity: 0;
536
- }
537
-
538
- &.fade-enter-to,
539
- &.fade-leave-from {
540
- opacity: 1;
541
- }
542
- }
543
248
  </style>
@@ -33,7 +33,6 @@ import CheckoutLayout from "./composite/CheckoutLayout.vue";
33
33
  import CheckoutMilestones from "./composite/CheckoutMilestones.vue";
34
34
  import ProductDetails from "./composite/ProductDetails.vue";
35
35
  import CjaMenuBar from "./composite/CjaMenuBar.vue";
36
- import CjaFooter from "./composite/CjaFooter.vue";
37
36
  import InfoShowcase from "./composite/InfoShowcase.vue";
38
37
 
39
38
  export {
@@ -68,7 +67,6 @@ export {
68
67
  CheckoutMilestones,
69
68
  JourneyMacroSteps,
70
69
  CjaMenuBar,
71
- CjaFooter,
72
70
  FixedContainer,
73
71
  InfoMessage,
74
72
  InfoShowcase,
@@ -1,8 +1,8 @@
1
1
  <template>
2
2
  <component
3
3
  class="cja-btn"
4
- :is="href ? 'a' : 'button'"
5
- :href="href"
4
+ :is="href || to ? altAnchor || 'a' : 'button'"
5
+ :href="href || to"
6
6
  :target="target"
7
7
  :class="[
8
8
  `btn-${type}`,
@@ -33,7 +33,9 @@ withDefaults(
33
33
  iconPosition?: "left" | "right";
34
34
  loading?: boolean;
35
35
  href?: AnchorHTMLAttributes["href"];
36
+ to?: AnchorHTMLAttributes["href"];
36
37
  target?: AnchorHTMLAttributes["target"];
38
+ altAnchor?: any;
37
39
  }>(),
38
40
  {
39
41
  type: "primary",
@@ -109,7 +109,7 @@ defineExpose({ active, openDrawer, closeDrawer, toggleDrawer });
109
109
  position: fixed;
110
110
  z-index: 1000;
111
111
  width: 100%;
112
- transition: all 0.3s ease-in-out;
112
+ transition: all 0.6s ease-in-out;
113
113
 
114
114
  @media screen and (min-width: $break-md-min) {
115
115
  max-width: var(--md-max-width);
@@ -132,7 +132,8 @@ defineExpose({ active, openDrawer, closeDrawer, toggleDrawer });
132
132
  transform: translateY(-100%);
133
133
  }
134
134
 
135
- &.active &.slide-enter-to,
135
+ &.active,
136
+ &.slide-enter-to,
136
137
  &.slide-leave-from {
137
138
  top: 0;
138
139
  transform: translateY(0);
@@ -142,13 +143,13 @@ defineExpose({ active, openDrawer, closeDrawer, toggleDrawer });
142
143
  &.drawer-vertical-bottom {
143
144
  bottom: -100%;
144
145
 
145
- &.active,
146
146
  &.slide-enter-from,
147
147
  &.slide-leave-to {
148
148
  bottom: -100%;
149
149
  transform: translateY(100%);
150
150
  }
151
151
 
152
+ &.active,
152
153
  &.slide-enter-to,
153
154
  &.slide-leave-from {
154
155
  bottom: 0;
package/src/types/Menu.ts CHANGED
@@ -1,19 +1,6 @@
1
- import { StoryLink } from "./Storyblok";
2
-
3
1
  export interface MacroStep {
4
2
  label: string;
5
3
  icon: string;
6
4
  status: "past" | "current" | "future";
7
5
  navigationUrl?: string;
8
6
  }
9
-
10
- export interface MenuLink {
11
- text: string;
12
- link: StoryLink;
13
- }
14
-
15
- export interface MenuCategory {
16
- text: string;
17
- link?: StoryLink;
18
- subLinks?: MenuLink[];
19
- }
@@ -1,5 +1,4 @@
1
- import { MacroStep, MenuLink, MenuCategory } from "./Menu";
2
- import { FooterCategory, SocialLink } from "./Footer";
1
+ import { MacroStep } from "./Menu";
3
2
  import { SelectOption } from "./SelectOption";
4
3
  import { TileOption } from "./TileOption";
5
4
  import { CheckoutMilestone } from "./CheckoutMilestone";
@@ -7,13 +6,9 @@ import { StoreData, StoreDataValue } from "./StoreDataValue";
7
6
 
8
7
  export type {
9
8
  MacroStep,
10
- MenuCategory,
11
- MenuLink,
12
9
  SelectOption,
13
10
  TileOption,
14
11
  CheckoutMilestone,
15
12
  StoreData,
16
13
  StoreDataValue,
17
- FooterCategory,
18
- SocialLink,
19
14
  };
@@ -0,0 +1,43 @@
1
+ export const getCalendarUrl = (options: {
2
+ title: string;
3
+ description?: string;
4
+ location?: string;
5
+ dateStart: Date;
6
+ dateEnd: Date;
7
+ allDay?: boolean;
8
+ }) => {
9
+ const url = new URL("calendar/render", "https://www.google.com");
10
+
11
+ const formatText = (text: string) => text.trim();
12
+ const formatDate = (date: Date) => {
13
+ const targetDate = new Date(date)
14
+ .toISOString()
15
+ .replaceAll(/:/g, "")
16
+ .replaceAll(/-/g, "")
17
+ .replaceAll(/\.\d{3}(?=Z)/g, "");
18
+
19
+ if (options.allDay) {
20
+ targetDate.replaceAll(/T\d{6}(?=Z)/g, "");
21
+ }
22
+
23
+ return targetDate;
24
+ };
25
+
26
+ url.searchParams.set("action", "TEMPLATE");
27
+ url.searchParams.set("text", formatText(options.title));
28
+
29
+ if (options.description) {
30
+ url.searchParams.set("details", formatText(options.description));
31
+ }
32
+
33
+ if (options.location) {
34
+ url.searchParams.set("location", formatText(options.location));
35
+ }
36
+
37
+ url.searchParams.set(
38
+ "dates",
39
+ `${formatDate(options.dateStart)}/${formatDate(options.dateEnd)}`
40
+ );
41
+
42
+ return url.toString();
43
+ };
@@ -3,6 +3,7 @@ import { generateRoutes } from "./generateRoutes";
3
3
  import { useViewportDetector } from "./useViewportDetector";
4
4
  import { useGlobalProperties } from "./useGlobalProperties";
5
5
  import { jsonReviver } from "./jsonReviver";
6
+ import { getCalendarUrl } from "./getCalendarUrl";
6
7
  import { getI18nMessages } from "./getMessages";
7
8
  import { findScrollAncestor } from "./findScrollAncestor";
8
9
  import { updateForm } from "./updateForm";
@@ -11,7 +12,6 @@ import { uploadFile } from "./uploadFile";
11
12
  import { useCjaGtm } from "./gtm";
12
13
  import { getCjaRouter } from "./cjaRouter";
13
14
  import { getCjaStore } from "./cjaStore";
14
- import { getStoryblokUrl } from "./storyblokLink";
15
15
 
16
16
  export {
17
17
  formValidation,
@@ -20,6 +20,7 @@ export {
20
20
  useGlobalProperties,
21
21
  jsonReviver,
22
22
  getI18nMessages,
23
+ getCalendarUrl,
23
24
  findScrollAncestor,
24
25
  updateForm,
25
26
  getFromUrl,
@@ -27,5 +28,4 @@ export {
27
28
  useCjaGtm,
28
29
  getCjaRouter,
29
30
  getCjaStore,
30
- getStoryblokUrl,
31
31
  };
@@ -1,34 +0,0 @@
1
- import { FooterCategory, SocialLink } from "../../types/Footer";
2
- declare const _default: import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
3
- navGroups: FooterCategory[][];
4
- socialLinksTitle?: string | undefined;
5
- socialLinks?: SocialLink[] | undefined;
6
- }>, {
7
- socialLinksTitle: string;
8
- }>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<{
9
- navGroups: FooterCategory[][];
10
- socialLinksTitle?: string | undefined;
11
- socialLinks?: SocialLink[] | undefined;
12
- }>, {
13
- socialLinksTitle: string;
14
- }>>>, {
15
- socialLinksTitle: string;
16
- }, {}>;
17
- export default _default;
18
- type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
19
- type __VLS_TypePropsToRuntimeProps<T> = {
20
- [K in keyof T]-?: {} extends Pick<T, K> ? {
21
- type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
22
- } : {
23
- type: import('vue').PropType<T[K]>;
24
- required: true;
25
- };
26
- };
27
- type __VLS_WithDefaults<P, D> = {
28
- [K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_Prettify<P[K] & {
29
- default: D[K];
30
- }> : P[K];
31
- };
32
- type __VLS_Prettify<T> = {
33
- [K in keyof T]: T[K];
34
- } & {};
@@ -1,15 +0,0 @@
1
- import { StoryLink } from "./Storyblok";
2
- interface FooterLink {
3
- text: string;
4
- link: StoryLink;
5
- }
6
- export interface FooterCategory {
7
- text: string;
8
- link?: StoryLink;
9
- subLinks?: FooterLink[];
10
- }
11
- export interface SocialLink {
12
- socialNetwork: string;
13
- link: StoryLink;
14
- }
15
- export {};
@@ -1,10 +0,0 @@
1
- export interface StoryLink {
2
- linktype: "url" | "story" | "asset" | "email";
3
- url?: string;
4
- target?: HTMLAnchorElement["target"];
5
- story?: {
6
- url: string;
7
- slug: string;
8
- full_slug: string;
9
- };
10
- }
@@ -1,2 +0,0 @@
1
- import { StoryLink } from "../types/Storyblok";
2
- export declare const getStoryblokUrl: (link: StoryLink) => string | undefined;