cja-phoenix 0.2.9 → 0.2.11

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 (33) hide show
  1. package/dist/cja-phoenix.es.js +5535 -4712
  2. package/dist/style.css +1 -1
  3. package/dist/types/components/composite/InfoShowcase.vue.d.ts +25 -0
  4. package/dist/types/components/composite/ResultsSidebar.vue.d.ts +1 -28
  5. package/dist/types/components/index.d.ts +2 -1
  6. package/dist/types/utils/findScrollAncestor.d.ts +1 -0
  7. package/dist/types/utils/getFromUrl.d.ts +1 -0
  8. package/dist/types/utils/getI18nMessages.d.ts +1 -0
  9. package/dist/types/utils/index.d.ts +9 -4
  10. package/dist/types/utils/jsonReviver.d.ts +1 -0
  11. package/dist/types/utils/updateForm.d.ts +10 -0
  12. package/dist/types/utils/uploadFile.d.ts +8 -0
  13. package/package.json +1 -1
  14. package/src/components/composite/CheckoutCrossSell.vue +37 -21
  15. package/src/components/composite/CheckoutLayout.vue +6 -4
  16. package/src/components/composite/CheckoutMilestones.vue +8 -8
  17. package/src/components/composite/InfoShowcase.vue +83 -0
  18. package/src/components/composite/ResultsSidebar.vue +1 -33
  19. package/src/components/forms/SelectInput.vue +9 -1
  20. package/src/components/index.ts +2 -0
  21. package/src/components/structural/InfoMessage.vue +17 -5
  22. package/src/utils/findScrollAncestor.ts +16 -0
  23. package/src/utils/getFromUrl.ts +16 -0
  24. package/src/utils/getI18nMessages.ts +23 -0
  25. package/src/utils/index.ts +18 -4
  26. package/src/utils/{JsonReviver.ts → jsonReviver.ts} +1 -1
  27. package/src/utils/updateForm.ts +35 -0
  28. package/src/utils/uploadFile.ts +22 -0
  29. package/dist/types/utils/JsonReviver.d.ts +0 -1
  30. /package/dist/types/utils/{RouteGenerator.d.ts → generateRoutes.d.ts} +0 -0
  31. /package/dist/types/utils/{ViewportDetector.d.ts → useViewportDetector.d.ts} +0 -0
  32. /package/src/utils/{RouteGenerator.ts → generateRoutes.ts} +0 -0
  33. /package/src/utils/{ViewportDetector.ts → useViewportDetector.ts} +0 -0
@@ -10,9 +10,11 @@
10
10
  </GridItem>
11
11
  <GridItem
12
12
  class="checkout-sidebar"
13
- v-if="activeViewport.lg && $slots.sidebar"
13
+ v-if="$slots.sidebar"
14
+ :size-sm="2"
15
+ :size-md="4"
14
16
  :size-lg="4"
15
- :style="{ background: sidebarBackground }"
17
+ :style="{ background: activeViewport.lg ? sidebarBackground : '' }"
16
18
  >
17
19
  <slot name="sidebar"></slot>
18
20
  </GridItem>
@@ -35,7 +37,7 @@ defineProps<{
35
37
  .checkout-container {
36
38
  .checkout-wrapper {
37
39
  max-width: 750px;
38
- padding: 32px 16px;
40
+ padding: 32px 0;
39
41
  margin: 0 auto;
40
42
 
41
43
  @media screen and (min-width: 1024px) {
@@ -44,7 +46,7 @@ defineProps<{
44
46
  }
45
47
 
46
48
  .checkout-sidebar {
47
- padding: 32px 16px;
49
+ padding: 32px 0;
48
50
  border-top: 1px solid #dedede;
49
51
 
50
52
  @media screen and (min-width: 992px) {
@@ -49,14 +49,14 @@ defineProps<{
49
49
  gap: 15px;
50
50
  padding: 0 16px;
51
51
 
52
+ $step-icon-size: 25px;
53
+
52
54
  .step-icon {
53
- position: relative;
54
- z-index: 1;
55
55
  display: flex;
56
56
  justify-content: center;
57
57
  align-items: center;
58
- width: 25px;
59
- height: 25px;
58
+ width: $step-icon-size;
59
+ height: $step-icon-size;
60
60
  border-radius: 50%;
61
61
  color: #fff;
62
62
  font-weight: 700;
@@ -95,9 +95,9 @@ defineProps<{
95
95
  &.milestone-past {
96
96
  &::after {
97
97
  content: "";
98
- top: 0;
98
+ top: $step-icon-size;
99
99
  background-color: #77aa43;
100
- height: calc(100% + 35px);
100
+ height: calc(100% - $step-icon-size + 35px);
101
101
  }
102
102
 
103
103
  .step-icon {
@@ -118,8 +118,8 @@ defineProps<{
118
118
  }
119
119
 
120
120
  &:not(:last-child)::after {
121
- top: 0;
122
- height: 100%;
121
+ top: $step-icon-size;
122
+ height: calc(100% - $step-icon-size);
123
123
  }
124
124
 
125
125
  .step-icon {
@@ -0,0 +1,83 @@
1
+ <template>
2
+ <div class="info-showcase">
3
+ <h2>{{ title }}</h2>
4
+ <div class="showcase-list">
5
+ <div class="showcase-item" v-for="item in items">
6
+ <div class="image-container">
7
+ <img :src="item.image" />
8
+ </div>
9
+ <div class="text-container">
10
+ <div class="title">
11
+ {{ item.title }}
12
+ </div>
13
+ <div class="description">
14
+ {{ item.description }}
15
+ </div>
16
+ </div>
17
+ </div>
18
+ </div>
19
+ </div>
20
+ </template>
21
+
22
+ <script lang="ts" setup>
23
+ defineProps<{
24
+ title: string;
25
+ items: {
26
+ title: string;
27
+ description: string;
28
+ image: string;
29
+ }[];
30
+ }>();
31
+ </script>
32
+
33
+ <style lang="scss" scoped>
34
+ .info-showcase {
35
+ padding: 24px 36px;
36
+ background: #fff;
37
+ box-shadow: 0px 4px 40px rgba(0, 0, 0, 0.15);
38
+
39
+ h2 {
40
+ text-align: center;
41
+ font-weight: 700;
42
+ font-size: 24px;
43
+ line-height: 29px;
44
+ margin: 0 0 30px;
45
+ }
46
+
47
+ .showcase-list {
48
+ display: grid;
49
+ grid-template-columns: repeat(3, 1fr);
50
+ gap: 56px;
51
+ max-width: 1200px;
52
+ margin: 0 auto;
53
+ }
54
+
55
+ .showcase-item {
56
+ display: grid;
57
+ align-items: center;
58
+ grid-template-columns: 80px 1fr;
59
+ gap: 24px;
60
+
61
+ .image-container {
62
+ img {
63
+ display: block;
64
+ max-width: 100%;
65
+ }
66
+ }
67
+
68
+ .text-container {
69
+ .title {
70
+ font-weight: 700;
71
+ font-size: 18px;
72
+ line-height: 22px;
73
+ margin-bottom: 10px;
74
+ }
75
+
76
+ .description {
77
+ font-size: 14px;
78
+ line-height: 17px;
79
+ }
80
+ }
81
+ }
82
+ }
83
+ </style>
@@ -12,14 +12,8 @@
12
12
  maxHeight: !fixedContainer?.positionFixed ? sidebarMaxHeight : '',
13
13
  }"
14
14
  >
15
- <div class="sidebar-title">
16
- <span class="m-cgg-icon--filtros"></span>
17
- <span>{{ title }}</span>
18
- </div>
19
15
  <div class="sidebar-body">
20
- <div class="sidebar-body-wrapper">
21
- <slot></slot>
22
- </div>
16
+ <slot></slot>
23
17
  </div>
24
18
  </div>
25
19
  </FixedContainer>
@@ -35,15 +29,6 @@ const fixedContainer = ref();
35
29
  const sidebarContainer = ref();
36
30
  const sidebarMaxHeight = ref();
37
31
 
38
- withDefaults(
39
- defineProps<{
40
- title?: string;
41
- }>(),
42
- {
43
- title: "Filtros",
44
- }
45
- );
46
-
47
32
  const setSidebarHeight = () => {
48
33
  sidebarMaxHeight.value = `${
49
34
  window.innerHeight - sidebarContainer.value.offsetTop - 16 + window.scrollY
@@ -64,7 +49,6 @@ onUnmounted(() => {
64
49
  .sidebar-container {
65
50
  display: flex;
66
51
  flex-direction: column;
67
- gap: 16px;
68
52
  padding: 24px 16px;
69
53
  background: #ffffff;
70
54
  border: 1px solid #dedede;
@@ -75,22 +59,6 @@ onUnmounted(() => {
75
59
  max-height: 100%;
76
60
  }
77
61
 
78
- .sidebar-title {
79
- display: flex;
80
- align-items: center;
81
- gap: 16px;
82
- border-bottom: 1px solid #dedede;
83
- padding-bottom: 16px;
84
- font-weight: 700;
85
- font-size: 18px;
86
- line-height: 22px;
87
-
88
- .m-cgg-icon--filtros {
89
- color: #076b9c;
90
- font-weight: 700;
91
- }
92
- }
93
-
94
62
  .sidebar-body {
95
63
  overflow-y: auto;
96
64
  overflow-x: hidden;
@@ -66,7 +66,6 @@ import { useField } from "vee-validate";
66
66
  import {
67
67
  ref,
68
68
  computed,
69
- watch,
70
69
  onMounted,
71
70
  onUnmounted,
72
71
  InputHTMLAttributes,
@@ -76,6 +75,7 @@ import { SelectHTMLAttributes } from "vue";
76
75
  import { SelectOption } from "../../types/SelectOption";
77
76
  import InputError from "./structure/InputError.vue";
78
77
  import InputContainer from "./structure/InputContainer.vue";
78
+ import { findScrollAncestor } from "../../utils";
79
79
 
80
80
  const props = withDefaults(
81
81
  defineProps<{
@@ -190,9 +190,17 @@ const toggleCollapse = () => {
190
190
  }, 300);
191
191
  window.removeEventListener("click", closeSelectOutside);
192
192
  window.removeEventListener("scroll", closeSelectOutside);
193
+ findScrollAncestor(inputEl.value).removeEventListener(
194
+ "scroll",
195
+ closeSelectOutside
196
+ );
193
197
  } else {
194
198
  window.addEventListener("click", closeSelectOutside);
195
199
  window.addEventListener("scroll", closeSelectOutside);
200
+ findScrollAncestor(inputEl.value).addEventListener(
201
+ "scroll",
202
+ closeSelectOutside
203
+ );
196
204
  }
197
205
  }
198
206
  };
@@ -31,6 +31,7 @@ import CheckoutLayout from "./composite/CheckoutLayout.vue";
31
31
  import CheckoutMilestones from "./composite/CheckoutMilestones.vue";
32
32
  import ProductDetails from "./composite/ProductDetails.vue";
33
33
  import CjaMenuBar from "./composite/CjaMenuBar.vue";
34
+ import InfoShowcase from "./composite/InfoShowcase.vue";
34
35
 
35
36
  export {
36
37
  Modal,
@@ -64,4 +65,5 @@ export {
64
65
  CjaMenuBar,
65
66
  FixedContainer,
66
67
  InfoMessage,
68
+ InfoShowcase,
67
69
  };
@@ -3,10 +3,10 @@
3
3
  class="info-message"
4
4
  :class="[
5
5
  `color-${color}`,
6
- { 'has-icon': $slots.icon, 'has-toggle': toggle },
6
+ { 'has-icon': $slots.icon && activeViewport.m, 'has-toggle': toggle },
7
7
  ]"
8
8
  >
9
- <div class="icon-container" v-if="$slots.icon">
9
+ <div class="icon-container" v-if="$slots.icon && activeViewport.m">
10
10
  <slot name="icon"></slot>
11
11
  </div>
12
12
  <div class="text-container">
@@ -20,6 +20,8 @@
20
20
  </template>
21
21
 
22
22
  <script lang="ts" setup>
23
+ import { inject } from "vue";
24
+
23
25
  defineProps<{
24
26
  title?: string;
25
27
  description?: string;
@@ -27,6 +29,8 @@ defineProps<{
27
29
  color: "blue" | "green";
28
30
  }>();
29
31
 
32
+ const activeViewport: any = inject("activeViewport");
33
+
30
34
  defineEmits(["btn:close"]);
31
35
  </script>
32
36
 
@@ -35,12 +39,18 @@ defineEmits(["btn:close"]);
35
39
  display: grid;
36
40
  grid-template-columns: 1fr;
37
41
  gap: 16px;
38
- padding: 16px 24px;
42
+ padding: 8px 16px;
39
43
  border: 2px solid #000;
40
44
  border-radius: 16px;
41
45
 
46
+ @media screen and (min-width: 768px) {
47
+ padding: 16px 24px;
48
+ }
49
+
42
50
  &.has-icon {
43
- grid-template-columns: auto 1fr;
51
+ @media screen and (min-width: 768px) {
52
+ grid-template-columns: auto 1fr;
53
+ }
44
54
  }
45
55
 
46
56
  &.has-toggle {
@@ -48,7 +58,9 @@ defineEmits(["btn:close"]);
48
58
  }
49
59
 
50
60
  &.has-icon.has-toggle {
51
- grid-template-columns: auto 1fr 18px;
61
+ @media screen and (min-width: 768px) {
62
+ grid-template-columns: auto 1fr 18px;
63
+ }
52
64
  }
53
65
 
54
66
  &.color-green {
@@ -0,0 +1,16 @@
1
+ export const findScrollAncestor = (element) => {
2
+ if (!element) {
3
+ return undefined;
4
+ }
5
+
6
+ let parent = element.parentElement;
7
+ while (parent) {
8
+ const { overflowY } = window.getComputedStyle(parent);
9
+ if (overflowY === "auto" || overflowY === "scroll") {
10
+ return parent;
11
+ }
12
+ parent = parent.parentElement;
13
+ }
14
+
15
+ return document.documentElement;
16
+ };
@@ -0,0 +1,16 @@
1
+ export const getFromUrl = (param: string, removeFromUrl?: boolean) => {
2
+ const url = new URL(window.location.href);
3
+
4
+ if (url.searchParams.has(param)) {
5
+ const returnParam = url.searchParams.get(param);
6
+
7
+ if (removeFromUrl) {
8
+ url.searchParams.delete(param);
9
+ history.replaceState(history.state, "", url.toString());
10
+ }
11
+
12
+ return returnParam;
13
+ } else {
14
+ return undefined;
15
+ }
16
+ };
@@ -0,0 +1,23 @@
1
+ import { I18nOptions, createI18n } from "vue-i18n";
2
+
3
+ export const getI18nMessages = async (queryMessages: string) => {
4
+ const i18n = createI18n({
5
+ locale: "PT",
6
+ fallbackLocale: "PT",
7
+ messages: undefined,
8
+ legacy: false,
9
+ missingWarn: false,
10
+ fallbackWarn: false,
11
+ warnHtmlMessage: false,
12
+ });
13
+
14
+ await fetch(
15
+ `${process.env.VUE_APP_API_URL}/Internationalization?contains=${queryMessages}`
16
+ )
17
+ .then((response) => response.json())
18
+ .then((data: I18nOptions["messages"]) =>
19
+ i18n.global.setLocaleMessage("PT", data || {})
20
+ );
21
+
22
+ return i18n;
23
+ };
@@ -1,5 +1,19 @@
1
- import { generateRoutes } from "./RouteGenerator";
2
- import { useViewportDetector } from "./ViewportDetector";
3
- import { JsonReviver } from "./JsonReviver";
1
+ import { generateRoutes } from "./generateRoutes";
2
+ import { useViewportDetector } from "./useViewportDetector";
3
+ import { jsonReviver } from "./jsonReviver";
4
+ import { getI18nMessages } from "./getI18nMessages";
5
+ import { findScrollAncestor } from "./findScrollAncestor";
6
+ import { updateForm } from "./updateForm";
7
+ import { getFromUrl } from "./getFromUrl";
8
+ import { uploadFile } from "./uploadFile";
4
9
 
5
- export { generateRoutes, useViewportDetector, JsonReviver };
10
+ export {
11
+ generateRoutes,
12
+ useViewportDetector,
13
+ jsonReviver,
14
+ getI18nMessages,
15
+ findScrollAncestor,
16
+ updateForm,
17
+ getFromUrl,
18
+ uploadFile,
19
+ };
@@ -1,4 +1,4 @@
1
- export const JsonReviver = (data: any) =>
1
+ export const jsonReviver = (data: any) =>
2
2
  JSON.parse(data, (k, v) => {
3
3
  if (v === "true" || v === "false") {
4
4
  return v === "true";
@@ -0,0 +1,35 @@
1
+ export const updateForm = (options: {
2
+ journeyId: string | undefined;
3
+ step: number;
4
+ payload: any;
5
+ stepName: string;
6
+ isCompleted?: boolean;
7
+ sentToDialer?: boolean;
8
+ eventType?: string;
9
+ formType: string;
10
+ }) =>
11
+ fetch(`${process.env.VUE_APP_API_URL}/core/apis/data/updateForm`, {
12
+ method: "PUT",
13
+ body: JSON.stringify(
14
+ Object.fromEntries(
15
+ Object.entries({
16
+ eventType: options.eventType || "STEP_CHANGED",
17
+ isActionEvent: true,
18
+ journeyId: options.journeyId,
19
+ stepName: options.stepName,
20
+ isCompleted: options.isCompleted || false,
21
+ sentToDialer: options.sentToDialer || true,
22
+ lastStepNumber: options.step,
23
+ lastStepType: options.formType,
24
+ lastStepUrl:
25
+ window.location.pathname +
26
+ window.location.search +
27
+ window.location.hash,
28
+ data: JSON.stringify({
29
+ ...options.payload,
30
+ formType: options.formType,
31
+ }),
32
+ }).filter(([_, v]) => v != null)
33
+ )
34
+ ),
35
+ });
@@ -0,0 +1,22 @@
1
+ export const uploadFile = (options: {
2
+ basePath: string;
3
+ journeyId: string;
4
+ file: any;
5
+ fileName: string;
6
+ extension: string;
7
+ bucketName: string;
8
+ }) => {
9
+ const data = new FormData();
10
+
11
+ data.append(
12
+ "path",
13
+ `${options.basePath}/${options.journeyId}/${options.fileName}.${options.extension}`
14
+ );
15
+ data.append("file", options.file);
16
+ data.append("bucketName", options.bucketName);
17
+
18
+ return fetch(`${process.env.VUE_APP_API_URL}/core/apis/data/saveFileToS3`, {
19
+ method: "POST",
20
+ body: data,
21
+ });
22
+ };
@@ -1 +0,0 @@
1
- export declare const JsonReviver: (data: any) => any;