/** * 어나운스 바 배경색 프리셋 * @type {ReadonlyArray<{ id: string, label: string, value: string, textColor: string }>} */ export const ANNOUNCEMENT_BACKGROUND_PRESETS = [ { id: 'black', label: '검정', value: '#15171a', textColor: '#ffffff' }, { id: 'white', label: '흰색', value: '#ffffff', textColor: '#15171a' }, { id: 'accent', label: '브랜드', value: '#ff4f2e', textColor: '#ffffff' } ] /** @type {string} 기본 어나운스 바 배경색 */ export const DEFAULT_ANNOUNCEMENT_BACKGROUND_COLOR = '#15171a' /** * 어나운스 바 배경색이 허용 프리셋인지 확인한다. * @param {string} value - hex 색상 * @returns {boolean} 허용 여부 */ export const isValidAnnouncementBackgroundColor = (value) => { const normalized = (value || '').trim().toLowerCase() return ANNOUNCEMENT_BACKGROUND_PRESETS.some((preset) => preset.value.toLowerCase() === normalized) } /** * 어나운스 바 배경색에 맞는 전경색을 반환한다. * @param {string} backgroundColor - hex 배경색 * @returns {string} 전경 hex 색상 */ export const getAnnouncementBarTextColor = (backgroundColor) => { const normalized = (backgroundColor || '').trim().toLowerCase() const preset = ANNOUNCEMENT_BACKGROUND_PRESETS.find((item) => item.value.toLowerCase() === normalized) if (preset) { return preset.textColor } return '#ffffff' } /** * 어나운스 링크를 정리한다. 빈 값은 링크 미사용. * @param {string} url - 입력 URL * @returns {string} 정리된 URL 또는 빈 문자열 */ export const normalizeAnnouncementUrl = (url) => { const trimmed = (url || '').trim() if (!trimmed) { return '' } if (trimmed.startsWith('/')) { return trimmed } try { const parsed = new URL(trimmed) if (parsed.protocol === 'http:' || parsed.protocol === 'https:') { return parsed.toString() } } catch { return '' } return '' } /** @type {string} 어나운스 바 7일 숨김 localStorage 키 */ export const ANNOUNCEMENT_DISMISS_STORAGE_KEY = 'SITE_ANNOUNCEMENT_DISMISS' /** @type {string} 어나운스 바 이번 방문(세션) 숨김 sessionStorage 키 */ export const ANNOUNCEMENT_SESSION_DISMISS_KEY = 'SITE_ANNOUNCEMENT_SESSION_DISMISS' /** @type {number} 기본 숨김 일수 */ export const ANNOUNCEMENT_SNOOZE_DAYS = 7 /** * 어나운스 바 닫기 식별 키(설정 저장 시각) * @param {{ updatedAt?: string | null }} settings - 사이트 설정 * @returns {string} 식별 키 */ export const getAnnouncementDismissKey = (settings) => settings?.updatedAt || '' /** * 어나운스 바가 숨김 상태인지 확인한다. * @param {{ updatedAt?: string | null }} settings - 사이트 설정 * @returns {boolean} 숨김 여부 */ export const isAnnouncementDismissed = (settings) => { if (!import.meta.client) { return false } const key = getAnnouncementDismissKey(settings) if (!key) { return false } const sessionDismissed = sessionStorage.getItem(ANNOUNCEMENT_SESSION_DISMISS_KEY) if (sessionDismissed === key) { return true } const raw = localStorage.getItem(ANNOUNCEMENT_DISMISS_STORAGE_KEY) if (!raw) { return false } try { const parsed = JSON.parse(raw) if (parsed?.key !== key) { return false } if (typeof parsed.until === 'number' && Date.now() < parsed.until) { return true } if (parsed.until == null && parsed.key === key) { return true } } catch { return false } return false } /** * 이번 브라우저 방문(세션) 동안만 어나운스 바를 숨긴다. * @param {{ updatedAt?: string | null }} settings - 사이트 설정 * @returns {void} */ export const dismissAnnouncementForSession = (settings) => { if (!import.meta.client) { return } const key = getAnnouncementDismissKey(settings) if (!key) { return } sessionStorage.setItem(ANNOUNCEMENT_SESSION_DISMISS_KEY, key) } /** * 지정 일수 동안 어나운스 바를 숨긴다. * @param {{ updatedAt?: string | null }} settings - 사이트 설정 * @param {number} [days=ANNOUNCEMENT_SNOOZE_DAYS] - 숨김 일수 * @returns {void} */ export const dismissAnnouncementForDays = (settings, days = ANNOUNCEMENT_SNOOZE_DAYS) => { if (!import.meta.client) { return } const key = getAnnouncementDismissKey(settings) if (!key) { return } const until = Date.now() + days * 24 * 60 * 60 * 1000 localStorage.setItem(ANNOUNCEMENT_DISMISS_STORAGE_KEY, JSON.stringify({ key, until })) sessionStorage.setItem(ANNOUNCEMENT_SESSION_DISMISS_KEY, key) }