구형 에디터 제거와 토스트 공통화

This commit is contained in:
2026-07-23 16:23:01 +09:00
parent b61a6a2295
commit 151349edc2
13 changed files with 55 additions and 2697 deletions

View File

@@ -10,8 +10,7 @@ const autoSaving = ref(false)
const deleting = ref(false)
const errorMessage = ref('')
const postForm = ref(null)
const toast = ref(null)
let toastTimer = null
const { toast, showToast, clearToast } = useAdminToast()
const { data: post } = await useFetch(() => `/admin/api/posts/${id.value}`)
@@ -32,20 +31,6 @@ const isPublicPost = (value) => value?.status === 'published'
const publicPostUrl = computed(() => post.value?.slug ? `/post/${post.value.slug}` : '')
/**
* 저장 상태 토스트 표시
* @param {'success'|'error'|'info'} type - 토스트 타입
* @param {string} message - 표시 메시지
* @returns {void}
*/
const showToast = (type, message) => {
window.clearTimeout(toastTimer)
toast.value = { type, message }
toastTimer = window.setTimeout(() => {
toast.value = null
}, 3200)
}
/**
* 저장 오류가 슬러그 중복인지 확인한다.
* @param {unknown} error - 저장 오류
@@ -109,8 +94,7 @@ const savePost = async (payload) => {
showToast('success', '변경 내용이 저장되었습니다.')
} catch (error) {
if (isDuplicateSlugError(error)) {
window.clearTimeout(toastTimer)
toast.value = null
clearToast()
errorMessage.value = ''
postForm.value?.markSlugError('이미 사용 중인 슬러그입니다.')
return
@@ -146,8 +130,7 @@ const autosaveDraftPost = async (payload) => {
const msg = error?.data?.message || error?.message || '자동 저장에 실패했습니다.'
postForm.value?.markAutosaveFailed(payload)
if (isDuplicateSlugError(error)) {
window.clearTimeout(toastTimer)
toast.value = null
clearToast()
errorMessage.value = ''
postForm.value?.markSlugError('이미 사용 중인 슬러그입니다.')
return false
@@ -196,10 +179,6 @@ const deletePost = async () => {
}
onMounted(showStoredToast)
onBeforeUnmount(() => {
window.clearTimeout(toastTimer)
})
</script>
<template>
@@ -223,7 +202,7 @@ onBeforeUnmount(() => {
/>
<div
v-if="toast"
class="admin-post-edit__toast fixed right-5 top-5 z-50 rounded border px-4 py-3 text-sm font-semibold shadow-lg"
class="admin-post-edit__toast fixed right-5 top-5 z-[100] max-w-[min(24rem,calc(100vw-2.5rem))] rounded border px-4 py-3 text-sm font-semibold shadow-lg"
:class="{
'border-green-200 bg-green-50 text-green-800': toast.type === 'success',
'border-red-200 bg-red-50 text-red-800': toast.type === 'error',

View File

@@ -7,8 +7,7 @@ const saving = ref(false)
const autoSaving = ref(false)
const errorMessage = ref('')
const postForm = ref(null)
const toast = ref(null)
let toastTimer = null
const { toast, showToast, clearToast } = useAdminToast()
/**
* 비교용 게시물 입력값을 직렬화한다.
@@ -58,20 +57,6 @@ const syncLatestDraftAfterCreate = async (postId, firstPayload) => {
return savedPayload
}
/**
* 저장 상태 토스트 표시
* @param {'success'|'error'|'info'} type - 토스트 타입
* @param {string} message - 표시 메시지
* @returns {void}
*/
const showToast = (type, message) => {
window.clearTimeout(toastTimer)
toast.value = { type, message }
toastTimer = window.setTimeout(() => {
toast.value = null
}, 3200)
}
/**
* 저장 오류가 슬러그 중복인지 확인한다.
* @param {unknown} error - 저장 오류
@@ -120,8 +105,7 @@ const savePost = async (payload) => {
await navigateTo(`/admin/posts/${post.id}`)
} catch (error) {
if (isDuplicateSlugError(error)) {
window.clearTimeout(toastTimer)
toast.value = null
clearToast()
errorMessage.value = ''
postForm.value?.markSlugError('이미 사용 중인 슬러그입니다.')
return
@@ -166,8 +150,7 @@ const createDraftAutosave = async (payload, options = {}) => {
const msg = error?.data?.message || error?.message || '자동 저장에 실패했습니다.'
postForm.value?.markAutosaveFailed(payload)
if (isDuplicateSlugError(error)) {
window.clearTimeout(toastTimer)
toast.value = null
clearToast()
errorMessage.value = ''
postForm.value?.markSlugError('이미 사용 중인 슬러그입니다.')
return false
@@ -189,9 +172,6 @@ onBeforeRouteLeave(async () => {
return createDraftAutosave(payload, { skipNavigate: true })
})
onBeforeUnmount(() => {
window.clearTimeout(toastTimer)
})
</script>
<template>
@@ -225,7 +205,7 @@ onBeforeUnmount(() => {
</div>
<div
v-if="toast"
class="admin-post-editor__toast fixed right-5 top-5 z-50 rounded border px-4 py-3 text-sm font-semibold shadow-lg"
class="admin-post-editor__toast fixed right-5 top-5 z-[100] max-w-[min(24rem,calc(100vw-2.5rem))] rounded border px-4 py-3 text-sm font-semibold shadow-lg"
:class="{
'border-green-200 bg-green-50 text-green-800': toast.type === 'success',
'border-red-200 bg-red-50 text-red-800': toast.type === 'error',