import { onUnmounted, ref } from 'vue' const TOAST_AUTO_HIDE_MS = 4000 /** * 브라우저 타이머 API를 안전하게 사용한다. * @returns {typeof window | null} window 객체 */ const getBrowserWindow = () => (typeof window !== 'undefined' ? window : null) /** * 관리자 화면 우측 상단 피드백 토스트. 모달(z-50 등)보다 위에 보이도록 사용처에서 `z-[100]` 클래스를 둔다. * @returns {{ toast: import('vue').Ref, showToast: (type: string, message: string) => void, clearToast: () => void }} */ export const useAdminToast = () => { const toast = ref(null) let toastTimer = null /** * 표시 중인 토스트를 즉시 제거한다. * @returns {void} */ const clearToast = () => { const browserWindow = getBrowserWindow() if (browserWindow) { browserWindow.clearTimeout(toastTimer) } toastTimer = null toast.value = null } /** * 토스트를 표시한다. 이전 타이머가 있으면 취소한다. * @param {'success' | 'error' | 'info'} type - 토스트 종류 * @param {string} message - 본문 * @returns {void} */ const showToast = (type, message) => { const browserWindow = getBrowserWindow() if (browserWindow) { browserWindow.clearTimeout(toastTimer) } const text = String(message || '').trim() || '알림' toast.value = { type, message: text } if (browserWindow) { toastTimer = browserWindow.setTimeout(() => { toast.value = null toastTimer = null }, TOAST_AUTO_HIDE_MS) } } onUnmounted(() => { const browserWindow = getBrowserWindow() if (browserWindow) { browserWindow.clearTimeout(toastTimer) } }) return { toast, showToast, clearToast } }