@dcodegroup-au/page-builder 0.2.7 → 0.2.9

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 (71) hide show
  1. package/dist/page-builder.css +2 -2
  2. package/dist/page-builder.es.js +33346 -11815
  3. package/dist/page-builder.umd.js +59 -59
  4. package/example/src/App.vue +40 -679
  5. package/example/src/main.js +2 -1
  6. package/example/src/pages/BestLife.js +351 -0
  7. package/example/src/pages/Home.js +677 -0
  8. package/package.json +1 -1
  9. package/src/assets/icons.json +3569 -0
  10. package/src/components/ItemEdit.vue +147 -71
  11. package/src/components/LinkCardEdit.vue +139 -0
  12. package/src/components/PageBuilder.vue +43 -10
  13. package/src/components/PageRender.vue +12 -0
  14. package/src/components/builders/CollectionCarousel.vue +62 -0
  15. package/src/components/builders/Header.vue +82 -0
  16. package/src/components/builders/ImageBlock.vue +56 -0
  17. package/src/components/builders/Items.vue +112 -0
  18. package/src/components/builders/Links.vue +123 -0
  19. package/src/components/builders/Logos.vue +122 -0
  20. package/src/components/builders/NewsGrid.vue +59 -0
  21. package/src/components/builders/Paragraph.vue +93 -0
  22. package/src/components/builders/VideoGrid.vue +101 -0
  23. package/src/components/common/Button.vue +53 -0
  24. package/src/components/common/Card.vue +5 -1
  25. package/src/components/common/FileUpload.vue +1 -1
  26. package/src/components/common/Icon.vue +41 -0
  27. package/src/components/common/IconSelector.vue +106 -0
  28. package/src/components/common/LinkedTo.vue +9 -3
  29. package/src/components/helpers/bundleIcons.js +1189 -0
  30. package/src/components/index.js +2 -1
  31. package/src/components/presenters/components/{VCarouselPresenter.vue → CarouselPresenter.vue} +8 -18
  32. package/src/components/presenters/components/{VCollectionGridPresenter.vue → CollectionGridPresenter.vue} +0 -5
  33. package/src/components/presenters/modules/CollectionCarousel.vue +2 -2
  34. package/src/components/presenters/modules/CollectionGrid.vue +2 -2
  35. package/src/components/presenters/modules/HeroHeader.vue +3 -3
  36. package/src/components/presenters/modules/LinkCard.vue +55 -0
  37. package/src/components/presenters/modules/LinkList.vue +51 -0
  38. package/src/components/presenters/modules/LogoCloud.vue +1 -1
  39. package/src/components/presenters/modules/Paragraph.vue +26 -0
  40. package/src/components/presenters/modules/QuickLinks.vue +2 -2
  41. package/src/components/presenters/modules/StandardHeader.vue +32 -0
  42. package/src/components/presenters/modules/Timeline.vue +55 -0
  43. package/src/components/presenters/modules/TwoColumnsImageContent.vue +36 -0
  44. package/src/components/presenters/modules/VTabs.vue +2 -2
  45. package/src/components/presenters/overridables/VCarouselPrimaryButton.vue +28 -0
  46. package/src/utils/generateIconBundle.js +33 -0
  47. package/src/utils/generateIconJson.js +30 -0
  48. package/tailwind.config.js +5 -0
  49. package/src/components/builders/BaseModuleForm.vue +0 -86
  50. package/src/components/builders/LogoBuilder.vue +0 -167
  51. package/src/components/builders/PageBuilderCarousel.vue +0 -18
  52. package/src/components/builders/PageBuilderGrid.vue +0 -18
  53. package/src/components/builders/PageBuilderSectionHeader.vue +0 -30
  54. package/src/components/builders/PageModal.vue +0 -92
  55. package/src/components/builders/VCollectionCarousel.vue +0 -58
  56. package/src/components/builders/VHeader.vue +0 -55
  57. package/src/components/builders/VItems.vue +0 -110
  58. package/src/components/builders/VLinks.vue +0 -121
  59. package/src/components/builders/VLogos.vue +0 -121
  60. package/src/components/builders/VNewsGrid.vue +0 -55
  61. package/src/components/builders/VVideoGrid.vue +0 -99
  62. package/src/components/common/forms/LogosForm.vue +0 -39
  63. package/src/components/common/forms/PageBuilderLinksForm.vue +0 -39
  64. package/src/components/common/forms/SectionHeaderForm.vue +0 -45
  65. package/src/components/common/forms/TabForm.vue +0 -90
  66. /package/src/components/common/{VModal.vue → Modal.vue} +0 -0
  67. /package/src/components/common/{VToggle.vue → Toggle.vue} +0 -0
  68. /package/src/components/presenters/components/{VHeaderPresenter.vue → HeaderPresenter.vue} +0 -0
  69. /package/src/components/presenters/components/{VLinkPresenter.vue → LinkPresenter.vue} +0 -0
  70. /package/src/components/presenters/components/{VSliderPresenter.vue → SliderPresenter.vue} +0 -0
  71. /package/src/components/presenters/components/{VVerticalTabPresenter.vue → VerticalTabPresenter.vue} +0 -0
@@ -2,5 +2,6 @@ import '@/assets/css/style.css';
2
2
  import PageBuilder from './PageBuilder.vue';
3
3
  import PageRender from './PageRender.vue';
4
4
  import ItemEdit from './ItemEdit.vue';
5
+ import LinkCardEdit from './LinkCardEdit.vue';
5
6
 
6
- export { PageBuilder, PageRender, ItemEdit };
7
+ export { PageBuilder, PageRender, ItemEdit, LinkCardEdit };
@@ -30,8 +30,8 @@
30
30
  {{ tag }}
31
31
  </span>
32
32
  </div>
33
- <h3 class="text-[24px] font-semibold text-gray-900 mb-3 leading-[32px] mt-3">
34
- {{ slide?.title }}
33
+ <h3 class="my-3">
34
+ <a class="text-[24px] font-semibold text-gray-900 leading-[32px] hover:underline" :href="slide.url" target="_blank">{{ slide?.title }}</a>
35
35
  </h3>
36
36
  <p
37
37
  class="text-base font-normal text-gray-600 leading-[24px] multiline-ellipsis"
@@ -47,19 +47,7 @@
47
47
  </div>
48
48
  </div>
49
49
  <div class="border-t border-gray-200 mt-4 pt-[17px] flex justify-between items-center">
50
- <a
51
- v-if="slide.primary_button?.url"
52
- :href="formatUrl(slide.primary_button.url)"
53
- target="_blank"
54
- class="hover:bg-brand-600 bg-brand-500 text-white h-[40px] rounded-full px-[14px] py-[10px] inline-flex gap-1.5 items-center shadow-xs text-sm"
55
- >
56
- <Plus v-if="slide.primary_button?.icon === 'plus'" class="w-4 h-4" />
57
- <ShoppingCart
58
- v-if="slide.primary_button?.icon === 'shopping-cart-01'"
59
- class="w-4 h-4"
60
- />
61
- {{ slide.primary_button.title }}
62
- </a>
50
+ <VCarouselPrimaryButton :button="slide.primary_button" />
63
51
  <a
64
52
  v-if="slide.secondary_button"
65
53
  target="_blank"
@@ -101,14 +89,16 @@
101
89
  </template>
102
90
 
103
91
  <script setup>
104
- import { ref } from "vue";
92
+ import { ref, inject } from "vue";
105
93
  import Clock from "@/assets/img/icons/clock.svg";
106
- import Plus from "@/assets/img/icons/plus.svg";
107
- import ShoppingCart from "@/assets/img/icons/shopping-cart-01.svg";
108
94
  import ChevronRight from "@/assets/img/icons/chevron-right.svg";
109
95
  import ChevronLeft from "@/assets/img/icons/chevron-left.svg";
110
96
  import ArrowUpRight from "@/assets/img/icons/arrow-up-right.svg";
111
97
  import Ticket from "@/assets/img/icons/ticket-02.svg";
98
+ import DefaultPrimaryButton from "@/components/presenters/overridables/VCarouselPrimaryButton.vue";
99
+
100
+ // Inject the FileUpload component or fallback to the default one
101
+ const VCarouselPrimaryButton = inject("VCarouselPrimaryButton", DefaultPrimaryButton);
112
102
 
113
103
  const props = defineProps({
114
104
  component: {
@@ -26,11 +26,6 @@
26
26
  alt="Card Image"
27
27
  class="w-full h-[281px] object-cover rounded-[16px] mb-4"
28
28
  />
29
- <img
30
- v-else
31
- alt="Card Image"
32
- class="w-full h-[281px] object-cover rounded-[16px] mb-4"
33
- >
34
29
  <img v-else class="w-full h-[281px] object-cover rounded-[16px] mb-4" src="@/assets/img/no_image_available.jpeg">
35
30
  <div class="flex flex-col gap-2 items-start text-left w-full">
36
31
  <div v-if="card.categories && card.categories.length" class="flex gap-2">
@@ -13,8 +13,8 @@
13
13
 
14
14
  <script setup>
15
15
  import { ref, computed } from "vue";
16
- import VHeaderPresenter from "@/components/presenters/components/VHeaderPresenter.vue";
17
- import VCarousel from "@/components/presenters/components/VCarouselPresenter.vue";
16
+ import VHeaderPresenter from "@/components/presenters/components/HeaderPresenter.vue";
17
+ import VCarousel from "@/components/presenters/components/CarouselPresenter.vue";
18
18
 
19
19
  const props = defineProps({
20
20
  section: {
@@ -13,8 +13,8 @@
13
13
 
14
14
  <script setup>
15
15
  import { ref, markRaw } from "vue";
16
- import VHeaderPresenter from "@/components/presenters/components/VHeaderPresenter.vue";
17
- import VCollectionGridPresenter from "@/components/presenters/components/VCollectionGridPresenter.vue";
16
+ import VHeaderPresenter from "@/components/presenters/components/HeaderPresenter.vue";
17
+ import VCollectionGridPresenter from "@/components/presenters/components/CollectionGridPresenter.vue";
18
18
 
19
19
  const props = defineProps({
20
20
  section: {
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="rounded-[48px] max-w-[1392px] 1xl:max-w-[1824px] mx-auto w-full">
2
+ <div class="rounded-[48px] 1xl:max-w-[1824px] mx-auto w-full">
3
3
  <div v-for="(component, index) in section.components" class="md:px-[90px]">
4
4
  <component
5
5
  :is="currentComponent(component)"
@@ -12,8 +12,8 @@
12
12
 
13
13
  <script setup>
14
14
  import { ref, markRaw } from "vue";
15
- import VSliderPresenter from "@/components/presenters/components/VSliderPresenter.vue";
16
- import VLinkPresenter from "@/components/presenters/components/VLinkPresenter.vue";
15
+ import VSliderPresenter from "@/components/presenters/components/SliderPresenter.vue";
16
+ import VLinkPresenter from "@/components/presenters/components/LinkPresenter.vue";
17
17
 
18
18
  const props = defineProps({
19
19
  section: {
@@ -0,0 +1,55 @@
1
+ <template>
2
+ <div class="overflow-hidden bg-aqua-100">
3
+ <div class="max-w-[1400px] mx-auto w-full my-[40px]">
4
+ <div class="rounded-xl px-[40px] text-center mb-6 max-w-[1280px] mx-auto" v-if="headerComponent">
5
+ <h3 class="text-[36px] text-gray-900 font-semibold">{{ headerComponent.title }}</h3>
6
+ <p v-if="headerComponent?.supporting_text" class="text-[20px] font-normal mt-2 text-gray-600 leading-[30px] max-w-[768px] mx-auto" v-html="headerComponent.supporting_text"></p>
7
+ </div>
8
+ <div v-if="cardComponent" class="flex w-full" :class="{'gap-8': headerComponent?.featured_image}">
9
+ <img v-if="headerComponent?.featured_image"
10
+ :src="headerComponent?.featured_image"
11
+ class="w-1/2 h-[492px] rounded-br-[24px] rounded-tl-[24px]"
12
+ alt="Feature"/>
13
+
14
+ <div class="flex gap-8 w-full" :class="{'!w-1/2 flex-col': headerComponent?.featured_image}">
15
+ <div v-for="(data, index) in cardComponent.data" class="relative bg-white p-8 rounded-[24px] w-full">
16
+ <div v-if="data.icon" class="w-[48px] h-[48px] flex justify-center items-center rounded-[10px] text-white bg-aqua-900 mb-4">
17
+ <IconComponent :icon="data.icon" icon-classes="w-5 h-5" :key="index"></IconComponent>
18
+ </div>
19
+ <h1 class="text-[20px] font-semibold text-gray-900">{{ data.title }}</h1>
20
+ <p class="text-lg text-gray-600 mt-2 mb-4 leading-[24px]">{{ data.description }}</p>
21
+ <a
22
+ v-if="data?.primary_button.url"
23
+ class="text-brand-700 inline-flex gap-1.5 items-center font-semibold text-base"
24
+ :href="data.primary_button.url"
25
+ :target="data.primary_button.is_new_tab ? '_blank' : ''">
26
+ {{ data.primary_button.label }}
27
+ <ArrowUpRight class="w-5 h-5"></ArrowUpRight>
28
+ </a>
29
+ </div>
30
+ </div>
31
+ </div>
32
+ </div>
33
+ </div>
34
+ </template>
35
+ <script setup>
36
+ import {ref, computed} from "vue";
37
+ import ArrowUpRight from "@/assets/img/icons/arrow-up-right.svg";
38
+ import IconComponent from "@/components/common/Icon.vue";
39
+
40
+ const props = defineProps({
41
+ section: {
42
+ required: true,
43
+ type: Object,
44
+ },
45
+ });
46
+
47
+ const section = ref(props.section);
48
+ const headerComponent = computed(() => {
49
+ return section.value.components.find((component) => component.type === "header");
50
+ });
51
+ const cardComponent = computed(() => {
52
+ return section.value.components.find((component) => component.type === "link_cards");
53
+ });
54
+
55
+ </script>
@@ -0,0 +1,51 @@
1
+ <template>
2
+ <div class="overflow-hidden">
3
+ <div class="max-w-[1400px] mx-auto w-full bg-white py-[40px] flex">
4
+ <div v-for="(header, index) in headerComponents" v-if="section.two_columns" class="w-1/2 gap-4 px-[120px]">
5
+ <div class="rounded-xl px-[40px] text-center mb-6 max-w-[1280px] mx-auto" v-if="header">
6
+ <h3 class="text-[36px] text-gray-900 font-semibold">{{ header.title }}</h3>
7
+ <p v-if="header?.supporting_text" class="text-[20px] font-normal mt-2 text-gray-600 leading-[30px] max-w-[768px] mx-auto" v-html="header.supporting_text"></p>
8
+ </div>
9
+ <div v-if="linkComponents[index]" class="flex w-full">
10
+ <div class="flex flex-col gap-4 w-full">
11
+ <div v-for="(link, index) in linkComponents[index].data" class="relative bg-white hover:bg-gray-100 p-2 rounded-lg w-full">
12
+ <a
13
+ v-if="link.url"
14
+ class="text-gray-900 w-full inline-flex justify-between gap-1.5 items-center leading-[28px] font-semibold text-lg hover:underline"
15
+ :href="link.url"
16
+ :target="link.open_in_new_tab ? '_blank' : ''">
17
+ <div class="flex gap-4 items-center max-w-[94%] w-full">
18
+ <LinkExternal class="w-5 h-5"></LinkExternal>
19
+ <span class="w-full">{{ link.title }}</span>
20
+ </div>
21
+ <ArrowUpRight class="w-5 h-5"></ArrowUpRight>
22
+ </a>
23
+ </div>
24
+ </div>
25
+ </div>
26
+ </div>
27
+ </div>
28
+ </div>
29
+ </template>
30
+ <script setup>
31
+ import {ref, computed} from "vue";
32
+ import ArrowUpRight from "@/assets/img/icons/arrow-up-right.svg";
33
+ import LinkExternal from "@/assets/img/icons/link-external-01.svg";
34
+
35
+ const props = defineProps({
36
+ section: {
37
+ required: true,
38
+ type: Object,
39
+ },
40
+ });
41
+
42
+ const section = ref(props.section);
43
+ const headerComponents = computed(() => {
44
+ return section.value.components.filter((component) => component.type === "header");
45
+ });
46
+
47
+ const linkComponents = computed(() => {
48
+ return section.value.components.filter((component) => component.type === "links");
49
+ });
50
+
51
+ </script>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="w-full relative" :class="{'bg-gray-50': !isHorizontal}">
2
+ <div class="w-full relative">
3
3
  <div class="1xl:max-w-[1824px] mx-auto relative flex justify-center items-center"
4
4
  :class="{'py-8': isHorizontal, 'flex-col py-6': !isHorizontal}">
5
5
  <div v-for="(component, index) in section.components">
@@ -0,0 +1,26 @@
1
+ <template>
2
+ <div class="overflow-hidden">
3
+ <div class="max-w-[1400px] mx-auto w-full pt-4 mb-4">
4
+ <div class="max-w-[800px]" v-if="section.components[0]?.title">
5
+ <h3 class="text-[36px] text-gray-900 font-semibold">
6
+ {{ section.components[0].title }}
7
+ </h3>
8
+ <p class="text-xl font-normal leading-[30px] mt-4 text-gray-600" v-html="section.components[0].paragraph"></p>
9
+ </div>
10
+ </div>
11
+ </div>
12
+ </template>
13
+
14
+ <script setup>
15
+ import {ref} from "vue";
16
+
17
+ const props = defineProps({
18
+ section: {
19
+ required: true,
20
+ type: Object,
21
+ },
22
+ });
23
+
24
+ const section = ref(props.section);
25
+
26
+ </script>
@@ -18,8 +18,8 @@
18
18
 
19
19
  <script setup>
20
20
  import { ref, markRaw } from "vue";
21
- import VLinkPresenter from "@/components/presenters/components/VLinkPresenter.vue";
22
- import VHeaderPresenter from "@/components/presenters/components/VHeaderPresenter.vue";
21
+ import VLinkPresenter from "@/components/presenters/components/LinkPresenter.vue";
22
+ import VHeaderPresenter from "@/components/presenters/components/HeaderPresenter.vue";
23
23
  import HeaderVector from "@/assets/svg/header_right_vector.svg";
24
24
 
25
25
  const props = defineProps({
@@ -0,0 +1,32 @@
1
+ <template>
2
+ <div class="rounded-[48px] 1xl:max-w-[1824px] mx-auto w-full">
3
+ <div v-if="section.hasOwnProperty('components') > 0 && section.components.length > 0"
4
+ class="md:px-[90px] bg-navy-50 rounded-[48px] relative mb-[64px] pt-[164px]"
5
+ :class="{'flex flex-col items-center text-center': section.components[0]?.center}">
6
+ <h3 class="text-[48px] font-semibold text-gray-900 w-1/2">{{ section.components[0].title }}</h3>
7
+ <h3 class="text-xl font-normal text-gray-600 mt-3 w-1/2">{{ section.components[0].supporting_text }}</h3>
8
+ <img
9
+ v-if="section?.components[0]?.featured_image"
10
+ :src="section.components[0]?.featured_image"
11
+ alt="Card Image"
12
+ class="w-full max-w-[1632px] h-[480px] object-cover rounded-[48px] relative top-[64px]"
13
+ />
14
+ <img v-else class="w-full max-w-[1632px] h-[480px] object-cover rounded-[48px] relative top-[64px]"
15
+ src="@/assets/img/no_image_available.jpeg">
16
+ </div>
17
+ </div>
18
+ </template>
19
+
20
+ <script setup>
21
+ import {ref} from "vue";
22
+
23
+ const props = defineProps({
24
+ section: {
25
+ required: true,
26
+ type: Object,
27
+ },
28
+ });
29
+
30
+ const section = ref(props.section);
31
+
32
+ </script>
@@ -0,0 +1,55 @@
1
+ <template>
2
+ <div class="overflow-hidden">
3
+ <div class="max-w-[1400px] mx-auto w-full mt-[40px]">
4
+ <div class="rounded-xl px-[40px] text-center mb-1 max-w-[1280px] mx-auto" v-if="headerComponent">
5
+ <h3 class="text-[36px] text-gray-900 font-semibold">{{ headerComponent.title }}</h3>
6
+ <p v-if="headerComponent?.supporting_text" class="text-[20px] font-normal mt-2 text-gray-600 leading-[30px] max-w-[768px] mx-auto" v-html="headerComponent.supporting_text"></p>
7
+ </div>
8
+ <div v-if="timelineComponent">
9
+ <img :src="timelineComponent.featured_image" :alt="timelineComponent.caption" class="w-full h-auto" />
10
+ <p v-html="timelineComponent.caption" class="mt-2 text-[13px]"></p>
11
+ <div class="mt-4">
12
+ <div v-for="(data, index) in timelineComponent.data" class="flex flex-row">
13
+ <div class="w-1/5 mr-[40px] relative">
14
+ <h1 class=" text-[24px] font-semibold text-navy-800">{{ data.title }}</h1>
15
+ <div class="w-[32px] h-[32px] flex items-center justify-center border-2 border-navy-100 rounded-full absolute right-[-17px] bg-white top-0">
16
+ <p class="w-[16px] h-[16px] rounded-full bg-navy-600"></p>
17
+ </div>
18
+ <div class="h-full absolute right-[-2px]" style="background: repeating-linear-gradient(to bottom, transparent, transparent 10px, #A9B8C6 8px, #A9B8C6 20px); width: 2px;"></div>
19
+ </div>
20
+ <div class="w-4/5">
21
+ <p v-if="data.group_title" class="text-[24px] mb-6 font-semibold text-navy-800">{{ data.group_title }}</p>
22
+ <div
23
+ v-for="(line, index) in data.lines"
24
+ :key="index"
25
+ class="bg-pale-orange-100 p-6 mb-6 rounded-[16px]"
26
+ >
27
+ <h4 class="text-xl font-semibold text-gray-900">{{ line.title }}</h4>
28
+ <p class="text-xl text-gray-600 mt-3 leading-[30px]">{{ line.description }}</p>
29
+ </div>
30
+ </div>
31
+ </div>
32
+ </div>
33
+ </div>
34
+ </div>
35
+ </div>
36
+ </template>
37
+ <script setup>
38
+ import {ref, computed} from "vue";
39
+
40
+ const props = defineProps({
41
+ section: {
42
+ required: true,
43
+ type: Object,
44
+ },
45
+ });
46
+
47
+ const section = ref(props.section);
48
+ const headerComponent = computed(() => {
49
+ return section.value.components.find((component) => component.type === "header");
50
+ });
51
+ const timelineComponent = computed(() => {
52
+ return section.value.components.find((component) => component.type === "timeline_items");
53
+ });
54
+
55
+ </script>
@@ -0,0 +1,36 @@
1
+ <template>
2
+ <div class="overflow-hidden">
3
+ <div class="max-w-[1400px] mx-auto w-full mt-4">
4
+ <div class="grid grid-cols-12 gap-4">
5
+ <div class="col-span-4 bg-gray-100 rounded-xl p-8" v-if="paragraphComponent">
6
+ <h3 class="text-[20px] text-gray-900 font-semibold">{{ paragraphComponent.title }}</h3>
7
+ <p class="text-md font-normal mt-2 text-gray-600 leading-6" v-html="paragraphComponent.paragraph"></p>
8
+ </div>
9
+ <div class="col-span-8" v-if="imageComponent">
10
+ <img :src="imageComponent.featured_image" :alt="imageComponent.caption" class="w-full h-auto" />
11
+ <p v-html="imageComponent.caption" class="mt-2 text-[13px]"></p>
12
+ </div>
13
+ </div>
14
+ </div>
15
+ </div>
16
+ </template>
17
+
18
+ <script setup>
19
+ import {ref, computed} from "vue";
20
+
21
+ const props = defineProps({
22
+ section: {
23
+ required: true,
24
+ type: Object,
25
+ },
26
+ });
27
+
28
+ const section = ref(props.section);
29
+ const paragraphComponent = computed(() => {
30
+ return section.value.components.find((component) => component.type === "paragraph");
31
+ });
32
+ const imageComponent = computed(() => {
33
+ return section.value.components.find((component) => component.type === "image_block");
34
+ });
35
+
36
+ </script>
@@ -14,8 +14,8 @@
14
14
 
15
15
  <script setup>
16
16
  import { ref, markRaw } from "vue";
17
- import VHeaderPresenter from "@/components/presenters/components/VHeaderPresenter.vue";
18
- import VVerticalTabPresenter from "@/components/presenters/components/VVerticalTabPresenter.vue";
17
+ import VHeaderPresenter from "@/components/presenters/components/HeaderPresenter.vue";
18
+ import VVerticalTabPresenter from "@/components/presenters/components/VerticalTabPresenter.vue";
19
19
 
20
20
  const props = defineProps({
21
21
  section: {
@@ -0,0 +1,28 @@
1
+ <template>
2
+ <a
3
+ v-if="button?.url"
4
+ :href="formatUrl(button.url)"
5
+ target="_blank"
6
+ class="hover:bg-brand-600 bg-brand-500 text-white h-[40px] rounded-full px-[14px] py-[10px] inline-flex gap-1.5 items-center shadow-xs text-sm"
7
+ >
8
+ <Plus v-if="button?.icon === 'plus'" class="w-4 h-4" />
9
+ <ShoppingCart v-if="button?.icon === 'shopping-cart-01'" class="w-4 h-4" />
10
+ {{ button.title }}
11
+ </a>
12
+ </template>
13
+
14
+ <script setup>
15
+ import Plus from "@/assets/img/icons/plus.svg";
16
+ import ShoppingCart from "@/assets/img/icons/shopping-cart-01.svg";
17
+
18
+ const props = defineProps({
19
+ button: {
20
+ type: Object,
21
+ required: true,
22
+ },
23
+ });
24
+
25
+ const formatUrl = (url) => {
26
+ return url.startsWith("http") ? url : `//${url}`;
27
+ };
28
+ </script>
@@ -0,0 +1,33 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ const iconsDir = path.resolve(__dirname, '../assets/img/icons');
5
+ const iconFolder = path.resolve(__dirname, '../components/helpers');
6
+ const outputFile = path.resolve(iconFolder, 'bundleIcons.js');
7
+
8
+ const generateIconsBundle = () => {
9
+ try {
10
+ const files = fs.readdirSync(iconsDir);
11
+ const components = files
12
+ .filter((file) => file.endsWith('.svg')) // Only include .svg files
13
+ .map((file) => {
14
+ const name = path.basename(file, '.svg').toLowerCase()
15
+ .split(/[^a-zA-Z0-9]+/) // Split by non-alphanumeric characters
16
+ .map((word, index) =>
17
+ index === 0
18
+ ? word.charAt(0).toUpperCase() + word.slice(1) // Uppercase first word
19
+ : word.charAt(0).toUpperCase() + word.slice(1) // Uppercase subsequent words
20
+ )
21
+ .join('');
22
+ return `export { default as ${name} } from '@/assets/img/icons/${file}?component';`;
23
+ });
24
+
25
+ const bundleContent = components.join('\n');
26
+ fs.writeFileSync(outputFile, bundleContent);
27
+ console.log(`Icons bundle generated successfully at ${outputFile}`);
28
+ } catch (error) {
29
+ console.error('Error generating icons bundle:', error);
30
+ }
31
+ };
32
+
33
+ generateIconsBundle();
@@ -0,0 +1,30 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+
4
+ const iconsDir = path.resolve(__dirname, '../assets/img/icons');
5
+ const outputFile = path.resolve(__dirname, '../assets/icons.json');
6
+
7
+ const generateIconsJson = () => {
8
+ try {
9
+ const files = fs.readdirSync(iconsDir);
10
+ const icons = files
11
+ .filter((file) => file.endsWith('.svg')) // Only include .svg files
12
+ .map((file) => ({
13
+ name: path.basename(file, '.svg').toLowerCase()
14
+ .split(/[^a-zA-Z0-9]+/) // Split by non-alphanumeric characters
15
+ .map((word, index) =>
16
+ index === 0
17
+ ? word.charAt(0).toUpperCase() + word.slice(1) // Uppercase first word
18
+ : word.charAt(0).toUpperCase() + word.slice(1) // Uppercase subsequent words
19
+ )
20
+ .join(''), // Extract the name without extension
21
+ }));
22
+
23
+ fs.writeFileSync(outputFile, JSON.stringify(icons, null, 2));
24
+ console.log(`Icons JSON generated successfully at ${outputFile}`);
25
+ } catch (error) {
26
+ console.error('Error generating icons JSON:', error);
27
+ }
28
+ };
29
+
30
+ generateIconsJson();
@@ -23,6 +23,7 @@ module.exports = {
23
23
  600: '#3E5F7E',
24
24
  400: '#69829B',
25
25
  200: '#94A6B8',
26
+ 100: '#A9B8C6',
26
27
  50: '#DFE5EC',
27
28
  25: '#EFF2F5',
28
29
  },
@@ -42,6 +43,10 @@ module.exports = {
42
43
  },
43
44
  aqua: {
44
45
  100: '#EEF2F2',
46
+ 900: '#0FAC9A',
47
+ },
48
+ 'pale-orange': {
49
+ 100: '#FBF5F4',
45
50
  },
46
51
  success: {
47
52
  50: 'rgba(236, 253, 243, 1)',
@@ -1,86 +0,0 @@
1
- <template>
2
- <div class="pb-8">
3
- <component :is="props.form" @update="update" :data="props.data" :errors="errors" :sites="sites"></component>
4
- </div>
5
- </template>
6
- <script setup>
7
- const props = defineProps({
8
- form: {
9
- type: String,
10
- required: true,
11
- },
12
- subType: {
13
- type: String,
14
- required: false,
15
- },
16
- page: {
17
- type: Object,
18
- required: true,
19
- },
20
- attribute: {
21
- type: Object,
22
- required: true,
23
- },
24
- moduleIndex: {
25
- required: true,
26
- },
27
- itemIndex: {
28
- required: false,
29
- },
30
- data: {
31
- type: Object,
32
- required: true,
33
- },
34
- backUrl: {
35
- type: String,
36
- required: true,
37
- },
38
- sites: {
39
- type: Object,
40
- required: true,
41
- },
42
- redirectAfterResponse: {
43
- type: Boolean,
44
- default: true,
45
- },
46
- });
47
-
48
- const errors = ref({});
49
- const content = ref(props.page.attributes);
50
- const route = inject("route");
51
- const contentUnchanged = ref(true);
52
-
53
- const update = (data) => {
54
- const attributeIndex = content.value.findIndex((item) => item.id === props.attribute.id);
55
- if (props.itemIndex) {
56
- content.value[attributeIndex]["value"]["submodules"][props.moduleIndex]["items"][props.itemIndex] = data;
57
- } else {
58
- content.value[attributeIndex]["value"]["submodules"][props.moduleIndex] = data;
59
- }
60
-
61
- axios
62
- .post(route("api.admin.pages.update-content", { page: props.page.id }), {
63
- attributes: content.value,
64
- changes: data,
65
- form: props.form,
66
- subType: props.subType,
67
- })
68
- .then((response) => {
69
- contentUnchanged.value = true;
70
- if (props.redirectAfterResponse) {
71
- window.location.href = props.backUrl;
72
- } else {
73
- alert("Success");
74
- }
75
- })
76
- .catch(({ response }) => {
77
- errors.value = response.data.errors;
78
- });
79
- };
80
-
81
- watch(
82
- () => content.value,
83
- () => (contentUnchanged.value = false),
84
- { deep: true },
85
- );
86
- </script>