fix. 템플릿 수정

This commit is contained in:
clkim
2025-10-30 16:23:12 +09:00
parent 7a4dfd9790
commit 74ce5a0714
15 changed files with 422 additions and 79 deletions

View File

@@ -14,19 +14,12 @@ const props = defineProps<Props>()
const gameDataStore = useGameDataStore()
const pageDataStore = usePageDataStore()
const { getCwmsArticleData } = useResourcesData()
const { locale } = useI18n()
const { sendLog, useAnalyticsLogDataDirect } = useAnalytics()
const { locale } = useI18n()
const { gameData } = storeToRefs(gameDataStore)
const { pageData } = storeToRefs(pageDataStore)
const defaultSlideItem = {
article_id: '',
media_thumbnail_url: '',
title: '',
create_datetime: 0,
}
const boardId = computed(
() => getComponentGroup(props.components, 'boardId')?.display?.text
)
@@ -65,28 +58,33 @@ const { data: slideData } = await useAsyncData(
server: false,
}
)
const getResponsiveMultiple = (): number => {
const breakpoints = useResponsiveBreakpoints()
if (breakpoints.value.isSm) return 1 // sm: 1개 단위
if (breakpoints.value.isMd) return 2 // md: 2개 단위
return 4 // 그 외: 4개 단위
}
const fillToMultipleOfFour = (arr: CwmsArticleItem[]): CwmsArticleItem[] => {
const remainderSize = getResponsiveMultiple()
const remainder = arr.length % remainderSize
const fillCount = remainder === 0 ? 0 : remainderSize - remainder
return [
...arr,
...Array(fillCount).fill({ ...defaultSlideItem } as CwmsArticleItem),
]
}
const filledSlideData = computed(() => {
return fillToMultipleOfFour(slideData.value)
})
const slideLength = computed(() => slideData.value.length)
const slideClass = computed(() => ({
'is-one-item': slideLength.value === 1,
'is-two-items': slideLength.value === 2,
'is-three-items': slideLength.value === 3,
'is-four-items': slideLength.value === 4,
}))
const splideOptions = computed(() => ({
gap: 20,
perPage: 4,
drag: false,
arrows: slideLength.value > 4,
pagination: slideLength.value > 4,
breakpoints: {
[BREAKPOINTS.lg - 1]: {
perPage: 2,
arrows: slideLength.value > 2,
pagination: slideLength.value > 2,
},
[BREAKPOINTS.md - 1]: {
drag: true,
perPage: 1,
arrows: false,
pagination: false,
},
},
}))
const getArticleUrl = (articleId: string) => {
const communityUrl = gameData.value?.url_json?.community
@@ -105,7 +103,7 @@ const onArrowClick = (direction, targetIndex) => {
<template>
<section
class="relative py-[80px] md:py-[120px]"
class="relative min-h-[483px] py-[80px] md:min-h-[684px] md:py-[120px]"
:style="getPaginationClass(paginationData)"
>
<WidgetsBackground v-if="backgroundData" :resources-data="backgroundData" />
@@ -117,37 +115,24 @@ const onArrowClick = (direction, targetIndex) => {
/>
<ClientOnly>
<BlocksSlideDefault
v-if="slideData.length > 0"
:slide-item-length="slideData.length"
:per-page="4"
:drag="false"
:arrows="slideData.length > 4"
:pagination="slideData.length > 4"
:breakpoints="{
[BREAKPOINTS.lg - 1]: {
perPage: 2,
arrows: slideData.length > 2,
pagination: slideData.length > 2,
},
[BREAKPOINTS.md - 1]: {
drag: true,
perPage: 1,
arrows: false,
pagination: false,
},
}"
:class="{ 'is-single': slideData.length === 1 }"
v-if="slideLength > 0"
:slide-item-length="slideLength"
v-bind="splideOptions"
:class="slideClass"
@arrow-click="onArrowClick"
>
<SplideSlide v-for="(item, index) in filledSlideData" :key="index">
<SplideSlide
v-for="(item, index) in slideData"
:key="item.article_id || `real-${index}`"
>
<div class="slide-inner">
<BlocksCardNews
:title="item.title"
:description="
formatTimestamp(item?.create_datetime, 'YYYY.MM.DD')
formatTimestamp(item.create_datetime, 'YYYY.MM.DD')
"
:img-path="getResolvedHost(item?.media_thumbnail_url)"
:url="getArticleUrl(item?.article_id)"
:img-path="getResolvedHost(item.media_thumbnail_url)"
:url="getArticleUrl(item.article_id)"
link-target="_blank"
/>
</div>
@@ -182,17 +167,24 @@ const onArrowClick = (direction, targetIndex) => {
.splide:deep(.arrow-next) {
@apply top-[calc(50%-28px)] right-[0];
}
.splide__slide {
@apply mr-[20px];
}
.slide-inner {
@apply w-[275px] aspect-[1/1] md:w-[306px] md:box-border;
}
.splide.is-single {
@apply flex justify-center w-auto;
.splide.is-one-item:deep(.splide__track) {
@apply max-w-[315px] sm:max-w-[355px] mx-auto md:max-w-[306px];
}
.splide.is-single:deep(.splide__track) {
@apply w-[calc(100%-20px)] md:w-auto;
.splide.is-two-items:deep(.splide__track) {
@apply lg:max-w-[632px];
}
.splide.is-two-items:deep(.splide__list) {
@apply md:!translate-x-0;
}
.splide.is-three-items:deep(.splide__track) {
@apply lg:max-w-[958px];
}
.splide.is-three-items:deep(.splide__list),
.splide.is-four-items:deep(.splide__list) {
@apply lg:!translate-x-0;
}
</style>

View File

@@ -1,7 +1,6 @@
<script setup lang="ts">
import { getComponentGroup } from '#layers/utils/dataUtil'
import type { PageDataTemplateComponents } from '#layers/types/api/pageData'
import AtomsImg from '#layers/components/atoms/Img.vue'
interface Props {
components: PageDataTemplateComponents
@@ -71,7 +70,7 @@ const buttonListData = computed(() => {
<style scoped>
.img-container {
@apply flex flex-col items-center justify-center gap-4 box-content mx-auto mt-[32px]
w-[334px]
w-[440px]
md:w-[944px];
}
.img-item {

View File

@@ -158,6 +158,14 @@ const onArrowClick = (direction, targetIndex) => {
.thumbnail-carousel:deep(.main-splide) {
@apply overflow-hidden rounded-lg border border-white/10 shadow-[0_4px_20px_0_rgba(0,0,0,0.5)];
}
.thumbnail-carousel:deep(.thumbnail-slide) {
@apply opacity-50;
}
.thumbnail-carousel:deep(.thumbnail-slide:hover),
.thumbnail-carousel:deep(.thumbnail-slide.is-active) {
@apply opacity-100;
}
.main-slide {
@apply relative aspect-[16/9];
}