diff --git a/package-lock.json b/package-lock.json index f184231..f27b1b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -46,7 +46,7 @@ "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.0.0", - "date-fns": "^3.6.0", + "date-fns": "^4.1.0", "embla-carousel-react": "^8.3.0", "input-otp": "^1.2.4", "lucide-react": "^0.462.0", @@ -4581,9 +4581,9 @@ } }, "node_modules/date-fns": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz", - "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz", + "integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==", "license": "MIT", "funding": { "type": "github", diff --git a/package.json b/package.json index de06305..35a3358 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.0.0", - "date-fns": "^3.6.0", + "date-fns": "^4.1.0", "embla-carousel-react": "^8.3.0", "input-otp": "^1.2.4", "lucide-react": "^0.462.0", diff --git a/src/utils/sync/transaction/dateUtils.ts b/src/utils/sync/transaction/dateUtils.ts index b8334fb..ff17b54 100644 --- a/src/utils/sync/transaction/dateUtils.ts +++ b/src/utils/sync/transaction/dateUtils.ts @@ -1,5 +1,5 @@ -import { formatISO } from 'date-fns'; +import { formatISO, parseISO, isValid } from 'date-fns'; /** * 날짜 문자열을 ISO 형식으로 변환하는 함수 @@ -12,7 +12,7 @@ export const normalizeDate = (dateStr: string): string => { } try { - // "오늘"라는 표현이 있으면 현재 날짜로 변환 + // "오늘"이라는 표현이 있으면 현재 날짜로 변환 if (dateStr.includes('오늘')) { const today = new Date(); @@ -28,10 +28,47 @@ export const normalizeDate = (dateStr: string): string => { } // 일반 날짜 문자열은 그대로 Date 객체로 변환 시도 - return formatISO(new Date(dateStr)); + const date = new Date(dateStr); + if (isValid(date)) { + return formatISO(date); + } + + // 변환 실패 시 현재 시간 반환 + console.warn(`날짜 변환 오류: "${dateStr}"를 ISO 형식으로 변환할 수 없습니다.`); + return formatISO(new Date()); } catch (error) { - console.warn(`날짜 변환 오류: "${dateStr}"를 ISO 형식으로 변환할 수 없습니다.`, error); + console.error(`날짜 변환 오류: "${dateStr}"를 ISO 형식으로 변환할 수 없습니다.`, error); // 오류 발생 시 현재 시간 반환 (데이터 손실 방지) return formatISO(new Date()); } }; + +/** + * ISO 형식의 날짜 문자열을 사용자 친화적인 형식으로 변환 + */ +export const formatDateForDisplay = (isoDateStr: string): string => { + try { + // 유효한 ISO 날짜인지 확인 + const date = parseISO(isoDateStr); + if (!isValid(date)) { + return isoDateStr; // 유효하지 않으면 원본 반환 + } + + // 현재 날짜와 비교 + const today = new Date(); + const isToday = + date.getDate() === today.getDate() && + date.getMonth() === today.getMonth() && + date.getFullYear() === today.getFullYear(); + + if (isToday) { + return `오늘, ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`; + } + + // 그 외의 경우 YYYY년 MM월 DD일 형식으로 반환 + return `${date.getFullYear()}년 ${date.getMonth() + 1}월 ${date.getDate()}일 ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`; + } catch (error) { + console.error('날짜 포맷 변환 오류:', error); + return isoDateStr; // 오류 발생 시 원본 반환 + } +}; diff --git a/src/utils/sync/transaction/downloadTransaction.ts b/src/utils/sync/transaction/downloadTransaction.ts index 0cebea0..fbd637f 100644 --- a/src/utils/sync/transaction/downloadTransaction.ts +++ b/src/utils/sync/transaction/downloadTransaction.ts @@ -2,6 +2,7 @@ import { supabase } from '@/lib/supabase'; import { Transaction } from '@/components/TransactionCard'; import { isSyncEnabled } from '../syncSettings'; +import { formatDateForDisplay } from './dateUtils'; /** * Download transaction data from Supabase to local storage @@ -34,9 +35,10 @@ export const downloadTransactions = async (userId: string): Promise => { id: t.transaction_id || t.id, title: t.title, amount: t.amount, - date: t.date, + date: t.date ? formatDateForDisplay(t.date) : '날짜 없음', category: t.category, - type: t.type + type: t.type, + notes: t.notes })); // 기존 로컬 데이터 불러오기 diff --git a/src/utils/sync/transaction/uploadTransaction.ts b/src/utils/sync/transaction/uploadTransaction.ts index 7d8f019..a312dbe 100644 --- a/src/utils/sync/transaction/uploadTransaction.ts +++ b/src/utils/sync/transaction/uploadTransaction.ts @@ -50,7 +50,8 @@ export const uploadTransactions = async (userId: string): Promise => { date: normalizedDate, // 정규화된 날짜 사용 category: t.category, type: t.type, - transaction_id: t.id + transaction_id: t.id, + notes: t.notes || null }; if (existingIds.has(t.id)) { @@ -76,6 +77,8 @@ export const uploadTransactions = async (userId: string): Promise => { // 기존 트랜잭션 업데이트 (있는 경우) if (updateTransactions.length > 0) { console.log(`${updateTransactions.length}개의 기존 트랜잭션 업데이트`); + + // 각 트랜잭션을 개별적으로 업데이트 for (const transaction of updateTransactions) { const { error: updateError } = await supabase .from('transactions') @@ -84,7 +87,7 @@ export const uploadTransactions = async (userId: string): Promise => { .eq('user_id', userId); if (updateError) { - console.error('트랜잭션 업데이트 실패:', updateError); + console.error('트랜잭션 업데이트 실패:', updateError, transaction); // 실패해도 계속 진행 } }