feat: 네이티브 alert/confirm/prompt → 공용 인앱 다이얼로그 (PC 'sb_pt' 제거)
CI / build (push) Failing after 15m30s

- composables/dialog + components/ui/AppDialog(App 루트 마운트)
- window.alert 전역 오버라이드로 모든 alert 인앱화
- confirm/prompt(동기)는 각 호출부를 await dialog.confirm/prompt 로 교체
  (가계부·예산·고정지출·계좌·태그·관리자·게시판·설정 — 삭제/열람제한 등)
- 웹/PC/APK 일관 UI, 의미있는 제목 부여

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
ByungCheol
2026-06-24 21:57:50 +09:00
parent 643bb8011b
commit f533df0024
13 changed files with 222 additions and 14 deletions
+3 -1
View File
@@ -3,9 +3,11 @@ import { onBeforeUnmount, onMounted, ref, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import Sortable from 'sortablejs'
import { accountApi } from '@/api/accountApi'
import { useDialog } from '@/composables/dialog'
import IconBtn from '@/components/ui/IconBtn.vue'
const router = useRouter()
const dialog = useDialog()
const tags = ref([])
const loading = ref(false)
@@ -79,7 +81,7 @@ async function saveTag(tag) {
}
async function removeTag(tag) {
if (!confirm(`'${tag.name}' 태그를 삭제할까요? (내역에서 연결도 해제됩니다)`)) return
if (!(await dialog.confirm(`'${tag.name}' 태그를 삭제할까요?\n내역에서 연결도 해제됩니다.`, { title: '태그 삭제', danger: true }))) return
try {
await accountApi.removeTag(tag.id)
await load()
+3 -1
View File
@@ -1,12 +1,14 @@
<script setup>
import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue'
import { accountApi } from '@/api/accountApi'
import { useDialog } from '@/composables/dialog'
import IconBtn from '@/components/ui/IconBtn.vue'
import { imageToBlob, parseReceiptText } from '@/utils/receiptOcr'
import { cardNotif } from '@/native/cardNotif'
import { Capacitor } from '@capacitor/core'
// @capacitor/camera 는 네이티브에서만 동적 로드 (웹은 file input 사용 — 정적 import 시 모바일 웹 청크 로드 실패 유발)
const dialog = useDialog()
const now = new Date()
const year = ref(now.getFullYear())
const month = ref(now.getMonth() + 1)
@@ -570,7 +572,7 @@ async function submit() {
}
async function remove(e) {
if (!confirm('이 내역을 삭제하시겠습니까?')) return
if (!(await dialog.confirm('이 내역을 삭제하시겠습니까?', { title: '내역 삭제', danger: true }))) return
try {
await accountApi.remove(e.id)
await load()
+3 -1
View File
@@ -3,9 +3,11 @@ import { onBeforeUnmount, onMounted, reactive, ref, watch, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import Sortable from 'sortablejs'
import { accountApi } from '@/api/accountApi'
import { useDialog } from '@/composables/dialog'
import IconBtn from '@/components/ui/IconBtn.vue'
const router = useRouter()
const dialog = useDialog()
const TABS = [
{ key: 'BANK', label: '은행계좌' },
@@ -285,7 +287,7 @@ async function submit() {
}
async function remove(w) {
if (!confirm(`'${w.name}' 을(를) 삭제할까요?`)) return
if (!(await dialog.confirm(`'${w.name}' 을(를) 삭제할까요?`, { title: '삭제', danger: true }))) return
try {
await accountApi.removeWallet(w.id)
await load()
+3 -1
View File
@@ -2,9 +2,11 @@
import { computed, onMounted, reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import { accountApi } from '@/api/accountApi'
import { useDialog } from '@/composables/dialog'
import IconBtn from '@/components/ui/IconBtn.vue'
const router = useRouter()
const dialog = useDialog()
const now = new Date()
const year = ref(now.getFullYear())
@@ -224,7 +226,7 @@ async function submit() {
}
async function remove(s) {
if (!confirm(`'${s.category}' 예산을 삭제할까요?`)) return
if (!(await dialog.confirm(`'${s.category}' 예산을 삭제할까요?`, { title: '예산 삭제', danger: true }))) return
try {
await accountApi.removeBudget(s.id)
await load()
+3 -1
View File
@@ -2,9 +2,11 @@
import { computed, onMounted, reactive, ref } from 'vue'
import { useRouter } from 'vue-router'
import { accountApi } from '@/api/accountApi'
import { useDialog } from '@/composables/dialog'
import IconBtn from '@/components/ui/IconBtn.vue'
const router = useRouter()
const dialog = useDialog()
const recurrings = ref([])
const wallets = ref([])
@@ -224,7 +226,7 @@ async function submit() {
}
async function remove(r) {
if (!confirm(`'${r.title}' 고정 지출를 삭제할까요? (이미 생성된 내역은 유지됩니다)`)) return
if (!(await dialog.confirm(`'${r.title}' 고정 지출를 삭제할까요?\n이미 생성된 내역은 유지됩니다.`, { title: '고정지출 삭제', danger: true }))) return
try {
await accountApi.removeRecurring(r.id)
await load()