Files
NSG_PORTAL_V2/components/dynamic-page/page-component/templates/articles/cards/Card.vue
T
2024-06-28 15:39:26 +07:00

287 lines
7.4 KiB
Vue

<script lang="ts" setup>
import { enumPageComponentTemplates } from "@/definitions/enum";
import { DEFAULT_QUERY_DROP } from "@/utils/parseSQL";
import { getInputValue } from "@/utils/parseSQL";
import { formatDate } from "@/utils/filters";
const props = defineProps<{
dataResult?: any;
dataType?: any;
dataQuery?: any;
layout?: string;
label?: string;
}>();
const LAYOUT_PARSE = computed(() => {
const designObject = props.label ? getInputValue(props.label, "OBJECT") : {};
return Object.assign({}, designObject);
});
const emit = defineEmits(["selectComponent", "dropData"]);
const selectComponent = () => {
emit("selectComponent");
};
const parseData = computed(() => {
if (!props.dataResult) return;
const result = getInputValue(props.dataResult, "OBJECT");
return result;
});
const drop = (e: any) => {
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>
<template>
<!-- <article class="article-card-default">
<div class="article-card-default__content">
<template v-if="currentArticle.tags && currentArticle?.tags.length > 0">
<nuxt-link class="article-card-default__tag" :to="`/${currentArticle?.tags[0].code}`">
<h5>{{ currentArticle?.tags[0].title }}</h5>
</nuxt-link>
</template>
<nuxt-link class="article-card-default__title" :to="`/bai-viet/${currentArticle.code}`">
<h2 v-html="currentArticle.title"></h2>
<p v-html="currentArticle.intro"></p>
</nuxt-link>
<div class="article-card-default__bottom">
<span>{{ formatDate(String(currentArticle.createdOn), "DD/MM/YYYY | HH:mm") }}</span> /
<nuxt-link :to="`/${currentArticle.category?.code}`"> {{ currentArticle.category?.title }}</nuxt-link>
</div>
</div>
<div class="article-card-default__thumbnail">
<figure>
<nuxt-link :to="`bai-viet${currentArticle.code}`">
<img :src="currentArticle?.thumbnail ? currentArticle?.thumbnail : 'http://picsum.photos/1024/600?random=1'" :alt="currentArticle?.title" />
</nuxt-link>
</figure>
</div>
</article> -->
<article
class="basic-article border-custom"
:class="LAYOUT_PARSE['article_Class']"
@click="selectComponent"
@dragover.prevent
@drop.stop.prevent="drop"
:style="LAYOUT_PARSE['article']"
>
<div class="basic-article_thumbnail" :class="LAYOUT_PARSE['thumbnail_Class']" :style="LAYOUT_PARSE['div.basic-article_thumbnail']">
<template v-if="parseData">
<img class="object-fit-cover" :src="parseData.thumbnail ? parseData.thumbnail : '/images/default-thumbnail.jpg'" :alt="parseData.title?.replace(/<[^>]+>/g, '')" />
</template>
<span v-else class="empty-block" style="width: 100%; height: 100%; min-height: 50px"></span>
</div>
<div class="basic-article_content" :class="[!parseData && 'no-data']">
<template v-if="parseData?.topics && parseData?.topics.length > 0">
<nuxt-link class="article-card-default__topic" :to="`/${parseData?.topics[0].code}`" :style="LAYOUT_PARSE['topic']">
<h5>{{ parseData?.topics[0].title }}</h5>
</nuxt-link>
</template>
<h3 class="line-clamp" :class="LAYOUT_PARSE['title_Class']" :style="LAYOUT_PARSE['h3.title']">
<template v-if="parseData">
{{ parseData.title?.replace(/<[^>]+>/g, "") }}
</template>
<span v-else class="empty-block" style="height: 8px"></span>
</h3>
<div class="article-card-default__bottom" v-if="LAYOUT_PARSE.layout === 'row'">
<span :style="LAYOUT_PARSE['time']" style="margin-right: 5px" :class="LAYOUT_PARSE['time_Class']">{{
formatDate(String(parseData?.createdOn), "DD/MM/YYYY | HH:mm")
}}</span>
<nuxt-link :style="LAYOUT_PARSE['category-article']" :class="LAYOUT_PARSE['category-article_Class']">{{ parseData?.category?.title }}</nuxt-link>
</div>
<p class="mb-0 line-clamp" :class="LAYOUT_PARSE['paragraph_Class']" :style="LAYOUT_PARSE['p.paragraph']">
<template v-if="parseData">
{{ parseData.intro?.replace(/<[^>]+>/g, "") }}
</template>
<span v-else class="empty-block" style="height: 5px"></span>
</p>
<div class="article-card-default__bottom" v-if="LAYOUT_PARSE?.layout !== 'row'" :style="LAYOUT_PARSE['metadata']">
<span :style="LAYOUT_PARSE['time']" style="margin-right: 5px" :class="LAYOUT_PARSE['time_Class']">{{
formatDate(String(parseData?.createdOn), "DD/MM/YYYY | HH:mm")
}}</span>
<nuxt-link :style="LAYOUT_PARSE['category-article']" :class="LAYOUT_PARSE['category-article_Class']">{{ parseData?.category?.title }}</nuxt-link>
</div>
</div>
<div v-html="LAYOUT_PARSE.styleClasses"></div>
</article>
</template>
<style lang="scss" scoped>
.article-card-default {
display: flex;
gap: 20px;
&__content {
flex: 1;
.article-card-default__title {
color: #000;
h2 {
display: inline-block;
/* margin: 12px 0 20px 0; */
font-size: 24px;
font-weight: 700;
line-height: 130%;
&:hover {
color: #9e1e0f;
}
}
p {
font-size: 14px;
line-height: 150%;
font-weight: 400;
}
}
}
&__thumbnail {
width: 60%;
}
}
.flex-column {
flex-direction: column;
}
.article-card-default__topic {
position: relative;
/* margin: 0 0 12px 12px; */
// background-color: #151411;
display: inline-block;
h5 {
font-size: 12px;
text-transform: uppercase;
// color: #fff;
padding: 0 12px;
height: 100%;
margin: 0;
border: 1px solid #000;
line-height: 180%;
font-weight: 300;
}
&::after {
position: absolute;
content: "";
display: block;
width: 12px;
height: 100%;
background-color: #ed1c24;
left: -12px;
top: 0;
}
}
.article-card-default__bottom {
font-size: 12px;
color: rgba(0, 0, 0, 0.35);
/* margin-top: 10px; */
a {
color: #ed1c24;
}
}
figure {
margin: 0;
padding: 0;
width: 100%;
}
img {
width: 100%;
object-fit: cover;
}
h3,
p {
margin: 0;
}
.basic-article {
display: flex;
gap: 16px;
height: 100%;
padding: 20px;
background-size: cover;
flex-direction: column;
&.no-data {
gap: 5px !important;
padding: 0;
}
.line-clamp {
display: -webkit-box;
/* -webkit-line-clamp: 3; */
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
.basic-article_thumbnail {
width: 100%;
}
&.border-custom {
border-color: #e5e5e5 !important;
}
/* &.horizontal {
flex-direction: row;
.basic-article_thumbnail {
width: 40%;
}
&.reverse {
flex-direction: row-reverse;
}
} */
&_thumbnail {
img {
width: 100%;
border-radius: 2px;
aspect-ratio: 16/10;
}
}
&_content {
/* padding: 10px 0px; */
display: flex;
flex-direction: column;
gap: 10px;
flex: 1;
&.no-data {
padding: 0px;
}
h3 {
font-size: 16px;
}
p {
font-size: 14px;
/* margin-top: 10px; */
opacity: 85%;
}
}
.empty-block {
background-color: #409eff;
height: 100px;
display: block;
}
}
</style>