Fix responsive layout and header icons

This commit is contained in:
2026-08-14 13:26:07 +09:00
parent 59ea372ac7
commit 45d2b74775
8 changed files with 44 additions and 13 deletions

1
assets/icons/search.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M784-120 532-372q-30 24-69 38t-83 14q-109 0-184.5-75.5T120-580q0-109 75.5-184.5T380-840q109 0 184.5 75.5T640-580q0 44-14 83t-38 69l252 252-56 56ZM380-400q75 0 127.5-52.5T560-580q0-75-52.5-127.5T380-760q-75 0-127.5 52.5T200-580q0 75 52.5 127.5T380-400Z"/></svg>

After

Width:  |  Height:  |  Size: 376 B

1
assets/icons/tune.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e3e3e3"><path d="M440-120v-240h80v80h320v80H520v80h-80Zm-320-80v-80h240v80H120Zm160-160v-80H120v-80h160v-80h80v240h-80Zm160-80v-80h400v80H440Zm160-160v-240h80v80h160v80H680v80h-80Zm-480-80v-80h400v80H120Z"/></svg>

After

Width:  |  Height:  |  Size: 312 B

View File

@@ -81,3 +81,7 @@
- 사용자 설정 테이블과 API를 추가하고, 설정 화면에서 주 화폐, 월 시작일, 주간 시작일을 저장할 수 있도록 했다.
- 월별 거래/자산 조회 범위가 사용자 설정의 월 시작일을 따르도록 연결했다.
- 내역 화면의 주간 날짜 스트립 요일 순서와 주 시작 계산이 사용자 설정의 주간 시작일을 따르도록 연결했다.
- 로그인 화면에서 PC 사이드바 여백이 적용되어 화면이 오른쪽으로 밀리는 문제를 수정했다.
- PC 중간 폭 화면에서 콘텐츠 오른쪽이 잘리지 않도록 전역 레이아웃을 margin 기반에서 padding 기반으로 변경했다.
- 내역 헤더의 검색과 필터 버튼을 `assets/icons/search.svg`, `assets/icons/tune.svg` 인라인 SVG로 교체했다.
- CSV 내보내기 컬럼을 한글 컬럼명과 앱의 거래 흐름에 맞는 순서로 정리하고 Excel 호환 BOM을 추가했다.

View File

@@ -27,6 +27,7 @@
- 통계 화면은 그래프보다 숫자와 분류별 리스트를 우선한다.
- 방향 이동 UI는 `assets/icons`의 키보드 화살표 SVG를 사용한다.
- 추가 버튼 UI는 텍스트 `+` 대신 `assets/icons/add.svg`를 사용한다.
- 검색과 필터 같은 헤더 액션도 텍스트 기호 대신 `assets/icons`의 SVG 아이콘을 사용한다.
- 거래 목록의 카테고리 표시는 하위 카테고리가 있으면 하위 이름만, 없으면 상위 이름만 보여준다.
- 카테고리 아이콘과 색상은 카테고리 관리 상세 화면에서 수정하고 거래 목록 아이콘에 즉시 반영한다.
@@ -38,6 +39,7 @@
- 자산은 활성/비활성으로 관리하지 않는다. 삭제는 거래가 연결되지 않은 자산에 한해 제공한다.
- 거래에 연결되는 카테고리 선택은 하위가 있으면 하위 카테고리를 우선하고, 하위가 없는 경우에만 상위 카테고리를 직접 선택한다.
- CSV Export는 데이터 보존을 위한 필수 기능으로 유지한다.
- CSV Export 컬럼은 사용자가 앱에서 보는 흐름에 맞춰 날짜, 유형, 자산, 분류, 금액, 내용, 메모 중심의 한글 컬럼으로 제공한다.
- 주 화폐, 월 시작일, 주간 시작일 같은 사용자별 기본 설정은 `UserSetting`에 저장한다.
## 개발/운영 기준

View File

@@ -28,7 +28,7 @@
</nav>
</aside>
<main class="min-h-dvh w-full bg-white md:ml-64 md:bg-paper" :class="showNav ? 'pb-20 md:pb-0' : ''">
<main class="min-h-dvh w-full bg-white md:bg-paper" :class="showNav ? 'pb-20 md:pb-0 md:pl-64' : ''">
<div class="mx-auto min-h-dvh w-full md:max-w-7xl md:bg-transparent">
<slot />
</div>

View File

@@ -7,9 +7,21 @@
</button>
<h1 class="text-lg font-extrabold">최근 이용 내역</h1>
<div class="flex items-center gap-1">
<button type="button" class="flex h-9 w-9 items-center justify-center rounded-md text-2xl leading-none active:bg-paper" aria-label="검색" @click="searchOpen = !searchOpen">⌕</button>
<button type="button" class="relative flex h-9 w-9 items-center justify-center rounded-md text-xl leading-none active:bg-paper" aria-label="필터" @click="filterSheetOpen = true">
☷
<button
type="button"
class="flex h-9 w-9 items-center justify-center rounded-md text-ink active:bg-paper"
aria-label="검색"
@click="searchOpen = !searchOpen"
>
<span class="nav-icon h-6 w-6" v-html="searchIcon" />
</button>
<button
type="button"
class="relative flex h-9 w-9 items-center justify-center rounded-md text-ink active:bg-paper"
aria-label="필터"
@click="filterSheetOpen = true"
>
<span class="nav-icon h-6 w-6" v-html="tuneIcon" />
<span v-if="activeFilterCount" class="absolute right-1 top-1 h-2 w-2 rounded-full bg-red-500" />
</button>
</div>
@@ -176,8 +188,16 @@
<script setup lang="ts">
import { addDays, addMonths, format, parse, startOfWeek } from 'date-fns'
import type { WeekStartsOn } from 'date-fns'
import searchIconRaw from '~/assets/icons/search.svg?raw'
import tuneIconRaw from '~/assets/icons/tune.svg?raw'
import type { Transaction } from '~/composables/useMoney'
const inlineIcon = (icon: string) => icon
.replace(/fill="[^"]*"/g, 'fill="currentColor"')
.replace(/height="[^"]*"/, 'height="100%"')
.replace(/width="[^"]*"/, 'width="100%"')
const searchIcon = inlineIcon(searchIconRaw)
const tuneIcon = inlineIcon(tuneIconRaw)
const selectedDate = ref(formatDateOnly())
const weekSwipeStartX = ref(0)
const weekDirection = ref<'next' | 'prev'>('next')

View File

@@ -1,4 +1,5 @@
import { setHeader } from 'h3'
import { format } from 'date-fns'
import { prisma } from '../../utils/db'
import { requireUser } from '../../utils/auth'
@@ -11,23 +12,26 @@ export default defineEventHandler(async (event) => {
})
const escape = (value: unknown) => `"${String(value ?? '').replaceAll('"', '""')}"`
const categoryName = (row: typeof rows[number]) => row.category.name
const parentCategoryName = (row: typeof rows[number]) => row.category.parent?.name || ''
const lines = [
['id', 'type', 'occurredAt', 'asset', 'category', 'amount', 'title', 'memo', 'latitude', 'longitude'].map(escape).join(','),
['날짜', '유형', '자산', '상위분류', '분류', '금액', '내용', '메모', '위도', '경도', '거래ID'].map(escape).join(','),
...rows.map(row => [
row.id,
row.type,
row.occurredAt.toISOString(),
format(row.occurredAt, 'yyyy-MM-dd'),
row.type === 'income' ? '수입' : '지출',
row.asset.name,
row.category.parent ? `${row.category.parent.name} > ${row.category.name}` : row.category.name,
parentCategoryName(row),
categoryName(row),
row.amount,
row.title,
row.memo,
row.latitude,
row.longitude
row.longitude,
row.id
].map(escape).join(','))
]
setHeader(event, 'content-type', 'text/csv; charset=utf-8')
setHeader(event, 'content-disposition', 'attachment; filename="transactions.csv"')
return lines.join('\n')
setHeader(event, 'content-disposition', 'attachment; filename="money-transactions.csv"')
return `\uFEFF${lines.join('\n')}`
})

View File

@@ -31,7 +31,6 @@
## 6. 데이터와 API
- 거래 목록 조회 성능을 고려해 필요한 index를 점검한다.
- CSV 내보내기 컬럼을 실제 사용 흐름에 맞게 정리한다.
## 7. 인증과 사용자 경험