Files
sori.studio/components/admin/AdminConfirmModal.vue
zenn 5b2ed97748 v1.7.1: 멤버 권한·추천 사이트·네비게이션 UI 개선
관리자는 VIP·멤버만 수정 가능하도록 서버·UI 권한을 정리하고 소유자 권한 이전 API와 확인 모달을 추가했다. 추천 사이트 파비콘 캐시·URL 접두사·카드 편집 UI를 보강하고 확인 얼럿을 AdminConfirmModal로 통일했다.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-17 14:32:11 +09:00

100 lines
3.1 KiB
Vue

<script setup>
defineProps({
open: {
type: Boolean,
default: false
},
title: {
type: String,
required: true
},
confirmLabel: {
type: String,
default: '확인'
},
cancelLabel: {
type: String,
default: '취소'
},
confirmTone: {
type: String,
default: 'primary'
},
loading: {
type: Boolean,
default: false
},
loadingLabel: {
type: String,
default: ''
}
})
defineEmits(['confirm', 'cancel'])
/**
* 확인 버튼 스타일 클래스를 반환한다.
* @param {string} tone - 버튼 톤
* @returns {string} 클래스 문자열
*/
const getConfirmButtonClass = (tone) => {
if (tone === 'danger') {
return 'bg-[#d21a26] text-white hover:bg-[#b81620]'
}
return 'bg-[#15171a] text-white hover:bg-[#2b2f35]'
}
</script>
<template>
<Teleport to="body">
<div
v-if="open"
class="admin-confirm-modal fixed inset-0 z-[100] flex items-start justify-center bg-black/35 px-4 pt-10"
role="dialog"
aria-modal="true"
:aria-labelledby="'admin-confirm-modal-title'"
>
<section class="admin-confirm-modal__panel w-full max-w-[520px] rounded-xl bg-white text-[#15171a] shadow-[0_22px_70px_rgba(15,23,42,0.25)]">
<header class="admin-confirm-modal__header flex items-center justify-between border-b border-line px-6 py-5">
<h2 id="admin-confirm-modal-title" class="admin-confirm-modal__title text-xl font-semibold">
{{ title }}
</h2>
<button
class="admin-confirm-modal__close grid h-8 w-8 place-items-center rounded-md text-[#657080] hover:bg-[#f3f5f7]"
type="button"
aria-label="닫기"
:disabled="loading"
@click="$emit('cancel')"
>
<svg class="h-4 w-4" viewBox="0 0 24 24" aria-hidden="true">
<path d="M12.707 12L23.854.854a.5.5 0 00-.707-.707L12 11.293.854.146a.5.5 0 00-.707.707L11.293 12 .146 23.146a.5.5 0 00.708.708L12 12.707l11.146 11.146a.5.5 0 10.708-.706L12.707 12z" fill="currentColor" />
</svg>
</button>
</header>
<div class="admin-confirm-modal__body grid gap-4 px-6 py-5 text-sm leading-6 text-[#657080]">
<slot />
</div>
<footer class="admin-confirm-modal__footer flex justify-end gap-2 border-t border-line px-6 py-4">
<button
class="admin-confirm-modal__cancel h-10 rounded-md border border-line bg-white px-4 text-sm font-semibold text-[#3f4650]"
type="button"
:disabled="loading"
@click="$emit('cancel')"
>
{{ cancelLabel }}
</button>
<button
class="admin-confirm-modal__confirm h-10 rounded-md px-4 text-sm font-semibold transition disabled:opacity-50"
:class="getConfirmButtonClass(confirmTone)"
type="button"
:disabled="loading"
@click="$emit('confirm')"
>
{{ loading && loadingLabel ? loadingLabel : confirmLabel }}
</button>
</footer>
</section>
</div>
</Teleport>
</template>