minhnt-dev: make UI
This commit is contained in:
+1
-11
@@ -37,7 +37,7 @@ const _dataResult = computed(() => {
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="collection-container p-2" :class="LAYOUT_PARSE['LAYOUT'] || 'horizontal'">
|
||||
<div class="collection-container grid gap-5" :class="LAYOUT_PARSE['LAYOUT'] || 'horizontal'">
|
||||
<div v-for="(component, index) in _dataResult" :key="index">
|
||||
<template v-if="!isEmpty(component)">
|
||||
<DynamicComponent
|
||||
@@ -65,8 +65,6 @@ const _dataResult = computed(() => {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.collection-container {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
&.vertical {
|
||||
grid-template-columns: repeat(1, minmax(0, 1fr));
|
||||
}
|
||||
@@ -74,13 +72,5 @@ const _dataResult = computed(() => {
|
||||
grid-template-rows: auto;
|
||||
grid-auto-flow: column;
|
||||
}
|
||||
.empty {
|
||||
min-height: 100px;
|
||||
border-radius: 6px;
|
||||
background: #409eff;
|
||||
}
|
||||
&.noData {
|
||||
border-radius: 6px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -46,26 +46,30 @@ const drop = (e: any) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<article class="basic-article" :class="[LAYOUT_PARSE['LAYOUT'] || 'horizontal', !parseData && 'no-data', LAYOUT_PARSE['REVERSE'] ? 'reverse' : '']" @click="selectComponent" @dragover.prevent @drop.stop.prevent="drop">
|
||||
<article class="basic-article gap-x-4" :class="[LAYOUT_PARSE['LAYOUT'] || 'horizontal', !parseData && 'no-data', LAYOUT_PARSE['REVERSE'] ? 'reverse' : '']">
|
||||
<div v-if="!LAYOUT_PARSE['HIDE'] || !LAYOUT_PARSE['HIDE'].includes('thumbnail')" class="basic-article_thumbnail">
|
||||
<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']">
|
||||
<div>
|
||||
<h3 v-if="!LAYOUT_PARSE['HIDE'] || !LAYOUT_PARSE['HIDE'].includes('title')" class="mb-1 text-truncate-two-lines">
|
||||
<template v-if="parseData">
|
||||
<nuxt-link :to="`/bai-viet/${parseData.slug}`">
|
||||
<h3 v-if="!LAYOUT_PARSE['HIDE'] || !LAYOUT_PARSE['HIDE'].includes('title')" class="mb-1 line-clamp-2 text-base font-600 hover:text-primary-100 transition-all duration-300">
|
||||
{{ parseData.title?.replace(/<[^>]+>/g, '') }}
|
||||
</h3>
|
||||
</nuxt-link>
|
||||
</template>
|
||||
<p v-if="!LAYOUT_PARSE['HIDE'] || !LAYOUT_PARSE['HIDE'].includes('paragraph')" class="mb-0 line-clamp-2">
|
||||
<template v-if="parseData">
|
||||
{{ parseData.title?.replace(/<[^>]+>/g, '') }}
|
||||
<template v-if="parseData.intro">
|
||||
{{ parseData.intro?.replace(/<[^>]+>/g, '') }}
|
||||
</template>
|
||||
<template v-if="parseData.sub">
|
||||
{{ parseData.sub?.replace(/<[^>]+>/g, '') }}
|
||||
</template>
|
||||
</template>
|
||||
<span v-else class="empty-block" style="height: 8px;"></span>
|
||||
</h3>
|
||||
<p v-if="!LAYOUT_PARSE['HIDE'] || !LAYOUT_PARSE['HIDE'].includes('paragraph')" class="mb-0 text-truncate-two-lines">
|
||||
<template v-if="parseData">
|
||||
{{ parseData.intro?.replace(/<[^>]+>/g, '') }}
|
||||
</template>
|
||||
<span v-else class="empty-block" style="height: 5px;"></span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -75,19 +79,20 @@ const drop = (e: any) => {
|
||||
<style lang="scss" scoped>
|
||||
.basic-article {
|
||||
display: grid;
|
||||
gap: 10px;
|
||||
height: 100%;
|
||||
|
||||
&.no-data {
|
||||
gap: 5px !important;
|
||||
}
|
||||
|
||||
&.vertical {
|
||||
grid-template-columns: repeat(1, minmax(0, 1fr));
|
||||
.basic-article_content {
|
||||
padding: 10px 0px;
|
||||
}
|
||||
}
|
||||
|
||||
&.horizontal {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
.basic-article_content {
|
||||
padding: 0px 0px;
|
||||
}
|
||||
|
||||
&.reverse {
|
||||
.basic-article_thumbnail {
|
||||
@@ -110,23 +115,6 @@ const drop = (e: any) => {
|
||||
}
|
||||
}
|
||||
|
||||
&_content {
|
||||
padding: 10px 0px;
|
||||
|
||||
&.no-data {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
p {
|
||||
font-size: 12px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.empty-block {
|
||||
background-color: #409eff;
|
||||
height: 100px;
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { isEmpty } from "lodash";
|
||||
import { COLLECTION_QUERY_DROP, getValueStringWithKeyAndColon, getInputValue } from '@/utils/parseSQL';
|
||||
|
||||
const emit = defineEmits(["dropData", "selectComponent"]);
|
||||
import { COLLECTION_QUERY_DROP, getValueStringWithKeyAndColon, getInputValue } from '@/utils/parseSQL';
|
||||
|
||||
const _props = defineProps<{
|
||||
dataResult?: any[];
|
||||
@@ -21,75 +19,18 @@ const _dataResult = computed(() => {
|
||||
})
|
||||
return _components;
|
||||
});
|
||||
|
||||
async function dropData(event: any) {
|
||||
const { dataResult, dataType } = JSON.parse(event.dataTransfer.getData("category"));
|
||||
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");
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="categories-container p-2" @click="selectComponent">
|
||||
<div
|
||||
v-for="(component, index) in _dataResult"
|
||||
:key="index"
|
||||
:class="isEmpty(component) ? 'empty' : 'category'"
|
||||
>
|
||||
<template v-if="!isEmpty(component)">
|
||||
<h3>{{ component.title }}</h3>
|
||||
</template>
|
||||
<div
|
||||
v-else
|
||||
@dragover.prevent
|
||||
@drop.stop.prevent="dropData($event)"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-4 items-end py-2" @click="selectComponent">
|
||||
<nuxt-link :to="`/${component.code}`" v-for="(component, index) in _dataResult" :key="index" class="font-medium text-[18px] first:font-600 first:text-[24px]">
|
||||
<h3 class="m-0 leading-none hover:text-primary-100 transition-all duration-300">{{ component.title }}</h3>
|
||||
</nuxt-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.categories-container {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: flex-end;
|
||||
.category {
|
||||
height: 100%;
|
||||
h3 {
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
margin: 0px !important;
|
||||
}
|
||||
&:first-child {
|
||||
h3 {
|
||||
font-weight: 600;
|
||||
font-size: 17px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.empty {
|
||||
border-radius: 6px;
|
||||
background: #409eff;
|
||||
width: 50px;
|
||||
> div {
|
||||
min-height: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user