feat. FX_VIDEO_01 템플릿 제작
@@ -6,6 +6,7 @@ import type { Splide as SplideType, ResponsiveOptions } from '@splidejs/splide'
|
||||
import type { PageDataResourceGroups } from '#layers/types/api/pageData'
|
||||
|
||||
interface Props {
|
||||
drag?: boolean
|
||||
autoplay?: boolean
|
||||
arrows?: boolean
|
||||
pagination?: boolean
|
||||
@@ -13,6 +14,7 @@ interface Props {
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
drag: true,
|
||||
autoplay: false,
|
||||
arrows: true,
|
||||
pagination: true,
|
||||
@@ -32,6 +34,7 @@ const options = computed((): ResponsiveOptions => {
|
||||
perMove: 1,
|
||||
speed: 500,
|
||||
updateOnMove: true,
|
||||
drag: props.drag,
|
||||
autoplay: props.autoplay,
|
||||
pauseOnHover: false,
|
||||
pauseOnFocus: false,
|
||||
|
||||
@@ -9,6 +9,7 @@ import GrDetail02 from '#layers/templates/GrDetail02/index.vue'
|
||||
import GrDetail03 from '#layers/templates/GrDetail03/index.vue'
|
||||
import GrBoard01 from '#layers/templates/GrBoard01/index.vue'
|
||||
import GrContents01 from '#layers/templates/GrContents01/index.vue'
|
||||
import FxVideo01 from '#layers/templates/FxVideo01/index.vue'
|
||||
import FxDownload01 from '#layers/templates/FxDownload01/index.vue'
|
||||
|
||||
const templateRegistry = {
|
||||
@@ -23,6 +24,7 @@ const templateRegistry = {
|
||||
GR_DETAIL_02: { component: GrDetail02 },
|
||||
GR_DETAIL_03: { component: GrDetail03 },
|
||||
GR_CONTENTS_01: { component: GrContents01 },
|
||||
FX_VIDEO_01: { component: FxVideo01 },
|
||||
FX_DOWNLOAD_01: { component: FxDownload01 },
|
||||
} as const
|
||||
|
||||
|
||||
BIN
layers/public/images/common/btn_system_arrow_next.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
BIN
layers/public/images/common/btn_system_arrow_rev.png
Normal file
|
After Width: | Height: | Size: 923 B |
@@ -1,20 +0,0 @@
|
||||
<svg width="56" height="56" viewBox="0 0 56 56" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<foreignObject x="-26" y="-28" width="108" height="108"><div xmlns="http://www.w3.org/1999/xhtml" style="backdrop-filter:blur(15px);clip-path:url(#bgblur_0_3300_15070_clip_path);height:100%;width:100%"></div></foreignObject><g filter="url(#filter0_d_3300_15070)" data-figma-bg-blur-radius="30">
|
||||
<path d="M4 26C4 12.7452 14.7452 2 28 2C41.2548 2 52 12.7452 52 26C52 39.2548 41.2548 50 28 50C14.7452 50 4 39.2548 4 26Z" fill="white" fill-opacity="0.1" shape-rendering="crispEdges"/>
|
||||
<path d="M28 2.5C40.9787 2.5 51.5 13.0213 51.5 26C51.5 38.9787 40.9787 49.5 28 49.5C15.0213 49.5 4.5 38.9787 4.5 26C4.5 13.0213 15.0213 2.5 28 2.5Z" stroke="white" stroke-opacity="0.06" shape-rendering="crispEdges"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M24.2929 18.2929C23.9024 18.6834 23.9024 19.3166 24.2929 19.7071L30.5858 26L24.2929 32.2929C23.9024 32.6834 23.9024 33.3166 24.2929 33.7071C24.6834 34.0976 25.3166 34.0976 25.7071 33.7071L32.7071 26.7071C33.0976 26.3166 33.0976 25.6834 32.7071 25.2929L25.7071 18.2929C25.3166 17.9024 24.6834 17.9024 24.2929 18.2929Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_d_3300_15070" x="-26" y="-28" width="108" height="108" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="2"/>
|
||||
<feGaussianBlur stdDeviation="2"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_3300_15070"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_3300_15070" result="shape"/>
|
||||
</filter>
|
||||
<clipPath id="bgblur_0_3300_15070_clip_path" transform="translate(26 28)"><path d="M4 26C4 12.7452 14.7452 2 28 2C41.2548 2 52 12.7452 52 26C52 39.2548 41.2548 50 28 50C14.7452 50 4 39.2548 4 26Z"/>
|
||||
</clipPath></defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.1 KiB |
@@ -1,20 +0,0 @@
|
||||
<svg width="56" height="56" viewBox="0 0 56 56" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<foreignObject x="-26" y="-28" width="108" height="108"><div xmlns="http://www.w3.org/1999/xhtml" style="backdrop-filter:blur(15px);clip-path:url(#bgblur_0_3300_15069_clip_path);height:100%;width:100%"></div></foreignObject><g filter="url(#filter0_d_3300_15069)" data-figma-bg-blur-radius="30">
|
||||
<path d="M4 26C4 12.7452 14.7452 2 28 2C41.2548 2 52 12.7452 52 26C52 39.2548 41.2548 50 28 50C14.7452 50 4 39.2548 4 26Z" fill="white" fill-opacity="0.1" shape-rendering="crispEdges"/>
|
||||
<path d="M28 2.5C40.9787 2.5 51.5 13.0213 51.5 26C51.5 38.9787 40.9787 49.5 28 49.5C15.0213 49.5 4.5 38.9787 4.5 26C4.5 13.0213 15.0213 2.5 28 2.5Z" stroke="white" stroke-opacity="0.06" shape-rendering="crispEdges"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M31.7071 18.2929C32.0976 18.6834 32.0976 19.3166 31.7071 19.7071L25.4142 26L31.7071 32.2929C32.0976 32.6834 32.0976 33.3166 31.7071 33.7071C31.3166 34.0976 30.6834 34.0976 30.2929 33.7071L23.2929 26.7071C22.9024 26.3166 22.9024 25.6834 23.2929 25.2929L30.2929 18.2929C30.6834 17.9024 31.3166 17.9024 31.7071 18.2929Z" fill="white"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_d_3300_15069" x="-26" y="-28" width="108" height="108" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="2"/>
|
||||
<feGaussianBlur stdDeviation="2"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_3300_15069"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_3300_15069" result="shape"/>
|
||||
</filter>
|
||||
<clipPath id="bgblur_0_3300_15069_clip_path" transform="translate(26 28)"><path d="M4 26C4 12.7452 14.7452 2 28 2C41.2548 2 52 12.7452 52 26C52 39.2548 41.2548 50 28 50C14.7452 50 4 39.2548 4 26Z"/>
|
||||
</clipPath></defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.1 KiB |
@@ -1,10 +0,0 @@
|
||||
<svg width="100" height="100" viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<foreignObject x="0" y="0" width="100" height="100"><div xmlns="http://www.w3.org/1999/xhtml" style="backdrop-filter:blur(5px);clip-path:url(#bgblur_0_3299_15025_clip_path);height:100%;width:100%"></div></foreignObject><g data-figma-bg-blur-radius="10">
|
||||
<circle cx="50" cy="50" r="40" fill="black" fill-opacity="0.5"/>
|
||||
<circle cx="50" cy="50" r="39.5" stroke="white" stroke-opacity="0.5"/>
|
||||
</g>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M48.4839 59.0812C46.7639 60.0629 45.079 60.9852 43.4291 61.8405C42.4954 62.3239 41.4072 61.6545 41.337 60.5612C41.2106 58.62 41.1193 56.6119 41.0632 54.5443C41.0211 53.0568 41 51.5396 41 50C41 48.4604 41.0211 46.9506 41.0632 45.4557C41.1193 43.3881 41.2106 41.38 41.337 39.4388C41.4072 38.3455 42.4954 37.6761 43.4291 38.1595C45.079 39.0149 46.7709 39.9371 48.4839 40.9188C49.7196 41.6254 50.9692 42.3617 52.2259 43.1352C53.4826 43.9087 54.7112 44.6822 55.9047 45.4631C57.5686 46.549 59.1622 47.6349 60.6857 48.7208C61.5492 49.3306 61.5492 50.6694 60.6857 51.2793C59.1622 52.3651 57.5615 53.4584 55.9047 54.5369C54.7112 55.3178 53.4826 56.0987 52.2259 56.8648C50.9692 57.6383 49.7196 58.3672 48.4839 59.0812Z" fill="white" fill-opacity="0.5"/>
|
||||
<defs>
|
||||
<clipPath id="bgblur_0_3299_15025_clip_path" transform="translate(0 0)"><circle cx="50" cy="50" r="40"/>
|
||||
</clipPath></defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
@@ -1,21 +0,0 @@
|
||||
<svg width="56" height="56" viewBox="0 0 56 56" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<foreignObject x="-26" y="-28" width="108" height="108"><div xmlns="http://www.w3.org/1999/xhtml" style="backdrop-filter:blur(15px);clip-path:url(#bgblur_0_3300_15079_clip_path);height:100%;width:100%"></div></foreignObject><g filter="url(#filter0_d_3300_15079)" data-figma-bg-blur-radius="30">
|
||||
<path d="M4 26C4 12.7452 14.7452 2 28 2C41.2548 2 52 12.7452 52 26C52 39.2548 41.2548 50 28 50C14.7452 50 4 39.2548 4 26Z" fill="black" fill-opacity="0.2" shape-rendering="crispEdges"/>
|
||||
<path d="M28 2.5C40.9787 2.5 51.5 13.0213 51.5 26C51.5 38.9787 40.9787 49.5 28 49.5C15.0213 49.5 4.5 38.9787 4.5 26C4.5 13.0213 15.0213 2.5 28 2.5Z" stroke="white" stroke-opacity="0.06" shape-rendering="crispEdges"/>
|
||||
<path d="M29 23.4142L33.2929 27.7071C33.6834 28.0976 34.3166 28.0976 34.7071 27.7071C35.0976 27.3166 35.0976 26.6834 34.7071 26.2929L28.7078 20.2936C28.5289 20.1143 28.2822 20.0026 28.0094 20C28.0063 20 28.0032 20 28 20C27.9968 20 27.9937 20 27.9906 20C27.7269 20.0025 27.4877 20.1069 27.3104 20.2758C27.3045 20.2815 27.2987 20.2871 27.2929 20.2929L21.2929 26.2929C20.9024 26.6834 20.9024 27.3166 21.2929 27.7071C21.6834 28.0976 22.3166 28.0976 22.7071 27.7071L27 23.4142L27 34C27 34.5523 27.4477 35 28 35C28.5523 35 29 34.5523 29 34L29 23.4142Z" fill="white" fill-opacity="0.5"/>
|
||||
<path d="M35.5 18C35.5 18.5523 35.0523 19 34.5 19L21.5 19C20.9477 19 20.5 18.5523 20.5 18C20.5 17.4477 20.9477 17 21.5 17L34.5 17C35.0523 17 35.5 17.4477 35.5 18Z" fill="white" fill-opacity="0.5"/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_d_3300_15079" x="-26" y="-28" width="108" height="108" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
|
||||
<feOffset dy="2"/>
|
||||
<feGaussianBlur stdDeviation="2"/>
|
||||
<feComposite in2="hardAlpha" operator="out"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.06 0"/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_3300_15079"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_3300_15079" result="shape"/>
|
||||
</filter>
|
||||
<clipPath id="bgblur_0_3300_15079_clip_path" transform="translate(26 28)"><path d="M4 26C4 12.7452 14.7452 2 28 2C41.2548 2 52 12.7452 52 26C52 39.2548 41.2548 50 28 50C14.7452 50 4 39.2548 4 26Z"/>
|
||||
</clipPath></defs>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 216 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M19.7071 5.70711C20.0976 5.31658 20.0976 4.68342 19.7071 4.29289C19.3166 3.90237 18.6834 3.90237 18.2929 4.29289L12 10.5858L5.70711 4.29289C5.31658 3.90237 4.68342 3.90237 4.29289 4.29289C3.90237 4.68342 3.90237 5.31658 4.29289 5.70711L10.5858 12L4.29289 18.2929C3.90237 18.6834 3.90237 19.3166 4.29289 19.7071C4.68342 20.0976 5.31658 20.0976 5.70711 19.7071L12 13.4142L18.2929 19.7071C18.6834 20.0976 19.3166 20.0976 19.7071 19.7071C20.0976 19.3166 20.0976 18.6834 19.7071 18.2929L13.4142 12L19.7071 5.70711Z" fill="white"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 638 B |
@@ -1,4 +0,0 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M5.45455 5C5.20351 5 5 5.20351 5 5.45455V18.5455C5 18.7965 5.20351 19 5.45455 19H18.5455C18.7965 19 19 18.7965 19 18.5455V14.9091C19 14.3568 19.4477 13.9091 20 13.9091C20.5523 13.9091 21 14.3568 21 14.9091V18.5455C21 19.9011 19.9011 21 18.5455 21H5.45455C4.09894 21 3 19.9011 3 18.5455L3 5.45455C3 4.09894 4.09894 3 5.45455 3L9.09091 3C9.64319 3 10.0909 3.44772 10.0909 4C10.0909 4.55228 9.64319 5 9.09091 5H5.45455Z" fill="#EBEBEB"/>
|
||||
<path d="M19 6.41421V9.81818C19 10.3705 19.4477 10.8182 20 10.8182C20.5523 10.8182 21 10.3705 21 9.81818V4C21 3.44772 20.5523 3 20 3H14.1818C13.6295 3 13.1818 3.44772 13.1818 4C13.1818 4.55228 13.6295 5 14.1818 5L17.5858 5L10.9292 11.6565C10.5387 12.0471 10.5387 12.6802 10.9292 13.0708C11.3198 13.4613 11.9529 13.4613 12.3435 13.0708L19 6.41421Z" fill="#EBEBEB"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 912 B |
@@ -1,4 +0,0 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M10.75 3.25L10.75 12.2322L6.88391 8.36611C6.39576 7.87796 5.6043 7.87796 5.11615 8.36611C4.62799 8.85427 4.62799 9.64573 5.11615 10.1339L11.1161 16.1339C11.3506 16.3683 11.6685 16.5 12 16.5C12.3316 16.5 12.6495 16.3683 12.8839 16.1339L18.8839 10.1339C19.3721 9.64573 19.3721 8.85427 18.8839 8.36611C18.3958 7.87796 17.6043 7.87796 17.1161 8.36611L13.25 12.2322L13.25 3.25C13.25 2.55964 12.6904 2 12 2C11.3097 2 10.75 2.55964 10.75 3.25Z" fill="#EBEBEB"/>
|
||||
<path d="M20 21C20.6904 21 21.25 20.4404 21.25 19.75L21.25 17.75C21.25 17.0596 20.6904 16.5 20 16.5C19.3097 16.5 18.75 17.0596 18.75 17.75L18.75 18.5L5.25003 18.5L5.25003 17.75C5.25003 17.0596 4.69039 16.5 4.00003 16.5C3.30967 16.5 2.75003 17.0596 2.75003 17.75L2.75003 19.75C2.75003 20.4404 3.30967 21 4.00003 21L20 21Z" fill="#EBEBEB"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 906 B |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
@@ -1,3 +0,0 @@
|
||||
<svg width="32" height="33" viewBox="0 0 32 33" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M26.2768 8.10947C26.7975 7.58877 26.7975 6.74455 26.2768 6.22385C25.7561 5.70315 24.9119 5.70315 24.3912 6.22385L16.0007 14.6144L7.61013 6.22385C7.08943 5.70315 6.24521 5.70315 5.72451 6.22385C5.20381 6.74455 5.20381 7.58877 5.72451 8.10947L14.115 16.5L5.72451 24.8905C5.20381 25.4112 5.20381 26.2554 5.72451 26.7761C6.24521 27.2968 7.08943 27.2968 7.61013 26.7761L16.0007 18.3856L24.3912 26.7761C24.9119 27.2968 25.7561 27.2968 26.2768 26.7761C26.7975 26.2554 26.7975 25.4112 26.2768 24.8905L17.8863 16.5L26.2768 8.10947Z" fill="#EBEBEB"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 653 B |
265
layers/templates/FxVideo01/index.vue
Normal file
@@ -0,0 +1,265 @@
|
||||
<script setup lang="ts">
|
||||
import { SplideSlide } from '@splidejs/vue-splide'
|
||||
import {
|
||||
getComponentGroup,
|
||||
getComponentContainer,
|
||||
} from '#layers/utils/dataUtil'
|
||||
import { getYouTubeThumbnail } from '#layers/utils/youtubeUtil'
|
||||
import { formatTimestamp } from '#layers/utils/formatUtil'
|
||||
import type { Splide as SplideType } from '@splidejs/splide'
|
||||
import type { PageDataTemplateComponents } from '#layers/types/api/pageData'
|
||||
import type { OperateGroupItem } from '#layers/types/api/resourcesData'
|
||||
|
||||
interface Props {
|
||||
components: PageDataTemplateComponents
|
||||
pageVerTmplSeq: number
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
|
||||
const pageDataStore = usePageDataStore()
|
||||
const breakpoints = useResponsiveBreakpoints()
|
||||
const { getOperateResourcesData } = useResourcesData()
|
||||
|
||||
const { pageData } = storeToRefs(pageDataStore)
|
||||
|
||||
// Configuration
|
||||
const runtimeConfig = useRuntimeConfig()
|
||||
const dataResourcesUrl = runtimeConfig.public.dataResourcesUrl
|
||||
const multilingualFileName = 'test_homepage_brand_video.json'
|
||||
|
||||
// Multilingual
|
||||
const resultGetMultilingual = await useGetMultilingual({
|
||||
baseApiUrl: dataResourcesUrl,
|
||||
fileName: multilingualFileName,
|
||||
})
|
||||
|
||||
const { tm, locale } = useI18n({
|
||||
useScope: 'local',
|
||||
messages: Object(resultGetMultilingual?.value?.multilingual),
|
||||
})
|
||||
|
||||
const backgroundData = computed(() =>
|
||||
getComponentGroup(props.components, 'background')
|
||||
)
|
||||
const officialUrlData = computed(
|
||||
() => getComponentGroup(props.components, 'officialUrl')?.display?.text ?? ''
|
||||
)
|
||||
|
||||
const { data: slideData } = await useAsyncData(
|
||||
`fx-video-01-resources-${pageData.value?.page_seq}-${pageData.value?.page_ver}-${props.pageVerTmplSeq}`,
|
||||
async () => {
|
||||
if (!pageData.value?.page_seq || !pageData.value?.page_ver) {
|
||||
return []
|
||||
}
|
||||
|
||||
const operateGroupList = await getOperateResourcesData({
|
||||
pageSeq: pageData.value.page_seq,
|
||||
pageVer: pageData.value.page_ver,
|
||||
pageVerTmplSeq: props.pageVerTmplSeq,
|
||||
langCode: locale.value,
|
||||
})
|
||||
|
||||
const mediaList = getComponentContainer(operateGroupList, 'mediaList', {
|
||||
hasGroup: true,
|
||||
}) as OperateGroupItem[]
|
||||
|
||||
return mediaList ?? []
|
||||
},
|
||||
{
|
||||
default: () => [],
|
||||
server: false,
|
||||
}
|
||||
)
|
||||
|
||||
const VIDEO_TYPE = {
|
||||
RECOMMENDED: 1,
|
||||
RECENT: 0,
|
||||
} as const
|
||||
const ITEMS_PER_PAGE = {
|
||||
MOBILE: 8,
|
||||
DESKTOP: 12,
|
||||
} as const
|
||||
const currentRecommendedIndex = ref(1)
|
||||
const currentRecentPage = ref(1)
|
||||
|
||||
// 추천 영상 (option01 === 1)
|
||||
const recommendedVideos = computed(
|
||||
() =>
|
||||
slideData.value?.filter(item => item.option01 === VIDEO_TYPE.RECOMMENDED) ||
|
||||
[]
|
||||
)
|
||||
// 최근 영상 (option01 === 0)
|
||||
const recentVideos = computed(
|
||||
() =>
|
||||
slideData.value?.filter(item => item.option01 === VIDEO_TYPE.RECENT) || []
|
||||
)
|
||||
// 페이지당 보여줄 개수 (PC: 12개, Mobile: 8개)
|
||||
const itemsPerPage = computed(() =>
|
||||
breakpoints.value.isMobile ? ITEMS_PER_PAGE.MOBILE : ITEMS_PER_PAGE.DESKTOP
|
||||
)
|
||||
const visibleVideos = computed(() => {
|
||||
const endIndex = currentRecentPage.value * itemsPerPage.value
|
||||
return recentVideos.value.slice(0, endIndex)
|
||||
})
|
||||
const hasMore = computed(
|
||||
() => visibleVideos.value.length < recentVideos.value.length
|
||||
)
|
||||
|
||||
const handleSplideMove = (_splide: SplideType, newIndex: number) => {
|
||||
currentRecommendedIndex.value = newIndex + 1
|
||||
}
|
||||
|
||||
const handleLoadMoreRecent = () => {
|
||||
if (hasMore.value) {
|
||||
currentRecentPage.value++
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<WidgetsFixMainTitle
|
||||
:title="tm('Video_Page_Title')"
|
||||
:resources-data="backgroundData"
|
||||
/>
|
||||
|
||||
<div class="section-container static">
|
||||
<section class="section-static">
|
||||
<WidgetsFixSubTitle
|
||||
:title="tm('Video_Section_Recommendation_Title')"
|
||||
:description="tm('Video_Page_Link')"
|
||||
:link="officialUrlData"
|
||||
/>
|
||||
<div
|
||||
class="relative content-static bg-[#fff] rounded-[12px] md:rounded-[16px]"
|
||||
>
|
||||
<BlocksSlideFade
|
||||
:pagination="false"
|
||||
:drag="false"
|
||||
@move="handleSplideMove"
|
||||
>
|
||||
<template
|
||||
v-for="(item, index) in recommendedVideos"
|
||||
:key="`recommended-${item.url}-${index}`"
|
||||
>
|
||||
<SplideSlide>
|
||||
<div
|
||||
class="overflow-hidden aspect-[16/9] flex-shrink-0 w-full rounded-[4px] sm:w-[60.3%] sm:rounded-[8px] md:w-[56%] lg:w-[710px] lg:rounded-[12px]"
|
||||
>
|
||||
<img
|
||||
:src="getYouTubeThumbnail(item.url)"
|
||||
:alt="item.title || 'Video thumbnail'"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
class="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
class="w-full mx-[8px] pb-[20px] border-b border-[rgba(0,0,0,0.08)] sm:mx-[0] sm:pt-[12px] sm:pr-[16px] sm:pb-[0] sm:border-none md:pt-[20px] md:pr-[28px] lg:pt-[40px] lg:pr-[48px]"
|
||||
>
|
||||
<h4
|
||||
class="h-[52px] text-[18px] font-[700] leading-[26px] tracking-[-0.54px] text-[#1F1F1F] line-clamp-2 sm:h-[auto] sm:text-[20px] sm:leading-[30px] sm:tracking-[-0.6px] sm:line-clamp-3 md:text-[32px] md:leading-[44px] md:tracking-[-0.96px]"
|
||||
>
|
||||
{{ item.title || '' }}
|
||||
</h4>
|
||||
<p
|
||||
class="mt-2 text-[14px] leading-[24px] tracking-[-0.42px] text-[#999] sm:mt-3.5 md:mt-4 md:text-[18px] md:font-[500] md:leading-[26px] md:tracking-[-0.54px] lg:mt-5 lg:text-[20px] lg:leading-[30px] lg:tracking-[-0.6px]"
|
||||
>
|
||||
{{ formatTimestamp(item.reg_dt, 'YYYY.MM.DD') }}
|
||||
</p>
|
||||
</div>
|
||||
</SplideSlide>
|
||||
</template>
|
||||
</BlocksSlideFade>
|
||||
<div class="splide-pagination">
|
||||
<span class="font-[700] text-[#1F1F1F]">
|
||||
{{ currentRecommendedIndex }}
|
||||
</span>
|
||||
/
|
||||
<span>{{ recommendedVideos.length }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section class="section-static">
|
||||
<WidgetsFixSubTitle :title="tm('Video_Section_Recent_Title')" />
|
||||
<div class="content-static">
|
||||
<ul class="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3">
|
||||
<li
|
||||
v-for="(item, index) in visibleVideos"
|
||||
:key="`recent-${item.url}-${index}`"
|
||||
class="p-3 rounded-[12px] bg-white md:p-4 md:rounded-[16px] lg:p-5"
|
||||
>
|
||||
<div
|
||||
class="overflow-hidden aspect-[16/9] w-full rounded-[4px] sm:rounded-[8px] lg:rounded-[12px]"
|
||||
>
|
||||
<img
|
||||
:src="getYouTubeThumbnail(item.url)"
|
||||
:alt="item.title || 'Video thumbnail'"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
class="w-full h-full object-cover"
|
||||
/>
|
||||
</div>
|
||||
<div class="p-2 pt-5 md:p-3 md:pt-5">
|
||||
<h4
|
||||
class="h-[48px] text-[16px] font-[700] leading-[24px] tracking-[-0.48px] text-[#1F1F1F] line-clamp-2 md:h-[52px] md:text-[18px] md:leading-[26px] md:tracking-[-0.54px]"
|
||||
>
|
||||
{{ item.title || '' }}
|
||||
</h4>
|
||||
<p
|
||||
class="mt-2 text-[14px] leading-[24px] tracking-[-0.42px] text-[#999] md:text-[16px] md:leading-[26px] md:tracking-[-0.48px]"
|
||||
>
|
||||
{{ formatTimestamp(item.reg_dt, 'YYYY.MM.DD') }}
|
||||
</p>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div v-if="hasMore" class="mt-[40px] flex justify-center md:mt-[80px]">
|
||||
<AtomsButton
|
||||
type="action"
|
||||
button-size="size-small md:size-medium"
|
||||
background-color="#383838"
|
||||
text-color="#FFFFFF"
|
||||
@click="handleLoadMoreRecent"
|
||||
>
|
||||
{{ tm('Text_More') }}
|
||||
</AtomsButton>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.splide {
|
||||
@apply pb-[68px] sm:pb-[0];
|
||||
}
|
||||
.splide:deep(.splide-arrows) {
|
||||
@apply block;
|
||||
}
|
||||
.splide:deep(.splide-arrows) .splide-arrow {
|
||||
@apply block top-[unset] bottom-[20px] translate-y-0 w-[40px] h-[40px] bg-cover bg-center bg-no-repeat
|
||||
sm:bottom-[24px] md:bottom-[36px] md:w-[48px] md:h-[48px] lg:bottom-[60px];
|
||||
}
|
||||
.splide:deep(.splide-arrows) .arrow-prev {
|
||||
@apply left-[20px] bg-[image:url('/images/common/btn_system_arrow_rev.png')]
|
||||
sm:left-[calc(60.3%+21px)]
|
||||
md:left-[calc(56%+39px)]
|
||||
lg:left-[790px];
|
||||
}
|
||||
.splide:deep(.splide-arrows) .arrow-next {
|
||||
@apply right-[20px] bg-[image:url('/images/common/btn_system_arrow_next.png')]
|
||||
sm:right-[28px]
|
||||
md:right-[unset] md:left-[calc(56%+99px)]
|
||||
lg:left-[850px];
|
||||
}
|
||||
.splide__slide {
|
||||
@apply flex flex-col p-3 gap-4 sm:flex-row sm:gap-6 md:gap-10 md:p-4 lg:gap-[60px] lg:p-5;
|
||||
}
|
||||
.splide-pagination {
|
||||
@apply absolute bottom-[28px] left-[80px] right-[80px] text-center font-[500] text-[16px] leading-[24px] tracking-[-0.48px] text-[#999]
|
||||
sm:bottom-[32px] sm:left-[calc(60.3%+73px)] sm:right-[80px]
|
||||
md:bottom-[47px] md:left-[calc(56%+167px)] md:right-[unset] md:text-[18px] md:leading-[26px] md:tracking-[-0.54px]
|
||||
lg:bottom-[71px] lg:left-[918px];
|
||||
}
|
||||
</style>
|
||||