@dcodegroup-au/page-builder 0.1.1 → 0.1.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.
@@ -0,0 +1,86 @@
1
+ <template>
2
+ <div class="flex flex-col md:flex-row justify-center gap-4 items-stretch mt-6">
3
+ <!-- Left Column: Links -->
4
+ <div class="flex-1 w-full md:w-1/2 flex flex-col">
5
+ <div v-for="item in publicTabs" :key="item.title">
6
+ <div
7
+ class="flex-col flex gap-1.5 cursor-pointer hover:bg-navy-50 mb-4 group"
8
+ :class="{'border-l-4 border-brand-600': selectedItem === item}"
9
+ @click.prevent="selectItem(item)"
10
+ >
11
+ <div class="py-4 pl-4 md:pl-6">
12
+ <p
13
+ :class="{'text-gray-900': selectedItem === item, 'text-gray-600': selectedItem !== item}"
14
+ class="text-lg md:text-xl font-semibold mb-2 group-hover:text-gray-900"
15
+ >
16
+ {{ item.title }}
17
+ </p>
18
+ <p
19
+ :class="{'text-gray-700': selectedItem === item, 'text-gray-400': selectedItem !== item}"
20
+ class="text-sm md:text-md font-normal group-hover:text-gray-700"
21
+ >
22
+ {{ item.description }}
23
+ </p>
24
+ </div>
25
+ </div>
26
+ </div>
27
+ </div>
28
+
29
+ <!-- Right Column: Image and Button -->
30
+ <div class="flex-1 w-full md:w-1/2 bg-transparent flex flex-col items-center">
31
+ <transition name="fade" mode="out-in">
32
+ <div class="flex flex-col items-center" :key="selectedItem?.title">
33
+ <img
34
+ v-if="selectedItem?.featured_image"
35
+ :src="selectedItem.featured_image"
36
+ alt="Selected Item Image"
37
+ class="rounded-[20px] md:rounded-[40px] object-contain max-h-[200px] md:max-h-[387px] w-full"/>
38
+ <img
39
+ v-else
40
+ class="rounded-[20px] md:rounded-[40px] object-contain max-h-[200px] md:max-h-[387px] w-full"
41
+ src="@/assets/img/no_image_available.jpeg"
42
+ alt="No Image Available">
43
+ <a
44
+ v-if="selectedItem?.primary_button?.show"
45
+ class="text-sm md:text-md font-semibold text-brand-600 flex items-center gap-2 mt-4"
46
+ :target="selectedItem?.primary_button?.is_new_tab ? '_blank' : ''"
47
+ :href="selectedItem?.primary_button?.url.startsWith('http') ? selectedItem.primary_button.url : `//${selectedItem.primary_button.url}`"
48
+ >
49
+ {{ selectedItem?.primary_button?.label ?? 'N/A' }}
50
+ <ArrowUpRight class="w-4 h-4 md:w-5 md:h-5" />
51
+ </a>
52
+ </div>
53
+ </transition>
54
+ </div>
55
+ </div>
56
+ </template>
57
+
58
+ <script setup>
59
+ import { ref, onMounted } from "vue";
60
+ import ArrowUpRight from '@/assets/img/icons/arrow-up-right.svg';
61
+
62
+ const props = defineProps({
63
+ component: {
64
+ required: true,
65
+ type: Object,
66
+ },
67
+ });
68
+
69
+ const component = ref(props.component);
70
+ const selectedItem = ref(null);
71
+
72
+ // Filter to get only public tabs
73
+ const publicTabs = ref(component.value.data.filter((item) => item.public));
74
+
75
+ // Method to select an item
76
+ const selectItem = (item) => {
77
+ selectedItem.value = item;
78
+ };
79
+
80
+ // Preselect the first public item on component mount
81
+ onMounted(() => {
82
+ if (publicTabs.value.length > 0) {
83
+ selectItem(publicTabs.value[0]);
84
+ }
85
+ });
86
+ </script>
@@ -0,0 +1,41 @@
1
+ <template>
2
+ <div class="max-w-[1392px] 1xl:max-w-[1824px] mx-auto w-full">
3
+ <div class="md:mx-[90px] bg-navy-25 rounded-[48px] p-16">
4
+ <div v-for="(component, index) in section.components">
5
+ <component
6
+ :is="currentComponent(component)"
7
+ :key="index"
8
+ :component="component"
9
+ ></component>
10
+ </div>
11
+ </div>
12
+ </div>
13
+ </template>
14
+
15
+ <script setup>
16
+ import { ref, markRaw } from "vue";
17
+ import VHeaderPresenter from "@/components/presenters/components/VHeaderPresenter.vue";
18
+ import VVerticalTabPresenter from "@/components/presenters/components/VVerticalTabPresenter.vue";
19
+
20
+ const props = defineProps({
21
+ section: {
22
+ required: true,
23
+ type: Object,
24
+ },
25
+ });
26
+
27
+ const section = ref(props.section);
28
+ const componentMaps = ref({
29
+ header: markRaw(VHeaderPresenter),
30
+ vertical_tabs: markRaw(VVerticalTabPresenter),
31
+ });
32
+
33
+ const currentComponent = (component) => {
34
+ if (!component?.type) {
35
+ return '';
36
+ }
37
+
38
+ return componentMaps.value[component?.type];
39
+ };
40
+
41
+ </script>
@@ -17,6 +17,7 @@ module.exports = {
17
17
  },
18
18
  colors: {
19
19
  navy: {
20
+ 900: '#182E43',
20
21
  800: '#203E5A',
21
22
  600: '#3E5F7E',
22
23
  400: '#69829B',
@@ -1,87 +0,0 @@
1
- <template>
2
- <div class="flex justify-between pb-6">
3
- <div class="text-lg font-semibold text-gray-900">
4
- {{ props.data.item.name }}
5
- </div>
6
- </div>
7
- <div class="flex flex-col gap-4">
8
- <div class="text-gray-600">
9
- {{ props.data.item.supportive_text }}
10
- </div>
11
- <hr class="bg-gray-200" />
12
- <div class="flex flex-col gap-3">
13
- <div class="flex justify-between">
14
- <div class="flex flex-col gap-1">
15
- <div class="font-semibold text-gray-900">{{ $t("pages.page_builder.vertical_tabs.tabs") }}</div>
16
- <div class="text-sm text-gray-600">{{ $t("menu.generic.up_to", { count: props.data.item.max_items }) }}</div>
17
- </div>
18
- <button
19
- :disabled="dataRef.items.length >= props.data.item.max_items"
20
- @click="addItem"
21
- type="button"
22
- class="text-sm flex items-center justify-center gap-1 rounded-[99px] border border-brand-600 bg-brand-600 px-3.5 py-2.5 font-semibold text-white"
23
- :class="{ 'border-gray-100 bg-gray-100 !text-gray-400': dataRef.items.length >= props.data.item.max_items }"
24
- >
25
- <PlusIcon class="h-5 w-5"></PlusIcon>
26
- <span>{{ $t("generic.buttons.add") }}</span>
27
- </button>
28
- </div>
29
- <div class="flex flex-col gap-3">
30
- <div class="flex items-center gap-4 px-2 py-1 hover:bg-gray-200" v-for="(item, index) in dataRef.items">
31
- <div class="flex flex-1 cursor-pointer items-center justify-between">
32
- <div class="flex flex-1 flex-col" @click="edit(index)">
33
- <div class="text-xs text-gray-600">
34
- {{ $t("pages.page_builder.vertical_tabs.item_title", { index: index + 1 }) }}
35
- </div>
36
- <div class="text-sm font-medium text-gray-900">
37
- {{ item.title }}
38
- </div>
39
- </div>
40
- <action-menu>
41
- <button class="flex items-center gap-2 p-2.5" type="button" @click="handleDeleteItem(index)">
42
- <TrashIcon class="h-5 w-5 cursor-pointer" />
43
- <span class="text-sm font-medium text-gray-700">
44
- {{ $t("pages.page_builder.vertical_tabs.delete_item") }}
45
- </span>
46
- </button>
47
- </action-menu>
48
- </div>
49
- </div>
50
- </div>
51
- </div>
52
- </div>
53
- </template>
54
- <script setup>
55
- import PlusIcon from "@/assets/img/icons/plus.svg";
56
- import TrashIcon from "@/assets/img/icons/trash-01.svg";
57
- import { defaultProps } from "@/js/vue/components/admin/pages/common/defaultProps.js";
58
- import { createTab } from "@/js/vue/components/admin/pages/common/pageBuilderFactory.js";
59
-
60
- const emit = defineEmits(["update"]);
61
- const route = inject("route");
62
-
63
- const props = defineProps({
64
- ...defaultProps,
65
- });
66
-
67
- const dataRef = ref(props.data.item);
68
-
69
- const addItem = () => {
70
- dataRef.value.items.push(createTab());
71
- emit("update", dataRef.value);
72
- };
73
-
74
- const handleDeleteItem = (index) => {
75
- dataRef.value.items.splice(index, 1);
76
- emit("update", dataRef.value);
77
- };
78
-
79
- const edit = (index) => {
80
- window.location.href = route("admin.pages.edit-attribute", {
81
- page: props.data.pageAttribute.page_id,
82
- attribute: props.data.pageAttribute.id,
83
- moduleIndex: props.data.subModuleIndex,
84
- itemIndex: index,
85
- });
86
- };
87
- </script>