Compare commits
3 Commits
51ab320799
...
7b01ce6170
| Author | SHA1 | Date | |
|---|---|---|---|
| 7b01ce6170 | |||
| 709a2c3232 | |||
| 94abf5ce61 |
@@ -44,6 +44,8 @@ useHead({
|
|||||||
</div>
|
</div>
|
||||||
</a-config-provider> -->
|
</a-config-provider> -->
|
||||||
<NuxtLayout>
|
<NuxtLayout>
|
||||||
|
<KeepAlive>
|
||||||
<NuxtPage />
|
<NuxtPage />
|
||||||
|
</KeepAlive>
|
||||||
</NuxtLayout>
|
</NuxtLayout>
|
||||||
</template>
|
</template>
|
||||||
@@ -2,20 +2,7 @@
|
|||||||
> .section-container {
|
> .section-container {
|
||||||
> .layout_define {
|
> .layout_define {
|
||||||
> .section_layout {
|
> .section_layout {
|
||||||
@apply gap-x-14
|
@apply gap-x-10 #{!important}
|
||||||
|
|
||||||
> div {
|
|
||||||
background: red;
|
|
||||||
|
|
||||||
> div {
|
|
||||||
article {
|
|
||||||
background: red;
|
|
||||||
h3 {
|
|
||||||
@apply text-xl #{!important}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ const drop = (e: any) => {
|
|||||||
<article class="basic-article gap-x-4" :class="[LAYOUT_PARSE['LAYOUT'] || 'horizontal', !parseData && 'no-data', LAYOUT_PARSE['REVERSE'] ? 'reverse' : '']">
|
<article class="basic-article gap-x-4" :class="[LAYOUT_PARSE['LAYOUT'] || 'horizontal', !parseData && 'no-data', LAYOUT_PARSE['REVERSE'] ? 'reverse' : '']">
|
||||||
<div v-if="!LAYOUT_PARSE['HIDE'] || !LAYOUT_PARSE['HIDE'].includes('thumbnail')" class="basic-article_thumbnail">
|
<div v-if="!LAYOUT_PARSE['HIDE'] || !LAYOUT_PARSE['HIDE'].includes('thumbnail')" class="basic-article_thumbnail">
|
||||||
<template v-if="parseData">
|
<template v-if="parseData">
|
||||||
<img class="object-fit-cover" :src="parseData.thumbnail ? parseData.thumbnail : '/images/default-thumbnail.jpg'" :alt="parseData.title?.replace(/<[^>]+>/g, '')" />
|
<img class="object-cover" :src="parseData.thumbnail ? parseData.thumbnail : '/images/default-thumbnail.jpg'" :alt="parseData.title?.replace(/<[^>]+>/g, '')" />
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div class="basic-article_content" :class="[!parseData && 'no-data']">
|
<div class="basic-article_content" :class="[!parseData && 'no-data']">
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { enumPageComponentTemplates } from "@/definitions/enum";
|
import { enumPageComponentTemplates } from "@/definitions/enum";
|
||||||
import { Article_BasicCard, BasicCategories, Article_BasicCollection, Dynamic_Other } from "./index";
|
import { Article_BasicCard, BasicCategories, Article_BasicCollection, CollectionPaging, Dynamic_Other } from "./index";
|
||||||
|
|
||||||
const _props = defineProps<{
|
const _props = defineProps<{
|
||||||
settings: any;
|
settings: any;
|
||||||
@@ -11,6 +11,7 @@ const definedDynamicComponent: Record<string, any> = {
|
|||||||
[enumPageComponentTemplates.ARTICLE]: Article_BasicCard,
|
[enumPageComponentTemplates.ARTICLE]: Article_BasicCard,
|
||||||
[enumPageComponentTemplates.CATEGORY]: BasicCategories,
|
[enumPageComponentTemplates.CATEGORY]: BasicCategories,
|
||||||
[enumPageComponentTemplates.COLLECTION]: Article_BasicCollection,
|
[enumPageComponentTemplates.COLLECTION]: Article_BasicCollection,
|
||||||
|
[enumPageComponentTemplates.SECTION]: CollectionPaging,
|
||||||
[enumPageComponentTemplates.OTHER]: Dynamic_Other
|
[enumPageComponentTemplates.OTHER]: Dynamic_Other
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+22
-44
@@ -1,12 +1,10 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { isEmpty } from "lodash";
|
import { isEmpty } from "lodash";
|
||||||
import DynamicComponent from "~/components/dynamic-page/page-component/templates/index.vue";
|
import DynamicComponent from "~/components/dynamic-page/page-component/templates/index.vue";
|
||||||
import { COLLECTION_PAGING_QUERY_DROP } from '@/utils/parseSQL';
|
import { COLLECTION_PAGING_QUERY_DROP, getInputValue } from "@/utils/parseSQL";
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
const emit = defineEmits(["dropData", "selectComponent"]);
|
|
||||||
|
|
||||||
const _props = defineProps<{
|
const _props = defineProps<{
|
||||||
dataResult?: any[];
|
dataResult?: any[];
|
||||||
dataQuery?: string;
|
dataQuery?: string;
|
||||||
@@ -21,34 +19,12 @@ const SETTING_OPTIONS = {
|
|||||||
|
|
||||||
// const page = ref(1);
|
// const page = ref(1);
|
||||||
const limit = ref(1);
|
const limit = ref(1);
|
||||||
const totals = ref(2);
|
const totals = ref(1);
|
||||||
const category = ref(0);
|
|
||||||
const listArticleByCategory = ref([]);
|
|
||||||
const type = "Article";
|
const type = "Article";
|
||||||
|
|
||||||
// watch(
|
const listArticleByCategory = computed(() => {
|
||||||
// () => _props.dataResult,
|
return getInputValue(_props.dataResult, "ARRAY");
|
||||||
// (newValue) => {
|
|
||||||
// const result = getInputValue(newValue, "ARRAY");
|
|
||||||
// listArticleByCategory.value = result;
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
|
|
||||||
|
|
||||||
const dropData = (event: any) => {
|
|
||||||
const queryBy = {
|
|
||||||
Category: "Categories",
|
|
||||||
};
|
|
||||||
const { dataResult, dataType } = JSON.parse(event.dataTransfer.getData("category"));
|
|
||||||
// const getDataQuery = `Get[${type}] Top[20] With[${queryBy[dataType]}:${dataResult.id}]`;
|
|
||||||
const getDataQuery = COLLECTION_PAGING_QUERY_DROP(type, { key: queryBy[dataType], value: dataResult.id })
|
|
||||||
category.value = dataResult.id;
|
|
||||||
emit("dropData", {
|
|
||||||
dataResult: [],
|
|
||||||
dataType,
|
|
||||||
dataQuery: getDataQuery,
|
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|
||||||
//?cpn_1=page:2&cpn_2=page:1
|
//?cpn_1=page:2&cpn_2=page:1
|
||||||
// Get[Article] Top[5] With[Categories:1]
|
// Get[Article] Top[5] With[Categories:1]
|
||||||
@@ -71,10 +47,8 @@ const handleRouteChange = (query: any) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
const result = getInputValue( _props.dataResult, "ARRAY");
|
if (route.query[`cpn_${_props.component?.id}`]) handleRouteChange(route.query);
|
||||||
listArticleByCategory.value = result;
|
});
|
||||||
handleRouteChange(route.query)
|
|
||||||
})
|
|
||||||
|
|
||||||
const loadPage = (page: string | number) => {
|
const loadPage = (page: string | number) => {
|
||||||
console.log(`Loading page ${page}`);
|
console.log(`Loading page ${page}`);
|
||||||
@@ -91,10 +65,8 @@ watch(
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<section>
|
<section>
|
||||||
<div class="section-container" @dragover.prevent @drop.stop.prevent="dropData($event)"
|
<div class="section-container" @click="selectComponent" @dragover.prevent @drop.stop.prevent="dropData($event)" :class="[listArticleByCategory && listArticleByCategory?.length > 0 ? '' : 'noData']">
|
||||||
:class="[listArticleByCategory && listArticleByCategory?.length > 0 ? '' : 'noData']">
|
|
||||||
<div class="collection-container">
|
<div class="collection-container">
|
||||||
<template v-if="category">
|
|
||||||
<template v-if="listArticleByCategory?.length > 0">
|
<template v-if="listArticleByCategory?.length > 0">
|
||||||
<template v-for="(component, index) in listArticleByCategory" :key="index">
|
<template v-for="(component, index) in listArticleByCategory" :key="index">
|
||||||
<DynamicComponent
|
<DynamicComponent
|
||||||
@@ -108,10 +80,8 @@ watch(
|
|||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<el-result icon="success" title="Success" sub-title="Nội dung danh sách bài viết sẽ ở đây"> </el-result>
|
<div class="empty"><h6>Nội dung danh sách bài viết của danh mục sẽ ở đây</h6></div>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
|
||||||
<template v-else><el-empty image-size="90px" description="Kéo Category vào đây" /></template>
|
|
||||||
<div class="button-page flex">
|
<div class="button-page flex">
|
||||||
<a class="btn-page prev-page">
|
<a class="btn-page prev-page">
|
||||||
<i class="el-icon">
|
<i class="el-icon">
|
||||||
@@ -123,7 +93,7 @@ watch(
|
|||||||
</svg>
|
</svg>
|
||||||
</i>
|
</i>
|
||||||
</a>
|
</a>
|
||||||
<a class="btn-page" @click="() => select(index + 1)" v-for="(_, index) in totals">{{ index + 1 }}</a>
|
<a class="btn-page" @click="() => select(index + 1)" v-for="(_, index) in totals" :key="index">{{ index + 1 }}</a>
|
||||||
<a class="btn-page next-page">
|
<a class="btn-page next-page">
|
||||||
<i class="el-icon">
|
<i class="el-icon">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
|
||||||
@@ -142,15 +112,23 @@ watch(
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.section-container {
|
.section-container {
|
||||||
.empty {
|
|
||||||
min-height: 100px;
|
|
||||||
border-radius: 6px;
|
|
||||||
background: #409eff;
|
|
||||||
}
|
|
||||||
.collection-container {
|
.collection-container {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
}
|
}
|
||||||
|
.empty {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
min-height: 50px;
|
||||||
|
background-color: #409eff;
|
||||||
|
display: flex;
|
||||||
|
white-space: normal;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
h6{
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
.basic-article {
|
.basic-article {
|
||||||
&.article {
|
&.article {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ const CLASS_FOR_SECTION = computed(() => {
|
|||||||
switch (props.layout) {
|
switch (props.layout) {
|
||||||
case enumPageSectionLayouts.VERTICAL_TWO:
|
case enumPageSectionLayouts.VERTICAL_TWO:
|
||||||
_classForSection = {
|
_classForSection = {
|
||||||
section_layout: "section_layout two_col_layout",
|
section_layout: "section_layout two_col_layout mb-5 mt-2",
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case enumPageSectionLayouts.VERTICAL_LEFT_TWO:
|
case enumPageSectionLayouts.VERTICAL_LEFT_TWO:
|
||||||
@@ -122,7 +122,7 @@ const CLASS_FOR_SECTION = computed(() => {
|
|||||||
break;
|
break;
|
||||||
case enumPageSectionLayouts.VERTICAL_THREE:
|
case enumPageSectionLayouts.VERTICAL_THREE:
|
||||||
_classForSection = {
|
_classForSection = {
|
||||||
section_layout: "section_layout three_col_layout",
|
section_layout: "section_layout three_col_layout mt-4",
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case enumPageSectionLayouts.VERTICAL_FOUR:
|
case enumPageSectionLayouts.VERTICAL_FOUR:
|
||||||
|
|||||||
@@ -15,13 +15,13 @@ const CLASS_FOR_LAYOUT = computed(() => {
|
|||||||
case 'Center_Page':
|
case 'Center_Page':
|
||||||
_classForLayout = {
|
_classForLayout = {
|
||||||
page_container: 'page_container w-full px-2',
|
page_container: 'page_container w-full px-2',
|
||||||
layout_container: 'layout_container container mx-auto',
|
layout_container: 'layout_container container-xxl mx-auto',
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case 'Background_Page':
|
case 'Background_Page':
|
||||||
_classForLayout = {
|
_classForLayout = {
|
||||||
page_container: 'page_container w-full background-container',
|
page_container: 'page_container w-full background-container',
|
||||||
layout_container: 'layout_container container mx-auto',
|
layout_container: 'layout_container container-xxl mx-auto',
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -7,19 +7,27 @@ import DynamicSection from "~/components/dynamic-page/page-section/templates/ind
|
|||||||
import { useDynamicPageStore } from '~/stores/dynamic-page';
|
import { useDynamicPageStore } from '~/stores/dynamic-page';
|
||||||
const { currentPage, sectionPublished, componentPublished } = storeToRefs(useDynamicPageStore());
|
const { currentPage, sectionPublished, componentPublished } = storeToRefs(useDynamicPageStore());
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
const store = reactive({
|
const store = reactive({
|
||||||
dynamicPage: useDynamicPageStore(),
|
dynamicPage: useDynamicPageStore(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const loadData = async () => {
|
(async () => {
|
||||||
store.dynamicPage.fetchPageById(7);
|
try {
|
||||||
|
store.dynamicPage.fetchPageByCode(route.path.replace('/', ''));
|
||||||
store.dynamicPage.setSectionPublished();
|
} catch (error) {
|
||||||
store.dynamicPage.setComponentPublished()
|
console.error("Error fetching data:", error);
|
||||||
}
|
}
|
||||||
await loadData()
|
})();
|
||||||
|
|
||||||
|
watch(currentPage, () => {
|
||||||
|
store.dynamicPage.setSectionPublished();
|
||||||
|
store.dynamicPage.setComponentPublished();
|
||||||
|
}, { deep: true })
|
||||||
|
|
||||||
|
useHead({
|
||||||
|
title: currentPage.value.title || ''
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const store = reactive({
|
|||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
store.article.getArticleById(Number(route.params.slug));
|
store.article.getArticleById(route.params.slug);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching data:", error);
|
console.error("Error fetching data:", error);
|
||||||
}
|
}
|
||||||
@@ -48,16 +48,16 @@ watch(currentArticle, async () => {
|
|||||||
case 4:
|
case 4:
|
||||||
isContentType = 'ArticleLayoutVideo'
|
isContentType = 'ArticleLayoutVideo'
|
||||||
case 5:
|
case 5:
|
||||||
if (currentArticle.value?.layoutType === 3) isContentType = 'ArticleLayoutInfographics'
|
if (currentArticle.value?.layoutType === 3) isContentType = 'trang-chi-tiet-emagazine'
|
||||||
else isContentType = 'ArticleLayoutFullPage'
|
else isContentType = 'trang-chi-tiet-emagazine'
|
||||||
default:
|
default:
|
||||||
isContentType = 'ArticleLayoutDefault'
|
isContentType = 'trang-chi-tiet-emagazine'
|
||||||
}
|
}
|
||||||
await loadPage(isContentType)
|
await loadPage(isContentType)
|
||||||
}, { deep: true })
|
}, { deep: true })
|
||||||
|
|
||||||
useSeoMeta({
|
useSeoMeta({
|
||||||
title: currentArticle.value?.title,
|
title: currentArticle.value?.title?.replace(/<[^>]+>/g, ''),
|
||||||
ogTitle: currentArticle.value?.title,
|
ogTitle: currentArticle.value?.title,
|
||||||
description: currentArticle.value?.intro,
|
description: currentArticle.value?.intro,
|
||||||
ogDescription: currentArticle.value?.intro,
|
ogDescription: currentArticle.value?.intro,
|
||||||
|
|||||||
+4
-1
@@ -7,18 +7,21 @@ import DynamicSection from "~/components/dynamic-page/page-section/templates/ind
|
|||||||
import { useDynamicPageStore } from '~/stores/dynamic-page';
|
import { useDynamicPageStore } from '~/stores/dynamic-page';
|
||||||
const { currentPage, sectionPublished, componentPublished } = storeToRefs(useDynamicPageStore());
|
const { currentPage, sectionPublished, componentPublished } = storeToRefs(useDynamicPageStore());
|
||||||
|
|
||||||
|
const route = useRoute();
|
||||||
const store = reactive({
|
const store = reactive({
|
||||||
dynamicPage: useDynamicPageStore(),
|
dynamicPage: useDynamicPageStore(),
|
||||||
});
|
});
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
store.dynamicPage.fetchPageByCode('trang-chu');
|
store.dynamicPage.fetchPageByCode(route.path === '/' ? 'trang-chu' : route.path.replace('/', ''));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching data:", error);
|
console.error("Error fetching data:", error);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
watch(currentPage, () => {
|
watch(currentPage, () => {
|
||||||
|
console.log(currentPage.value)
|
||||||
store.dynamicPage.setSectionPublished();
|
store.dynamicPage.setSectionPublished();
|
||||||
store.dynamicPage.setComponentPublished()
|
store.dynamicPage.setComponentPublished()
|
||||||
}, { deep: true })
|
}, { deep: true })
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ export const getArticleBySlug = async (event : any) => {
|
|||||||
site: '1' || 1,
|
site: '1' || 1,
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
console.log(item)
|
||||||
return item
|
return item
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
handleError(error);
|
handleError(error);
|
||||||
|
|||||||
+10
-1
@@ -10,9 +10,18 @@ export const useArticleStore = defineStore("article", () => {
|
|||||||
} catch (error: any) {}
|
} catch (error: any) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getArticleByCode = async (slug: string) => {
|
||||||
|
try {
|
||||||
|
const { data} = await useFetch(`/api/articles/get-by-slug/${slug}`)
|
||||||
|
currentArticle.value = {}
|
||||||
|
currentArticle.value = data.value.item
|
||||||
|
} catch (error: any) {}
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
currentArticle,
|
currentArticle,
|
||||||
getArticleById
|
getArticleById,
|
||||||
|
getArticleByCode
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user