Files
web-temp/app/pages/inspection/index.vue
2025-10-29 20:56:58 +09:00

326 lines
9.6 KiB
Vue

<template>
<section class="inspection-section">
<!-- 로고 -->
<div v-if="isClient" class="inspection-logo">
<img :src="logoImgUrl" alt="logo" class="w-full h-full object-contain" />
</div>
<div class="inspection-content">
<!-- 점검 메시지 -->
<h1 class="inspection-title">
<template v-if="isClient && webInspectionData?.inspection_title1">
{{ webInspectionData.inspection_title1 }}
</template>
<template v-else>
{{ tm('Inspection_Now_Maintenance') }}
</template>
</h1>
<div class="inspection-cards">
<!-- 점검 시간 카드 -->
<div v-if="isClient && webInspectionData" class="inspection-card inspection-time-card">
<h2 class="card-title">{{ tm('Inspection_Maintenance_Time') }}</h2>
<div class="inspection-time">
<div class="time-row">
{{ getLocaleTimezone(locale) }}
</div>
<div class="time-row">
{{ getLocaleTimezone('en', 'US') }}
</div>
<div class="time-row">
{{ getLocaleTimezone('zh-tw', '') }}
</div>
<div class="time-row">
{{ getLocaleTimezone('ja', '') }}
</div>
</div>
</div>
<!-- 온스토브 & 다운로드 카드 -->
<div class="inspection-bottom-cards">
<!-- 온스토브 카드 -->
<div class="inspection-card inspection-stove-card">
<h3 v-dompurify-html="tm('Inspection_Game_During_Maintenance') || '홈페이지 점검 중에도 게임과 공식 커뮤니티는 그대로 이용할 수 있어요!'" class="card-title"></h3>
<div class="button-group">
<a
:href="communityUrl"
target="_blank"
rel="noopener noreferrer"
class="inspection-btn inspection-btn-outline"
>
<span>{{ tm('Inspection_Community_Btn') || '공식 커뮤니티' }}</span>
<AtomsIconsLongArrowRightLine :size="16" color="#1F1F1F" />
</a>
<button
class="inspection-btn inspection-btn-primary"
@click="handleGameStart"
>
<span>{{ tm('game_start_btn') || '게임 실행' }}</span>
<AtomsIconsLongArrowRightLine :size="16" color="#FFFFFF" />
</button>
</div>
</div>
<!-- 다운로드 카드 -->
<div v-if="isClient" class="inspection-card inspection-download-card">
<h3 class="card-title">
{{ tm('Inspection_Txt_Download') || '게임 다운로드' }}
</h3>
<div v-if="webInspectionData?.inspection_content" class="inspection-content-text">
{{ webInspectionData.inspection_content }}
</div>
</div>
</div>
</div>
</div>
</section>
</template>
<script setup lang="ts">
import {globalDateFormat} from '@seed-next/date';
import { formatDateOffset } from '#layers/utils/dataUtil'
import { useCheckGameStart } from '#layers/composables/useGameStart'
const config = useRuntimeConfig()
const rootPath = config.public.staticUrl
const runType = config.public.runType
const translationApi = `${rootPath}/${runType}/test`
const isClient = import.meta.client
const inspectionStore = useInspectionStore()
const { webInspectionData } = storeToRefs(inspectionStore)
const resultGetMultilingual = await useGetMultilingual({
baseApiUrl: translationApi,
fileName: 'test_common_inspection.json'
})
const { tm, locale } = useI18n({
useScope: 'local',
messages: Object(resultGetMultilingual.value.multilingual)
})
console.log("🚀 ~ globalDateFormat(new Date(webInspectionData.value?.ts_start_date || 0), 'ko'):", )
// locale에 따라 뒤에 KST 또는 UTC 추가 ko, en, zh-tw, ja
// ko: (KST)
// en: (UTC)
// zh-tw: 台灣時間 (KST)
// ja: (JST)
// 나머지: (KST)
const getLocaleTimezone = (localeType: string, region) => {
const tsStartDate = webInspectionData.value?.start_date || 0
const tsEndDate = webInspectionData.value?.end_date || 0
switch (localeType) {
case 'ko':
return `${globalDateFormat(new Date(tsStartDate), localeType, region || '', {useFullDate: true})} ~ ${globalDateFormat(new Date(tsEndDate), localeType, region || 'KR', {useFullDate: true})} (KST)`
case 'en':
return `${globalDateFormat(new Date(tsStartDate), localeType, region || '', {useFullDate: true})} ~ ${globalDateFormat(new Date(tsEndDate), localeType, region || '', {useFullDate: true})} (UTC)`
case 'zh-tw':
return `${globalDateFormat(new Date(tsStartDate), localeType, region || '', {useFullDate: true})} ~ ${globalDateFormat(new Date(tsEndDate), localeType, region || '', {useFullDate: true})} (台灣時間)`
case 'ja':
return `${globalDateFormat(new Date(tsStartDate), localeType, region || '', {useFullDate: true})} ~ ${globalDateFormat(new Date(tsEndDate), localeType, region || '', {useFullDate: true})} (JST)`
default:
return `${globalDateFormat(new Date(tsStartDate), localeType, region || '', {useFullDate: true})} ~ ${globalDateFormat(new Date(tsEndDate), localeType, region || '', {useFullDate: true})} (KST)`
}
}
// 날짜 포맷팅 함수 (CSR에서만 실행)
const formatInspectionTime = (timestamp: number, isKST: boolean): string => {
if (!import.meta.client || !timestamp) return ''
const lang = locale.value || 'ko'
const formatted = formatDateOffset({
ts: timestamp,
lang: isKST ? lang : 'en',
useSeconds: true,
useTimezone: true
})
// formatDateOffset의 결과를 YYYY.MM.DD, HH:MM:SS 형식으로 변환
// KST의 경우: YYYY-MM-DD HH:MM:SS (KST) -> YYYY.MM.DD, HH:MM:SS (KST)
// UTC의 경우: MM/DD/YYYY HH:MM:SS (UTC) -> YYYY.MM.DD, HH:MM:SS (UTC)
if (isKST) {
return formatted.replace(/-/g, '.').replace(' ', ', ')
} else {
// UTC 형식 변환: MM/DD/YYYY HH:MM:SS (UTC) -> YYYY.MM.DD, HH:MM:SS (UTC)
const parts = formatted.match(/(\d{2})\/(\d{2})\/(\d{4}) (.+)/)
if (parts) {
return `${parts[3]}.${parts[1]}.${parts[2]}, ${parts[4]}`
}
return formatted
}
}
const logoImgUrl = computed(() => {
// CSR에서만 처리
if (!import.meta.client || !webInspectionData.value) return ''
const currentLocale = locale.value || 'ko'
const localeData = (webInspectionData.value as any)?.[currentLocale]
if (localeData?.img_json?.bi_large) {
return localeData.img_json.bi_large
}
return webInspectionData.value.back_ground_image_url || ''
})
// 커뮤니티 URL
const communityUrl = computed(() => {
return '#'
})
// 게임 시작
const { validateLauncher } = useCheckGameStart()
const handleGameStart = () => {
validateLauncher()
}
definePageMeta({
middleware: ['inspection'],
layout: 'inspection',
showLoading: false
})
</script>
<style scoped>
.inspection-section {
@apply flex flex-col items-center gap-8 px-10 py-[120px] pb-[200px] min-h-screen;
background-color: #F0F0F0;
}
.inspection-logo {
@apply w-[944px] h-[150px] flex-shrink-0;
}
.inspection-logo img {
@apply w-full h-full object-contain;
}
.inspection-content {
@apply flex flex-col items-center gap-10 w-full max-w-[944px];
}
.inspection-title {
@apply text-center text-[24px] leading-[34px] font-bold tracking-[-0.72px] text-[#1F1F1F];
font-family: 'Spoqa Han Sans Neo', sans-serif;
}
.inspection-cards {
@apply flex flex-col gap-5 w-full;
}
.inspection-card {
@apply bg-white rounded-2xl p-8;
}
.inspection-time-card {
@apply flex flex-col items-center gap-4;
width: 944px;
min-height: 162px;
}
.card-title {
@apply text-center text-[20px] leading-[30px] font-bold tracking-[-0.6px] text-[#1F1F1F];
font-family: 'Spoqa Han Sans Neo', sans-serif;
}
.inspection-time {
@apply flex flex-col items-center gap-2;
}
.time-row {
@apply text-center text-[16px] leading-[26px] font-medium tracking-[-0.48px] text-[#1F1F1F];
font-family: 'Spoqa Han Sans Neo', sans-serif;
}
.inspection-bottom-cards {
@apply flex flex-row gap-5 w-full;
}
.inspection-stove-card,
.inspection-download-card {
@apply flex flex-col justify-between gap-4 flex-1;
}
.inspection-stove-card .card-title {
@apply text-left text-[18px] leading-[26px] font-bold tracking-[-0.54px] text-[#1F1F1F];
}
.inspection-download-card .card-title {
@apply text-left text-[18px] leading-[26px] font-bold tracking-[-0.54px] text-[#1F1F1F];
}
.inspection-content-text {
@apply text-left text-[16px] leading-[26px] font-medium tracking-[-0.48px] text-[#1F1F1F];
font-family: 'Spoqa Han Sans Neo', sans-serif;
white-space: pre-line;
}
.button-group {
@apply flex flex-row gap-3 w-full;
}
.inspection-btn {
@apply flex items-center justify-center gap-1 px-10 h-12 rounded-lg border border-black/10;
font-family: 'Spoqa Han Sans Neo', sans-serif;
font-size: 14px;
line-height: 20px;
font-weight: 500;
letter-spacing: -0.42px;
cursor: pointer;
transition: all 0.2s;
flex: 1;
}
.inspection-btn span {
@apply text-[#1F1F1F];
}
.inspection-btn-outline {
@apply bg-white;
}
.inspection-btn-outline:hover {
@apply bg-gray-50;
}
.inspection-btn-primary {
@apply bg-[#C7AE8B] border-[#C7AE8B];
}
.inspection-btn-primary span {
@apply text-white;
}
.inspection-btn-primary:hover {
@apply bg-[#B89D7A];
}
@media (max-width: 1024px) {
.inspection-section {
@apply px-5 py-20 pb-32;
}
.inspection-logo {
@apply w-full max-w-[944px];
}
.inspection-time-card {
@apply w-full;
}
.inspection-bottom-cards {
@apply flex-col;
}
.inspection-stove-card,
.inspection-download-card {
@apply w-full;
}
}
</style>