diff --git a/docs/changelog.md b/docs/changelog.md index 58af617..85baeb0 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -48,3 +48,5 @@ - README에 개발, 빌드, Prisma 관련 주요 명령과 현재 검증 기준을 정리했다. - TODO에서 요구사항과 맞지 않던 이체 관련 작업 항목을 제거했다. - 설정의 계정 관리 화면에서 이름 수정과 비밀번호 변경 기능을 구현했다. +- 내역 화면의 주간 날짜 스트립에 좌우 슬라이드 전환 애니메이션을 추가했다. +- 거래 입력/수정 화면의 자산, 분류, 금액, 내용 placeholder를 제거하고 메모/위치 영역을 같은 입력 리스트 안의 얇은 행으로 정리했다. diff --git a/docs/project-guidelines.md b/docs/project-guidelines.md index 7f29386..c19434c 100644 --- a/docs/project-guidelines.md +++ b/docs/project-guidelines.md @@ -16,7 +16,8 @@ - 거래 입력에서는 시간 입력을 요구하지 않고 날짜만 선택한다. - 거래 타입은 수입과 지출만 사용하고 이체 타입이나 이체 탭은 만들지 않는다. - 날짜 선택은 모바일 친화적인 바텀 시트 캘린더를 사용한다. -- 금액 입력은 기본값 `0`을 채우지 않고 placeholder로만 안내한다. +- 자산, 분류, 금액, 내용 입력은 placeholder 문구를 넣지 않고 비어 있는 입력 상태로 둔다. +- 금액 입력은 기본값 `0`을 채우지 않는다. - 셀렉트 박스보다 모바일 친화적인 바텀 시트를 우선한다. - 활성/비활성 같은 상태는 텍스트 버튼보다 토글처럼 현재 상태가 보이는 UI를 쓴다. - 통계 화면은 그래프보다 숫자와 분류별 리스트를 우선한다. diff --git a/pages/add.vue b/pages/add.vue index 30d540c..a01f045 100644 --- a/pages/add.vue +++ b/pages/add.vue @@ -34,7 +34,7 @@ @@ -44,41 +44,39 @@
- +
- +
- -
-
+
+ + +
+ +
위치 -
+
+ + {{ form.latitude }}, {{ form.longitude }} +
-

- {{ form.latitude ? `${form.latitude}, ${form.longitude}` : '선택 사항입니다.' }} -

-
- - -
- - @@ -123,13 +121,13 @@ const categoryOptions = computed(() => selectableCategories.value.map((category: description: category.parent?.name || (category.type === 'income' ? '수입' : '지출') }))) -watch(assets, (items: any[]) => { - if (!form.assetId && items[0]) form.assetId = items[0].id +watch(selectableCategories, (items: any[]) => { + if (form.categoryId && !items.some(item => item.id === form.categoryId)) form.categoryId = '' }, { immediate: true }) -watch(selectableCategories, (items: any[]) => { - if (!items.some(item => item.id === form.categoryId)) form.categoryId = items[0]?.id || '' -}, { immediate: true }) +const canSubmit = computed(() => { + return Boolean(form.assetId && form.categoryId && form.amount && form.amount > 0 && form.title.trim()) +}) function setType(type: TransactionType) { form.type = type diff --git a/pages/index.vue b/pages/index.vue index 4653197..9d0b9aa 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -56,29 +56,36 @@ {{ day }}
- +
+ +
+
@@ -183,6 +190,7 @@ import type { Transaction } from '~/composables/useMoney' const selectedDate = ref(formatDateOnly()) const weekSwipeStartX = ref(0) +const weekDirection = ref<'next' | 'prev'>('next') const searchOpen = ref(false) const filterSheetOpen = ref(false) const monthPickerOpen = ref(false) @@ -193,9 +201,13 @@ const filters = reactive({ categoryId: '' }) const selectedMonth = computed(() => monthKey(parse(selectedDate.value, 'yyyy-MM-dd', new Date()))) +const weekKey = computed(() => format(startOfWeek(parse(selectedDate.value, 'yyyy-MM-dd', new Date()), { weekStartsOn: 0 }), 'yyyy-MM-dd')) +const weekTransitionName = computed(() => weekDirection.value === 'next' ? 'week-next' : 'week-prev') const selectedMonthModel = computed({ get: () => selectedMonth.value, set: (value: string) => { + const current = selectedMonth.value + weekDirection.value = value >= current ? 'next' : 'prev' selectedDate.value = `${value}-01` } }) @@ -287,11 +299,13 @@ watch(() => filters.type, () => { }) function moveMonth(amount: number) { + weekDirection.value = amount > 0 ? 'next' : 'prev' const date = parse(selectedDate.value, 'yyyy-MM-dd', new Date()) selectedDate.value = format(addMonths(date, amount), 'yyyy-MM-dd') } function moveWeek(amount: number) { + weekDirection.value = amount > 0 ? 'next' : 'prev' const date = parse(selectedDate.value, 'yyyy-MM-dd', new Date()) selectedDate.value = format(addDays(date, amount * 7), 'yyyy-MM-dd') } @@ -352,3 +366,32 @@ function goBack() { if (history.length > 1) history.back() } + + diff --git a/pages/transactions/[id].vue b/pages/transactions/[id].vue index 8ea127f..43d4e7f 100644 --- a/pages/transactions/[id].vue +++ b/pages/transactions/[id].vue @@ -34,7 +34,7 @@ @@ -44,30 +44,33 @@
- +
- -
- - -
+
+ + +
-
- 위치 보기 - +
+ 위치 +
+ 보기 + +
+
@@ -76,7 +79,7 @@
- @@ -142,7 +145,11 @@ watch(transaction, (value) => { }, { immediate: true }) watch(selectableCategories, (items: any[]) => { - if (!items.some(item => item.id === form.categoryId)) form.categoryId = items[0]?.id || '' + if (form.categoryId && !items.some(item => item.id === form.categoryId)) form.categoryId = '' +}) + +const canSubmit = computed(() => { + return Boolean(form.assetId && form.categoryId && form.amount && form.amount > 0 && form.title.trim()) }) function setType(type: TransactionType) { diff --git a/todo.md b/todo.md index 77de4c3..99b5341 100644 --- a/todo.md +++ b/todo.md @@ -8,6 +8,7 @@ - 내역, 통계, 자산 페이지의 월 표시 위치와 좌우 이동 버튼 위치를 맞춘다. - PC 화면에서 각 페이지가 너무 모바일 화면처럼 보이지 않도록 표/패널 밀도를 조정한다. - 모바일과 PC에서 같은 기능이 서로 다른 위치에 흩어지지 않도록 액션 버튼 배치를 정리한다. +- 화면 전환, 날짜 이동, 바텀 시트 표시처럼 사용자가 조작 결과를 바로 느껴야 하는 부분에 모션 피드백을 추가한다. ## 2. 내역 화면