- 가계부: 내역 추가 → month-nav(검색·필터 옆), 헤더는 pending 있을 때만 - 예산: 예산 추가 → month-nav(월 변경 옆) - 고정지출: 지금 반영/추가 → 안내문구 아래 - 커뮤니티: 글쓰기 → 태그 필터와 같은 줄(list-top) - 분류 관리: 기본 분류 불러오기 → 지출/수입 탭과 같은 줄(tabs-row) - 미사용 boardTitle/boardLabel 정리 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -823,9 +823,8 @@ onMounted(async () => {
|
||||
|
||||
<template>
|
||||
<section class="account">
|
||||
<header class="account-head">
|
||||
<span class="pending-wrap"><span v-if="pendingCount" class="pending-count">확인 필요 {{ pendingCount }}건</span></span>
|
||||
<IconBtn icon="plus" title="내역 추가" variant="primary" @click="openCreate" />
|
||||
<header v-if="pendingCount" class="account-head">
|
||||
<span class="pending-count">확인 필요 {{ pendingCount }}건</span>
|
||||
</header>
|
||||
<Transition name="fade"><p v-if="flashMsg" class="flash">{{ flashMsg }}</p></Transition>
|
||||
|
||||
@@ -856,6 +855,7 @@ onMounted(async () => {
|
||||
icon="filter" title="검색·필터" class="filter-toggle"
|
||||
:variant="hasFilter ? 'primary' : 'default'" @click="filterOpen = !filterOpen"
|
||||
/>
|
||||
<IconBtn icon="plus" title="내역 추가" variant="primary" @click="openCreate" />
|
||||
</div>
|
||||
|
||||
<div v-if="filterOpen" class="filter-bar">
|
||||
|
||||
@@ -242,16 +242,11 @@ onMounted(() => {
|
||||
|
||||
<template>
|
||||
<section class="budget">
|
||||
<header class="head" style="justify-content: flex-end">
|
||||
<div class="head-actions">
|
||||
<IconBtn icon="plus" title="예산 추가" variant="primary" @click="openCreate" />
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="month-nav">
|
||||
<IconBtn icon="chevronLeft" title="이전 달" size="sm" @click="prevMonth" />
|
||||
<span class="period">{{ periodLabel }}</span>
|
||||
<IconBtn icon="chevronRight" title="다음 달" size="sm" @click="nextMonth" />
|
||||
<IconBtn icon="plus" title="예산 추가" variant="primary" @click="openCreate" />
|
||||
</div>
|
||||
|
||||
<!-- 월 예상 수입 vs 총 예산 -->
|
||||
|
||||
@@ -182,17 +182,15 @@ onBeforeUnmount(destroySortables)
|
||||
|
||||
<template>
|
||||
<section class="cat">
|
||||
<header class="head" style="justify-content: flex-end">
|
||||
<div class="head-actions">
|
||||
<button type="button" class="text-btn" @click="importDefaults">기본 분류 불러오기</button>
|
||||
</div>
|
||||
</header>
|
||||
<p class="hint">내역·예산에서 선택할 분류를 관리합니다. <b>대분류 아래 소분류</b>로 묶을 수 있고(2단계), 예산·통계는 소분류 기준입니다. 이름을 바꾸면 기존 내역·예산에도 반영됩니다.</p>
|
||||
|
||||
<div class="tabs-row">
|
||||
<div class="tabs">
|
||||
<button type="button" :class="{ active: activeType === 'EXPENSE' }" @click="activeType = 'EXPENSE'">지출 분류</button>
|
||||
<button type="button" :class="{ active: activeType === 'INCOME' }" @click="activeType = 'INCOME'">수입 분류</button>
|
||||
</div>
|
||||
<button type="button" class="text-btn" @click="importDefaults">기본 분류 불러오기</button>
|
||||
</div>
|
||||
|
||||
<form class="new-cat" @submit.prevent="addCategory">
|
||||
<select v-model="newParent" class="parent-sel" title="대분류 선택">
|
||||
@@ -296,6 +294,16 @@ button.danger {
|
||||
border-color: #c0392b;
|
||||
color: #c0392b;
|
||||
}
|
||||
.tabs-row {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: space-between;
|
||||
gap: 0.75rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.tabs-row .tabs {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.tabs {
|
||||
display: flex;
|
||||
gap: 0.25rem;
|
||||
|
||||
@@ -238,13 +238,11 @@ onMounted(load)
|
||||
|
||||
<template>
|
||||
<section class="recur">
|
||||
<header class="head" style="justify-content: flex-end">
|
||||
<div class="head-actions">
|
||||
<p class="hint">등록한 주기에 맞춰 가계부 진입 시 자동으로 <b>‘확인 필요’</b> 내역이 생성됩니다(중복 없이). 가계부에서 실제 결제·이체를 확인한 뒤 <b>‘확인’</b>을 눌러 확정하세요.</p>
|
||||
<div class="recur-actions">
|
||||
<IconBtn icon="refresh" title="지금 반영" @click="runNow" />
|
||||
<IconBtn icon="plus" title="고정 지출 추가" variant="primary" @click="openCreate" />
|
||||
</div>
|
||||
</header>
|
||||
<p class="hint">등록한 주기에 맞춰 가계부 진입 시 자동으로 <b>‘확인 필요’</b> 내역이 생성됩니다(중복 없이). 가계부에서 실제 결제·이체를 확인한 뒤 <b>‘확인’</b>을 눌러 확정하세요.</p>
|
||||
|
||||
<p v-if="error" class="msg error">{{ error }}</p>
|
||||
<p v-if="loading" class="msg">불러오는 중...</p>
|
||||
@@ -412,6 +410,12 @@ h1 {
|
||||
opacity: 0.7;
|
||||
margin: 0.5rem 0 1rem;
|
||||
}
|
||||
.recur-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 0.5rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
button {
|
||||
padding: 0.45rem 0.85rem;
|
||||
border: 1px solid var(--color-border);
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useRoute, useRouter } from 'vue-router'
|
||||
import { boardApi } from '@/api/boardApi'
|
||||
import { formatRelative } from '@/utils/datetime'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import { boardLabel, DEFAULT_BOARD } from '@/constants/boards'
|
||||
import { DEFAULT_BOARD } from '@/constants/boards'
|
||||
import IconBtn from '@/components/ui/IconBtn.vue'
|
||||
|
||||
const route = useRoute()
|
||||
@@ -14,7 +14,6 @@ const isAdmin = computed(() => auth.user?.role === 'ADMIN')
|
||||
|
||||
// 현재 게시판(카테고리)
|
||||
const category = computed(() => route.params.category || DEFAULT_BOARD)
|
||||
const boardTitle = computed(() => boardLabel(category.value))
|
||||
|
||||
const posts = ref([])
|
||||
const tags = ref([])
|
||||
@@ -128,11 +127,8 @@ onMounted(loadTags)
|
||||
|
||||
<template>
|
||||
<section class="board">
|
||||
<header class="board-head" style="justify-content: flex-end">
|
||||
<IconBtn icon="edit" title="글쓰기" variant="primary" @click="router.push(`/board/${category}/write`)" />
|
||||
</header>
|
||||
|
||||
<div v-if="tags.length" class="tag-filter">
|
||||
<div class="list-top">
|
||||
<div class="tag-filter">
|
||||
<button
|
||||
v-for="t in tags"
|
||||
:key="t"
|
||||
@@ -142,6 +138,8 @@ onMounted(loadTags)
|
||||
@click="filterByTag(t)"
|
||||
>{{ t }}</button>
|
||||
</div>
|
||||
<IconBtn icon="edit" title="글쓰기" variant="primary" @click="router.push(`/board/${category}/write`)" />
|
||||
</div>
|
||||
|
||||
<!-- 검색 적용 표시 -->
|
||||
<div v-if="activeKeyword" class="active-search">
|
||||
@@ -247,6 +245,20 @@ button:disabled {
|
||||
opacity: 0.5;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.list-top {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 0.75rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.list-top .tag-filter {
|
||||
flex: 1;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.list-top > .icon-btn {
|
||||
flex: none;
|
||||
}
|
||||
.tag-filter {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
Reference in New Issue
Block a user