feat: 페이지 타이틀 제거(헤더만 표기) + 게시글 상세 목록아이콘/공지 체크박스화
CI / build (push) Failing after 11m0s

- 각 화면 내 <h1> 페이지 타이틀 제거 → 헤더 타이틀로 일원화
  (가계부 pending 카운트는 유지, 액션 헤더는 우측 정렬)
- 게시글 상세: 공지 등록/해제 버튼 제거 + '목록' 아이콘 추가(list 아이콘 신규)
- 글 작성/수정 공지 체크박스로 일원화(편집 시 기존값 로드)
- ProfileEdit/AccountInfo 화면 내 뒤로가기 제거, 미사용 router 정리

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
ByungCheol
2026-06-27 22:59:20 +09:00
parent b737720d29
commit c4872c93a8
17 changed files with 12 additions and 63 deletions
+1
View File
@@ -27,6 +27,7 @@ const ICONS = {
refresh: ['M23 4v6h-6', 'M1 20v-6h6', 'M3.51 9a9 9 0 0 1 14.85-3.36L23 10', 'M1 14l4.64 4.36A9 9 0 0 0 20.49 15'],
filter: ['M22 3H2l8 9.46V19l4 2v-8.54L22 3z'],
menu: ['M3 12h18', 'M3 6h18', 'M3 18h18'],
list: ['M8 6h13', 'M8 12h13', 'M8 18h13', 'M3 6h.01', 'M3 12h.01', 'M3 18h.01'],
back: ['M19 12H5', 'M12 19l-7-7 7-7'],
logout: ['M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4', 'M16 17l5-5-5-5', 'M21 12H9'],
login: ['M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4', 'M10 17l5-5-5-5', 'M15 12H3'],
+1 -2
View File
@@ -108,8 +108,7 @@ onMounted(() => {
<template>
<main class="members">
<header class="head">
<h1>회원 관리</h1>
<header class="head" style="justify-content: flex-end">
<div class="head-actions">
<input v-model="keyword" type="search" class="search" placeholder="아이디·이름·이메일 검색" />
<IconBtn icon="refresh" title="새로고침" size="sm" :disabled="loading" @click="load" />
@@ -324,9 +324,6 @@ onMounted(async () => {
<template>
<section class="dash">
<header class="head">
<h1>통계</h1>
</header>
<div class="month-nav">
<IconBtn icon="chevronLeft" title="이전 달" size="sm" @click="prevMonth" />
-5
View File
@@ -1,12 +1,10 @@
<script setup>
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([])
@@ -100,9 +98,6 @@ onBeforeUnmount(() => sortable?.destroy())
<template>
<section class="tag-admin">
<header class="head">
<h1>가계부 태그 관리</h1>
</header>
<p class="hint">내가 등록한 태그는 나의 가계부 내역에서만 사용됩니다.</p>
<form class="new-tag" @submit.prevent="addTag">
+1 -1
View File
@@ -824,7 +824,7 @@ onMounted(async () => {
<template>
<section class="account">
<header class="account-head">
<h1>가계부<span v-if="pendingCount" class="pending-count">확인 필요 {{ pendingCount }}</span></h1>
<span class="pending-wrap"><span v-if="pendingCount" class="pending-count">확인 필요 {{ pendingCount }}</span></span>
<IconBtn icon="plus" title="내역 추가" variant="primary" @click="openCreate" />
</header>
<Transition name="fade"><p v-if="flashMsg" class="flash">{{ flashMsg }}</p></Transition>
-5
View File
@@ -1,12 +1,10 @@
<script setup>
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 = [
@@ -310,9 +308,6 @@ onBeforeUnmount(() => sortable?.destroy())
<template>
<section class="wallet">
<header class="head">
<h1>계좌 관리</h1>
</header>
<!-- 순자산 요약 -->
<div class="networth">
+1 -4
View File
@@ -1,11 +1,9 @@
<script setup>
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()
@@ -244,8 +242,7 @@ onMounted(() => {
<template>
<section class="budget">
<header class="head">
<h1>예산 설정</h1>
<header class="head" style="justify-content: flex-end">
<div class="head-actions">
<IconBtn icon="plus" title="예산 추가" variant="primary" @click="openCreate" />
</div>
+1 -4
View File
@@ -1,11 +1,9 @@
<script setup>
import { computed, onBeforeUnmount, onMounted, reactive, ref, watch, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import Sortable from 'sortablejs'
import { accountApi } from '@/api/accountApi'
import IconBtn from '@/components/ui/IconBtn.vue'
const router = useRouter()
const categories = ref([])
const rows = ref([]) // 현재 탭(activeType)의 분류 — 드래그 정렬 대상
@@ -184,8 +182,7 @@ onBeforeUnmount(destroySortables)
<template>
<section class="cat">
<header class="head">
<h1>분류 관리</h1>
<header class="head" style="justify-content: flex-end">
<div class="head-actions">
<button type="button" class="text-btn" @click="importDefaults">기본 분류 불러오기</button>
</div>
+1 -4
View File
@@ -1,11 +1,9 @@
<script setup>
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([])
@@ -240,8 +238,7 @@ onMounted(load)
<template>
<section class="recur">
<header class="head">
<h1>고정 지출</h1>
<header class="head" style="justify-content: flex-end">
<div class="head-actions">
<IconBtn icon="refresh" title="지금 반영" @click="runNow" />
<IconBtn icon="plus" title="고정 지출 추가" variant="primary" @click="openCreate" />
-5
View File
@@ -1,12 +1,10 @@
<script setup>
import { computed, onBeforeUnmount, onMounted, ref, watch, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import Sortable from 'sortablejs'
import { adminApi } from '@/api/adminApi'
import { useDialog } from '@/composables/dialog'
import IconBtn from '@/components/ui/IconBtn.vue'
const router = useRouter()
const dialog = useDialog()
const categories = ref([])
@@ -150,9 +148,6 @@ onBeforeUnmount(destroySortables)
<template>
<section class="cat">
<header class="head">
<h1>기본 분류 관리</h1>
</header>
<p class="hint">
전체 사용자 공용 <b>기본 분류</b> 템플릿입니다. 사용자가 분류 관리에서 <b>기본 분류 불러오기</b> 자기 분류에 복사해 씁니다.
<b>대분류 아래 소분류</b> 묶을 있습니다(2단계).
-2
View File
@@ -100,8 +100,6 @@ onMounted(load)
<template>
<section class="tag-admin">
<h1>태그 관리</h1>
<div class="board-setting">
<label>게시판 사용 카테고리</label>
<select v-model="boardCategoryId">
+2 -13
View File
@@ -80,15 +80,6 @@ async function unblockPost() {
}
}
async function setNoticePost(on) {
try {
await (on ? boardApi.setNotice(postId) : boardApi.unsetNotice(postId))
await load()
} catch (e) {
alert(e.response?.data?.message || '처리에 실패했습니다.')
}
}
async function addComment() {
const content = commentText.value.trim()
if (!content) return
@@ -151,10 +142,8 @@ onMounted(load)
</div>
<div class="actions">
<IconBtn icon="list" title="목록" @click="router.push(`/board/${category}`)" />
<div class="right-actions">
<!-- 관리자 공지 설정/해제 (커뮤니티) -->
<button v-if="isAdmin && category === 'community' && !post.notice" type="button" class="notice-btn" @click="setNoticePost(true)">공지 등록</button>
<button v-if="isAdmin && category === 'community' && post.notice" type="button" class="notice-btn" @click="setNoticePost(false)">공지 해제</button>
<!-- 관리자 제한/해제 -->
<button v-if="isAdmin && !post.blocked" type="button" class="warn" @click="blockPost">열람 제한</button>
<button v-if="isAdmin && post.blocked" type="button" class="warn" @click="unblockPost">제한 해제</button>
@@ -295,7 +284,7 @@ button.notice-btn {
}
.actions {
display: flex;
justify-content: flex-end;
justify-content: space-between;
border-top: 1px solid var(--color-border);
padding-top: 1rem;
}
+1 -2
View File
@@ -128,8 +128,7 @@ onMounted(loadTags)
<template>
<section class="board">
<header class="board-head">
<h1>{{ boardTitle }}</h1>
<header class="board-head" style="justify-content: flex-end">
<IconBtn icon="edit" title="글쓰기" variant="primary" @click="router.push(`/board/${category}/write`)" />
</header>
+3 -3
View File
@@ -14,9 +14,9 @@ const auth = useAuthStore()
const category = route.params.category || DEFAULT_BOARD
const editId = route.params.id || null
const isEdit = computed(() => !!editId)
// :
// : /
const isAdmin = computed(() => auth.user?.role === 'ADMIN')
const canNotice = computed(() => isAdmin.value && category === 'community' && !isEdit.value)
const canNotice = computed(() => isAdmin.value && category === 'community')
const title = ref('')
const content = ref('')
@@ -49,6 +49,7 @@ async function loadForEdit() {
const p = await boardApi.get(editId)
title.value = p.title
content.value = p.content
notice.value = !!p.notice
// () id
const nameToId = {}
tagGroups.value.forEach((c) => c.tags.forEach((t) => (nameToId[t.name] = t.id)))
@@ -99,7 +100,6 @@ onMounted(async () => {
<template>
<section class="write">
<h1>{{ isEdit ? '글 수정' : '글쓰기' }}</h1>
<form class="write-form" @submit.prevent="submit">
<input v-model="title" type="text" placeholder="제목" maxlength="200" :disabled="loading" />
-1
View File
@@ -25,7 +25,6 @@ function goEdit() {
<template>
<div class="account-info">
<h1 class="page-title">계정정보</h1>
<section class="card">
<div class="row">
-8
View File
@@ -93,14 +93,6 @@ function cancel() {
<template>
<div class="profile-edit">
<button type="button" class="back" @click="cancel">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M19 12H5" /><path d="M12 19l-7-7 7-7" />
</svg>
<span>계정정보</span>
</button>
<h1 class="page-title">가입정보 변경</h1>
<!-- 1단계: 비밀번호 재인증 -->
<form v-if="step === 'verify'" class="card form" @submit.prevent="verify">
-1
View File
@@ -42,7 +42,6 @@ async function clearAppData() {
<template>
<div class="settings">
<h1 class="page-title">설정</h1>
<section class="card">
<div class="row">