1. PC 네이티브 confirm 제목('sb_pt') 노출 → '고정지출 등록' 인앱 확인 모달로 교체
(성공 시 토스트 안내). electron app.setName('Slim Budget')로 다른 네이티브
대화상자 제목도 개선(다음 Electron 빌드 시 반영).
2. 분류 관리 드래그를 계층형으로: 대분류는 블록 단위(소분류 함께) 이동,
소분류는 그 대분류 안에서만 이동(고유 group). 로컬 즉시반영으로 스냅백 방지.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -579,8 +579,18 @@ async function remove(e) {
|
||||
}
|
||||
}
|
||||
|
||||
// 현재 수정 중인 내역을 '매월' 고정지출로 바로 등록 (주기·시작일은 고정지출 화면에서 변경)
|
||||
async function registerAsRecurring() {
|
||||
// 고정지출 등록 확인 모달 상태 (네이티브 confirm 대신 — PC 팝업 제목 'sb_pt' 노출 방지)
|
||||
const recurConfirm = reactive({ open: false, title: '', dom: 1, amount: 0, payload: null })
|
||||
const flashMsg = ref('')
|
||||
let flashTimer = null
|
||||
function flash(msg) {
|
||||
flashMsg.value = msg
|
||||
if (flashTimer) clearTimeout(flashTimer)
|
||||
flashTimer = setTimeout(() => (flashMsg.value = ''), 2800)
|
||||
}
|
||||
|
||||
// 현재 수정 중인 내역을 '매월' 고정지출로 등록 — 확인 모달을 띄운다
|
||||
function registerAsRecurring() {
|
||||
if (form.type === 'REPAYMENT') return // 고정지출은 수입/지출/이체만
|
||||
const amount = Number(form.amount)
|
||||
if (!amount || amount <= 0) {
|
||||
@@ -597,26 +607,36 @@ async function registerAsRecurring() {
|
||||
// 이번 회차 중복 방지: 시작일을 내역 다음날로 → 다음 발생부터 생성
|
||||
const start = new Date(y, m - 1, d + 1)
|
||||
const startStr = `${start.getFullYear()}-${String(start.getMonth() + 1).padStart(2, '0')}-${String(start.getDate()).padStart(2, '0')}`
|
||||
if (!confirm(`'${title}'\n매월 ${dom}일 · ${won(amount)} 고정지출로 등록할까요?\n(주기·시작일은 고정지출 화면에서 변경할 수 있어요)`)) return
|
||||
recurConfirm.title = title
|
||||
recurConfirm.dom = dom
|
||||
recurConfirm.amount = amount
|
||||
recurConfirm.payload = {
|
||||
title,
|
||||
type: form.type,
|
||||
amount,
|
||||
category: form.type === 'TRANSFER' ? null : form.category || null,
|
||||
memo: form.memo || null,
|
||||
walletId: form.walletId || null,
|
||||
toWalletId: form.type === 'TRANSFER' ? form.toWalletId || null : null,
|
||||
frequency: 'MONTHLY',
|
||||
dayOfMonth: dom,
|
||||
startDate: startStr,
|
||||
active: true,
|
||||
}
|
||||
recurConfirm.open = true
|
||||
}
|
||||
|
||||
async function doRegisterRecurring() {
|
||||
if (!recurConfirm.payload) return
|
||||
submitting.value = true
|
||||
try {
|
||||
await accountApi.createRecurring({
|
||||
title,
|
||||
type: form.type,
|
||||
amount,
|
||||
category: form.type === 'TRANSFER' ? null : form.category || null,
|
||||
memo: form.memo || null,
|
||||
walletId: form.walletId || null,
|
||||
toWalletId: form.type === 'TRANSFER' ? form.toWalletId || null : null,
|
||||
frequency: 'MONTHLY',
|
||||
dayOfMonth: dom,
|
||||
startDate: startStr,
|
||||
active: true,
|
||||
})
|
||||
await accountApi.createRecurring(recurConfirm.payload)
|
||||
recurConfirm.open = false
|
||||
formOpen.value = false
|
||||
alert('고정지출로 등록했습니다. 고정지출 화면에서 주기를 변경할 수 있어요.')
|
||||
flash('고정지출로 등록했습니다. 고정지출 화면에서 주기를 변경할 수 있어요.')
|
||||
} catch (e) {
|
||||
formError.value = e.response?.data?.message || '고정지출 등록에 실패했습니다.'
|
||||
recurConfirm.open = false
|
||||
} finally {
|
||||
submitting.value = false
|
||||
}
|
||||
@@ -644,6 +664,7 @@ onMounted(async () => {
|
||||
<h1>가계부<span v-if="pendingCount" class="pending-count">확인 필요 {{ pendingCount }}건</span></h1>
|
||||
<IconBtn icon="plus" title="내역 추가" variant="primary" @click="openCreate" />
|
||||
</header>
|
||||
<Transition name="fade"><p v-if="flashMsg" class="flash">{{ flashMsg }}</p></Transition>
|
||||
|
||||
<!-- 카드 결제 알림 자동인식 권한 안내 (네이티브, 미허용 시) -->
|
||||
<div v-if="notifNative && !notifEnabled" class="notif-banner">
|
||||
@@ -936,6 +957,26 @@ onMounted(async () => {
|
||||
</div>
|
||||
</Transition>
|
||||
</Teleport>
|
||||
|
||||
<!-- 고정지출 등록 확인 (네이티브 confirm 대체 — 제목 'sb_pt' 노출 방지) -->
|
||||
<Teleport to="body">
|
||||
<Transition name="fade">
|
||||
<div v-if="recurConfirm.open" class="modal-backdrop" @click.self="recurConfirm.open = false">
|
||||
<div class="modal confirm-modal" role="dialog" aria-modal="true">
|
||||
<h2>고정지출 등록</h2>
|
||||
<p class="confirm-body">
|
||||
<b>{{ recurConfirm.title }}</b><br />
|
||||
매월 <b>{{ recurConfirm.dom }}일</b> · <b>{{ won(recurConfirm.amount) }}</b> 으로 등록할까요?
|
||||
</p>
|
||||
<p class="confirm-sub">주기·시작일은 고정지출 화면에서 변경할 수 있어요.</p>
|
||||
<div class="buttons">
|
||||
<IconBtn icon="close" title="취소" @click="recurConfirm.open = false" />
|
||||
<IconBtn icon="save" title="등록" variant="primary" :disabled="submitting" @click="doRegisterRecurring" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</Teleport>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
@@ -1256,6 +1297,26 @@ button.primary {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
padding: 1rem;
|
||||
}
|
||||
.flash {
|
||||
margin: 0.5rem 0 0;
|
||||
padding: 0.6rem 0.9rem;
|
||||
background: hsla(160, 100%, 37%, 0.12);
|
||||
border: 1px solid hsla(160, 100%, 37%, 0.5);
|
||||
border-radius: 8px;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
.confirm-modal {
|
||||
max-width: 340px;
|
||||
}
|
||||
.confirm-body {
|
||||
margin: 0.5rem 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.confirm-sub {
|
||||
margin: 0 0 0.5rem;
|
||||
font-size: 0.8rem;
|
||||
opacity: 0.6;
|
||||
}
|
||||
.modal {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
Reference in New Issue
Block a user