/** * 통계 수치에 한국어 천 단위 구분을 적용한다. * @param {unknown} value - 표시할 수치 * @returns {string} 구분 기호가 있는 숫자 */ export const formatAnalyticsCount = (value) => { const number = Number(value || 0) return new Intl.NumberFormat('ko-KR').format(Number.isFinite(number) ? number : 0) } /** * 현재 접속 시간을 최대 두 단위로 짧게 표시한다. * @param {number} seconds - 접속 시간(초) * @returns {string} 일·시간·분·초 표시 */ export const formatRealtimeDuration = (seconds) => { const input = Number(seconds) const value = Number.isFinite(input) ? Math.max(0, Math.floor(input)) : 0 if (value >= 86400) { const hours = Math.floor(value % 86400 / 3600) return `${formatAnalyticsCount(Math.floor(value / 86400))}일${hours ? ` ${hours}시간` : ''}` } if (value >= 3600) { const minutes = Math.floor(value % 3600 / 60) return `${formatAnalyticsCount(Math.floor(value / 3600))}시간${minutes ? ` ${minutes}분` : ''}` } const minutes = Math.floor(value / 60) const remainder = value % 60 return minutes ? `${minutes}분${remainder ? ` ${remainder}초` : ''}` : `${remainder}초` } /** * 접속 페이지의 표시 제목을 반환한다. * @param {Object} page - 활성 페이지 * @returns {string} 페이지 제목 */ export const getActivePageTitle = (page) => page.postTitle || page.pageTitle || (page.path === '/' ? '홈' : page.path) || '알 수 없음' /** * 접속 페이지의 사이트 내부 공개 경로를 반환한다. * @param {Object} page - 활성 페이지 * @returns {string} 바로가기 경로 */ export const getActivePageHref = (page) => { if (page.postSlug) return `/post/${encodeURIComponent(page.postSlug)}` if (page.pageSlug) return `/pages/${encodeURIComponent(page.pageSlug)}` const path = String(page.path || '').trim() return path.startsWith('/') && !path.startsWith('//') && !path.includes('\\') && !/^\/admin(?:[/?#]|$)/.test(path) ? path : '' } /** * 열린 페이지를 최근 확인 순으로 정렬하고 같은 경로를 중복 제거한다. * @param {Object} session - 묶인 접속자 * @returns {Array} 최신 페이지부터의 고유 목록 */ export const getRealtimePages = (session) => { const pages = session.pages?.length ? session.pages : [session] const ordered = [...pages].sort((left, right) => (Date.parse(right.lastSeenAt) || 0) - (Date.parse(left.lastSeenAt) || 0)) const seen = new Set() return ordered.filter((page) => { const key = getActivePageHref(page) || page.path || page.key || '' if (seen.has(key)) return false seen.add(key) return true }) }