67 lines
2.6 KiB
JavaScript
67 lines
2.6 KiB
JavaScript
/**
|
|
* 통계 수치에 한국어 천 단위 구분을 적용한다.
|
|
* @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<Object>} 최신 페이지부터의 고유 목록
|
|
*/
|
|
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
|
|
})
|
|
}
|