미저장 변경 이탈 확인 추가

This commit is contained in:
2026-05-13 11:29:11 +09:00
parent fb0dadb7b9
commit 79d0a30475
12 changed files with 258 additions and 9 deletions

View File

@@ -16,6 +16,7 @@ const isNewMember = computed(() => props.mode === 'new')
const saveMessage = ref('')
const saveError = ref('')
const isSaving = ref(false)
const savedMemberSnapshot = ref('')
const form = reactive({
username: '',
@@ -58,6 +59,12 @@ const normalizedLabels = computed(() => [...new Set(
.filter(Boolean)
)])
/**
* 회원 저장 요청 본문을 문자열로 직렬화한다.
* @returns {string} 직렬화된 회원 입력값
*/
const serializeMemberPayload = () => JSON.stringify(getMemberPayload())
/**
* 날짜 표시 형식 변환
* @param {string | null} value - ISO 날짜 문자열
@@ -131,6 +138,14 @@ const getMemberPayload = () => ({
note: form.note
})
const hasUnsavedMemberChanges = computed(() => serializeMemberPayload() !== savedMemberSnapshot.value)
const {
isUnsavedModalOpen,
stayOnUnsavedPage,
leaveUnsavedPage
} = useAdminUnsavedChangesGuard(hasUnsavedMemberChanges)
/**
* 회원 기본 정보를 저장한다.
* @returns {Promise<void>}
@@ -156,6 +171,7 @@ const saveMember = async () => {
body: payload
})
savedMemberSnapshot.value = serializeMemberPayload()
emit('saved', saved)
saveMessage.value = '저장되었습니다.'
} catch (error) {
@@ -164,6 +180,10 @@ const saveMember = async () => {
isSaving.value = false
}
}
watch(() => props.member, () => {
savedMemberSnapshot.value = serializeMemberPayload()
}, { immediate: true, flush: 'post' })
</script>
<template>
@@ -198,7 +218,7 @@ const saveMember = async () => {
</div>
</div>
<div class="admin-member-form__body grid gap-8 py-8 xl:grid-cols-[280px_minmax(0,1fr)]">
<div class="admin-member-form__body grid gap-8 py-8 xl:grid-cols-3">
<aside class="admin-member-form__summary">
<div class="admin-member-form__identity flex items-center gap-4">
<img
@@ -251,7 +271,7 @@ const saveMember = async () => {
</div>
</aside>
<div class="admin-member-form__content space-y-8">
<div class="admin-member-form__content space-y-8 xl:col-span-2">
<form class="admin-member-form__card rounded-xl border border-line bg-white p-5 md:p-6" @submit.prevent="saveMember">
<div class="grid gap-5 md:grid-cols-2">
<label class="admin-member-form__field block">
@@ -315,5 +335,11 @@ const saveMember = async () => {
</section>
</div>
</div>
<AdminUnsavedChangesModal
:open="isUnsavedModalOpen"
@stay="stayOnUnsavedPage"
@leave="leaveUnsavedPage"
/>
</section>
</template>