/** * 데이터 유틸리티 함수 * @description gameData, pageData 처리에 필요한 유틸리티 함수를 제공합니다. */ import type { PageDataValue, PageDataResourceContainer, PageDataTemplateComponents, PageDataTemplateComponentSet, PageDataResourceGroupType, } from '#layers/types/api/pageData' import type { OperateComponents, OperateGroupItem, } from '#layers/types/api/resourcesData' /** * 페이지 데이터를 기반으로 레이아웃 타입을 결정합니다. * @param pageData 페이지 데이터 * @returns 레이아웃 타입 ('default' | 'promotion') */ export const getLayoutType = ( pageData: PageDataValue | null ): 'default' | 'promotion' => { return pageData?.page_type === 1 ? 'default' : 'promotion' } /** * 이미지 타입인지 확인합니다. * @param type 리소스 그룹 타입 * @returns 이미지 타입 여부 */ export const isTypeImage = (type: PageDataResourceGroupType): boolean => { return ( type === 'IMG_COMM' || type === 'IMG_LANG' || type === 'IMG_COMM_GLOBAL' ) } /** * 비디오 타입인지 확인합니다. * @param type 리소스 그룹 타입 * @returns 비디오 타입 여부 */ export const isTypeVideo = (type: PageDataResourceGroupType): boolean => { return type === 'VID' } /** * 텍스트 타입인지 확인합니다. * @param type 리소스 그룹 타입 * @returns 텍스트 타입 여부 */ export const isTypeText = (type: PageDataResourceGroupType): boolean => { return type === 'TXT' } /** * 버튼 타입인지 확인합니다. * @param type 리소스 그룹 타입 * @returns 버튼 타입 여부 */ export const isTypeButton = (type: PageDataResourceGroupType): boolean => { return type === 'BTN' } /** * 컴포넌트 컨테이너를 반환합니다. * @param components props.components * @param componentName 컴포넌트 이름 * @param options 옵션 (maxLength: 최대 길이) * @returns 컴포넌트 컨테이너 */ export const getComponentContainer = ( components: PageDataTemplateComponents | OperateComponents, componentName: string, { maxLength }: { maxLength?: number } = {} ) => { if (!components) return [] const container = components[componentName] || [] return maxLength ? container.slice(0, maxLength) : container } /** * 컴포넌트 그룹에 데이터가 존재하는지 확인합니다. * @param components props.components 또는 group 객체 * @param componentName 컴포넌트 이름 * @returns 데이터 존재 여부 */ export const hasComponentGroup = ( components: PageDataTemplateComponents, componentName: string ): boolean => { if (!components) return false const component = components[componentName] as PageDataResourceContainer return component?.groups && component.groups.length > 0 } /** * 컴포넌트 그룹의 첫 번째 데이터를 반환합니다. * @param components props.components 또는 group 객체 * @param componentName 컴포넌트 이름 * @returns 첫 번째 그룹 데이터 또는 null */ export const getComponentGroup = ( components: PageDataTemplateComponents | OperateComponents, componentName: string ) => { if (!components) return null return components[componentName]?.groups?.[0] || null } /** * 컴포넌트 그룹의 모든 데이터를 반환합니다. * @param components props.components 또는 group 객체 * @param componentName 컴포넌트 이름 * @returns 그룹 배열 데이터 */ export const getComponentGroupAry = ( components: PageDataTemplateComponents | OperateComponents, componentName: string ) => { if (!components) return [] return components[componentName]?.groups || [] } /** * 슬라이드 데이터를 최소 개수로 보장합니다. (페이지 데이터용) * @param components 원본 데이터 배열 또는 객체 * @param minCount 최소 보장할 개수 (기본값: 3) * @returns 최소 개수가 보장된 데이터 배열 */ export const ensureMinimumSlideData = ( components: PageDataTemplateComponents, minCount: number = 4 ): PageDataTemplateComponentSet[] => { if (!components) return [] const arrayData = Array.isArray(components.group_sets) ? components.group_sets : [] // 빈 배열이거나 이미 최소 개수를 만족하면 그대로 반환 if (arrayData.length <= 1 || arrayData.length >= minCount) { return arrayData } // 최소 개수를 보장하기 위해 데이터 반복 const repeatTimes = Math.ceil(minCount / arrayData.length) return Array(repeatTimes).fill(arrayData).flat() } /** * 슬라이드 데이터를 최소 개수로 보장합니다. (운영 그룹용) * @param data 원본 데이터 배열 * @param minCount 최소 보장할 개수 (기본값: 3) * @returns 최소 개수가 보장된 데이터 배열 */ export const ensureMinimumSlideOperateData = ( data: OperateGroupItem[], minCount: number = 4 ): OperateGroupItem[] => { // 빈 배열이거나 이미 최소 개수를 만족하면 그대로 반환 if (data.length <= 1 || data.length >= minCount) { return data } // 최소 개수를 보장하기 위해 데이터 반복 const repeatTimes = Math.ceil(minCount / data.length) return Array(repeatTimes).fill(data).flat() } /** * 현재 시간의 타임스탬프를 반환합니다. * @param unit 단위 ('ms' | 's') - 밀리초 또는 초 * @returns 타임스탬프 */ export const getCurrentTimestamp = (unit: 'ms' | 's' = 'ms'): number => { const now = Date.now() return unit === 's' ? Math.floor(now / 1000) : now }