Compare commits
19 Commits
phongdt
...
043f97743c
| Author | SHA1 | Date | |
|---|---|---|---|
| 043f97743c | |||
| dffbe39fa6 | |||
| 7151e7d311 | |||
| 7da82c9101 | |||
| 212e6d357c | |||
| 7cb6199610 | |||
| 0dba7790b1 | |||
| 776a3cf2c7 | |||
| 2e49529934 | |||
| 28ce3d42a0 | |||
| 08ad924483 | |||
| 76b2fa4771 | |||
| 81bfa351e8 | |||
| a3e20c9445 | |||
| 6806201085 | |||
| 4ec2e425df | |||
| 31175ade27 | |||
| ccd92c86ee | |||
| a47229f44e |
@@ -20,6 +20,7 @@ $color-line: #EDEDED;
|
|||||||
body {
|
body {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-family: $font-raleway;
|
font-family: $font-raleway;
|
||||||
|
scroll-behavior: smooth;
|
||||||
}
|
}
|
||||||
|
|
||||||
// %headings {
|
// %headings {
|
||||||
@@ -180,3 +181,35 @@ div[layout="ARTICLE_PAGE"] {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
.collection-container {
|
||||||
|
grid-template-columns: repeat(1, minmax(0, 1fr)) !important;
|
||||||
|
& > article.basic-article {
|
||||||
|
flex-direction: row!important;
|
||||||
|
|
||||||
|
& > .basic-article_thumbnail {
|
||||||
|
width: 50%!important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.emagazine, .infographic, .image {
|
||||||
|
p {
|
||||||
|
@apply w-full max-w-660px mx-auto text-18px font-raleway leading-180%;
|
||||||
|
}
|
||||||
|
|
||||||
|
figure {
|
||||||
|
@apply w-full;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
@apply mx-auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-default {
|
||||||
|
p {
|
||||||
|
@apply text-18px font-raleway leading-180% my-10px;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,6 +18,7 @@ const { currentPollOptions } = storeToRefs(store.pollOptions);
|
|||||||
const { currentPollResponses } = storeToRefs(store.pollResponse);
|
const { currentPollResponses } = storeToRefs(store.pollResponse);
|
||||||
const poll = reactive<Poll | any>({});
|
const poll = reactive<Poll | any>({});
|
||||||
const options = ref<PollOption[] | any[]>([]);
|
const options = ref<PollOption[] | any[]>([]);
|
||||||
|
|
||||||
async function loadData() {
|
async function loadData() {
|
||||||
await store.poll.fetchById(String(props.dataId));
|
await store.poll.fetchById(String(props.dataId));
|
||||||
await store.pollOptions.fetchByPollId(String(props.dataId));
|
await store.pollOptions.fetchByPollId(String(props.dataId));
|
||||||
@@ -30,13 +31,14 @@ function assignData() {
|
|||||||
options.value = currentPollOptions.value;
|
options.value = currentPollOptions.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
|
||||||
await loadData();
|
await loadData();
|
||||||
});
|
// onBeforeMount(async () => {
|
||||||
|
// });
|
||||||
|
|
||||||
const selectedOption = ref<any>(-1);
|
// const selectedOption = ref<any>(-1);
|
||||||
const showResult = ref(false);
|
// const showResult = ref(false);
|
||||||
const alreadyVoted = ref(false);
|
const alreadyVoted = ref(false);
|
||||||
|
const showResult = ref(false)
|
||||||
const canShowResult = computed(() => {
|
const canShowResult = computed(() => {
|
||||||
switch (poll.settings?.resultPublication) {
|
switch (poll.settings?.resultPublication) {
|
||||||
case 0:
|
case 0:
|
||||||
@@ -49,29 +51,74 @@ const canShowResult = computed(() => {
|
|||||||
return alreadyVoted.value && (!poll.endTime || new Date() > new Date(poll.endTime));
|
return alreadyVoted.value && (!poll.endTime || new Date() > new Date(poll.endTime));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// const toggleResults = () => {
|
||||||
|
// if (canShowResult.value) showResult.value = !showResult.value;
|
||||||
|
// };
|
||||||
|
|
||||||
|
const singleSelect = ref<number>(-1)
|
||||||
|
const multipleSelect = ref<number []>([])
|
||||||
|
|
||||||
const totalResponses = ref(0);
|
const totalResponses = ref(0);
|
||||||
async function submitVote() {
|
async function submitVote() {
|
||||||
if (selectedOption.value >= 0 && !alreadyVoted.value) {
|
// if (selectedOption.value >= 0 && !alreadyVoted.value) {
|
||||||
const result = await store.pollResponse.create({ optionId: selectedOption.value });
|
// const result = await store.pollResponse.create({ optionId: selectedOption.value });
|
||||||
if (result?.id) {
|
// if (result?.id) {
|
||||||
|
// totalResponses.value = options.value?.reduce((sum, option) => sum + Number(option.responseCount ?? 0), 1);
|
||||||
|
// options?.value?.forEach((option: PollOption | any) => {
|
||||||
|
// if (option.id === selectedOption.value) {
|
||||||
|
// option.responseCount = (option.responseCount ?? 0) + 1;
|
||||||
|
// }
|
||||||
|
// option.percentage = Number(((option.responseCount / totalResponses.value) * 100).toFixed(1));
|
||||||
|
// });
|
||||||
|
// alreadyVoted.value = true;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
switch (poll.type) {
|
||||||
|
case 1:
|
||||||
|
if(singleSelect.value >= 0) {
|
||||||
totalResponses.value = options.value?.reduce((sum, option) => sum + Number(option.responseCount ?? 0), 1);
|
totalResponses.value = options.value?.reduce((sum, option) => sum + Number(option.responseCount ?? 0), 1);
|
||||||
options?.value?.forEach((option: PollOption | any) => {
|
options?.value?.forEach((option: PollOption | any) => {
|
||||||
if (option.id === selectedOption.value) {
|
if (option.id === singleSelect.value) {
|
||||||
option.responseCount = (option.responseCount ?? 0) + 1;
|
option.responseCount = (option.responseCount ?? 0) + 1;
|
||||||
}
|
}
|
||||||
option.percentage = Number(((option.responseCount / totalResponses.value) * 100).toFixed(1));
|
option.percentage = Number(((option.responseCount / totalResponses.value) * 100).toFixed(1));
|
||||||
|
alreadyVoted.value = true
|
||||||
});
|
});
|
||||||
alreadyVoted.value = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const toggleResults = () => {
|
|
||||||
if (canShowResult.value) showResult.value = !showResult.value;
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<span class="inline-block px-4 py-2 shadow-xl rounded-lg bg-[#f5f5f5]">
|
|
||||||
|
<div class="inline-block px-4 py-2 mb-5">
|
||||||
|
<h3 class="text-#000 font-raleway font-italic text-16px font-500 leading-140% mb-2">{{ poll?.title }}</h3>
|
||||||
|
<ul class="flex flex-col gap-3">
|
||||||
|
<template v-if="poll.type === 1">
|
||||||
|
<li v-for="(option, index) in options" :key="index">
|
||||||
|
<input :id="`option-${index}`" :disabled="singleSelect >= 0 && alreadyVoted ? true : false" type="radio" class="peer opacity-0" :value="option.id" v-model="singleSelect">
|
||||||
|
<label :for="`option-${index}`" class="font-raleway text-16px relative text-#000 font-400 leading-140% pl-16px before:content-[''] before:inline-block before:w-14px before:h-14px before:rounded-50% before:border-1 before:absolute before:left--3 before:top-10px before:border-1px before:border-#000 before:translate-y--50% after:absolute after:left--10px after:top-10px after:translate-y--50% after:border-#000 after:content-[''] after:inline-block after:w-10px after:h-10px after:rounded-full peer-checked:after:bg-primary peer-checked:before:border-primary ">{{ option?.title }}</label>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="flex items-center justify-center mt-3">
|
||||||
|
<button @click="submitVote()" v-if="!alreadyVoted" :disabled="alreadyVoted && singleSelect >= 0 ? true : false" class="px-5 py-10px rounded-6px bg-primary text-#fff font-raleway text-14px font-400">Gửi kết quả</button>
|
||||||
|
<button @click="showResult = true" v-if="alreadyVoted" class="px-5 py-10px rounded-6px bg-primary text-#fff font-raleway text-14px font-400">Xem kết quả</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-5" v-if="showResult && canShowResult">
|
||||||
|
<h3 class="text-#000 font-raleway font-italic text-16px font-500 leading-140% mb-2">{{ poll?.title }}</h3>
|
||||||
|
<ul>
|
||||||
|
<li v-for="(answer, index) in options" :key="index" class="flex gap-4 items-center text-#000 font-raleway text-12px leading-140%">
|
||||||
|
{{ answer.percentage}}%
|
||||||
|
<div :style="{ width: `${answer.percentage}%` }" :class="answer.id === singleSelect ? 'bg-primary' : 'bg-#AEAEAE'" class="h-1.5 rounded-full"></div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- <span class="inline-block px-4 py-2 shadow-xl rounded-lg bg-[#f5f5f5]">
|
||||||
<span class="block">
|
<span class="block">
|
||||||
<span class="underline decoration-gray-500 font-bold">
|
<span class="underline decoration-gray-500 font-bold">
|
||||||
{{ poll?.title }}
|
{{ poll?.title }}
|
||||||
@@ -100,5 +147,5 @@ const toggleResults = () => {
|
|||||||
</span>
|
</span>
|
||||||
<b>Tổng số lượt binh chọn: {{ totalResponses }}</b>
|
<b>Tổng số lượt binh chọn: {{ totalResponses }}</b>
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</span> -->
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -246,23 +246,33 @@ async function submitSend() {}
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="inline-block px-4 py-2 shadow-xl rounded-lg bg-[#f5f5f5] !text-black-500">
|
<div class="inline-block px-4 py-2 !text-black-500">
|
||||||
<h5 class="underline decoration-gray-500 font-bold mb-2">Câu đố: {{ data?.title }}</h5>
|
<h5 class="underline decoration-gray-500 font-bold mb-2">Câu đố: {{ data?.title }}</h5>
|
||||||
|
|
||||||
<ul class="px-3">
|
<ul class="px-3 flex flex-col gap-3">
|
||||||
<li v-for="(question, questionIndex) in data.questionGeneral" :key="questionIndex" class="mb-2">
|
<li v-for="(question, questionIndex) in data.questionGeneral" :key="questionIndex" class="mb-2">
|
||||||
<h5 class="mb-1 font-700 text-black-500">{{ `${questionIndex + 1}. ${question.title}` }}</h5>
|
<h5 class="text-#000 font-raleway font-italic text-16px font-500 leading-140% mb-2">{{ `${questionIndex + 1}. ${question.title}` }}</h5>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
<template v-if="question.type === 1">
|
||||||
<li v-for="(answer, answerIndex) in question.answers" :key="answerIndex" class="flex items-center gap-1 py-1">
|
<li v-for="(answer, answerIndex) in question.answers" :key="answerIndex" class="flex items-center gap-1 py-1">
|
||||||
<input :id="`answer-${questionIndex}-${answerIndex}`" :type="question.type === 1 ? 'radio' : 'checkbox'" :value="answerIndex" v-model="selectQuizAnswer[questionIndex]" />
|
<input :id="`answer-${questionIndex}-${answerIndex}`" type="radio" :value="answerIndex" class="peer opacity-0" v-model="selectQuizAnswer[questionIndex]" />
|
||||||
<label :for="`answer-${questionIndex}-${answerIndex}`" class="font-semibold">{{ answer.title }}</label>
|
<label :for="`answer-${questionIndex}-${answerIndex}`" class="font-raleway text-16px relative text-#000 font-400 leading-140% pl-16px before:content-[''] before:inline-block before:w-14px before:h-14px before:rounded-50% before:border-1 before:absolute before:left--3 before:top-10px before:border-1px before:border-#000 before:translate-y--50% after:absolute after:left--10px after:top-10px after:translate-y--50% after:border-#000 after:content-[''] after:inline-block after:w-10px after:h-10px after:rounded-full peer-checked:after:bg-primary peer-checked:before:border-primary ">{{ answer.title }}</label>
|
||||||
</li>
|
</li>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<li v-for="(answer, answerIndex) in question.answers" :key="answerIndex" class="flex items-center gap-1 py-1">
|
||||||
|
<input :id="`answer-${questionIndex}-${answerIndex}`" type="checkbox" :value="answerIndex" class="peer opacity-0" v-model="selectQuizAnswer[questionIndex]" />
|
||||||
|
<label :for="`answer-${questionIndex}-${answerIndex}`" class="font-raleway text-16px relative text-#000 font-400 leading-140% pl-16px before:content-[''] before:inline-block before:w-14px before:h-14px before:rounded-2px before:border-1 before:absolute before:left--3 before:top-10px before:border-1px before:border-#000 before:translate-y--50% after:absolute after:left--10px after:top-6px after:translate-y--50% after:border-#000 after:content-['✔'] after:text-12px after:text-transparent after:inline-block after:w-14px after:h-14px peer-checked:after:text-white peer-checked:before:border-primary peer-checked:before:bg-primary ">{{ answer.title }}</label>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<button @click="submitSend" class="bg-primary-500 text-white py-1 px-3 rounded-4px cursor-pointer hover:bg-primary-600 float-right">Gửi câu trả lời</button>
|
<div class="flex justify-center">
|
||||||
|
<button @click="submitSend" class="mx-auto px-5 py-10px rounded-6px bg-primary text-#fff font-raleway text-14px font-400">Gửi câu trả lời</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div>
|
<!-- <div>
|
||||||
<h5 class="text-black text-18px font-700">{{ data?.title }}</h5>
|
<h5 class="text-black text-18px font-700">{{ data?.title }}</h5>
|
||||||
|
|||||||
@@ -270,24 +270,41 @@ async function submitSend() {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
||||||
<div class="inline-block px-4 py-2 shadow-xl rounded-lg bg-[#f5f5f5] !text-black-500">
|
<div class="inline-block px-4 py-2 !text-black-500">
|
||||||
<h5 class="underline decoration-gray-500 font-bold mb-2">Khảo sát: {{ dataSurvey?.title }}</h5>
|
<h5 class="underline decoration-gray-500 font-bold mb-2">Khảo sát: {{ dataSurvey?.title }}</h5>
|
||||||
|
|
||||||
<ul class="px-3">
|
<ul class="px-3">
|
||||||
<li v-for="(question, questionIndex) in dataSurvey.questionGeneral" :key="questionIndex" class="mb-2">
|
<li v-for="(question, questionIndex) in dataSurvey.questionGeneral" :key="questionIndex" class="mb-2">
|
||||||
<h5 class="mb-1 font-700 text-black-500">{{ `${questionIndex + 1}. ${question.title}` }}</h5>
|
<h5 class="text-#000 font-raleway font-italic text-16px font-500 leading-140% mb-2">{{ `${questionIndex + 1}. ${question.title}` }}</h5>
|
||||||
|
|
||||||
<ul>
|
<!-- <ul>
|
||||||
<li v-for="(answer, answerIndex) in question.answers" :key="answerIndex" class="flex items-center gap-1 py-1">
|
<li v-for="(answer, answerIndex) in question.answers" :key="answerIndex" class="flex items-center gap-1 py-1">
|
||||||
<input :id="`answer-survey-${questionIndex}-${answerIndex}`" :type="question.type === 1 ? 'radio' : 'checkbox'" :value="answerIndex" v-model="selectSurveyAnswer[questionIndex]">
|
<input :id="`answer-survey-${questionIndex}-${answerIndex}`" :type="question.type === 1 ? 'radio' : 'checkbox'" :value="answerIndex" v-model="selectSurveyAnswer[questionIndex]">
|
||||||
<label :for="`answer-survey-${questionIndex}-${answerIndex}`" class="font-semibold">{{ answer.title }}</label>
|
<label :for="`answer-survey-${questionIndex}-${answerIndex}`" class="font-semibold">{{ answer.title }}</label>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
</ul> -->
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<template v-if="question.type === 1">
|
||||||
|
<li v-for="(answer, answerIndex) in question.answers" :key="answerIndex" class="flex items-center gap-1 py-1">
|
||||||
|
<input :id="`answer-survey-${questionIndex}-${answerIndex}`" type="radio" :value="answerIndex" class="peer opacity-0" v-model="selectSurveyAnswer[questionIndex]" />
|
||||||
|
<label :for="`answer-survey-${questionIndex}-${answerIndex}`" class="font-raleway text-16px relative text-#000 font-400 leading-140% pl-16px before:content-[''] before:inline-block before:w-14px before:h-14px before:rounded-50% before:border-1 before:absolute before:left--3 before:top-10px before:border-1px before:border-#000 before:translate-y--50% after:absolute after:left--10px after:top-10px after:translate-y--50% after:border-#000 after:content-[''] after:inline-block after:w-10px after:h-10px after:rounded-full peer-checked:after:bg-primary peer-checked:before:border-primary ">{{ answer.title }}</label>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<li v-for="(answer, answerIndex) in question.answers" :key="answerIndex" class="flex items-center gap-1 py-1">
|
||||||
|
<input :id="`answer-survey-${questionIndex}-${answerIndex}`" type="checkbox" :value="answerIndex" class="peer opacity-0" v-model="selectSurveyAnswer[questionIndex]" />
|
||||||
|
<label :for="`answer-survey-${questionIndex}-${answerIndex}`" class="font-raleway text-16px relative text-#000 font-400 leading-140% pl-16px before:content-[''] before:inline-block before:w-14px before:h-14px before:rounded-2px before:border-1 before:absolute before:left--3 before:top-10px before:border-1px before:border-#000 before:translate-y--50% after:absolute after:left--10px after:top-6px after:translate-y--50% after:border-#000 after:content-['✔'] after:text-12px after:text-transparent after:inline-block after:w-14px after:h-14px peer-checked:after:text-white peer-checked:before:border-primary peer-checked:before:bg-primary ">{{ answer.title }}</label>
|
||||||
|
</li>
|
||||||
|
</template>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<button @click="submitSend" class="bg-primary-500 text-white py-1 px-3 rounded-4px cursor-pointer hover:bg-primary-600 float-right">Gửi câu trả lời</button>
|
<div class="flex justify-center">
|
||||||
|
<button @click="submitSend" class="mx-auto px-5 py-10px rounded-6px bg-primary text-#fff font-raleway text-14px font-400">Gửi câu trả lời</button>
|
||||||
|
</div>
|
||||||
|
<!-- <button @click="submitSend" class="bg-primary-500 text-white py-1 px-3 rounded-4px cursor-pointer hover:bg-primary-600 float-right">Gửi câu trả lời</button> -->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -54,8 +54,8 @@ const parseData = computed(() => {
|
|||||||
<article class="card-audio" :class="LAYOUT_PARSE['article_Class']" :style="LAYOUT_PARSE['article']">
|
<article class="card-audio" :class="LAYOUT_PARSE['article_Class']" :style="LAYOUT_PARSE['article']">
|
||||||
<img :src="parseData?.thumbnail ? parseData?.thumbnail : 'https://indiaeducationdiary.in/wp-content/uploads/2021/02/SD-default-image.png'" :alt="parseData?.title?.replace(/<[^>]+>/g, '')" />
|
<img :src="parseData?.thumbnail ? parseData?.thumbnail : 'https://indiaeducationdiary.in/wp-content/uploads/2021/02/SD-default-image.png'" :alt="parseData?.title?.replace(/<[^>]+>/g, '')" />
|
||||||
<div class="card-audio__content">
|
<div class="card-audio__content">
|
||||||
<span>
|
<span class="flex justify-center">
|
||||||
<template v-if="type === 'Image'">
|
<template v-if="['Image', 'Infographics', 'Emagazine'].includes(type)">
|
||||||
<svg width="28" height="22" viewBox="0 0 28 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
<svg width="28" height="22" viewBox="0 0 28 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path
|
<path
|
||||||
d="M25.25 0.5H7.25C5.98438 0.5 5 1.53125 5 2.75V14.75C5 16.0156 5.98438 17 7.25 17H25.25C26.4688 17 27.5 16.0156 27.5 14.75V2.75C27.5 1.53125 26.4688 0.5 25.25 0.5ZM10.9531 3.5C11.75 3.5 12.4531 4.20312 12.4531 5C12.4531 5.84375 11.7969 6.5 10.9531 6.5C10.1094 6.5 9.45312 5.84375 9.45312 5C9.45312 4.20312 10.1562 3.5 10.9531 3.5ZM23.6562 13.625C23.5156 13.8594 23.2344 14 23 14H9.5C9.17188 14 8.9375 13.8594 8.79688 13.625C8.70312 13.3438 8.70312 13.0625 8.89062 12.8281L12.1719 8.32812C12.3125 8.14062 12.5 8 12.7812 8C13.0156 8 13.2031 8.14062 13.3438 8.32812L14.4219 9.78125L17.375 5.375C17.4688 5.14062 17.7031 5 17.9844 5C18.2188 5 18.4531 5.14062 18.5938 5.375L23.6094 12.875C23.75 13.0625 23.75 13.3906 23.6562 13.625ZM21.875 19.25H6.125C4.25 19.25 2.75 17.75 2.75 15.875V4.625C2.75 4.01562 2.23438 3.5 1.625 3.5C0.96875 3.5 0.5 4.01562 0.5 4.625V15.875C0.5 19.0156 2.98438 21.5 6.125 21.5H21.875C22.4844 21.5 23 21.0312 23 20.375C23 19.7656 22.4844 19.25 21.875 19.25Z"
|
d="M25.25 0.5H7.25C5.98438 0.5 5 1.53125 5 2.75V14.75C5 16.0156 5.98438 17 7.25 17H25.25C26.4688 17 27.5 16.0156 27.5 14.75V2.75C27.5 1.53125 26.4688 0.5 25.25 0.5ZM10.9531 3.5C11.75 3.5 12.4531 4.20312 12.4531 5C12.4531 5.84375 11.7969 6.5 10.9531 6.5C10.1094 6.5 9.45312 5.84375 9.45312 5C9.45312 4.20312 10.1562 3.5 10.9531 3.5ZM23.6562 13.625C23.5156 13.8594 23.2344 14 23 14H9.5C9.17188 14 8.9375 13.8594 8.79688 13.625C8.70312 13.3438 8.70312 13.0625 8.89062 12.8281L12.1719 8.32812C12.3125 8.14062 12.5 8 12.7812 8C13.0156 8 13.2031 8.14062 13.3438 8.32812L14.4219 9.78125L17.375 5.375C17.4688 5.14062 17.7031 5 17.9844 5C18.2188 5 18.4531 5.14062 18.5938 5.375L23.6094 12.875C23.75 13.0625 23.75 13.3906 23.6562 13.625ZM21.875 19.25H6.125C4.25 19.25 2.75 17.75 2.75 15.875V4.625C2.75 4.01562 2.23438 3.5 1.625 3.5C0.96875 3.5 0.5 4.01562 0.5 4.625V15.875C0.5 19.0156 2.98438 21.5 6.125 21.5H21.875C22.4844 21.5 23 21.0312 23 20.375C23 19.7656 22.4844 19.25 21.875 19.25Z"
|
||||||
@@ -63,11 +63,16 @@ const parseData = computed(() => {
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
</template>
|
</template>
|
||||||
</span>
|
<template v-if="['Postcard', 'Video'].includes(type)">
|
||||||
|
<svg width="28" height="18" viewBox="0 0 28 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M18.5 2.25V15.75C18.5 17.0156 17.4688 18 16.25 18H2.75C1.48438 18 0.5 17.0156 0.5 15.75V2.25C0.5 1.03125 1.48438 0 2.75 0H16.25C17.4688 0 18.5 1.03125 18.5 2.25ZM27.5 3V15.0469C27.5 16.2188 26.0938 16.9219 25.1094 16.2656L20 12.7031V5.34375L25.1094 1.78125C26.0938 1.125 27.5 1.82812 27.5 3Z" fill="white"/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
</span>
|
||||||
<div class="card-audio__type-category" >
|
<div class="card-audio__type-category" >
|
||||||
<div class="card-audio__type" v-if="type">{{ type }}</div>
|
<div class="card-audio__type" v-if="type">{{ type }}</div>
|
||||||
<nuxt-link to="#" class="card-audio__category" :style="LAYOUT_PARSE['category-article']" :class="LAYOUT_PARSE['category-article_Class']">{{
|
<nuxt-link v-if="parseData?.category" to="#" class="card-audio__category" :style="LAYOUT_PARSE['category-article']" :class="LAYOUT_PARSE['category-article_Class']">{{
|
||||||
parseData?.category?.title
|
parseData?.category?.title
|
||||||
}}</nuxt-link>
|
}}</nuxt-link>
|
||||||
</div>
|
</div>
|
||||||
@@ -78,9 +83,6 @@ const parseData = computed(() => {
|
|||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
<div v-if="LAYOUT_PARSE.styleClasses" v-html="LAYOUT_PARSE.styleClasses" style="display:none;"></div>
|
<div v-if="LAYOUT_PARSE.styleClasses" v-html="LAYOUT_PARSE.styleClasses" style="display:none;"></div>
|
||||||
<!-- <div>
|
|
||||||
aaaaaaa
|
|
||||||
</div> -->
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ const parseData = computed(() => {
|
|||||||
}}</span>
|
}}</span>
|
||||||
<nuxt-link :style="LAYOUT_PARSE['category-article']" :class="LAYOUT_PARSE['category-article_Class']">{{ parseData?.category?.title }}</nuxt-link>
|
<nuxt-link :style="LAYOUT_PARSE['category-article']" :class="LAYOUT_PARSE['category-article_Class']">{{ parseData?.category?.title }}</nuxt-link>
|
||||||
</div>
|
</div>
|
||||||
<p class="mb-0 line-clamp" :class="LAYOUT_PARSE['paragraph_Class']" :style="LAYOUT_PARSE['p.paragraph']">
|
<p class="mb-0 line-clamp-5" :class="LAYOUT_PARSE['paragraph_Class']" :style="LAYOUT_PARSE['p.paragraph']">
|
||||||
<template v-if="parseData">
|
<template v-if="parseData">
|
||||||
{{ parseData.intro?.replace(/<[^>]+>/g, "") }}
|
{{ parseData.intro?.replace(/<[^>]+>/g, "") }}
|
||||||
</template>
|
</template>
|
||||||
@@ -239,5 +239,16 @@ p {
|
|||||||
height: 100px;
|
height: 100px;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
padding-left: 0px!important;
|
||||||
|
padding-right: 0px!important;
|
||||||
|
border: 0px solid transparent!important;
|
||||||
|
flex-direction: column !important;
|
||||||
|
|
||||||
|
& .basic-article_thumbnail {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
+52
-26
@@ -8,7 +8,8 @@ const props = defineProps<{
|
|||||||
dataType?: any;
|
dataType?: any;
|
||||||
dataQuery?: any;
|
dataQuery?: any;
|
||||||
layout?: string;
|
layout?: string;
|
||||||
label?: any;
|
label?: string;
|
||||||
|
component?: any;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const LAYOUT_PARSE = computed(() => {
|
const LAYOUT_PARSE = computed(() => {
|
||||||
@@ -16,56 +17,71 @@ const LAYOUT_PARSE = computed(() => {
|
|||||||
return Object.assign({}, designObject);
|
return Object.assign({}, designObject);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(["selectComponent", "dropData"]);
|
||||||
|
|
||||||
|
const selectComponent = () => {
|
||||||
|
emit("selectComponent");
|
||||||
|
};
|
||||||
|
|
||||||
const parseData = computed(() => {
|
const parseData = computed(() => {
|
||||||
if (!props.dataResult) return;
|
if (!props.dataResult) return;
|
||||||
const result = getInputValue(props.dataResult, "OBJECT");
|
const result = getInputValue(props.dataResult, "OBJECT");
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
|
||||||
const playVideo = ref<boolean>(false)
|
const drop = (e: any) => {
|
||||||
|
if (e.dataTransfer.getData(`${enumPageComponentTemplates.ARTICLE}`)) {
|
||||||
onMounted(() => {
|
const data = e.dataTransfer.getData(`${enumPageComponentTemplates.ARTICLE}`);
|
||||||
getResource(JSON.parse(props.dataResult).detail)
|
const { dataType, dataResult } = JSON.parse(data);
|
||||||
})
|
const dataQuery = DEFAULT_QUERY_DROP(dataType, dataResult.id);
|
||||||
|
emit("dropData", {
|
||||||
|
dataType,
|
||||||
|
dataResult,
|
||||||
|
dataQuery: dataQuery,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<article
|
<article :id="`cpn_${props.component?.id}`" class="basic-article border-custom" :class="LAYOUT_PARSE['article_Class']" @click="selectComponent" @dragover.prevent @drop.stop.prevent="drop" :style="LAYOUT_PARSE['article']">
|
||||||
class="basic-article border-custom"
|
|
||||||
:class="LAYOUT_PARSE['article_Class']"
|
|
||||||
:style="LAYOUT_PARSE['article']"
|
|
||||||
>
|
|
||||||
<div class="article_video">
|
<div class="article_video">
|
||||||
<template v-if="parseData">
|
<template v-if="parseData">
|
||||||
<div
|
<div class="article_video_thumb article-thumbnail" :style="{ backgroundImage: `url('${parseData.thumbnail ? parseData.thumbnail : '/images/default-thumbnail.jpg'}')` }">
|
||||||
v-if="!playVideo"
|
|
||||||
class="article_video_thumb h-full"
|
|
||||||
:style="{ backgroundImage: `url('${parseData.thumbnail ? parseData.thumbnail : '/images/default-thumbnail.jpg'}')` }"
|
|
||||||
>
|
|
||||||
<div></div>
|
<div></div>
|
||||||
<div class="article_video_content">
|
<div class="article_video_content">
|
||||||
<span><Icon name="ri:play-circle-line" class="text-white" /></span>
|
<span>
|
||||||
<h3 class="line-clamp text-white" :class="LAYOUT_PARSE['title_Class']" :style="LAYOUT_PARSE['h3.title']">
|
<svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M23.5 18.5C24.375 17.875 25.625 17.875 26.5 18.5L44.5 29.5C45.375 30 46 31 46 32C46 33.125 45.375 34.125 44.5 34.625L26.5 45.625C25.625 46.125 24.375 46.25 23.5 45.625C22.5 45.125 22 44.125 22 43V21C22 20 22.5 19 23.5 18.5ZM64 32C64 49.75 49.625 64 32 64C14.25 64 0 49.75 0 32C0 14.375 14.25 0 32 0C49.625 0 64 14.375 64 32ZM32 6C17.625 6 6 17.75 6 32C6 46.375 17.625 58 32 58C46.25 58 58 46.375 58 32C58 17.75 46.25 6 32 6Z"
|
||||||
|
fill="#ED1C24"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
<h3 class="line-clamp article-title" :class="LAYOUT_PARSE['title_Class']" :style="LAYOUT_PARSE['h3.title']">
|
||||||
{{ parseData.title?.replace(/<[^>]+>/g, "") }}
|
{{ parseData.title?.replace(/<[^>]+>/g, "") }}
|
||||||
</h3>
|
</h3>
|
||||||
<p class="mb-0 line-clamp text-white" :class="LAYOUT_PARSE['paragraph_Class']" :style="LAYOUT_PARSE['p.paragraph']">
|
<p class="mb-0 line-clamp article-intro" :class="LAYOUT_PARSE['paragraph_Class']" :style="LAYOUT_PARSE['p.paragraph']">
|
||||||
{{ parseData.intro?.replace(/<[^>]+>/g, "") }}
|
{{ parseData.intro?.replace(/<[^>]+>/g, "") }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<video src=""></video>
|
|
||||||
</template>
|
</template>
|
||||||
|
<div v-else class="empty-box">
|
||||||
|
<div class="d-flex justify-content-center align-items-center flex-column">
|
||||||
|
<i class="ri-play-circle-line"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="LAYOUT_PARSE.styleClasses" v-html="LAYOUT_PARSE.styleClasses"></div>
|
<div v-html="LAYOUT_PARSE.styleClasses" v-if="LAYOUT_PARSE.styles"></div>
|
||||||
</article>
|
</article>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.article_video {
|
.article_video {
|
||||||
@apply min-h-465px;
|
|
||||||
.article_video_thumb {
|
.article_video_thumb {
|
||||||
@apply flex flex-col justify-end min-h-465px;
|
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
@@ -73,10 +89,10 @@ onMounted(() => {
|
|||||||
z-index: 0;
|
z-index: 0;
|
||||||
padding: 120px 85px 60px 85px;
|
padding: 120px 85px 60px 85px;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
overflow: hidden;
|
margin: 10px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
&::after {
|
&::after {
|
||||||
content: '';
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@@ -95,18 +111,28 @@ onMounted(() => {
|
|||||||
line-height: 57.2px;
|
line-height: 57.2px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
svg {
|
i {
|
||||||
font-size: 80px;
|
font-size: 80px;
|
||||||
color: #ed1c24;
|
color: #ed1c24;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.empty-box {
|
||||||
|
background-color: #409eff;
|
||||||
|
margin: 10px;
|
||||||
|
min-height: 60px;
|
||||||
|
i {
|
||||||
|
font-size: 60px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const emit = defineEmits(["dropData", "selectComponent"]);
|
||||||
|
const _props = defineProps<{
|
||||||
|
dataResult?: any;
|
||||||
|
dataType?: any;
|
||||||
|
dataQuery?: any;
|
||||||
|
layout?: string;
|
||||||
|
label?: string;
|
||||||
|
}>();
|
||||||
|
const { currentArticle } = storeToRefs(useArticleStore())
|
||||||
|
console.log(currentArticle.value, 'currentArticle')
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div class="overflow-hidden emagazine">
|
||||||
|
<!-- bổ sung sau -->
|
||||||
|
<!-- <img :src="currentArticle.thumbnail" alt="" class="w-full object-cover">
|
||||||
|
|
||||||
|
<div class="px-44px pb-30px my-30px max-w-660px mx-auto border-b-1px border-#000">
|
||||||
|
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
<div v-html="currentArticle.detail"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.content {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,15 +1,14 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { enumPageComponentTemplates } from "@/definitions/enum";
|
import { enumPageComponentTemplates } from "@/definitions/enum";
|
||||||
import { DEFAULT_QUERY_DROP } from "@/utils/parseSQL";
|
import { DEFAULT_QUERY_DROP, getInputValue } from "@/utils/parseSQL";
|
||||||
import { isEmpty } from "@/utils/lodash";
|
const emit = defineEmits(["dropData", "selectComponent"]);
|
||||||
import { getInputValue } from "@/utils/parseSQL";
|
|
||||||
|
|
||||||
const _props = defineProps<{
|
const _props = defineProps<{
|
||||||
dataResult?: any;
|
dataResult?: any;
|
||||||
dataType?: any;
|
dataType?: any;
|
||||||
dataQuery?: any;
|
dataQuery?: any;
|
||||||
layout?: string;
|
layout?: string;
|
||||||
label?: any;
|
label?: string;
|
||||||
}>();
|
}>();
|
||||||
const SETTING_OPTIONS = {
|
const SETTING_OPTIONS = {
|
||||||
BREADCRUMB_MAX_ELEMENT: 3,
|
BREADCRUMB_MAX_ELEMENT: 3,
|
||||||
@@ -18,6 +17,9 @@ const LAYOUT_PARSE = computed(() => {
|
|||||||
const designObject = _props.label ? getInputValue(_props.label, "OBJECT") : {};
|
const designObject = _props.label ? getInputValue(_props.label, "OBJECT") : {};
|
||||||
return Object.assign({}, designObject);
|
return Object.assign({}, designObject);
|
||||||
});
|
});
|
||||||
|
const selectComponent = () => {
|
||||||
|
emit("selectComponent");
|
||||||
|
};
|
||||||
|
|
||||||
const parseData = computed(() => {
|
const parseData = computed(() => {
|
||||||
if (!_props.dataResult) return;
|
if (!_props.dataResult) return;
|
||||||
@@ -25,20 +27,29 @@ const parseData = computed(() => {
|
|||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
|
|
||||||
const articleStore = useArticleStore();
|
const drop = (e: any) => {
|
||||||
const currentArticle = computed(() => articleStore.currentArticleGeneral);
|
if (e.dataTransfer.getData(`${enumPageComponentTemplates.ARTICLE}`)) {
|
||||||
|
const data = e.dataTransfer.getData(`${enumPageComponentTemplates.ARTICLE}`);
|
||||||
|
const { dataType, dataResult } = JSON.parse(data);
|
||||||
|
const dataQuery = DEFAULT_QUERY_DROP(dataType, dataResult.id);
|
||||||
|
emit("dropData", {
|
||||||
|
dataType,
|
||||||
|
dataResult,
|
||||||
|
dataQuery: dataQuery,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="overflow-hidden">
|
<div @click="selectComponent" class="overflow-hidden" @dragover.prevent @drop.stop.prevent="drop">
|
||||||
<div class="breadcrumb" v-if="!LAYOUT_PARSE['HideBreadcrumb']">
|
<div class="breadcrumb" v-if="!LAYOUT_PARSE['HideBreadcrumb']">
|
||||||
<ul class="breadcrumb__list">
|
<ul class="breadcrumb__list">
|
||||||
<li
|
<li
|
||||||
class="breadcrumb__list__item"
|
class="breadcrumb__list__item"
|
||||||
v-for="(item, index) in _props.dataResult && _props.dataResult?.length > 0 ? _props.dataResult : Array(SETTING_OPTIONS.BREADCRUMB_MAX_ELEMENT).fill(null)"
|
v-for="(item, index) in _props.dataResult && _props.dataResult?.length > 0 ? _props.dataResult : Array(SETTING_OPTIONS.BREADCRUMB_MAX_ELEMENT).fill(null)"
|
||||||
:key="index"
|
:key="index"
|
||||||
:class="isEmpty(item) && 'empty'"
|
|
||||||
>
|
>
|
||||||
<p v-if="!isEmpty(item)" class="breadcrumb__list__item__title">
|
<p class="breadcrumb__list__item__title">
|
||||||
{{ item?.title }}
|
{{ item?.title }}
|
||||||
</p>
|
</p>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -1,55 +1,76 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { isEmpty } from "@/utils/lodash";
|
const emit = defineEmits(["dropData", "selectComponent"]);
|
||||||
|
const { categoryTree } = storeToRefs(useCategoryStore());
|
||||||
|
const { currentArticle } = storeToRefs(useArticleStore());
|
||||||
|
if (categoryTree.value) {
|
||||||
|
await useCategoryStore().fetchBySiteId();
|
||||||
|
}
|
||||||
const _props = defineProps<{
|
const _props = defineProps<{
|
||||||
dataResult?: any;
|
dataResult?: any[];
|
||||||
}>();
|
}>();
|
||||||
const SETTING_OPTIONS = {
|
const SETTING_OPTIONS = {
|
||||||
BREADCRUMB_MAX_ELEMENT: 3,
|
BREADCRUMB_MAX_ELEMENT: 3,
|
||||||
};
|
};
|
||||||
|
const currentCategoryTree = findElementPathById(categoryTree.value, currentArticle.value.categoryId);
|
||||||
|
function findElementPathById(categories: any[], targetId: number, path: any[] = []) {
|
||||||
|
for (const category of categories) {
|
||||||
|
const currentPath = [...path, { title: category.title, code: category.code }];
|
||||||
|
if (category.id === targetId) {
|
||||||
|
return currentPath;
|
||||||
|
}
|
||||||
|
if (category.children) {
|
||||||
|
const result: any = findElementPathById(category.children, targetId, currentPath);
|
||||||
|
if (result) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(currentArticle.value, "currentArticle");
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="overflow-hidden">
|
<div class="overflow-hidden w-full max-w-1385px mx-auto px-30px image">
|
||||||
<div class="breadcrumb">
|
<div class="">
|
||||||
<ul class="breadcrumb__list">
|
<div class="category flex justify-between flex-wrap items-center mb-10px">
|
||||||
<li
|
<ul class="flex gap-32px">
|
||||||
class="breadcrumb__list__item"
|
<li v-for="(category, index) in currentCategoryTree" :key="index" class="first:text-#000 text-#929292 last:after:content-[''] relative after:absolute after:content-['/'] after:text-20px after:right--20px">
|
||||||
v-for="(item, index) in _props.dataResult && _props.dataResult?.length > 0 ? _props.dataResult : Array(SETTING_OPTIONS.BREADCRUMB_MAX_ELEMENT).fill(null)"
|
<nuxt-link class="font-raleway text-18px font-500 leading-180% uppercase" :to="`/${category.code}`">{{ category.title }}</nuxt-link>
|
||||||
:key="index"
|
|
||||||
:class="isEmpty(item) && 'empty'"
|
|
||||||
>
|
|
||||||
<p v-if="!isEmpty(item)" class="breadcrumb__list__item__title">
|
|
||||||
{{ item?.title }}
|
|
||||||
</p>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p class="breakcrumb__time">Ngày tạo image</p>
|
<div v-if="currentArticle.topics" class="pl-20px relative bg-primary inline-block">
|
||||||
|
<nuxt-link class="h-30px block py-4px px-16px border-1 border-#000 bg-white text-12px leading-180% font-raleway font-400" :to="`/topic/${currentArticle.topics[0].code}`">{{ currentArticle.topics[0].title }}</nuxt-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content">Nội dung bài viết sẽ ở đây</div>
|
|
||||||
|
|
||||||
<div class="btn-wrap w-100 max-w">
|
|
||||||
<div class="center-y">
|
|
||||||
<p title="Quay trở lại" class="button--back">
|
|
||||||
<Icon name="fa6-solid:arrow-left" />
|
|
||||||
</p>
|
|
||||||
<button class="button--bookmark">
|
|
||||||
<Icon name="fa6-regular:bookmark" />
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
<h2 class="font-gelasio text-44px font-bold leading-130%" v-if="currentArticle.title" v-html="currentArticle.title"></h2>
|
||||||
|
<!-- <div class="grid grid-cols-12 gap-20px">
|
||||||
|
<div class="col-span-3"></div>
|
||||||
|
</div> -->
|
||||||
|
|
||||||
<div class="center-y">
|
<div class="author flex gap-12px my-20px" v-if="currentArticle.authors">
|
||||||
<button title="Copy link" class="button--back copy-link">
|
<ul class="flex">
|
||||||
<Icon name="mdi:link-variant" />
|
<li :style="{ 'z-index': index + 1 }" class="relative ml--12px first:ml-0" v-for="(author, index) in currentArticle.authors" :key="index">
|
||||||
</button>
|
<nuxt-link :to="`/tac-gia/${author.code}`">
|
||||||
|
<img :src="author.thumbnail || `http://picsum.photos/1024/600?random=1`" alt="" class="w-64px p-1px border-1px border-white h-64px object-cover rounded-full" />
|
||||||
|
</nuxt-link>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div>
|
||||||
|
<div class="mt-10px">
|
||||||
|
<nuxt-link class="font-raleway text-#000" v-for="(author, index) in currentArticle.authors" :key="index" :to="`/tac-gia/${author.code}`">{{ author.title + (index < currentArticle.authors.length - 1 ? ", " : "") }}</nuxt-link>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="text-12px">Xuất bản vào {{ formatDate(currentArticle.publishedOn, "DD/MM/YYYY | hh:mm") }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-html="currentArticle.detail"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
$max-width: 680px;
|
$max-width: 1276px;
|
||||||
|
|
||||||
.breadcrumb {
|
.breadcrumb {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
const emit = defineEmits(["dropData", "selectComponent"]);
|
||||||
|
const _props = defineProps<{
|
||||||
|
dataResult?: any;
|
||||||
|
dataType?: any;
|
||||||
|
dataQuery?: any;
|
||||||
|
layout?: string;
|
||||||
|
label?: string;
|
||||||
|
}>();
|
||||||
|
const { currentArticle } = storeToRefs(useArticleStore())
|
||||||
|
console.log(currentArticle.value, 'currentArticle')
|
||||||
|
</script>
|
||||||
|
<template>
|
||||||
|
<div class="overflow-hidden infographic">
|
||||||
|
<!-- bổ sung sau -->
|
||||||
|
<!-- <img :src="currentArticle.thumbnail" alt="" class="w-full object-cover">
|
||||||
|
|
||||||
|
<div class="px-44px pb-30px my-30px max-w-660px mx-auto border-b-1px border-#000">
|
||||||
|
|
||||||
|
</div> -->
|
||||||
|
|
||||||
|
<div v-html="currentArticle.detail"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
|
||||||
|
.center-y {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,93 +1,254 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { useArticleStore } from "~/stores/articles";
|
||||||
|
import Poll from "~/components/article/immerse/Poll.vue";
|
||||||
|
import Quiz from "~/components/article/immerse/Quiz.vue";
|
||||||
|
import Survey from "~/components/article/immerse/Survey.vue";
|
||||||
|
import Document from "~/components/article/immerse/Document.vue";
|
||||||
|
import Attachment from "@/components/article/immerse/Attachment.vue";
|
||||||
|
import Tag from "@/components/article/immerse/Tag.vue";
|
||||||
|
const { currentArticle } = storeToRefs(useArticleStore());
|
||||||
|
import { useDynamicPageStore } from "~/stores/dynamic-page";
|
||||||
|
import { useCategoryStore } from "~/stores/category";
|
||||||
|
|
||||||
|
const store = reactive({
|
||||||
|
dynamicPage: useDynamicPageStore(),
|
||||||
|
article: useArticleStore(),
|
||||||
|
category: useCategoryStore(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const { categoryTree } = storeToRefs(store.category);
|
||||||
|
|
||||||
|
await store.category.fetchBySiteId();
|
||||||
|
const currentCategoryTree = (store.category.currentCategoryTree = findElementPathById(categoryTree.value, currentArticle.value.categoryId));
|
||||||
|
function findElementPathById(categories: any[], targetId: number, path: any[] = []) {
|
||||||
|
for (const category of categories) {
|
||||||
|
const currentPath = [...path, { title: category.title, code: category.code }];
|
||||||
|
if (category.id === targetId) {
|
||||||
|
return currentPath;
|
||||||
|
}
|
||||||
|
if (category.children) {
|
||||||
|
const result: any = findElementPathById(category.children, targetId, currentPath);
|
||||||
|
if (result) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
clickElement("figure", "custom-figure", "data-code");
|
||||||
|
clickElement("author", "author", "data-code");
|
||||||
|
|
||||||
|
let detailEmagazine = document.querySelector('div[layout="ARTICLE_DETAIL_EMAGAZINE"]');
|
||||||
|
let breadcrumb = document.querySelector('div[layout="BREADCRUM_DEFAULT"]');
|
||||||
|
if (detailEmagazine && breadcrumb) {
|
||||||
|
breadcrumb.classList.add("lg:max-w-640px", "mx-auto");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function clickElement(type: string, selector: string, attribute: string) {
|
||||||
|
const elements = document.querySelectorAll(selector);
|
||||||
|
elements.forEach((element) => {
|
||||||
|
element.addEventListener("click", (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
const url = `${window.location.protocol}//${window.location.host}/${type}/${element.getAttribute(attribute)}`;
|
||||||
|
|
||||||
|
const a = document.createElement("a");
|
||||||
|
a.href = url;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const isBookmark = ref(false);
|
||||||
|
const onClickBookmark = () => {
|
||||||
|
isBookmark.value = !isBookmark.value;
|
||||||
|
};
|
||||||
|
async function copyLink() {
|
||||||
|
try {
|
||||||
|
const url = window.location.href;
|
||||||
|
await navigator.clipboard.writeText(url);
|
||||||
|
alert("copy link thành công");
|
||||||
|
} catch (error) {
|
||||||
|
alert(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getSrc = (htmlString: string) => {
|
||||||
|
const srcRegex = /src="([^"]+)"/;
|
||||||
|
return htmlString?.match(srcRegex);
|
||||||
|
};
|
||||||
|
|
||||||
|
const isMoreControl = ref(false);
|
||||||
|
const isPlayed = ref(true);
|
||||||
|
const isVolume = ref(true);
|
||||||
|
const speedList = ref<{ [key: number]: string }>({
|
||||||
|
1: "0.5x",
|
||||||
|
2: "0.75x",
|
||||||
|
3: "1.0x",
|
||||||
|
4: "1.25x",
|
||||||
|
5: "1.50x",
|
||||||
|
});
|
||||||
|
const speedIndexDefault = ref(3);
|
||||||
|
const speedDefault = ref(speedList.value[speedIndexDefault.value]);
|
||||||
|
const volume = ref(1.0);
|
||||||
|
const audioPlayer = ref<HTMLAudioElement | null>(null);
|
||||||
|
const currentTime = ref(0);
|
||||||
|
const duration = ref(0);
|
||||||
|
|
||||||
|
function setUpVolums() {
|
||||||
|
isVolume.value = !isVolume.value;
|
||||||
|
if (audioPlayer.value) {
|
||||||
|
if (isVolume.value) {
|
||||||
|
audioPlayer.value.volume = 1;
|
||||||
|
} else {
|
||||||
|
audioPlayer.value.volume = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateVolume = (num?: number) => {
|
||||||
|
if (audioPlayer.value) {
|
||||||
|
if(num) {
|
||||||
|
volume.value += num
|
||||||
|
}
|
||||||
|
// console.log('1231321')
|
||||||
|
audioPlayer.value.volume = volume.value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function chanageSpeed() {
|
||||||
|
if (speedIndexDefault.value < 5) {
|
||||||
|
speedIndexDefault.value += 1;
|
||||||
|
if (audioPlayer.value) {
|
||||||
|
audioPlayer.value.playbackRate += 0.25;
|
||||||
|
}
|
||||||
|
speedDefault.value = speedList.value[speedIndexDefault.value];
|
||||||
|
} else {
|
||||||
|
if (audioPlayer.value) {
|
||||||
|
audioPlayer.value.playbackRate = 0.5;
|
||||||
|
}
|
||||||
|
speedIndexDefault.value = 1;
|
||||||
|
speedDefault.value = speedList.value[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function togglePlayer() {
|
||||||
|
isPlayed.value = !isPlayed.value;
|
||||||
|
if (audioPlayer.value) {
|
||||||
|
if (isPlayed.value) {
|
||||||
|
audioPlayer.value.pause();
|
||||||
|
} else {
|
||||||
|
audioPlayer.value.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function replayAndForward(time: number) {
|
||||||
|
if (audioPlayer.value) {
|
||||||
|
if (audioPlayer.value.currentTime == audioPlayer.value.duration) {
|
||||||
|
isPlayed.value = true;
|
||||||
|
} else {
|
||||||
|
audioPlayer.value.currentTime = audioPlayer.value.currentTime + time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const seekToTime = () => {
|
||||||
|
if (audioPlayer.value) {
|
||||||
|
audioPlayer.value.currentTime = currentTime.value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateCurrentTime = () => {
|
||||||
|
if (audioPlayer.value) {
|
||||||
|
currentTime.value = audioPlayer.value.currentTime;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateDuration = () => {
|
||||||
|
if (audioPlayer.value) {
|
||||||
|
duration.value = audioPlayer.value.duration;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const currrentTimeComputed = computed(() => {
|
||||||
|
return utils.formattedTime(currentTime.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
const durationComputed = computed(() => {
|
||||||
|
return utils.formattedTime(duration.value);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div class="lg:p-40px md:p-30px p-5 border-1px border-solid border-black/10 rounded-8px">
|
||||||
class="podcast__wrapper overflow-hidden"
|
<div class="flex md:flex-row flex-col md:gap-6 gap-2 justify-between mb-10px">
|
||||||
>
|
<p class="text-#9f9f9f text-14px mb-2 md:hidden block text-center">
|
||||||
<div
|
{{ utils.dateFormat(currentArticle?.publishedOn, "dddd, DD/MM/YYYY - HH:mm") }}
|
||||||
class="podcast"
|
|
||||||
>
|
|
||||||
<p
|
|
||||||
class="podcast__content__time"
|
|
||||||
>
|
|
||||||
Ngày tạo podcast
|
|
||||||
</p>
|
</p>
|
||||||
<figure><img src="http://picsum.photos/1024/600?random=1'" alt="Ảnh podcast" title="Ảnh podcast" /></figure>
|
<figure class="!w-auto"><img class="w-150px h-150px rounded-8px shadow-md cursor-pointer" :src="currentArticle?.thumbnail" alt="Ảnh podcast" title="Ảnh podcast" /></figure>
|
||||||
<div
|
<div class="flex-1 text-#222 m-0 md:text-left text-center">
|
||||||
class="podcast__content"
|
<p class="text-#9f9f9f text-14px mb-2 md:block hidden">
|
||||||
>
|
{{ utils.dateFormat(currentArticle?.publishedOn, "dddd, DD/MM/YYYY - HH:mm") }}
|
||||||
<p
|
|
||||||
class="podcast__content__time"
|
|
||||||
>
|
|
||||||
Ngày tạo podcast
|
|
||||||
</p>
|
|
||||||
<h1 class="podcast__content__title">Tiêu đề podcast</h1>
|
|
||||||
<p
|
|
||||||
class="podcast__content__text"
|
|
||||||
>
|
|
||||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
|
||||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
|
||||||
</p>
|
</p>
|
||||||
|
<h1 class="text-24px md:mb-4 mb-2 font-bold" v-html="currentArticle?.title"></h1>
|
||||||
|
<p class="hidden md:line-clamp-3" v-html="currentArticle?.intro"></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul
|
<ul class="items-start gap-2 m-0 p-0 md:flex hidden">
|
||||||
class="buttons"
|
<li class="w-9 h-9 bg-white border-1 border-solid border-[rgb(229, 231, 235)] cursor-pointer shadow-md rounded-50px relative hover:bg-primary-100 hover:text-primary-600">
|
||||||
>
|
<Icon class="text-18px absolute top-50% left-50% translate-x--50% translate-y--50%" name="mdi:bookmark-outline" />
|
||||||
<li><Icon name="mdi:bookmark-outline" /></li>
|
</li>
|
||||||
<li><Icon name="material-symbols:mode-comment-outline" /></li>
|
<li class="w-9 h-9 bg-white border-1 border-solid border-[rgb(229, 231, 235)] cursor-pointer shadow-md rounded-50px relative hover:bg-primary-100 hover:text-primary-600">
|
||||||
|
<Icon class="text-18px absolute top-50% left-50% translate-x--50% translate-y--50%" name="material-symbols:mode-comment-outline" />
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
<audio :src="getSrc(currentArticle?.detail)?.[1]" preload="auto" ref="audioPlayer" @timeupdate="updateCurrentTime" @loadedmetadata="updateDuration" />
|
||||||
<div class="playlist">
|
<div class="p-2">
|
||||||
<div class="playlist__time">
|
<input class="w-full accent-primary-600 cursor-pointer" type="range" v-model="currentTime" @input="seekToTime" :max="duration" />
|
||||||
<span>5:00</span>
|
<div class="flex justify-between">
|
||||||
<span>10:00</span>
|
<span>{{ currrentTimeComputed }}</span>
|
||||||
|
<span>{{ durationComputed }}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="playlist__buttons">
|
<div class="flex justify-between items-center">
|
||||||
<div class="playlist__buttons__left">
|
<div class="md:w-150px text-left">
|
||||||
<div
|
<div class="text-28px text-primary-600 md:hidden block">
|
||||||
class="button__prev"
|
|
||||||
>
|
|
||||||
<Icon name="material-symbols:skip-previous" />
|
<Icon name="material-symbols:skip-previous" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div class="md:inline-flex hidden items-center gap-2 ml--10px h9 text-primary-600 rounded-8px text-28px cursor-pointer hover:bg-primary-100">
|
||||||
class="sound"
|
<Icon @click="updateVolume(-0.1)" name="material-symbols:volume-mute"></Icon>
|
||||||
>
|
<input v-if="isVolume" class="accent-primary-600 h-1 w-12 lg:w-20 cursor-pointer" type="range" v-model="volume" @input="updateVolume()" min="0.1" max="1" step="0.1" />
|
||||||
<Icon name="material-symbols:volume-mute"></Icon>
|
<Icon @click="updateVolume(0.1)" name="material-symbols:volume-up"></Icon>
|
||||||
<div></div>
|
|
||||||
<Icon name="material-symbols:volume-up"></Icon>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="play">
|
<div class="flex items-center justify-center gap-4 flex-1 text-28px text-primary-600">
|
||||||
<Icon name="fluent:skip-back-10-48-filled" />
|
<Icon @click="replayAndForward(-10)" name="fluent:skip-back-10-48-filled" />
|
||||||
<Icon name="material-symbols:play-arrow" class="button" />
|
<button @click="togglePlayer" class="bg-transparent">
|
||||||
<Icon name="fluent:skip-forward-10-48-filled" />
|
<Icon v-if="isPlayed" name="material-symbols:play-arrow-rounded" class="text-64px" />
|
||||||
|
<Icon v-if="!isPlayed" name="material-symbols:pause" class="text-64px" />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<Icon @click="replayAndForward(10)" name="fluent:skip-forward-10-48-filled" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="playlist__buttons__right">
|
<div class="md:w-150px text-right">
|
||||||
<div
|
<div class="text-28px text-primary-600 md:hidden block">
|
||||||
class="button__next"
|
|
||||||
>
|
|
||||||
<Icon name="material-symbols:skip-next" />
|
<Icon name="material-symbols:skip-next" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div class="text-14px text-primary-600 md:block hidden cursor-pointer" @click="chanageSpeed">
|
||||||
class="speed"
|
<span class="font-300">Tốc độ phát: </span>
|
||||||
>
|
<strong class="font-bold text-20px ml-1">{{ speedDefault }}</strong>
|
||||||
<span>Tốc độ phát: </span>
|
|
||||||
<strong>1x</strong>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p
|
<p class="md:hidden block" v-html="currentArticle?.intro"></p>
|
||||||
class="podcast__content__text"
|
|
||||||
>
|
|
||||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
|
|
||||||
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
@@ -1,42 +1,93 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Comment from "@/components/dynamic-page/page-component/templates/others/comments/Default.vue";
|
const { categoryTree } = storeToRefs(useCategoryStore());
|
||||||
|
const { currentArticle } = storeToRefs(useArticleStore());
|
||||||
|
if (categoryTree.value) {
|
||||||
|
await useCategoryStore().fetchBySiteId();
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentCategoryTree = findElementPathById(categoryTree.value, currentArticle.value.categoryId);
|
||||||
|
function findElementPathById(categories: any[], targetId: number, path: any[] = []) {
|
||||||
|
for (const category of categories) {
|
||||||
|
const currentPath = [...path, { title: category.title, code: category.code }];
|
||||||
|
if (category.id === targetId) {
|
||||||
|
return currentPath;
|
||||||
|
}
|
||||||
|
if (category.children) {
|
||||||
|
const result: any = findElementPathById(category.children, targetId, currentPath);
|
||||||
|
if (result) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="container overflow-hidden">
|
<div class="video-container">
|
||||||
<div class="video row">
|
<ul class="flex gap-32px lg:ml-80px md:ml-40px sm:ml-20px">
|
||||||
<div
|
<li v-for="(category, index) in currentCategoryTree" :key="index" class="first:text-#000 text-#929292 last:after:content-[''] relative after:absolute after:content-['/'] after:text-20px after:right--20px">
|
||||||
class="video__left"
|
<nuxt-link class="font-raleway text-18px font-500 leading-180% uppercase" :to="`/${category.code}`">{{ category.title }}</nuxt-link>
|
||||||
>
|
</li>
|
||||||
<video controls="controls" width="100%" height="100%" data-file-id="149" data-resource="https://acp-api.vpress.vn/Resources/Video/983d2f57-7743-472f-b22d-fc73085af6d5.mp4" data-title="Download.mp4">
|
</ul>
|
||||||
<source src="" type="video/mp4" />
|
|
||||||
</video>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
<div class="video-content" v-html="currentArticle.detail"></div>
|
||||||
class="video__right bg-body-tertiary"
|
|
||||||
>
|
|
||||||
<h1
|
|
||||||
class=""
|
|
||||||
>
|
|
||||||
Tiêu đề video
|
|
||||||
</h1>
|
|
||||||
<p class="line-clamp-3 fs-5 fw-light">
|
|
||||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
|
|
||||||
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
|
||||||
</p>
|
|
||||||
<h5 class="text-end fs-4 opacity-75">Tác giả</h5>
|
|
||||||
|
|
||||||
<p><b class="text-primary fw-semibold">Danh mục</b> <span class="ms-2 opacity-25 fw-semibold">Ngày đăng video</span></p>
|
|
||||||
<Comment />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.line-clamp-3 {
|
.video-container {
|
||||||
overflow: hidden;
|
width: 100%;
|
||||||
display: -webkit-box;
|
max-width: 1080px;
|
||||||
-webkit-box-orient: vertical;
|
margin: auto;
|
||||||
-webkit-line-clamp: 3;
|
|
||||||
|
.category-list {
|
||||||
|
display: flex;
|
||||||
|
gap: 32px;
|
||||||
|
margin-bottom: 26px;
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0 0 0 80px;
|
||||||
|
|
||||||
|
.category-item {
|
||||||
|
color: #929292;
|
||||||
|
position: relative;
|
||||||
|
font-size: 18px;
|
||||||
|
|
||||||
|
& > span {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 180%;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
position: absolute;
|
||||||
|
content: "/";
|
||||||
|
font-size: 20px;
|
||||||
|
right: -20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
&::after {
|
||||||
|
content: "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-content {
|
||||||
|
width: 100%;
|
||||||
|
// max-width: 1080px;
|
||||||
|
margin: 26px 0 26px 0px;
|
||||||
|
// background-color: #eee;
|
||||||
|
// height: 500px;
|
||||||
|
font-size: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -4,3 +4,5 @@ export { default as Article_Detail_General } from './General.vue'
|
|||||||
export { default as Article_Detail_Podcast } from './Podcast.vue'
|
export { default as Article_Detail_Podcast } from './Podcast.vue'
|
||||||
export { default as Article_Detail_Video } from './Video.vue'
|
export { default as Article_Detail_Video } from './Video.vue'
|
||||||
export { default as Article_Detail_Image } from './Image.vue'
|
export { default as Article_Detail_Image } from './Image.vue'
|
||||||
|
export { default as Article_Detail_Emagazine } from './Emagazine.vue'
|
||||||
|
export { default as Article_Detail_Infographic } from './Infographic.vue'
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
import { enumPageComponentTemplate, enumPageComponentKey, enumPageComponentLayouts } from "@/definitions/enum";
|
import { enumPageComponentTemplate, enumPageComponentKey, enumPageComponentLayouts } from "@/definitions/enum";
|
||||||
|
|
||||||
// import { Article_Card, Article_Detail_Video, Article_Detail_Podcast, Article_Detail_General, Article_Detail_Image } from "./index";
|
// import { Article_Card, Article_Detail_Video, Article_Detail_Podcast, Article_Detail_General, Article_Detail_Image } from "./index";
|
||||||
import { Article_Detail_General, Article_Detail_Podcast, Article_Detail_Video, Article_Detail_Image } from "./index";
|
import { Article_Detail_General, Article_Detail_Podcast, Article_Detail_Video, Article_Detail_Image, Article_Detail_Emagazine, Article_Detail_Infographic } from "./index";
|
||||||
const _props = defineProps<{
|
const _props = defineProps<{
|
||||||
settings: any;
|
settings: any;
|
||||||
component?: any;
|
component?: any;
|
||||||
@@ -13,6 +13,8 @@ const definedDynamicComponent: Record<string, any> = {
|
|||||||
[enumPageComponentLayouts[enumPageComponentTemplate[enumPageComponentKey.ARTICLE]["ARTICLE_DETAIL"]]["DETAIL_PODCAST"]]: Article_Detail_Podcast,
|
[enumPageComponentLayouts[enumPageComponentTemplate[enumPageComponentKey.ARTICLE]["ARTICLE_DETAIL"]]["DETAIL_PODCAST"]]: Article_Detail_Podcast,
|
||||||
[enumPageComponentLayouts[enumPageComponentTemplate[enumPageComponentKey.ARTICLE]["ARTICLE_DETAIL"]]["DETAIL_VIDEO"]]: Article_Detail_Video,
|
[enumPageComponentLayouts[enumPageComponentTemplate[enumPageComponentKey.ARTICLE]["ARTICLE_DETAIL"]]["DETAIL_VIDEO"]]: Article_Detail_Video,
|
||||||
[enumPageComponentLayouts[enumPageComponentTemplate[enumPageComponentKey.ARTICLE]["ARTICLE_DETAIL"]]["DETAIL_IMAGE"]]: Article_Detail_Image,
|
[enumPageComponentLayouts[enumPageComponentTemplate[enumPageComponentKey.ARTICLE]["ARTICLE_DETAIL"]]["DETAIL_IMAGE"]]: Article_Detail_Image,
|
||||||
|
[enumPageComponentLayouts[enumPageComponentTemplate[enumPageComponentKey.ARTICLE]["ARTICLE_DETAIL"]]["DETAIL_EMAGAZINE"]]: Article_Detail_Emagazine,
|
||||||
|
[enumPageComponentLayouts[enumPageComponentTemplate[enumPageComponentKey.ARTICLE]["ARTICLE_DETAIL"]]["DETAIL_INFOGRAPHIC"]]: Article_Detail_Infographic,
|
||||||
};
|
};
|
||||||
|
|
||||||
const getCurrentComponent = computed(() => `${_props.settings.layout}`);
|
const getCurrentComponent = computed(() => `${_props.settings.layout}`);
|
||||||
|
|||||||
@@ -8,6 +8,22 @@ const _props = defineProps<{
|
|||||||
label?: any;
|
label?: any;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const SETTING_OPTIONS = {
|
||||||
|
MAX_ELEMENT: 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
const _dataResult = computed(() => {
|
||||||
|
const designObject = _props.label ? getInputValue(_props.label, "OBJECT") : {};
|
||||||
|
let _components = Array(Number(designObject.MAX) || SETTING_OPTIONS.MAX_ELEMENT).fill(null);
|
||||||
|
const result = getInputValue(_props.dataResult, "ARRAY");
|
||||||
|
result &&
|
||||||
|
result.length > 0 &&
|
||||||
|
_components.map((_: any, index: any) => {
|
||||||
|
_components[index] = result[index] || null;
|
||||||
|
});
|
||||||
|
return Object.assign({}, _components);
|
||||||
|
});
|
||||||
|
|
||||||
const designObject = computed(() => {
|
const designObject = computed(() => {
|
||||||
return _props.label ? getInputValue(_props.label, "OBJECT") : {};
|
return _props.label ? getInputValue(_props.label, "OBJECT") : {};
|
||||||
});
|
});
|
||||||
@@ -26,7 +42,7 @@ const mapActivesToItems = (index: number) => {
|
|||||||
<template v-if="!isEmpty(component)">
|
<template v-if="!isEmpty(component)">
|
||||||
<div>
|
<div>
|
||||||
<h3 :style="mapActivesToItems(index)['h3.categories']">
|
<h3 :style="mapActivesToItems(index)['h3.categories']">
|
||||||
<nuxt-link to="#">{{ component.title }}</nuxt-link>
|
<nuxt-link :to="`/${component.code}`">{{ component.title }}</nuxt-link>
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<div v-html="designObject.styleClasses"></div>
|
<div v-html="designObject.styleClasses"></div>
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ const mapActivesToItems = (index: number) => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="categories-container border-custom" :class="designObject['categories_Class']" :style="designObject['div.categories-container']">
|
<div class="categories-container border-custom flex-wrap" :class="designObject['categories_Class']" :style="designObject['div.categories-container']">
|
||||||
<div v-for="(component, index) in _dataResult" :key="index" :class="['border-custom', isEmpty(component) ? 'empty' : 'category', designObject['category_Class']]" :style="mapActivesToItems(index)['category']">
|
<div v-for="(component, index) in _dataResult" :key="index" :class="['border-custom', isEmpty(component) ? 'empty' : 'category', designObject['category_Class']]" :style="mapActivesToItems(index)['category']">
|
||||||
<template v-if="!isEmpty(component)">
|
<template v-if="!isEmpty(component)">
|
||||||
<div class="category-content">
|
<div class="category-content">
|
||||||
@@ -45,8 +45,8 @@ const mapActivesToItems = (index: number) => {
|
|||||||
<path d="M5.984 2.456V4.184H4.336V5.992H2.4V4.184H0.752V2.456H2.4V0.648H4.336V2.456H5.984Z" fill="black" />
|
<path d="M5.984 2.456V4.184H4.336V5.992H2.4V4.184H0.752V2.456H2.4V0.648H4.336V2.456H5.984Z" fill="black" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
<h3 :style="mapActivesToItems(index)['h3.categories']">
|
<h3 :style="mapActivesToItems(index)['h3.categories']" class="whitespace-nowrap">
|
||||||
{{ component.title }}
|
<nuxt-link :to="`/${component.code}`">{{ component.title }}</nuxt-link>
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="designObject.styleClasses" v-html="designObject.styleClasses"></div>
|
<div v-if="designObject.styleClasses" v-html="designObject.styleClasses"></div>
|
||||||
|
|||||||
@@ -0,0 +1,247 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import DynamicComponent from "~/components/dynamic-page/page-component/templates/index.vue";
|
||||||
|
import { COLLECTION_QUERY_DROP, getValueStringWithKeyAndColon, getInputValue } from "@/utils/parseSQL";
|
||||||
|
import { isEmpty } from "@/utils/lodash";
|
||||||
|
import { enumPageComponentTemplates } from "@/definitions/enum";
|
||||||
|
const emit = defineEmits(["dropComponent", "dropData", "selectComponent"]);
|
||||||
|
|
||||||
|
// const store = reactive({
|
||||||
|
// page: useCmsPageStore(),
|
||||||
|
// section: usePageSectionStore(),
|
||||||
|
// });
|
||||||
|
// const { currentScreenMode } = storeToRefs(useCmsPageStore());
|
||||||
|
|
||||||
|
const _props = defineProps<{
|
||||||
|
dataResult?: any[];
|
||||||
|
dataQuery?: string;
|
||||||
|
layout?: string;
|
||||||
|
label?: string;
|
||||||
|
content?: any;
|
||||||
|
component?: any;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const SETTING_OPTIONS = {
|
||||||
|
MAX_ELEMENT: 9,
|
||||||
|
TEMPLATE: "TYPE:Card",
|
||||||
|
LAYOUT: "TYPE:Card_VideoHightLight",
|
||||||
|
};
|
||||||
|
|
||||||
|
const COMPONENT = {
|
||||||
|
taxonomy: enumPageComponentTemplates.ARTICLE,
|
||||||
|
};
|
||||||
|
|
||||||
|
const LAYOUT_PARSE = computed(() => {
|
||||||
|
return _props.label ? getInputValue(_props.label, "OBJECT") : {};
|
||||||
|
});
|
||||||
|
|
||||||
|
const _dataResult = computed(() => {
|
||||||
|
let _components = Array(Number(LAYOUT_PARSE.value.MAX) || SETTING_OPTIONS.MAX_ELEMENT).fill(null);
|
||||||
|
const result = getInputValue(_props.dataResult, "ARRAY");
|
||||||
|
result &&
|
||||||
|
result.length > 0 &&
|
||||||
|
_components.map((_: any, index: any) => {
|
||||||
|
_components[index] = result[index] || null;
|
||||||
|
});
|
||||||
|
return _components;
|
||||||
|
});
|
||||||
|
|
||||||
|
async function dropData(data: any) {
|
||||||
|
if (data) {
|
||||||
|
const { dataResult, dataType } = data;
|
||||||
|
const checkDataResult = getInputValue(_props.dataResult, "ARRAY");
|
||||||
|
const result = _props.dataResult ? [...checkDataResult, { ...dataResult }] : [{ ...dataResult }];
|
||||||
|
const getDataQuery = _props.dataQuery ? COLLECTION_QUERY_DROP(dataType, getValueStringWithKeyAndColon(_props.dataQuery) + "," + dataResult.id) : COLLECTION_QUERY_DROP(dataType, dataResult.id);
|
||||||
|
|
||||||
|
emit("dropData", {
|
||||||
|
dataResult: result,
|
||||||
|
dataType,
|
||||||
|
dataQuery: getDataQuery,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const selectComponent = () => {
|
||||||
|
emit("selectComponent");
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapActivesToItems = (index: number) => {
|
||||||
|
if (LAYOUT_PARSE.value && LAYOUT_PARSE.value.listCss) {
|
||||||
|
return LAYOUT_PARSE.value.listCss[index] || {};
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
:id="`cpn_${_props.component?.id}`"
|
||||||
|
class="collection-video-container border-custom"
|
||||||
|
:class="[LAYOUT_PARSE['div.collection-container_Class'], LAYOUT_PARSE['collection_Class']]"
|
||||||
|
@click="selectComponent"
|
||||||
|
:style="LAYOUT_PARSE['div.collection-container']"
|
||||||
|
>
|
||||||
|
<div v-for="(component, index) in _dataResult" :key="index">
|
||||||
|
<div class="wrap">
|
||||||
|
<!-- {{ index }} -->
|
||||||
|
<DynamicComponent
|
||||||
|
:settings="{
|
||||||
|
template: SETTING_OPTIONS.TEMPLATE,
|
||||||
|
layout: SETTING_OPTIONS.LAYOUT,
|
||||||
|
label: mapActivesToItems(Number(index)),
|
||||||
|
dataResult: !isEmpty(component) ? { ...component } : null,
|
||||||
|
}"
|
||||||
|
:component="COMPONENT"
|
||||||
|
@drop-data="dropData"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-html="LAYOUT_PARSE.styleClasses" style="display: none" v-if="LAYOUT_PARSE.styles"></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.collection-video-container {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||||
|
grid-template-rows: repeat(3, minmax(0, 1fr));
|
||||||
|
gap: 20px;
|
||||||
|
& > div {
|
||||||
|
background-color: #eee;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
padding-top: calc((9 / 16) * 100%);
|
||||||
|
|
||||||
|
& > .wrap {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
& > .basic-article {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
& > .article_video {
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
& > .article_video_thumb {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-end;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
& > .article_video_content {
|
||||||
|
padding: 0 24px 8px 24px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
& > span {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
& > .article-title {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 130%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
& > .article-intro {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .empty-box {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
margin: 0px;
|
||||||
|
& > div {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:nth-child(1) {
|
||||||
|
grid-column: span 2 / span 2;
|
||||||
|
grid-row: span 2 / span 2;
|
||||||
|
order: 6;
|
||||||
|
background-color: aqua;
|
||||||
|
|
||||||
|
& > .wrap {
|
||||||
|
& > .basic-article {
|
||||||
|
& > .article_video {
|
||||||
|
& > .article_video_thumb {
|
||||||
|
& > .article_video_content {
|
||||||
|
padding: 0 120px 24px 120px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(2) {
|
||||||
|
order: 2;
|
||||||
|
background-color: red;
|
||||||
|
}
|
||||||
|
&:nth-child(3) {
|
||||||
|
order: 3;
|
||||||
|
background-color: green;
|
||||||
|
}
|
||||||
|
&:nth-child(4) {
|
||||||
|
order: 4;
|
||||||
|
background-color: orange;
|
||||||
|
}
|
||||||
|
&:nth-child(5) {
|
||||||
|
order: 5;
|
||||||
|
background-color: orangered;
|
||||||
|
}
|
||||||
|
&:nth-child(6) {
|
||||||
|
order: 6;
|
||||||
|
background-color: brown;
|
||||||
|
}
|
||||||
|
&:nth-child(7) {
|
||||||
|
order: 7;
|
||||||
|
background-color: blueviolet;
|
||||||
|
}
|
||||||
|
&:nth-child(8) {
|
||||||
|
order: 8;
|
||||||
|
background-color: darkred;
|
||||||
|
}
|
||||||
|
&:nth-child(9) {
|
||||||
|
order: 9;
|
||||||
|
background-color: darkcyan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// &.column-phone {
|
||||||
|
// grid-template-columns: repeat(1, minmax(0, 1fr)) !important;
|
||||||
|
// }
|
||||||
|
// &.column {
|
||||||
|
// grid-template-columns: repeat(1, minmax(0, 1fr));
|
||||||
|
// }
|
||||||
|
// &.row {
|
||||||
|
// grid-template-rows: auto;
|
||||||
|
// grid-auto-flow: column;
|
||||||
|
// }
|
||||||
|
// &.border-pri {
|
||||||
|
// gap: 5px;
|
||||||
|
// }
|
||||||
|
// &.border-custom {
|
||||||
|
// border-color: #e5e5e5 !important;
|
||||||
|
// }
|
||||||
|
// .empty {
|
||||||
|
// min-height: 100px;
|
||||||
|
// border-radius: 6px;
|
||||||
|
// background: #409eff;
|
||||||
|
// }
|
||||||
|
// &.noData {
|
||||||
|
// border-radius: 6px;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
export { default as Default_Collection } from './Default.vue'
|
export { default as Default_Collection } from './Default.vue'
|
||||||
export { default as Audio_Collection } from './Audio.vue'
|
export { default as Audio_Collection } from './Audio.vue'
|
||||||
|
export { default as Video_Collection } from './Video.vue'
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { enumPageComponentTemplate, enumPageComponentKey, enumPageComponentLayouts } from "@/definitions/enum";
|
import { enumPageComponentTemplate, enumPageComponentKey, enumPageComponentLayouts } from "@/definitions/enum";
|
||||||
import { Default_Collection, Audio_Collection } from "./index";
|
import { Default_Collection, Audio_Collection, Video_Collection } from "./index";
|
||||||
|
|
||||||
const _props = defineProps<{
|
const _props = defineProps<{
|
||||||
settings: any;
|
settings: any;
|
||||||
@@ -10,6 +10,7 @@ const _props = defineProps<{
|
|||||||
const definedDynamicComponent: Record<string, any> = {
|
const definedDynamicComponent: Record<string, any> = {
|
||||||
[enumPageComponentLayouts[`${enumPageComponentTemplate[enumPageComponentKey.COLLECTION]["ARTICLE"]}`]["ARTICLE_COLLECTION_DEFAULT"]]: Default_Collection,
|
[enumPageComponentLayouts[`${enumPageComponentTemplate[enumPageComponentKey.COLLECTION]["ARTICLE"]}`]["ARTICLE_COLLECTION_DEFAULT"]]: Default_Collection,
|
||||||
[enumPageComponentLayouts[`${enumPageComponentTemplate[enumPageComponentKey.COLLECTION]["ARTICLE"]}`]["ARTICLE_COLLECTION_AUDIO"]]: Audio_Collection,
|
[enumPageComponentLayouts[`${enumPageComponentTemplate[enumPageComponentKey.COLLECTION]["ARTICLE"]}`]["ARTICLE_COLLECTION_AUDIO"]]: Audio_Collection,
|
||||||
|
[enumPageComponentLayouts[`${enumPageComponentTemplate[enumPageComponentKey.COLLECTION]["ARTICLE"]}`]["ARTICLE_COLLECTION_VIDEO"]]: Video_Collection,
|
||||||
};
|
};
|
||||||
|
|
||||||
const getCurrentComponent = computed(() => _props.settings.layout);
|
const getCurrentComponent = computed(() => _props.settings.layout);
|
||||||
|
|||||||
+13
-1
@@ -1,7 +1,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import DynamicComponent from "~/components/dynamic-page/page-component/templates/index.vue";
|
import DynamicComponent from "~/components/dynamic-page/page-component/templates/index.vue";
|
||||||
import { COLLECTION_QUERY_DROP, getValueStringWithKeyAndColon, getInputValue } from "@/utils/parseSQL";
|
import { COLLECTION_QUERY_DROP, getValueStringWithKeyAndColon, getInputValue } from "@/utils/parseSQL";
|
||||||
import { isEmpty, groupBy } from "lodash";
|
import { isEmpty } from "@/utils/lodash";
|
||||||
import { enumPageComponentTemplates } from "@/definitions/enum";
|
import { enumPageComponentTemplates } from "@/definitions/enum";
|
||||||
const emit = defineEmits(["dropComponent", "dropData", "selectComponent"]);
|
const emit = defineEmits(["dropComponent", "dropData", "selectComponent"]);
|
||||||
const _props = defineProps<{
|
const _props = defineProps<{
|
||||||
@@ -111,6 +111,18 @@ const mapActivesToItems = (index: number) => {
|
|||||||
-moz-column-count: 4;
|
-moz-column-count: 4;
|
||||||
gap: 16px;
|
gap: 16px;
|
||||||
|
|
||||||
|
@media (min-width: 640px) and (max-width: 1024px) {
|
||||||
|
column-count: 2;
|
||||||
|
-webkit-column-count: 2;
|
||||||
|
-moz-column-count: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 640px) {
|
||||||
|
column-count: 1;
|
||||||
|
-webkit-column-count: 1;
|
||||||
|
-moz-column-count: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.wrap {
|
.wrap {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
@@ -4,11 +4,10 @@ import { getInputValue } from "@/utils/parseSQL";
|
|||||||
import { enumPageComponentTemplates } from "@/definitions/enum";
|
import { enumPageComponentTemplates } from "@/definitions/enum";
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
import { useScroll } from '@vueuse/core';
|
||||||
const store = reactive({
|
const store = reactive({
|
||||||
component: useDynamicPageStore(),
|
component: useDynamicPageStore(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const _props = defineProps<{
|
const _props = defineProps<{
|
||||||
dataResult?: any[];
|
dataResult?: any[];
|
||||||
dataQuery?: string;
|
dataQuery?: string;
|
||||||
@@ -108,10 +107,11 @@ const mapActivesToItems = (index: number) => {
|
|||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
};
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<section v-if="listArticleByCategory?.length > 0">
|
<section :id="`cpn_[${_props.component.id}]`" v-if="listArticleByCategory?.length > 0">
|
||||||
<div class="section-container">
|
<div class="section-container">
|
||||||
<div class="section-layout" :style="designObject['div.section']">
|
<div class="section-layout" :style="designObject['div.section']">
|
||||||
<template v-for="(component, index) in listArticlePaging?.length > 0 ? listArticlePaging : listArticleByCategory" :key="index">
|
<template v-for="(component, index) in listArticlePaging?.length > 0 ? listArticlePaging : listArticleByCategory" :key="index">
|
||||||
@@ -126,13 +126,13 @@ const mapActivesToItems = (index: number) => {
|
|||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<div class="button-page flex">
|
<div class="button-page flex">
|
||||||
<span class="btn-page prev-page" @click.stop="() => handleNextPrev('-')" v-if="page > 1">
|
<a :href="`#cpn_[${_props.component.id}]`" class="btn-page prev-page" @click.stop="() => handleNextPrev('-')" v-if="page > 1">
|
||||||
<Icon name="ooui:previous-ltr"></Icon>
|
<Icon name="ooui:previous-ltr"></Icon>
|
||||||
</span>
|
</a>
|
||||||
<span :class="['btn-page', page === index + 1 && 'active']" @click.stop="() => select(index + 1)" v-for="(_, index) in Math.ceil(totals / limit)">{{ index + 1 }}</span>
|
<a :href="`#cpn_[${_props.component.id}]`" :class="['btn-page', page === index + 1 && 'active']" @click.stop="() => select(index + 1)" v-for="(_, index) in Math.ceil(totals / limit)" :key="index">{{ index + 1 }}</a>
|
||||||
<span class="btn-page next-page" @click.stop="() => handleNextPrev('+')" v-if="page < Math.ceil(totals / limit)">
|
<a :href="`#cpn_[${_props.component.id}]`" class="btn-page next-page" @click.stop="() => handleNextPrev('+')" v-if="page < Math.ceil(totals / limit)">
|
||||||
<Icon name="ooui:previous-rtl"></Icon>
|
<Icon name="ooui:previous-rtl"></Icon>
|
||||||
</span>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import Poll from "~/components/article/immerse/Poll.vue";
|
||||||
|
import Quiz from "~/components/article/immerse/Quiz.vue";
|
||||||
|
import Survey from "~/components/article/immerse/Survey.vue";
|
||||||
|
import Document from "~/components/article/immerse/Document.vue";
|
||||||
|
import Attachment from "@/components/article/immerse/Attachment.vue";
|
||||||
|
import Tag from "@/components/article/immerse/Tag.vue";
|
||||||
|
// import articlerelation from "@/components/article/immerse/ArticleRelation.vue";
|
||||||
import RecusiveSection from "@/components/dynamic-page/page-section/RecusiveSection.vue";
|
import RecusiveSection from "@/components/dynamic-page/page-section/RecusiveSection.vue";
|
||||||
import { getInputValue } from "@/utils/parseSQL";
|
import { getInputValue } from "@/utils/parseSQL";
|
||||||
import { enumPageSectionLayouts, enumPageSectionTemplate, enumPageSectionKey } from "~/definitions/enum";
|
import { enumPageSectionLayouts, enumPageSectionTemplate, enumPageSectionKey } from "~/definitions/enum";
|
||||||
@@ -92,6 +99,8 @@ function findElementPathById(categories: any[], targetId: number, path: any[] =
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log(currentArticle.value ,'currentArticle')
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -192,7 +201,7 @@ function findElementPathById(categories: any[], targetId: number, path: any[] =
|
|||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="(tag, index) in currentArticle.tags">
|
<li v-for="(tag, index) in currentArticle.tags">
|
||||||
<nuxt-link class="font-raleway font-500" :to="`tag/${tag.code}`">{{ tag.title }}</nuxt-link>
|
<nuxt-link class="font-raleway font-500" :to="`/tag/${tag.code}`">{{ tag.title }}</nuxt-link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -208,17 +217,17 @@ function findElementPathById(categories: any[], targetId: number, path: any[] =
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content">
|
<div class="content detail-default">
|
||||||
<div class="content__top">
|
<div class="content__top">
|
||||||
<div class="flex justify-between flex-wrap items-center mb-10px">
|
<div class="flex justify-between flex-wrap items-center mb-10px">
|
||||||
<ul class="flex gap-32px">
|
<ul class="flex gap-32px">
|
||||||
<li v-for="( category, index ) in currentCategoryTree" :key="index" class="first:text-#000 text-#929292 last:after:content-[''] relative after:absolute after:content-['/'] after:text-20px after:right--20px" >
|
<li v-for="( category, index ) in currentCategoryTree" :key="index" class="first:text-#000 text-#929292 last:after:content-[''] relative after:absolute after:content-['/'] after:text-20px after:right--20px" >
|
||||||
<nuxt-link class=" font-raleway text-18px font-500 leading-180% uppercase" :to="`${category.code}`">{{ category.title }}</nuxt-link>
|
<nuxt-link class=" font-raleway text-18px font-500 leading-180% uppercase" :to="`/${category.code}`">{{ category.title }}</nuxt-link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div v-if="currentArticle.topics" class="pl-20px relative bg-primary inline-block">
|
<div v-if="currentArticle.topics" class="pl-20px relative bg-primary inline-block">
|
||||||
<nuxt-link class="h-30px block py-4px px-16px border-1 border-#000 bg-white text-12px leading-180% font-raleway font-400" :to="`/topic/${currentArticle.topics[0].code}`">{{ currentArticle.topics[0].title }}</nuxt-link>
|
<nuxt-link class="h-30px block py-4px px-16px border-1 border-#000 bg-white text-12px leading-180% font-raleway font-400" :to="`/topic/${currentArticle.topics[0].slug}`">{{ currentArticle.topics[0].title }}</nuxt-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h2 class="font-gelasio text-44px font-bold leading-130%" v-if="currentArticle.title" v-html="currentArticle.title"></h2>
|
<h2 class="font-gelasio text-44px font-bold leading-130%" v-if="currentArticle.title" v-html="currentArticle.title"></h2>
|
||||||
@@ -226,7 +235,7 @@ function findElementPathById(categories: any[], targetId: number, path: any[] =
|
|||||||
<div class="author flex gap-12px my-20px" v-if="currentArticle.authors">
|
<div class="author flex gap-12px my-20px" v-if="currentArticle.authors">
|
||||||
<ul class="flex">
|
<ul class="flex">
|
||||||
<li :style="{'z-index': index + 1}" class="relative ml--12px first:ml-0" v-for="(author, index) in currentArticle.authors" :key="index">
|
<li :style="{'z-index': index + 1}" class="relative ml--12px first:ml-0" v-for="(author, index) in currentArticle.authors" :key="index">
|
||||||
<nuxt-link :to="`tac-gia/${author.code}`">
|
<nuxt-link :to="`/tac-gia/${author.code}`">
|
||||||
<img :src="author.thumbnail || `http://picsum.photos/1024/600?random=1`" alt="" class="w-64px p-1px border-1px border-white h-64px object-cover rounded-full">
|
<img :src="author.thumbnail || `http://picsum.photos/1024/600?random=1`" alt="" class="w-64px p-1px border-1px border-white h-64px object-cover rounded-full">
|
||||||
</nuxt-link>
|
</nuxt-link>
|
||||||
</li>
|
</li>
|
||||||
@@ -296,7 +305,8 @@ function findElementPathById(categories: any[], targetId: number, path: any[] =
|
|||||||
<p class="my-10px" v-if="currentArticle.intro" v-html="currentArticle.intro">
|
<p class="my-10px" v-if="currentArticle.intro" v-html="currentArticle.intro">
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div v-html="currentArticle.detail" class="[&_p_>_span]:!font-raleway [&_p]:mb-10px"></div>
|
<!-- <div v-html="currentArticle.detail" class="[&_p_>_span]:!font-raleway [&_p]:mb-10px"></div> -->
|
||||||
|
<component :is="{ template: currentArticle.detail, components: { Poll, Quiz, Survey, Document, Attachment, Tag } }" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content__bottom__right">
|
<div class="content__bottom__right">
|
||||||
|
|||||||
@@ -166,20 +166,23 @@ const CLASS_FOR_SECTION = computed(() => {
|
|||||||
|
|
||||||
case enumPageSectionLayouts[enumPageSectionTemplate[enumPageSectionKey.NONE]["NONE"]]["VERTICAL_LEFT_TWO"]:
|
case enumPageSectionLayouts[enumPageSectionTemplate[enumPageSectionKey.NONE]["NONE"]]["VERTICAL_LEFT_TWO"]:
|
||||||
_classForSection = {
|
_classForSection = {
|
||||||
section_layout: "section_layout three_col_layout",
|
section_layout: "section_layout twelve_col_layout",
|
||||||
0: "col-span-2",
|
0: "md:col-span-8 col-span-12",
|
||||||
|
1: "md:col-span-4 col-span-12",
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case enumPageSectionLayouts[enumPageSectionTemplate[enumPageSectionKey.NONE]["NONE"]]["VERTICAL_RIGHT_TWO"]:
|
case enumPageSectionLayouts[enumPageSectionTemplate[enumPageSectionKey.NONE]["NONE"]]["VERTICAL_RIGHT_TWO"]:
|
||||||
_classForSection = {
|
_classForSection = {
|
||||||
section_layout: "section_layout three_col_layout",
|
section_layout: "section_layout grid-cols-12",
|
||||||
1: "col-span-2",
|
0: "md:col-span-4 col-span-12",
|
||||||
|
1: "md:col-span-8 col-span-12",
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case enumPageSectionLayouts[enumPageSectionTemplate[enumPageSectionKey.NONE]["NONE"]]["VERTICAL_ONE_FIVE"]:
|
case enumPageSectionLayouts[enumPageSectionTemplate[enumPageSectionKey.NONE]["NONE"]]["VERTICAL_ONE_FIVE"]:
|
||||||
_classForSection = {
|
_classForSection = {
|
||||||
section_layout: "section_layout six_col_layout",
|
section_layout: "section_layout grid-cols-12",
|
||||||
1: "col-span-5",
|
0: "lg:col-span-2 lg:block hidden",
|
||||||
|
1: "lg:col-span-10 col-span-12",
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case enumPageSectionLayouts[enumPageSectionTemplate[enumPageSectionKey.NONE]["NONE"]]["VERTICAL_FIVE_THREE_TWO_TWO"]:
|
case enumPageSectionLayouts[enumPageSectionTemplate[enumPageSectionKey.NONE]["NONE"]]["VERTICAL_FIVE_THREE_TWO_TWO"]:
|
||||||
@@ -193,20 +196,20 @@ const CLASS_FOR_SECTION = computed(() => {
|
|||||||
break;
|
break;
|
||||||
case enumPageSectionLayouts[enumPageSectionTemplate[enumPageSectionKey.NONE]["NONE"]]["VERTICAL_FIVE_TWO_TWO_THREE"]:
|
case enumPageSectionLayouts[enumPageSectionTemplate[enumPageSectionKey.NONE]["NONE"]]["VERTICAL_FIVE_TWO_TWO_THREE"]:
|
||||||
_classForSection = {
|
_classForSection = {
|
||||||
section_layout: "section_layout twelve_col_layout",
|
section_layout: "section_layout grid-cols-12",
|
||||||
0: "col-span-5",
|
0: "md:col-span-5 col-span-12",
|
||||||
1: "col-span-2",
|
1: "md:col-span-2 sm:col-span-6 col-span-12",
|
||||||
2: "col-span-2",
|
2: "md:col-span-2 sm:col-span-6 col-span-12",
|
||||||
3: "col-span-3",
|
3: "md:col-span-3 col-span-12",
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case enumPageSectionLayouts[enumPageSectionTemplate[enumPageSectionKey.NONE]["NONE"]]["VERTICAL_TWO_FIVE_THREE_TWO"]:
|
case enumPageSectionLayouts[enumPageSectionTemplate[enumPageSectionKey.NONE]["NONE"]]["VERTICAL_TWO_FIVE_THREE_TWO"]:
|
||||||
_classForSection = {
|
_classForSection = {
|
||||||
section_layout: "section_layout twelve_col_layout",
|
section_layout: "section_layout grid-cols-12",
|
||||||
0: "col-span-2",
|
0: "col-span-2 md:block hidden",
|
||||||
1: "col-span-5",
|
1: "md:col-span-5 sm:col-span-7 col-span-12",
|
||||||
2: "col-span-3",
|
2: "md:col-span-3 sm:col-span-5 col-span-12",
|
||||||
3: "col-span-2",
|
3: "col-span-2 md:block hidden",
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case enumPageSectionLayouts[enumPageSectionTemplate[enumPageSectionKey.NONE]["NONE"]]["VERTICAL_ONE_FOUR"]:
|
case enumPageSectionLayouts[enumPageSectionTemplate[enumPageSectionKey.NONE]["NONE"]]["VERTICAL_ONE_FOUR"]:
|
||||||
@@ -217,7 +220,10 @@ const CLASS_FOR_SECTION = computed(() => {
|
|||||||
break;
|
break;
|
||||||
case enumPageSectionLayouts[enumPageSectionTemplate[enumPageSectionKey.NONE]["NONE"]]["VERTICAL_THREE"]:
|
case enumPageSectionLayouts[enumPageSectionTemplate[enumPageSectionKey.NONE]["NONE"]]["VERTICAL_THREE"]:
|
||||||
_classForSection = {
|
_classForSection = {
|
||||||
section_layout: "section_layout three_col_layout",
|
section_layout: "section_layout grid-cols-12",
|
||||||
|
0: "sm:col-span-4 col-span-12",
|
||||||
|
1: "sm:col-span-4 col-span-12",
|
||||||
|
2: "sm:col-span-4 col-span-12"
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case enumPageSectionLayouts[enumPageSectionTemplate[enumPageSectionKey.NONE]["NONE"]]["VERTICAL_FOUR"]:
|
case enumPageSectionLayouts[enumPageSectionTemplate[enumPageSectionKey.NONE]["NONE"]]["VERTICAL_FOUR"]:
|
||||||
@@ -239,15 +245,19 @@ const CLASS_FOR_SECTION = computed(() => {
|
|||||||
break;
|
break;
|
||||||
case enumPageSectionLayouts[enumPageSectionTemplate[enumPageSectionKey.NONE]["NONE"]]["VERTICAL_CENTER_FOUR"]:
|
case enumPageSectionLayouts[enumPageSectionTemplate[enumPageSectionKey.NONE]["NONE"]]["VERTICAL_CENTER_FOUR"]:
|
||||||
_classForSection = {
|
_classForSection = {
|
||||||
section_layout: "section_layout six_col_layout",
|
section_layout: "section_layout grid-cols-12",
|
||||||
1: "col-span-4",
|
0: "lg:col-span-2 md:col-span-6 col-span-12 lg:order-1 md:order-2 order-2",
|
||||||
|
1: "lg:col-span-8 md:col-span-12 col-span-12 lg:order-2 md:order-1 order-1",
|
||||||
|
2: "lg:col-span-2 md:col-span-6 col-span-12 lg:order-3 md:order-3 order-3",
|
||||||
|
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case enumPageSectionLayouts[enumPageSectionTemplate[enumPageSectionKey.NONE]["NONE"]]["VERTICAL_ONE_TWO_THREE"]:
|
case enumPageSectionLayouts[enumPageSectionTemplate[enumPageSectionKey.NONE]["NONE"]]["VERTICAL_ONE_TWO_THREE"]:
|
||||||
_classForSection = {
|
_classForSection = {
|
||||||
section_layout: "section_layout six_col_layout",
|
section_layout: "section_layout grid-cols-12",
|
||||||
1: "col-span-2",
|
0: "col-span-2 lg:block hidden",
|
||||||
2: "col-span-3",
|
1: "lg:col-span-4 md:col-span-5 col-span-12",
|
||||||
|
2: "lg:col-span-6 md:col-span-7 col-span-12",
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -295,11 +305,10 @@ const mapActivesToItems = (index: number) => {
|
|||||||
:key="index"
|
:key="index"
|
||||||
:class="['border-custom', CLASS_FOR_SECTION[index]]"
|
:class="['border-custom', CLASS_FOR_SECTION[index]]"
|
||||||
:style="mapActivesToItems(index)['div.section_child']"
|
:style="mapActivesToItems(index)['div.section_child']"
|
||||||
@dragover.prevent
|
|
||||||
@drop.stop.prevent="dropPlacementInSection($event, index, position.data)"
|
|
||||||
>
|
>
|
||||||
<RecusiveSection :type="position.type" :id="position.data" :section="props.section" />
|
<RecusiveSection :type="position.type" :id="position.data" :section="props.section" />
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="LAYOUT_PARSE['div.background']?.includes('display:block;')" class="attributeBackground" :style="LAYOUT_PARSE['div.background']"></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -313,6 +322,15 @@ const mapActivesToItems = (index: number) => {
|
|||||||
display: grid;
|
display: grid;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
.attributeBackground {
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 0;
|
||||||
|
display: none;
|
||||||
|
left: -50vw;
|
||||||
|
width: 150vw;
|
||||||
|
}
|
||||||
|
|
||||||
.section_child {
|
.section_child {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
@@ -366,39 +384,39 @@ const mapActivesToItems = (index: number) => {
|
|||||||
&.twelve_col_layout {
|
&.twelve_col_layout {
|
||||||
grid-template-columns: repeat(12, minmax(0, 1fr));
|
grid-template-columns: repeat(12, minmax(0, 1fr));
|
||||||
}
|
}
|
||||||
.col-span-2 {
|
// .col-span-2 {
|
||||||
grid-column: span 2 / span 2;
|
// grid-column: span 2 / span 2;
|
||||||
}
|
// }
|
||||||
.col-span-3 {
|
// .col-span-3 {
|
||||||
grid-column: span 3 / span 3;
|
// grid-column: span 3 / span 3;
|
||||||
}
|
// }
|
||||||
.col-span-4 {
|
// .col-span-4 {
|
||||||
grid-column: span 4 / span 4;
|
// grid-column: span 4 / span 4;
|
||||||
}
|
// }
|
||||||
.col-span-5 {
|
// .col-span-5 {
|
||||||
grid-column: span 5 / span 5;
|
// grid-column: span 5 / span 5;
|
||||||
}
|
// }
|
||||||
.col-span-6 {
|
// .col-span-6 {
|
||||||
grid-column: span 6 / span 6;
|
// grid-column: span 6 / span 6;
|
||||||
}
|
// }
|
||||||
.col-span-7 {
|
// .col-span-7 {
|
||||||
grid-column: span 7 / span 7;
|
// grid-column: span 7 / span 7;
|
||||||
}
|
// }
|
||||||
.col-span-8 {
|
// .col-span-8 {
|
||||||
grid-column: span 8 / span 8;
|
// grid-column: span 8 / span 8;
|
||||||
}
|
// }
|
||||||
.col-span-9 {
|
// .col-span-9 {
|
||||||
grid-column: span 9 / span 9;
|
// grid-column: span 9 / span 9;
|
||||||
}
|
// }
|
||||||
.col-span-10 {
|
// .col-span-10 {
|
||||||
grid-column: span 10 / span 10;
|
// grid-column: span 10 / span 10;
|
||||||
}
|
// }
|
||||||
.col-span-11 {
|
// .col-span-11 {
|
||||||
grid-column: span 11 / span 11;
|
// grid-column: span 11 / span 11;
|
||||||
}
|
// }
|
||||||
.col-span-12 {
|
// .col-span-12 {
|
||||||
grid-column: span 12 / span 12;
|
// grid-column: span 12 / span 12;
|
||||||
}
|
// }
|
||||||
.border-custom {
|
.border-custom {
|
||||||
border-color: #e5e5e5 !important;
|
border-color: #e5e5e5 !important;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,76 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import { getInputValue } from "@/utils/parseSQL";
|
|
||||||
const props = defineProps<{
|
|
||||||
layout?: any,
|
|
||||||
label?:any
|
|
||||||
}>()
|
|
||||||
|
|
||||||
const CLASS_FOR_LAYOUT = computed(() => {
|
|
||||||
let _classForLayout = {};
|
|
||||||
switch (props.layout) {
|
|
||||||
case 'Full_Page':
|
|
||||||
_classForLayout = {
|
|
||||||
page_container: 'page_container full-size-page',
|
|
||||||
layout_container: 'layout_container full-size-layout',
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
case 'Center_Page':
|
|
||||||
_classForLayout = {
|
|
||||||
page_container: 'page_container full-size-page',
|
|
||||||
layout_container: 'layout_container center-layout',
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
case 'Background_Page':
|
|
||||||
_classForLayout = {
|
|
||||||
page_container: 'page_container full-size-page background-container',
|
|
||||||
layout_container: 'layout_container center-layout',
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
_classForLayout = {
|
|
||||||
page_container: 'page_container',
|
|
||||||
layout_container: 'layout_container',
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return _classForLayout;
|
|
||||||
})
|
|
||||||
|
|
||||||
const LAYOUT_PARSE = computed(() => {
|
|
||||||
return props?.label ? getInputValue(props.label, "OBJECT") : {};
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div :class="[CLASS_FOR_LAYOUT.page_container]" :style="LAYOUT_PARSE['div.page_container']">
|
|
||||||
<div :class="[CLASS_FOR_LAYOUT.layout_container]" class="grid-container">
|
|
||||||
<slot />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
.page_container {
|
|
||||||
&.full-size-page {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.full-size-layout {
|
|
||||||
padding-left: 20px;
|
|
||||||
padding-right: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.layout_container {
|
|
||||||
padding-top: 20px;
|
|
||||||
|
|
||||||
&.center-layout {
|
|
||||||
max-width: 1385px;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.grid-container {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(1, minmax(0, 1fr));
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { getInputValue } from "@/utils/parseSQL";
|
||||||
|
import { enumPageLayouts, enumPageTemplate, enumPageKey } from "@/definitions/enum";
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
layout?: any,
|
||||||
|
label?:any
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const CLASS_FOR_LAYOUT = computed(() => {
|
||||||
|
let _classForLayout = {};
|
||||||
|
switch (props.layout) {
|
||||||
|
case enumPageLayouts[enumPageTemplate[enumPageKey.HOME]['DEFAULT']]['DEFAULT']:
|
||||||
|
_classForLayout = {
|
||||||
|
page_container: "page_container full-size-page",
|
||||||
|
layout_container: "layout_container center-layout",
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case enumPageLayouts[enumPageTemplate[enumPageKey.HOME]['DEFAULT']]['FULL']:
|
||||||
|
_classForLayout = {
|
||||||
|
page_container: "page_container full-size-page",
|
||||||
|
layout_container: "layout_container full-size-layout",
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
case enumPageLayouts[enumPageTemplate[enumPageKey.HOME]['DEFAULT']]['BACKGROUND_PAGE']:
|
||||||
|
_classForLayout = {
|
||||||
|
page_container: "page_container full-size-page background-container",
|
||||||
|
layout_container: "layout_container center-layout",
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_classForLayout = {
|
||||||
|
page_container: "page_container",
|
||||||
|
layout_container: "layout_container",
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return _classForLayout;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :class="[CLASS_FOR_LAYOUT.page_container]">
|
||||||
|
<div :class="[CLASS_FOR_LAYOUT.layout_container]" class="grid-container">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.page_container {
|
||||||
|
// padding: 20px 0;
|
||||||
|
&.full-size-page {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
// .full-size-layout {
|
||||||
|
// padding-left: 20px;
|
||||||
|
// padding-right: 20px;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout_container {
|
||||||
|
padding-top: 20px;
|
||||||
|
|
||||||
|
&.center-layout {
|
||||||
|
max-width: 1440px;
|
||||||
|
padding: 0 27.5px;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.grid-container {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(1, minmax(0, 1fr));
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
export { default as BASE_LAYOUT } from './Default.vue'
|
export { default as Home_Default } from './homes/Default.vue'
|
||||||
|
|
||||||
// Article
|
// Article
|
||||||
export { default as ARTICLE_LONG_LAYOUT } from './articles/Long.vue'
|
export { default as ARTICLE_LONG_LAYOUT } from './articles/Long.vue'
|
||||||
|
|||||||
@@ -1,33 +1,24 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { layouts } from "@/definitions/enum";
|
import { enumPageKey, enumPageTemplate, enumPageLayouts } from "@/definitions/enum";
|
||||||
|
import { Home_Default, ARTICLE_LONG_LAYOUT, ARTICLE_NONE_LAYOUT, ARTICLE_NORMAL_LAYOUT, ARTICLE_PAGE_LAYOUT, ARTICLE_SHORT_LAYOUT } from "./index";
|
||||||
import {
|
|
||||||
BASE_LAYOUT,
|
|
||||||
ARTICLE_SHORT_LAYOUT,
|
|
||||||
ARTICLE_PAGE_LAYOUT,
|
|
||||||
ARTICLE_NORMAL_LAYOUT,
|
|
||||||
ARTICLE_NONE_LAYOUT,
|
|
||||||
ARTICLE_LONG_LAYOUT,
|
|
||||||
} from './index';
|
|
||||||
|
|
||||||
const _props = defineProps<{
|
const _props = defineProps<{
|
||||||
settings?: any,
|
settings?: any;
|
||||||
}>()
|
}>();
|
||||||
|
|
||||||
const definedDynamicPageLayout: Record<string, any> = {
|
const definedDynamicPageLayout: Record<string, any> = {
|
||||||
'Default': BASE_LAYOUT,
|
[enumPageLayouts[enumPageTemplate[enumPageKey.HOME]["DEFAULT"]]["DEFAULT"]]: Home_Default,
|
||||||
[layouts.FULL_PAGE]: BASE_LAYOUT,
|
[enumPageLayouts[enumPageTemplate[enumPageKey.HOME]["DEFAULT"]]["FULL"]]: Home_Default,
|
||||||
[layouts.CENTER_PAGE]: BASE_LAYOUT,
|
[enumPageLayouts[enumPageTemplate[enumPageKey.HOME]["DEFAULT"]]["BACKGROUND_PAGE"]]: Home_Default,
|
||||||
[layouts.BACKGROUND_PAGE]: BASE_LAYOUT,
|
|
||||||
|
|
||||||
'ARTICLE_SHORT': ARTICLE_SHORT_LAYOUT,
|
[enumPageLayouts[enumPageTemplate[enumPageKey.ARTICLE]["DETAIL"]]["ARTICLE_SHORT"]]: ARTICLE_SHORT_LAYOUT,
|
||||||
'ARTICLE_PAGE': ARTICLE_PAGE_LAYOUT,
|
[enumPageLayouts[enumPageTemplate[enumPageKey.ARTICLE]["DETAIL"]]["ARTICLE_PAGE"]]: ARTICLE_PAGE_LAYOUT,
|
||||||
'ARTICLE_NORMAL': ARTICLE_NORMAL_LAYOUT,
|
[enumPageLayouts[enumPageTemplate[enumPageKey.ARTICLE]["DETAIL"]]["ARTICLE_NORMAL"]]: ARTICLE_NORMAL_LAYOUT,
|
||||||
'ARTICLE_NONE': ARTICLE_NONE_LAYOUT,
|
[enumPageLayouts[enumPageTemplate[enumPageKey.ARTICLE]["DETAIL"]]["ARTICLE_NONE"]]: ARTICLE_NONE_LAYOUT,
|
||||||
'ARTICLE_LONG': ARTICLE_LONG_LAYOUT,
|
[enumPageLayouts[enumPageTemplate[enumPageKey.ARTICLE]["DETAIL"]]["ARTICLE_LONG"]]: ARTICLE_LONG_LAYOUT,
|
||||||
}
|
};
|
||||||
|
|
||||||
const getCurrentLayout = computed(() => _props.settings.layout);
|
const getCurrentLayout = computed(() => _props.settings?.layout);
|
||||||
|
|
||||||
const GET_PROPS = computed(() => {
|
const GET_PROPS = computed(() => {
|
||||||
return () => {
|
return () => {
|
||||||
@@ -35,12 +26,12 @@ const GET_PROPS = computed(() => {
|
|||||||
for (const [key, value] of Object.entries(_props.settings)) {
|
for (const [key, value] of Object.entries(_props.settings)) {
|
||||||
props = {
|
props = {
|
||||||
...props,
|
...props,
|
||||||
[key]: value
|
[key]: value,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
return props;
|
return props;
|
||||||
};
|
};
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ const props = defineProps<{
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="h-100 overflow-y-auto">
|
<div class="h-full overflow-y-auto">
|
||||||
<HeaderHomeTemplate />
|
<HeaderHomeTemplate />
|
||||||
<DynamicLayout :settings="props.settings">
|
<DynamicLayout :settings="props.settings">
|
||||||
<slot />
|
<slot />
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export { default as DetailDefault } from './DetailDefault.vue';
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { DetailDefault } from './index';
|
||||||
|
import { enumPageKey, enumPageTemplate } from "@/definitions/enum";
|
||||||
|
|
||||||
|
const _props = defineProps<{
|
||||||
|
settings: any
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const definedDynamicPage: Record<string, any> = {
|
||||||
|
[enumPageTemplate[enumPageKey.ARTICLE]['DETAIL']]: DetailDefault,
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCurrentTemplate = computed(() => {
|
||||||
|
return _props.settings?.template || '';
|
||||||
|
});
|
||||||
|
|
||||||
|
const GET_PROPS = computed(() => {
|
||||||
|
return () => {
|
||||||
|
let props : any = {};
|
||||||
|
if (_props.settings) {
|
||||||
|
for (const [key, value] of Object.entries(_props.settings)) {
|
||||||
|
props = {
|
||||||
|
...props,
|
||||||
|
[key]: value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return props;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<component v-if="definedDynamicPage[getCurrentTemplate]" :is="definedDynamicPage[getCurrentTemplate]" v-bind="{...(GET_PROPS()), settings: _props.settings}">
|
||||||
|
<slot />
|
||||||
|
</component>
|
||||||
|
</template>
|
||||||
@@ -6,55 +6,56 @@ import { enumPageComponentLayouts, enumPageComponentTemplate, enumPageComponentK
|
|||||||
<template>
|
<template>
|
||||||
<footer id="footer" class="main-footer mt-20">
|
<footer id="footer" class="main-footer mt-20">
|
||||||
<div class="main-footer-container">
|
<div class="main-footer-container">
|
||||||
<div class="footer-centertab">
|
<div class="footer-centertab grid lg:grid-cols-6">
|
||||||
<div>
|
<div class="col-span-1 lg:block hidden"></div>
|
||||||
<div class="footer-navigation-container">
|
<div class="col-span-5">
|
||||||
|
<div class="footer-navigation-container md:block hidden">
|
||||||
<div>
|
<div>
|
||||||
<AssignComponent :type="enumPageComponentLayouts[`${enumPageComponentTemplate[enumPageComponentKey.NAVIGATION]['BOTTOM']}`]['NAVIGATION_BOTTOM_DEFAULT']" />
|
<AssignComponent :type="enumPageComponentLayouts[`${enumPageComponentTemplate[enumPageComponentKey.NAVIGATION]['BOTTOM']}`]['NAVIGATION_BOTTOM_DEFAULT']" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="footer-contact-container">
|
<div class="footer-contact-container md:grid-cols-2 grid-cols-1">
|
||||||
<div>
|
<div class="md:order-1 order-2">
|
||||||
<h3>BÁO GIẤY</h3>
|
<h3 class="md:text-left text-center">BÁO GIẤY</h3>
|
||||||
|
|
||||||
<div class="footer-contact">
|
<div class="footer-contact">
|
||||||
<div>
|
<div class="md:justify-start justify-center">
|
||||||
<div>
|
<div>
|
||||||
<span><Icon name="material-symbols:call-outline" /></span>
|
<span><Icon name="material-symbols:call-outline" /></span>
|
||||||
<span>024.39434341</span>
|
<span>0123456789</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span><Icon name="material-symbols:mail-outline" /></span>
|
<span><Icon name="material-symbols:mail-outline" /></span>
|
||||||
<span>toasoan@baotienphong.vn</span>
|
<span>toasoan@vpress.vn</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="footer-contact-buynow">
|
<div class="footer-contact-buynow md:justify-start justify-center">
|
||||||
<img src="~/assets/images/tienphong/muabaogiay-footer.png" alt="" />
|
<img src="~/assets/images/tienphong/muabaogiay-footer.png" alt="" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="md:order-2 order-1">
|
||||||
<h3>THEO DÕI TRÊN MẠNG XÃ HỘI</h3>
|
<h3 class="md:text-left text-center md:!border-#3d3d3d !border-transparent">THEO DÕI TRÊN MẠNG XÃ HỘI</h3>
|
||||||
|
|
||||||
<div class="footer-socials">
|
<div class="footer-socials">
|
||||||
<div>
|
<div class="md:grid lg:grid-cols-2 md:grid-cols-1 flex md:gap-50px gap-32px md:justify-start justify-center">
|
||||||
<div>
|
<div class="xl:gap-22px gap-6px">
|
||||||
<span><Icon name="ic:baseline-facebook" /></span>
|
<span><Icon name="ic:baseline-facebook" /></span>
|
||||||
<span>facebook.com/baotienphong</span>
|
<span class="md:inline hidden whitespace-normal">facebook.com/vpress</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="xl:gap-22px gap-6px">
|
||||||
<span><Icon name="uil:youtube" /></span>
|
<span><Icon name="uil:youtube" /></span>
|
||||||
<span>youtube.com/baotienphong</span>
|
<span class="md:inline hidden whitespace-normal">youtube.com/vpress</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="xl:gap-22px gap-6px">
|
||||||
<span><Icon name="ic:baseline-tiktok" /></span>
|
<span><Icon name="ic:baseline-tiktok" /></span>
|
||||||
<span>tiktok.com/baotienphong</span>
|
<span class="md:inline hidden whitespace-normal">tiktok.com/vpress</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="xl:gap-22px gap-6px">
|
||||||
<span><Icon name="arcticons:zalo" /></span>
|
<span><Icon name="arcticons:zalo" /></span>
|
||||||
<span>zalo.vn/baotienphong</span>
|
<span class="md:inline hidden whitespace-normal">zalo.vn/vpress</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -62,19 +63,19 @@ import { enumPageComponentLayouts, enumPageComponentTemplate, enumPageComponentK
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="footer-ads">
|
<div class="footer-ads">
|
||||||
<h3>LIÊN HỆ QUẢNG CÁO</h3>
|
<h3 class="md:text-left text-center">LIÊN HỆ QUẢNG CÁO</h3>
|
||||||
|
|
||||||
<div class="footer-ads-container">
|
<div class="footer-ads-container flex-wrap lg:gap-60px gap-20px md:flex-row flex-col">
|
||||||
<div class="align-items-center">
|
<div class="align-items-center">
|
||||||
<span><Icon name="material-symbols:call-outline" /></span>
|
<span><Icon name="material-symbols:call-outline" /></span>
|
||||||
<span class="flex flex-column">
|
<span class="flex flex-column">
|
||||||
<span>024.39434340</span>
|
<span>0123456789 - </span>
|
||||||
<span>0909559988</span>
|
<span>0123456789</span>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span><Icon name="material-symbols:mail-outline" /></span>
|
<span><Icon name="material-symbols:mail-outline" /></span>
|
||||||
<span>kinhdoanh@baotienphong.vn</span>
|
<span>kinhdoanh@vpress.vn</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-ads-price">
|
<div class="button-ads-price">
|
||||||
<span><Icon name="ic:outline-format-list-bulleted" /></span>
|
<span><Icon name="ic:outline-format-list-bulleted" /></span>
|
||||||
@@ -86,33 +87,34 @@ import { enumPageComponentLayouts, enumPageComponentTemplate, enumPageComponentK
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer-bottomtab">
|
<div class="footer-bottomtab">
|
||||||
<div>
|
<div class="lg:grid-cols-6 grid">
|
||||||
<div>
|
<div class="lg:block hidden"></div>
|
||||||
|
<div class="col-span-5">
|
||||||
<div class="flex justify-between items-end">
|
<div class="flex justify-between items-end">
|
||||||
<div class="w-1/2">
|
<div class="flex-1 flex md:justify-start justify-center">
|
||||||
<div>
|
<div>
|
||||||
<img class="w-200px" src="~/assets/images/tienphong/logo.png" alt="" />
|
<img class="w-200px" src="~/assets/images/tienphong/logo.png" alt="" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="footer-bottomtab-relations w-1/2">
|
<div class="footer-bottomtab-relations">
|
||||||
<img src="~/assets/images/tienphong/sinhvien-logo.png" alt="" />
|
<!-- <img src="~/assets/images/tienphong/sinhvien-logo.png" alt="" />
|
||||||
<img src="~/assets/images/tienphong/hht-online-logo.png" alt="" />
|
<img src="~/assets/images/tienphong/hht-online-logo.png" alt="" />
|
||||||
<img src="~/assets/images/tienphong/tamviet-logo.png" alt="" />
|
<img src="~/assets/images/tienphong/tamviet-logo.png" alt="" /> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-between items-end footer-bottomtab-description">
|
<div class="flex justify-between md:flex-row flex-col gap-20px footer-bottomtab-description md:text-left text-center">
|
||||||
<div class="w-1/2 space-y-10px">
|
<div class="flex-1 space-y-10px">
|
||||||
<p>© Bản quyền thuộc báo điện tử <span class="fw-bold">Tiền Phong</span></p>
|
<p>© Bản quyền thuộc báo điện tử <span class="fw-bold">....</span></p>
|
||||||
<p><span class="fw-bold">Tổng Biên tập</span>: LÊ XUÂN SƠN</p>
|
<p><span class="fw-bold">Tổng Biên tập</span>: ...</p>
|
||||||
<p>Tòa soạn: 15 Hồ Xuân Hương, Hà Nội - Điện thoại: 024.39431250</p>
|
<p>Tòa soạn: Hà Nội - Điện thoại: 0123456789</p>
|
||||||
<p>Email: <span class="fw-bold">online.baotienphong@gmail.com</span> - Hotline: <span class="fw-bold">0865.015.015 - 0977.456.112</span></p>
|
<p>Email: <span class="fw-bold">online.vpress@gmail.com</span> - Hotline: <span class="fw-bold">0123456789</span></p>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-1/2 space-y-10px">
|
<div class="flex-1 space-y-10px">
|
||||||
<p>Giấy phép số <span class="fw-bold">76/GP-BTTTT</span>, cấp ngày 26/02/2020.</p>
|
<p>Giấy phép số <span class="fw-bold">...</span>, cấp ngày ....</p>
|
||||||
<p>Cơ quan chủ quản: <span class="fw-bold">Trung ương Đoàn TNCS Hồ Chí Minh</span></p>
|
<p>Cơ quan chủ quản: <span class="fw-bold">....</span></p>
|
||||||
<p>Cấm sao chép dưới mọi hình thức nếu không có sự chấp thuận bằng văn bản</p>
|
<p>Cấm sao chép dưới mọi hình thức nếu không có sự chấp thuận bằng văn bản</p>
|
||||||
<p>Powered by Hemera Media</p>
|
<p>Powered by GCT</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -125,16 +127,17 @@ import { enumPageComponentLayouts, enumPageComponentTemplate, enumPageComponentK
|
|||||||
.main-footer {
|
.main-footer {
|
||||||
.main-footer-container {
|
.main-footer-container {
|
||||||
background: #2b2b2b;
|
background: #2b2b2b;
|
||||||
padding: 54px 15px 20px 15px;
|
padding: 54px 0 32px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-centertab {
|
.footer-centertab {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
max-width: 1385px;
|
max-width: 1440px;
|
||||||
|
padding: 0 27.5px;
|
||||||
> div {
|
> div {
|
||||||
max-width: 1145px;
|
// max-width: 1145px;
|
||||||
margin-left: auto;
|
// margin-left: auto;
|
||||||
padding: 0 33px;
|
// padding: 0 33px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.footer-navigation-container {
|
.footer-navigation-container {
|
||||||
@@ -147,7 +150,7 @@ import { enumPageComponentLayouts, enumPageComponentTemplate, enumPageComponentK
|
|||||||
|
|
||||||
.footer-contact-container {
|
.footer-contact-container {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
// grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
margin-top: 22px;
|
margin-top: 22px;
|
||||||
gap: 60px;
|
gap: 60px;
|
||||||
border-bottom: 1px solid #ed1c24;
|
border-bottom: 1px solid #ed1c24;
|
||||||
@@ -189,13 +192,13 @@ import { enumPageComponentLayouts, enumPageComponentTemplate, enumPageComponentK
|
|||||||
.footer-socials {
|
.footer-socials {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
> div {
|
> div {
|
||||||
display: grid;
|
// display: grid;
|
||||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
// grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||||
gap: 55px;
|
// gap: 55px;
|
||||||
> div {
|
> div {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
gap: 22px;
|
// gap: 22px;
|
||||||
}
|
}
|
||||||
span {
|
span {
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
@@ -213,7 +216,7 @@ import { enumPageComponentLayouts, enumPageComponentTemplate, enumPageComponentK
|
|||||||
> div {
|
> div {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 60px;
|
// gap: 60px;
|
||||||
> div {
|
> div {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-end;
|
align-items: flex-end;
|
||||||
@@ -262,18 +265,19 @@ import { enumPageComponentLayouts, enumPageComponentTemplate, enumPageComponentK
|
|||||||
|
|
||||||
.footer-bottomtab {
|
.footer-bottomtab {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 5px 15px;
|
// padding: 5px 15px;
|
||||||
> div {
|
> div {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
max-width: 1385px;
|
max-width: 1440px;
|
||||||
|
padding: 0 27.5px;
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
max-width: 1145px;
|
// max-width: 1145px;
|
||||||
margin-left: auto;
|
// margin-left: auto;
|
||||||
padding: 0 33px;
|
// padding: 0 33px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
padding: 0 33px;
|
// padding: 0 33px;
|
||||||
padding-bottom: 80px;
|
padding-bottom: 80px;
|
||||||
padding-top: 24px;
|
padding-top: 24px;
|
||||||
.footer-bottomtab-relations {
|
.footer-bottomtab-relations {
|
||||||
|
|||||||
@@ -8,23 +8,23 @@ const currentDateTime = ref<string>("");
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
currentDateTime.value = dayjs().format("dddd, DD/MM/YYYY, HH:mm");
|
currentDateTime.value = dayjs().format("dddd, DD/MM/YYYY, HH:mm");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const showMenuMobile = ref(false)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<header id="header" class="main-header">
|
<header id="header" class="main-header">
|
||||||
<div class="main-header-topbar ">
|
<div class="main-header-topbar lg:block hidden">
|
||||||
<div class="flex items-center !py-3px">
|
<div class="flex items-center !py-3px">
|
||||||
<time class="text-capitalize text-white text-12px" :datetime="currentDateTime">{{ currentDateTime }} GMT+7</time>
|
<time class="text-capitalize text-white text-12px" :datetime="currentDateTime">{{ currentDateTime }} GMT+7</time>
|
||||||
<div class="main-header-topbar-listag">
|
<div class="main-header-topbar-listag"></div>
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="main-header-topbar-infor flex items-center">
|
<div class="main-header-topbar-infor flex items-center">
|
||||||
<div>
|
<div>
|
||||||
<div class="text-white text-12px">
|
<div class="text-white text-12px">
|
||||||
<span>HOTLINE: </span>
|
<span>HOTLINE: </span>
|
||||||
<a href="tel:0865015015"> 0865.015.015</a>
|
<a href="tel:0865015015"> 0123456789</a>
|
||||||
<span> - </span>
|
<span> - </span>
|
||||||
<a href="tel:0977456112">0977.456.112</a>
|
<a href="tel:0977456112">0123456789</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
@@ -34,16 +34,16 @@ onMounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="main-header-centerbar">
|
<div class="main-header-centerbar lg:block hidden">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="main-header-logo">
|
<div class="main-header-logo">
|
||||||
<nuxt-link to="/"><img class="w-200px" src="~/assets/images/tienphong/logo.png" alt="logo"></nuxt-link>
|
<nuxt-link to="/"><img class="w-200px" src="~/assets/images/tienphong/logo.png" alt="logo" /></nuxt-link>
|
||||||
</div>
|
</div>
|
||||||
<div class="main-header-control">
|
<div class="main-header-control">
|
||||||
<div class="main-header-relations">
|
<div class="main-header-relations">
|
||||||
<img src="~/assets/images/tienphong/sinhvien-logo.png" alt="">
|
<!-- <img src="~/assets/images/tienphong/sinhvien-logo.png" alt="">
|
||||||
<img src="~/assets/images/tienphong/hht-online-logo.png" alt="">
|
<img src="~/assets/images/tienphong/hht-online-logo.png" alt="">
|
||||||
<img src="~/assets/images/tienphong/tamviet-logo.png" alt="">
|
<img src="~/assets/images/tienphong/tamviet-logo.png" alt=""> -->
|
||||||
</div>
|
</div>
|
||||||
<div class="main-header-navbar">
|
<div class="main-header-navbar">
|
||||||
<AssignComponent :type="enumPageComponentLayouts[`${enumPageComponentTemplate[enumPageComponentKey.NAVIGATION]['TOP']}`]['NAVIGATION_TOP_DEFAULT']" />
|
<AssignComponent :type="enumPageComponentLayouts[`${enumPageComponentTemplate[enumPageComponentKey.NAVIGATION]['TOP']}`]['NAVIGATION_TOP_DEFAULT']" />
|
||||||
@@ -51,16 +51,16 @@ onMounted(() => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="main-ads">
|
<div class="main-ads lg:block hidden">
|
||||||
<div class="main-ads-container">
|
<div class="main-ads-container py-20px border-y-1px border-#000">
|
||||||
<div class="main-ads-content">
|
<div class="main-ads-content">
|
||||||
<img src="~/assets/images/tienphong/main-ads.png" alt="">
|
<img src="~/assets/images/tienphong/main-ads.png" alt="" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="main-header-control">
|
<div class="main-header-control lg:block hidden">
|
||||||
<div class="header-control-container !py-2">
|
<div class="header-control-container">
|
||||||
<div>
|
<div class="border-b-1px border-#000 py-2">
|
||||||
<div class="header-control_tag">
|
<div class="header-control_tag">
|
||||||
<label>Xu hướng</label>
|
<label>Xu hướng</label>
|
||||||
</div>
|
</div>
|
||||||
@@ -72,22 +72,67 @@ onMounted(() => {
|
|||||||
<Icon name="material-symbols-light:search" />
|
<Icon name="material-symbols-light:search" />
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<img src="http://picsum.photos/1024/600?random=1" width="40" height="40" class="rounded-circle" alt="">
|
<img src="http://picsum.photos/1024/600?random=1" width="40" height="40" class="rounded-circle" alt="" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="main-header-mobile px-3 lg:hidden block">
|
||||||
|
<div class="flex items-center justify-between py-4 border-b-1px border-solid border-#000">
|
||||||
|
<div class="main-header-mobile-logo">
|
||||||
|
<nuxt-link to="/"><img class="w-128px" src="~/assets/images/tienphong/logo.png" alt="logo" /></nuxt-link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="main-header-mobile-control flex gap-20px">
|
||||||
|
<button class="bg-transparent" @click="showMenuMobile = true">
|
||||||
|
<svg width="21" height="17" viewBox="0 0 21 17" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M0 0.75C0 0.375 0.328125 0 0.75 0H20.25C20.625 0 21 0.375 21 0.75C21 1.17188 20.625 1.5 20.25 1.5H0.75C0.328125 1.5 0 1.17188 0 0.75ZM0 8.25C0 7.875 0.328125 7.5 0.75 7.5H20.25C20.625 7.5 21 7.875 21 8.25C21 8.67188 20.625 9 20.25 9H0.75C0.328125 9 0 8.67188 0 8.25ZM20.25 16.5H0.75C0.328125 16.5 0 16.1719 0 15.75C0 15.375 0.328125 15 0.75 15H20.25C20.625 15 21 15.375 21 15.75C21 16.1719 20.625 16.5 20.25 16.5Z"
|
||||||
|
fill="black"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<button class="bg-transparent">
|
||||||
|
<svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M23.7656 22.7344L17.1094 16.125C18.6094 14.3906 19.4531 12.1875 19.4531 9.75C19.4531 4.40625 15.0469 0 9.70312 0C4.3125 0 0 4.40625 0 9.75C0 15.1406 4.35938 19.5 9.70312 19.5C12.0938 19.5 14.2969 18.6562 16.0312 17.1562L22.6406 23.8125C22.8281 23.9531 23.0156 24 23.25 24C23.4375 24 23.625 23.9531 23.7656 23.8125C24.0469 23.5312 24.0469 23.0156 23.7656 22.7344ZM9.75 18C5.15625 18 1.5 14.2969 1.5 9.75C1.5 5.20312 5.15625 1.5 9.75 1.5C14.2969 1.5 18 5.20312 18 9.75C18 14.3438 14.2969 18 9.75 18Z" fill="black"/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- navigation header -->
|
||||||
|
<div class="main-header-mobile-navigation fixed inset-0 bg-white z-999" v-if="showMenuMobile">
|
||||||
|
<div class="main-header-mobile px-3">
|
||||||
|
<div class="flex items-center justify-between py-4">
|
||||||
|
<div class="main-header-mobile-logo" @click="showMenuMobile = false">
|
||||||
|
<nuxt-link to="/"><img class="w-128px" src="~/assets/images/tienphong/logo.png" alt="logo" /></nuxt-link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="main-header-mobile-control flex gap-20px">
|
||||||
|
<button class="bg-transparent" @click="showMenuMobile = false">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24"><path fill="currentColor" d="m12 13.4l-4.9 4.9q-.275.275-.7.275t-.7-.275t-.275-.7t.275-.7l4.9-4.9l-4.9-4.9q-.275-.275-.275-.7t.275-.7t.7-.275t.7.275l4.9 4.9l4.9-4.9q.275-.275.7-.275t.7.275t.275.7t-.275.7L13.4 12l4.9 4.9q.275.275.275.7t-.275.7t-.7.275t-.7-.275z"/></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="p-3">
|
||||||
|
<AssignComponent :type="enumPageComponentLayouts[`${enumPageComponentTemplate[enumPageComponentKey.NAVIGATION]['TOP']}`]['NAVIGATION_TOP_DEFAULT']" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss">
|
||||||
.main-header {
|
.main-header {
|
||||||
.main-header-topbar {
|
.main-header-topbar {
|
||||||
background: #ED1C24;
|
background: #ed1c24;
|
||||||
> div {
|
> div {
|
||||||
max-width: 1385px;
|
max-width: 1385px;
|
||||||
padding: 5px 15px;
|
padding: 5px 20px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
@@ -110,9 +155,9 @@ onMounted(() => {
|
|||||||
.main-header-centerbar {
|
.main-header-centerbar {
|
||||||
padding: 20px 0px;
|
padding: 20px 0px;
|
||||||
> div {
|
> div {
|
||||||
max-width: 1385px;
|
max-width: 1440px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0px 15px;
|
padding: 0px 27.5px;
|
||||||
}
|
}
|
||||||
.main-header-control {
|
.main-header-control {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@@ -128,15 +173,17 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.main-ads {
|
.main-ads {
|
||||||
max-width: 1385px;
|
max-width: 1440px;
|
||||||
margin: 0px auto;
|
margin: 0px auto;
|
||||||
padding: 20px 0px;
|
padding: 0px 27.5px;
|
||||||
border-top: 1px solid #000000;
|
// border-top: 1px solid #000000;
|
||||||
border-bottom: 1px solid #000000;
|
// border-bottom: 1px solid #000000;
|
||||||
|
|
||||||
.main-ads-content {
|
.main-ads-content {
|
||||||
width: 970px;
|
width: 100%;
|
||||||
height: 250px;
|
max-width: 970px;
|
||||||
|
|
||||||
|
// height: 250px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -147,10 +194,10 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
.main-header-control {
|
.main-header-control {
|
||||||
.header-control-container {
|
.header-control-container {
|
||||||
max-width: 1385px;
|
max-width: 1440px;
|
||||||
margin: 0px auto 10px auto;
|
margin: 0px auto 10px auto;
|
||||||
padding: 10px 0px;
|
padding: 0 27.5px;
|
||||||
border-bottom: 1px solid #000000;
|
// border-bottom: 1px solid #000000;
|
||||||
> div {
|
> div {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -211,5 +258,45 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.main-header-mobile-navigation {
|
||||||
|
& > div > nav > div {
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
& .navigation-container {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0px;
|
||||||
|
width: 100%;
|
||||||
|
align-items: start;
|
||||||
|
|
||||||
|
& > .navigation-branch {
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
border-top: 1px solid #dee2e6;
|
||||||
|
&:first-child {
|
||||||
|
border: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .navigation-item {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
& > a {
|
||||||
|
font-family: "Gelasio", serif !important;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-weight: 800!important;
|
||||||
|
display: block;
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 8px 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
+6
-9
@@ -2,22 +2,19 @@
|
|||||||
import DynamicLayout from "~/components/dynamic-page/page/layouts/index.vue";
|
import DynamicLayout from "~/components/dynamic-page/page/layouts/index.vue";
|
||||||
import HeaderHomeTemplate from "~/components/dynamic-page/page/templates/components/headers/HeaderHomeTemplate.vue";
|
import HeaderHomeTemplate from "~/components/dynamic-page/page/templates/components/headers/HeaderHomeTemplate.vue";
|
||||||
import FooterHomeTemplate from "~/components/dynamic-page/page/templates/components/footers/FooterHomeTemplate.vue";
|
import FooterHomeTemplate from "~/components/dynamic-page/page/templates/components/footers/FooterHomeTemplate.vue";
|
||||||
const props = defineProps<{
|
|
||||||
settings?: any;
|
|
||||||
}>();
|
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
settings?: any
|
||||||
|
}>()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="h-full overflow-y-auto">
|
||||||
<HeaderHomeTemplate>
|
<HeaderHomeTemplate />
|
||||||
<DynamicLayout :settings="props.settings">
|
|
||||||
<slot />
|
|
||||||
</DynamicLayout>
|
|
||||||
</HeaderHomeTemplate>
|
|
||||||
<DynamicLayout :settings="props.settings">
|
<DynamicLayout :settings="props.settings">
|
||||||
<slot />
|
<slot />
|
||||||
</DynamicLayout>
|
</DynamicLayout>
|
||||||
<FooterHomeTemplate />
|
<FooterHomeTemplate />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
export { default as Home } from './Home.vue';
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { Home } from './index';
|
||||||
|
import { enumPageKey, enumPageTemplate } from "@/definitions/enum";
|
||||||
|
|
||||||
|
const _props = defineProps<{
|
||||||
|
settings: any
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const definedDynamicPage: Record<string, any> = {
|
||||||
|
[enumPageTemplate[enumPageKey.HOME]['DEFAULT']]: Home,
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCurrentTemplate = computed(() => {
|
||||||
|
return _props.settings?.template || '';
|
||||||
|
});
|
||||||
|
|
||||||
|
const GET_PROPS = computed(() => {
|
||||||
|
return () => {
|
||||||
|
let props : any = {};
|
||||||
|
if (_props.settings) {
|
||||||
|
for (const [key, value] of Object.entries(_props.settings)) {
|
||||||
|
props = {
|
||||||
|
...props,
|
||||||
|
[key]: value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return props;
|
||||||
|
};
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<component v-if="definedDynamicPage[getCurrentTemplate]" :is="definedDynamicPage[getCurrentTemplate]" v-bind="{...(GET_PROPS()), settings: _props.settings}">
|
||||||
|
<slot />
|
||||||
|
</component>
|
||||||
|
</template>
|
||||||
@@ -1 +1,2 @@
|
|||||||
export { default as HomeBasic } from './homes/Basic.vue'
|
export { default as Home } from './homes/index.vue'
|
||||||
|
export { default as Article } from './articles/index.vue'
|
||||||
@@ -1,38 +1,41 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { HomeBasic } from './index';
|
import { Home, Article } from "./index";
|
||||||
|
import type { Page } from "@/models/cms";
|
||||||
|
import { enumPageKey } from "@/definitions/enum";
|
||||||
|
|
||||||
const _props = defineProps<{
|
const _props = defineProps<{
|
||||||
settings: any
|
settings: any;
|
||||||
}>()
|
page: Page;
|
||||||
|
}>();
|
||||||
|
|
||||||
const definedDynamicPage: Record<string, any> = {
|
const definedDynamicPage: Record<string, any> = {
|
||||||
'Home' : HomeBasic,
|
[enumPageKey.HOME]: Home,
|
||||||
'Article': HomeBasic
|
[enumPageKey.ARTICLE]: Article,
|
||||||
}
|
};
|
||||||
|
|
||||||
const getCurrentTemplate = computed(() => {
|
const getCurrentTemplate = computed(() => {
|
||||||
return _props.settings && _props.settings.template || '';
|
return _props.page?.taxonomy || "";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
const GET_PROPS = computed(() => {
|
const GET_PROPS = computed(() => {
|
||||||
return () => {
|
return () => {
|
||||||
let props: any = {};
|
let props: any = {};
|
||||||
if (_props.settings) {
|
if (_props.settings) {
|
||||||
for (const [key, value] of _props.settings ? Object.entries(_props.settings) : []) {
|
for (const [key, value] of Object.entries(_props.settings)) {
|
||||||
props = {
|
props = {
|
||||||
...props,
|
...props,
|
||||||
[key]: value
|
[key]: value,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return props;
|
return props;
|
||||||
};
|
};
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<component
|
<component
|
||||||
|
class="overflow-x-hidden"
|
||||||
v-if="definedDynamicPage[getCurrentTemplate]"
|
v-if="definedDynamicPage[getCurrentTemplate]"
|
||||||
:is="definedDynamicPage[getCurrentTemplate]"
|
:is="definedDynamicPage[getCurrentTemplate]"
|
||||||
v-bind="{...(GET_PROPS()), settings: _props.settings}"
|
v-bind="{...(GET_PROPS()), settings: _props.settings}"
|
||||||
|
|||||||
@@ -35,11 +35,13 @@ export {
|
|||||||
pageTypes,
|
pageTypes,
|
||||||
pageComponentTypes,
|
pageComponentTypes,
|
||||||
pageSectionTypes,
|
pageSectionTypes,
|
||||||
pageTaxonomy,
|
|
||||||
pageDataQuery,
|
pageDataQuery,
|
||||||
pageDataType,
|
pageDataType,
|
||||||
pageLayouts,
|
|
||||||
|
/* PAGE SETTINGS */
|
||||||
|
pageTaxonomy,
|
||||||
pageTemplates,
|
pageTemplates,
|
||||||
|
pageLayouts,
|
||||||
|
|
||||||
/* SECTION SETTINGS */
|
/* SECTION SETTINGS */
|
||||||
pageSectionTaxonomy,
|
pageSectionTaxonomy,
|
||||||
@@ -50,6 +52,7 @@ export {
|
|||||||
pageComponentTaxonomy,
|
pageComponentTaxonomy,
|
||||||
pageComponentTemplates,
|
pageComponentTemplates,
|
||||||
pageComponentLayouts,
|
pageComponentLayouts,
|
||||||
|
|
||||||
} from "./page.type";
|
} from "./page.type";
|
||||||
export { placementType } from "./placement.type";
|
export { placementType } from "./placement.type";
|
||||||
export { pollType, pollParticipantType, pollOptionType, pollResultPublication } from "./poll.type";
|
export { pollType, pollParticipantType, pollOptionType, pollResultPublication } from "./poll.type";
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { enumPageComponentLayouts, enumPageSectionLayouts, templates, enumPageComponentKey, enumPageComponentTemplate, enumPageSectionKey, enumPageSectionTemplate } from "@/definitions/enum";
|
import { enumPageKey, enumPageTemplate, enumPageLayouts, enumPageComponentLayouts, enumPageSectionLayouts, enumPageComponentKey, enumPageComponentTemplate, enumPageSectionKey, enumPageSectionTemplate } from "@/definitions/enum";
|
||||||
|
|
||||||
export const pageTypes = [
|
export const pageTypes = [
|
||||||
{ title: "None", value: 0 }, // Không xác định
|
{ title: "None", value: 0 }, // Không xác định
|
||||||
@@ -24,49 +24,6 @@ export const pageTypes = [
|
|||||||
];
|
];
|
||||||
// LayoutType: None=0 | Normal=1 | Short=2 | Long=3 | Page=4
|
// LayoutType: None=0 | Normal=1 | Short=2 | Long=3 | Page=4
|
||||||
|
|
||||||
export const pageLayouts = (key: string) => {
|
|
||||||
if (key === templates.ARTICLE) {
|
|
||||||
return [
|
|
||||||
{ title: "None", key: 0, value: "ARTICLE_NONE" },
|
|
||||||
{ title: "Normal", key: 1, value: "ARTICLE_NORMAL" },
|
|
||||||
{ title: "Short", key: 2, value: "ARTICLE_SHORT" },
|
|
||||||
{ title: "Long", key: 3, value: "ARTICLE_LONG" },
|
|
||||||
{ title: "Page", key: 4, value: "ARTICLE_PAGE" },
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
return [
|
|
||||||
{ title: "None", value: 0 },
|
|
||||||
{ title: "Cơ bản", value: "Default" },
|
|
||||||
{ title: "Full Page", value: "Full_Page" }, // full with 100%
|
|
||||||
{ title: "Center Page", value: "Center_Page" }, // ở giữa
|
|
||||||
{ title: "Backgroud Page", value: "Backgroud_Page" }, // Phân trang
|
|
||||||
];
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const pageTemplates = [
|
|
||||||
{ title: "None", value: "None" }, // Không xác định
|
|
||||||
{ title: "Home", value: "Home" }, // Trang chủ
|
|
||||||
{ title: "Section", value: "Section" }, // Chuyên trang
|
|
||||||
{ title: "Category", value: "Category" }, // Trang danh mục
|
|
||||||
{ title: "Topic", value: "Topic" }, // Trang chủ đề
|
|
||||||
{ title: "Event", value: "Event" }, // Trang sự kiện
|
|
||||||
{ title: "Collection", value: "Collection" }, // Trang sưu tập
|
|
||||||
{ title: "Article", value: "Article" }, // Trang bài viết
|
|
||||||
{ title: "Tag", value: "Tag" }, // Trang từ khóa
|
|
||||||
{ title: "Author", value: "Author" }, // Trang tác giả
|
|
||||||
{ title: "Search", value: "Search" }, // Trang tìm kiếm
|
|
||||||
{ title: "Contact", value: "Contact" }, // Trang liên hệ
|
|
||||||
{ title: "About", value: "About" }, // Trang giới thiệu
|
|
||||||
{ title: "Service", value: "Service" }, // Trang dịch vụ
|
|
||||||
{ title: "Policy", value: "Policy" }, // Trang chính sách
|
|
||||||
{ title: "Terms", value: "Terms" }, // Trang điều khoản
|
|
||||||
{ title: "Privacy", value: "Privacy" }, // Trang bảo mật
|
|
||||||
{ title: "Error", value: "Error" }, // Trang lỗi
|
|
||||||
{ title: "Maintenance", value: "Maintenance" }, // Trang bảo trì
|
|
||||||
{ title: "Custom", value: "Custom" }, // Trang tùy chỉnh
|
|
||||||
];
|
|
||||||
|
|
||||||
export const pageComponentTypes = [
|
export const pageComponentTypes = [
|
||||||
{ title: "None", value: 0 }, // Không xác định
|
{ title: "None", value: 0 }, // Không xác định
|
||||||
{ title: "Individual", value: 1 }, // Đơn lẻ
|
{ title: "Individual", value: 1 }, // Đơn lẻ
|
||||||
@@ -103,6 +60,7 @@ export const pageDataQuery = [
|
|||||||
{ title: "REQUEST", value: "REQUEST" },
|
{ title: "REQUEST", value: "REQUEST" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/* PAGE SETTINGS */
|
||||||
export const pageTaxonomy = [
|
export const pageTaxonomy = [
|
||||||
{ title: "Home", value: "Home" }, // Trang khác
|
{ title: "Home", value: "Home" }, // Trang khác
|
||||||
{ title: "Section", value: "Section" }, // Chuyên trang
|
{ title: "Section", value: "Section" }, // Chuyên trang
|
||||||
@@ -121,6 +79,31 @@ export const pageTaxonomy = [
|
|||||||
{ title: "Navigation", value: "Navigation" }, // Navigation
|
{ title: "Navigation", value: "Navigation" }, // Navigation
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const pageTemplates = {
|
||||||
|
[enumPageKey.HOME]: [
|
||||||
|
{ title: "Trang chủ - Báo Tiền Phong", value: enumPageTemplate[enumPageKey.HOME]['DEFAULT'] },
|
||||||
|
{ title: "Trang chủ - Báo Kinh tế đô thị", value: enumPageTemplate[enumPageKey.HOME]['DEFAULT'] },
|
||||||
|
],
|
||||||
|
[enumPageKey.ARTICLE]: [
|
||||||
|
{ title: "Chi tiết bài viết", value: enumPageTemplate[enumPageKey.ARTICLE]['DETAIL'] },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
export const pageLayouts = {
|
||||||
|
[enumPageTemplate[enumPageKey.HOME]['DEFAULT']]: [
|
||||||
|
{ title: "Giới hạn chiều rộng", value: enumPageLayouts[enumPageTemplate[enumPageKey.HOME]['DEFAULT']]['DEFAULT'] },
|
||||||
|
{ title: "Không giới hạn chiều rộng", value: enumPageLayouts[enumPageTemplate[enumPageKey.HOME]['DEFAULT']]['FULL'] },
|
||||||
|
{ title: "Giới hạn chiều rộng có Quảng cáo", value: enumPageLayouts[enumPageTemplate[enumPageKey.HOME]['DEFAULT']]['BACKGROUND_PAGE'] },
|
||||||
|
],
|
||||||
|
[enumPageTemplate[enumPageKey.ARTICLE]['DETAIL']]: [
|
||||||
|
{ title: "Không có", value: enumPageLayouts[enumPageTemplate[enumPageKey.ARTICLE]['DETAIL']]['ARTICLE_NONE'] },
|
||||||
|
{ title: "Bài viết thường", value: enumPageLayouts[enumPageTemplate[enumPageKey.ARTICLE]['DETAIL']]['ARTICLE_NORMAL'] },
|
||||||
|
{ title: "Bài viết ngắn", value: enumPageLayouts[enumPageTemplate[enumPageKey.ARTICLE]['DETAIL']]['ARTICLE_SHORT'] },
|
||||||
|
{ title: "Bài viết dài", value: enumPageLayouts[enumPageTemplate[enumPageKey.ARTICLE]['DETAIL']]['ARTICLE_LONG'] },
|
||||||
|
{ title: "Bài viết toàn trang", value: enumPageLayouts[enumPageTemplate[enumPageKey.ARTICLE]['DETAIL']]['ARTICLE_PAGE'] },
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
/* SECTION SETTINGS */
|
/* SECTION SETTINGS */
|
||||||
export const pageSectionTaxonomy = [
|
export const pageSectionTaxonomy = [
|
||||||
{ title: "None", value: "None" }, // Phân vùng của Chuyên trang
|
{ title: "None", value: "None" }, // Phân vùng của Chuyên trang
|
||||||
@@ -267,6 +250,7 @@ export const pageComponentLayouts = {
|
|||||||
[`${enumPageComponentTemplate[enumPageComponentKey.COLLECTION]['ARTICLE']}`]: [
|
[`${enumPageComponentTemplate[enumPageComponentKey.COLLECTION]['ARTICLE']}`]: [
|
||||||
{ title: "Thẻ bài viết cơ bản", value: enumPageComponentLayouts[`${enumPageComponentTemplate[enumPageComponentKey.COLLECTION]['ARTICLE']}`]['ARTICLE_COLLECTION_DEFAULT'] },
|
{ title: "Thẻ bài viết cơ bản", value: enumPageComponentLayouts[`${enumPageComponentTemplate[enumPageComponentKey.COLLECTION]['ARTICLE']}`]['ARTICLE_COLLECTION_DEFAULT'] },
|
||||||
{ title: "Thẻ bài viết Audio", value: enumPageComponentLayouts[`${enumPageComponentTemplate[enumPageComponentKey.COLLECTION]['ARTICLE']}`]['ARTICLE_COLLECTION_AUDIO'] },
|
{ title: "Thẻ bài viết Audio", value: enumPageComponentLayouts[`${enumPageComponentTemplate[enumPageComponentKey.COLLECTION]['ARTICLE']}`]['ARTICLE_COLLECTION_AUDIO'] },
|
||||||
|
{ title: "Thẻ bài viết Video", value: enumPageComponentLayouts[`${enumPageComponentTemplate[enumPageComponentKey.COLLECTION]['ARTICLE']}`]['ARTICLE_COLLECTION_VIDEO'] },
|
||||||
],
|
],
|
||||||
[`${enumPageComponentTemplate[enumPageComponentKey.COLLECTION]['CATEGORY']}`]: [
|
[`${enumPageComponentTemplate[enumPageComponentKey.COLLECTION]['CATEGORY']}`]: [
|
||||||
{ title: "Hoa hậu - Cơ bản", value: enumPageComponentLayouts[`${enumPageComponentTemplate[enumPageComponentKey.COLLECTION]['CATEGORY']}`]['MISSES_COLLECTION_DEFAULT'] },
|
{ title: "Hoa hậu - Cơ bản", value: enumPageComponentLayouts[`${enumPageComponentTemplate[enumPageComponentKey.COLLECTION]['CATEGORY']}`]['MISSES_COLLECTION_DEFAULT'] },
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
export { PublishTypes as publishTypes, sharingTypes } from "./publishTypes.enum";
|
export { PublishTypes as publishTypes, sharingTypes } from "./publishTypes.enum";
|
||||||
export { categoryTypes } from "./categoryTypes.enum";
|
export { categoryTypes } from "./categoryTypes.enum";
|
||||||
export {
|
export {
|
||||||
templates, layouts, dataTypes, dataQuery, sectionTypes, sectionTaxonomy, enumPageType, enumPageSectionLayouts, enumPageComponentLayouts, enumPageComponentTemplates, enumPageComponentStaticChild,
|
dataTypes, dataQuery, sectionTypes, sectionTaxonomy, enumPageType, enumPageSectionLayouts, enumPageComponentLayouts, enumPageComponentTemplates, enumPageComponentStaticChild,
|
||||||
dataTypeSort, dataTypeKeyInSort, dataTypeKeyInWith, dataSelectQuery, dataTypeTTL, dataMethodRequest, dataDesignLayout, dataBorderDesign, dataHideDesign, dataFontWeightDesign, dataPaddingDesign,
|
dataTypeSort, dataTypeKeyInSort, dataTypeKeyInWith, dataSelectQuery, dataTypeTTL, dataMethodRequest, dataDesignLayout, dataBorderDesign, dataHideDesign, dataFontWeightDesign, dataPaddingDesign,
|
||||||
enumPageComponentKey, enumPageComponentTemplate, dataStaticType, enumPageSectionKey, enumPageSectionTemplate, enumPageComponentDefaultSetting
|
enumPageComponentKey, enumPageComponentTemplate, dataStaticType, enumPageSectionKey, enumPageSectionTemplate, enumPageComponentDefaultSetting, enumPageComponentDefaultStyle,
|
||||||
|
enumPageKey, enumPageTemplate, enumPageLayouts
|
||||||
} from "./page.enum";
|
} from "./page.enum";
|
||||||
export { enumStatus } from "./status.enum";
|
export { enumStatus } from "./status.enum";
|
||||||
export { actionCommands } from "./actionCommands.enum";
|
export { actionCommands } from "./actionCommands.enum";
|
||||||
|
|||||||
+152
-57
@@ -1,33 +1,3 @@
|
|||||||
export const templates = {
|
|
||||||
NONE: "None", // Không xác định
|
|
||||||
HOME: "Home", // Trang chủ
|
|
||||||
SECTION: "Section", // Chuyên trang
|
|
||||||
CATEGORY: "Category", // Trang danh mục
|
|
||||||
TOPIC: "Topic", // Trang chủ đề
|
|
||||||
EVENT: "Event", // Trang sự kiện
|
|
||||||
COLLECTION: "Collection", // Trang sưu tập
|
|
||||||
ARTICLE: "Article", // Trang bài viết
|
|
||||||
TAG: "Tag", // Trang từ khóa
|
|
||||||
AUTHOR: "Author", // Trang tác giả
|
|
||||||
SEARCH: "Search", // Trang tìm kiếm
|
|
||||||
CONTACT: "Contact", // Trang liên hệ
|
|
||||||
ABOUT: "About", // Trang giới thiệu
|
|
||||||
SERVICE: "Service", // Trang dịch vụ
|
|
||||||
POLICY: "Policy", // Trang chính sách
|
|
||||||
TERMS: "Terms", // Trang điều khoản
|
|
||||||
PRIVACY: "Privacy", // Trang bảo mật
|
|
||||||
ERROR: "Error", // Trang lỗi
|
|
||||||
MAINTENANCE: "Maintenance", // Trang bảo trì
|
|
||||||
CUSTOM: "Custom", // Trang tùy chỉnh
|
|
||||||
};
|
|
||||||
|
|
||||||
export const layouts = {
|
|
||||||
NONE: "None", // Không xác định
|
|
||||||
FULL_PAGE: "Full_Page", // full width 100%
|
|
||||||
CENTER_PAGE: "Center_Page", // ở giữa
|
|
||||||
BACKGROUND_PAGE: "Background_Page", // Phân trang
|
|
||||||
};
|
|
||||||
|
|
||||||
export const dataTypes = {
|
export const dataTypes = {
|
||||||
SECTION: "Section",
|
SECTION: "Section",
|
||||||
CATEGORY: "Category",
|
CATEGORY: "Category",
|
||||||
@@ -86,34 +56,26 @@ export const enumPageType = {
|
|||||||
CUSTOM: 99, // Trang tùy chỉnh
|
CUSTOM: 99, // Trang tùy chỉnh
|
||||||
};
|
};
|
||||||
|
|
||||||
export const enumPageComponentTemplates = { // KHÔNG ĐƯỢC XÓA KEY - BIẾN này
|
export const dataTypeKeyInSort = [
|
||||||
NONE: "None", // Không xác định
|
{ title: "Thời gian tạo", value: "CreatedOn" },
|
||||||
SECTION: "Section", // Chuyên trang
|
{ title: "Lượt xem", value: "Views" },
|
||||||
CATEGORY: "Category", // Trang danh mục
|
{ title: "Lượt chia sẻ", value: "Shares" },
|
||||||
TOPIC: "Topic", // Trang chủ đề
|
];
|
||||||
EVENT: "Event", // Trang sự kiện
|
|
||||||
COLLECTION: "Collection", // Trang sưu tập
|
export const dataTypeSort = {
|
||||||
ARTICLE: "Article", // Trang bài viết
|
Views: [
|
||||||
TAG: "Tag", // Trang từ khóa
|
{ title: "Tăng dần", value: "-" },
|
||||||
AUTHOR: "Author", // Trang tác giả
|
{ title: "Giảm dần", value: "+" },
|
||||||
POLL: "Poll", // Trang poll
|
],
|
||||||
QUIZ: "Quiz", // Trang quiz
|
Shares: [
|
||||||
SURVEY: "Survey", // Trang survey
|
{ title: "Tăng dần", value: "-" },
|
||||||
ADVERTISING: "Advertising", // Trang quảng cáo
|
{ title: "Giảm dần", value: "+" },
|
||||||
OTHER: "Other", // Trang khác
|
],
|
||||||
NAVIGATION: "Navigation", // Navigation
|
CreatedOn: [
|
||||||
LOCATION: 'Location', // Location
|
{ title: "Mới nhất", value: "-" },
|
||||||
FIGURE: 'Figure', // Figure
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
export const dataTypeSort = [
|
|
||||||
{ title: "Tăng dần", value: "+" },
|
|
||||||
{ title: "Giảm dần", value: "-" },
|
|
||||||
];
|
|
||||||
export const dataTypeKeyInSort = [
|
|
||||||
{ title: "Views", value: "Views" },
|
|
||||||
{ title: "Shares", value: "Shares" },
|
|
||||||
];
|
|
||||||
export const dataTypeKeyInWith = [
|
export const dataTypeKeyInWith = [
|
||||||
{ title: "Ids", value: "Ids" },
|
{ title: "Ids", value: "Ids" },
|
||||||
{ title: "Sites", value: "Sites" },
|
{ title: "Sites", value: "Sites" },
|
||||||
@@ -192,6 +154,56 @@ export const enumPageComponentStaticChild = {
|
|||||||
DEFAULT: "Default", // Chuyên trang
|
DEFAULT: "Default", // Chuyên trang
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* PAGE SETTINGS */
|
||||||
|
// KHÔNG ĐƯỢC XÓA KEY - BIẾN này
|
||||||
|
export const enumPageKey = {
|
||||||
|
NONE: "None", // Không xác định
|
||||||
|
HOME: "Home", // Trang chủ
|
||||||
|
SECTION: "Section", // Chuyên trang
|
||||||
|
CATEGORY: "Category", // Trang danh mục
|
||||||
|
TOPIC: "Topic", // Trang chủ đề
|
||||||
|
EVENT: "Event", // Trang sự kiện
|
||||||
|
COLLECTION: "Collection", // Trang sưu tập
|
||||||
|
ARTICLE: "Article", // Trang bài viết
|
||||||
|
TAG: "Tag", // Trang từ khóa
|
||||||
|
AUTHOR: "Author", // Trang tác giả
|
||||||
|
SEARCH: "Search", // Trang tìm kiếm
|
||||||
|
CONTACT: "Contact", // Trang liên hệ
|
||||||
|
ABOUT: "About", // Trang giới thiệu
|
||||||
|
SERVICE: "Service", // Trang dịch vụ
|
||||||
|
POLICY: "Policy", // Trang chính sách
|
||||||
|
TERMS: "Terms", // Trang điều khoản
|
||||||
|
PRIVACY: "Privacy", // Trang bảo mật
|
||||||
|
ERROR: "Error", // Trang lỗi
|
||||||
|
MAINTENANCE: "Maintenance", // Trang bảo trì
|
||||||
|
CUSTOM: "Custom", // Trang tùy chỉnh
|
||||||
|
};
|
||||||
|
|
||||||
|
export const enumPageTemplate = {
|
||||||
|
[enumPageKey.HOME]: {
|
||||||
|
'DEFAULT': "TYPE:Default",
|
||||||
|
},
|
||||||
|
[enumPageKey.ARTICLE]: {
|
||||||
|
'DETAIL': "TYPE:Article_Detail",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const enumPageLayouts = {
|
||||||
|
/* Home */
|
||||||
|
[`${enumPageTemplate[enumPageKey.HOME]['DEFAULT']}`]: {
|
||||||
|
'DEFAULT': 'TYPE:Center_Page',
|
||||||
|
'FULL': 'TYPE:Full_Page',
|
||||||
|
// 'CENTER_PAGE': 'TYPE:Center_Page',
|
||||||
|
'BACKGROUND_PAGE': 'TYPE:Background_Page'
|
||||||
|
},
|
||||||
|
[`${enumPageTemplate[enumPageKey.ARTICLE]['DETAIL']}`]: {
|
||||||
|
'ARTICLE_NONE': 'TYPE:ARTICLE_NONE',
|
||||||
|
'ARTICLE_NORMAL': 'TYPE:ARTICLE_NORMAL',
|
||||||
|
'ARTICLE_SHORT': 'TYPE:ARTICLE_SHORT',
|
||||||
|
'ARTICLE_LONG': 'TYPE:ARTICLE_LONG',
|
||||||
|
'ARTICLE_PAGE': 'TYPE:ARTICLE_PAGE',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
/* SECTION SETTINGS */
|
/* SECTION SETTINGS */
|
||||||
// KHÔNG ĐƯỢC XÓA KEY - BIẾN này
|
// KHÔNG ĐƯỢC XÓA KEY - BIẾN này
|
||||||
@@ -293,6 +305,26 @@ export const enumPageComponentKey = {
|
|||||||
FIGURE: 'Figure', // Figure
|
FIGURE: 'Figure', // Figure
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const enumPageComponentTemplates = { // KHÔNG ĐƯỢC XÓA KEY - BIẾN này
|
||||||
|
NONE: "None", // Không xác định
|
||||||
|
SECTION: "Section", // Chuyên trang
|
||||||
|
CATEGORY: "Category", // Trang danh mục
|
||||||
|
TOPIC: "Topic", // Trang chủ đề
|
||||||
|
EVENT: "Event", // Trang sự kiện
|
||||||
|
COLLECTION: "Collection", // Trang sưu tập
|
||||||
|
ARTICLE: "Article", // Trang bài viết
|
||||||
|
TAG: "Tag", // Trang từ khóa
|
||||||
|
AUTHOR: "Author", // Trang tác giả
|
||||||
|
POLL: "Poll", // Trang poll
|
||||||
|
QUIZ: "Quiz", // Trang quiz
|
||||||
|
SURVEY: "Survey", // Trang survey
|
||||||
|
ADVERTISING: "Advertising", // Trang quảng cáo
|
||||||
|
OTHER: "Other", // Trang khác
|
||||||
|
NAVIGATION: "Navigation", // Navigation
|
||||||
|
LOCATION: 'Location', // Location
|
||||||
|
FIGURE: 'Figure', // Figure
|
||||||
|
};
|
||||||
|
|
||||||
export const enumPageComponentTemplate = {
|
export const enumPageComponentTemplate = {
|
||||||
[enumPageComponentKey.ARTICLE]: {
|
[enumPageComponentKey.ARTICLE]: {
|
||||||
'ARTICLE_CARD': "TYPE:Card",
|
'ARTICLE_CARD': "TYPE:Card",
|
||||||
@@ -354,6 +386,7 @@ export const enumPageComponentLayouts = {
|
|||||||
[`${enumPageComponentTemplate[enumPageComponentKey.COLLECTION]['ARTICLE']}`]: {
|
[`${enumPageComponentTemplate[enumPageComponentKey.COLLECTION]['ARTICLE']}`]: {
|
||||||
'ARTICLE_COLLECTION_DEFAULT': "TYPE:Article_Collection_Default",
|
'ARTICLE_COLLECTION_DEFAULT': "TYPE:Article_Collection_Default",
|
||||||
'ARTICLE_COLLECTION_AUDIO': "TYPE:Article_Collection_Audio",
|
'ARTICLE_COLLECTION_AUDIO': "TYPE:Article_Collection_Audio",
|
||||||
|
'ARTICLE_COLLECTION_VIDEO': "TYPE:Article_Collection_Video",
|
||||||
},
|
},
|
||||||
[`${enumPageComponentTemplate[enumPageComponentKey.COLLECTION]['CATEGORY']}`]: {
|
[`${enumPageComponentTemplate[enumPageComponentKey.COLLECTION]['CATEGORY']}`]: {
|
||||||
'MISSES_COLLECTION_DEFAULT': "TYPE:Category_Collection_MISS_Default",
|
'MISSES_COLLECTION_DEFAULT': "TYPE:Category_Collection_MISS_Default",
|
||||||
@@ -386,6 +419,7 @@ export const enumPageComponentLayouts = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const defaultArticle = {
|
const defaultArticle = {
|
||||||
WidthImg: 40,
|
WidthImg: 40,
|
||||||
layout: "column",
|
layout: "column",
|
||||||
@@ -418,6 +452,9 @@ export const enumPageComponentDefaultSetting = {
|
|||||||
"TYPE:Card_Audio": defaultArticleAudio,
|
"TYPE:Card_Audio": defaultArticleAudio,
|
||||||
"TYPE:Card_Video": defaultArticleVideo,
|
"TYPE:Card_Video": defaultArticleVideo,
|
||||||
"TYPE:Card_VideoHightLight": defaultArticleVideoHightLight,
|
"TYPE:Card_VideoHightLight": defaultArticleVideoHightLight,
|
||||||
|
"TYPE:Card_MissHightLight": {
|
||||||
|
background: "rgba(255, 93, 2, 0.7)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
[enumPageComponentKey.COLLECTION]: {
|
[enumPageComponentKey.COLLECTION]: {
|
||||||
"TYPE:Article_Collection_Default": {
|
"TYPE:Article_Collection_Default": {
|
||||||
@@ -436,7 +473,11 @@ export const enumPageComponentDefaultSetting = {
|
|||||||
defaultFontSizeTitle: 16,
|
defaultFontSizeTitle: 16,
|
||||||
defaultFontWeightTitle: 600,
|
defaultFontWeightTitle: 600,
|
||||||
...defaultArticleAudio
|
...defaultArticleAudio
|
||||||
}
|
},
|
||||||
|
"TYPE:Category_Collection_MISS_Default": {
|
||||||
|
background: "rgba(255, 93, 2, 0.7)"
|
||||||
|
},
|
||||||
|
"TYPE:Article_Collection_Video": { column: 4 }
|
||||||
},
|
},
|
||||||
[enumPageComponentKey.SECTION]: {
|
[enumPageComponentKey.SECTION]: {
|
||||||
"TYPE:Article_Section_Default": {
|
"TYPE:Article_Section_Default": {
|
||||||
@@ -466,3 +507,57 @@ export const enumPageComponentDefaultSetting = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
export const enumPageComponentDefaultStyle = {
|
||||||
|
[enumPageComponentKey.ARTICLE]: {
|
||||||
|
"TYPE:Card_Default": `#cpn_[] {}
|
||||||
|
#cpn_[] .article-title {}
|
||||||
|
#cpn_[] .article-time {}
|
||||||
|
#cpn_[] .article-intro {}
|
||||||
|
#cpn_[] .article-thumbnail {}`,
|
||||||
|
|
||||||
|
"TYPE:Card_Audio": `#cpn_[] {}
|
||||||
|
#cpn_[] .article-title {}`,
|
||||||
|
"TYPE:Card_Video": ``,
|
||||||
|
|
||||||
|
"TYPE:Card_VideoHightLight": `#cpn_[] {}
|
||||||
|
#cpn_[] .article-title {}
|
||||||
|
#cpn_[] .article-intro {}
|
||||||
|
#cpn_[] .article-thumbnail {}`,
|
||||||
|
|
||||||
|
"TYPE:Card_MissHightLight": `#cpn_[] {}
|
||||||
|
#cpn_[] article{}
|
||||||
|
#cpn_[] .article-thumbnail{}
|
||||||
|
#cpn_[] .article-title{}`
|
||||||
|
},
|
||||||
|
[enumPageComponentKey.COLLECTION]: {
|
||||||
|
"TYPE:Article_Collection_Default": `#cpn_[] {}
|
||||||
|
#cpn_[] article{}
|
||||||
|
#cpn_[] .article-thumbnail img{}
|
||||||
|
#cpn_[] .article-title{}
|
||||||
|
#cpn_[] .article-intro{}`,
|
||||||
|
|
||||||
|
"TYPE:Article_Collection_Audio": `#cpn_[] {}
|
||||||
|
#cpn_[] article{}
|
||||||
|
#cpn_[] .article-title {}`,
|
||||||
|
|
||||||
|
"TYPE:Category_Collection_MISS_Default": `#cpn_[] {}
|
||||||
|
#cpn_[] article{}
|
||||||
|
#cpn_[] .article-thumbnail{}
|
||||||
|
#cpn_[] .article-title{}`,
|
||||||
|
"TYPE:Article_Collection_Video": ""
|
||||||
|
},
|
||||||
|
[enumPageComponentKey.SECTION]: {
|
||||||
|
"TYPE:Article_Section_Default": `#cpn_[] {}
|
||||||
|
#cpn_[] article{}
|
||||||
|
#cpn_[] .article-thumbnail img{}
|
||||||
|
#cpn_[] .article-title{}
|
||||||
|
#cpn_[] .article-intro{}`
|
||||||
|
},
|
||||||
|
[enumPageComponentKey.CATEGORY]: {
|
||||||
|
"TYPE:Category_Vertical": `#cpn_[] {}
|
||||||
|
#cpn_[] .category h3{}`,
|
||||||
|
|
||||||
|
"TYPE:Default": `#cpn_[] {}
|
||||||
|
#cpn_[] .category h3{}`,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,6 +15,10 @@ export default defineNuxtConfig({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
plugins: [
|
||||||
|
'~/plugins/scroll.plugin',
|
||||||
|
],
|
||||||
|
|
||||||
modules: [
|
modules: [
|
||||||
'@nuxt/image',
|
'@nuxt/image',
|
||||||
"@unocss/nuxt",
|
"@unocss/nuxt",
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ useHead({
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<main class="h-screen" v-if="asycnCurrentPage">
|
<main class="h-screen" v-if="asycnCurrentPage">
|
||||||
<DynamicTemplate :settings="asycnCurrentPage.settings">
|
<DynamicTemplate :page="asycnCurrentPage" :settings="asycnCurrentPage.settings">
|
||||||
<DynamicSection
|
<DynamicSection
|
||||||
v-for="(section, index) in asycnSectionPublished"
|
v-for="(section, index) in asycnSectionPublished"
|
||||||
:key="index"
|
:key="index"
|
||||||
|
|||||||
+29
-29
@@ -19,34 +19,34 @@ import { useDynamicPageStore } from '~/stores/dynamic-page';
|
|||||||
import { useArticleStore } from '~/stores/articles';
|
import { useArticleStore } from '~/stores/articles';
|
||||||
|
|
||||||
const loadPage = async () => {
|
const loadPage = async () => {
|
||||||
const article = await store.article.getArticleBySlug(route.params.slug);
|
const article = await store.article.getArticleBySlug(String(route.params.slug));
|
||||||
let isContentType = 'trang-chi-tiet';
|
let isContentType
|
||||||
// switch (article.value?.contentType) {
|
switch (article.value?.contentType) {
|
||||||
// case 1:
|
case 1:
|
||||||
// isContentType = 'trang-chi-tiet-bai-viet-general';
|
isContentType = 'trang-chi-tiet';
|
||||||
// break;
|
break;
|
||||||
// case 2:
|
case 2:
|
||||||
// isContentType = 'trang-chi-tiet-bai-viet-image';
|
isContentType = 'trang-image';
|
||||||
// break;
|
break;
|
||||||
// case 3:
|
case 3:
|
||||||
// isContentType = 'trang-chi-tiet-podcast';
|
isContentType = 'trang-chi-tiet';
|
||||||
// break;
|
break;
|
||||||
// case 4:
|
case 4:
|
||||||
// isContentType = 'trang-chi-tiet-bai-viet-video';
|
isContentType = 'trang-video';
|
||||||
// break;
|
break;
|
||||||
// case 5:
|
case 5:
|
||||||
// if (article.value?.layoutType === 4) {
|
if (article.value?.layoutType === 4) {
|
||||||
// isContentType = 'trang-chi-tiet-bai-viet-emagazine';
|
isContentType = 'trang-emagazine';
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
// if (article.value?.layoutType === 3) {
|
if (article.value?.layoutType === 3) {
|
||||||
// isContentType = 'trang-chi-tiet-bai-viet-infographics';
|
isContentType = 'trang-inforgraphic';
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
// default:
|
default:
|
||||||
// isContentType = 'trang-chi-tiet-bai-viet-general';
|
isContentType = 'trang-chi-tiet';
|
||||||
// break;
|
break;
|
||||||
// }
|
}
|
||||||
const dynamicPage = await store.dynamicPage.fetchPageByCode(isContentType);
|
const dynamicPage = await store.dynamicPage.fetchPageByCode(isContentType);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -75,7 +75,7 @@ useSeoMeta({
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<main class="h-screen" v-if="asycnCurrentPage">
|
<main class="h-screen" v-if="asycnCurrentPage">
|
||||||
<DynamicTemplate :settings="asycnCurrentPage.settings">
|
<DynamicTemplate :page="asycnCurrentPage" :settings="asycnCurrentPage.settings">
|
||||||
<DynamicSection
|
<DynamicSection
|
||||||
v-for="(section, index) in asycnSectionPublished"
|
v-for="(section, index) in asycnSectionPublished"
|
||||||
:key="index"
|
:key="index"
|
||||||
|
|||||||
+1
-1
@@ -29,7 +29,7 @@ useHead({
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<main class="h-screen" v-if="asycnCurrentPage">
|
<main class="h-screen" v-if="asycnCurrentPage">
|
||||||
<DynamicTemplate :settings="asycnCurrentPage.settings">
|
<DynamicTemplate :page="asycnCurrentPage" :settings="asycnCurrentPage.settings">
|
||||||
<DynamicSection
|
<DynamicSection
|
||||||
class="mb-10"
|
class="mb-10"
|
||||||
v-for="(section, index) in asycnSectionPublished"
|
v-for="(section, index) in asycnSectionPublished"
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
export default defineNuxtPlugin((nuxtApp : any) => {
|
||||||
|
nuxtApp.$router.options.scrollBehavior = () => {
|
||||||
|
return { left: 0, top: 0 }
|
||||||
|
}
|
||||||
|
})
|
||||||
+3
-1
@@ -42,7 +42,9 @@ export default defineConfig({
|
|||||||
"after:no-content": "after:content-['']",
|
"after:no-content": "after:content-['']",
|
||||||
"before:no-content": "before:content-['']",
|
"before:no-content": "before:content-['']",
|
||||||
'container-xxl': 'px-[8px] mx-auto w-full sm:w-620px md:w-760px lg:w-980px xl:w-1100px 2xl:w-1200px',
|
'container-xxl': 'px-[8px] mx-auto w-full sm:w-620px md:w-760px lg:w-980px xl:w-1100px 2xl:w-1200px',
|
||||||
'container-long': 'px-2 mx-auto w-full sm:w-620px md:w-760px lg:w-980px xl:w-1100px 2xl:w-1200px'
|
'container-long': 'px-2 mx-auto w-full sm:w-620px md:w-760px lg:w-980px xl:w-1100px 2xl:w-1200px',
|
||||||
|
// Size tiền phong
|
||||||
|
'container-tp': "px-30px mx-auto w-full max-w-1385px"
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
rules: [
|
rules: [
|
||||||
|
|||||||
+12
-20
@@ -1,26 +1,18 @@
|
|||||||
import * as cherrio from 'cheerio'
|
import * as cherrio from 'cheerio'
|
||||||
|
|
||||||
const getResource = (data: any) => {
|
const getResource = (key: any, data: any) => {
|
||||||
// const result = {
|
const $ = cherrio.load(`<div class="">${data}</div>`)
|
||||||
// videoHightlight: null,
|
let result = null;
|
||||||
// imageHightlight: null,
|
switch (key) {
|
||||||
// resources: [],
|
case 'HIGHLIGHT_VIDEO':
|
||||||
// };
|
result = $('video').first().parent().html();
|
||||||
// const $ = cherrio.load(`<div class="get-resource">${data}</div>`)
|
break;
|
||||||
// const html : any = $('.get-resource').html();
|
default:
|
||||||
// html.find('video, figure img, img').each((index : any, element: any) => {
|
result = $.html();
|
||||||
// // if (index === 0) result.videoHightlight =
|
}
|
||||||
// });
|
console.log(result)
|
||||||
|
return result;
|
||||||
// console.log(html)
|
|
||||||
|
|
||||||
// <div>
|
|
||||||
// <video controls="controls" width="100%" height="auto" data-id="578" data-resource="https://resource.vpress.vn/resources/1/private/13cee27a2bd93915479f049378cffdd3/video/28thi-tot-nghiep-ptth-2024-1719829616.mp4" data-title="28thi-tot-nghiep-ptth-2024">
|
|
||||||
// <source src="https://resource.vpress.vn/resources/1/private/13cee27a2bd93915479f049378cffdd3/video/28thi-tot-nghiep-ptth-2024-1719829616.mp4" type="video/mp4">
|
|
||||||
// </video>
|
|
||||||
// </div>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
getResource
|
getResource
|
||||||
|
|||||||
Reference in New Issue
Block a user