Format dates for synchronization
Use ISO format for data synchronization and user-friendly format for display.
This commit is contained in:
@@ -8,6 +8,7 @@ import { supabase } from '@/lib/supabase';
|
||||
import { isSyncEnabled } from '@/utils/syncUtils';
|
||||
import ExpenseForm, { ExpenseFormValues } from './expenses/ExpenseForm';
|
||||
import { Transaction } from '@/components/TransactionCard';
|
||||
import { normalizeDate } from '@/utils/sync/transaction/dateUtils';
|
||||
|
||||
const AddTransactionButton = () => {
|
||||
const [showExpenseDialog, setShowExpenseDialog] = useState(false);
|
||||
@@ -53,11 +54,14 @@ const AddTransactionButton = () => {
|
||||
const { data: { user } } = await supabase.auth.getUser();
|
||||
|
||||
if (isSyncEnabled() && user) {
|
||||
// ISO 형식으로 날짜 변환
|
||||
const isoDate = normalizeDate(formattedDate);
|
||||
|
||||
const { error } = await supabase.from('transactions').insert({
|
||||
user_id: user.id,
|
||||
title: data.title,
|
||||
amount: parseInt(numericAmount),
|
||||
date: formattedDate,
|
||||
date: isoDate, // ISO 형식 사용
|
||||
category: data.category,
|
||||
type: 'expense',
|
||||
transaction_id: newExpense.id
|
||||
|
||||
@@ -3,6 +3,45 @@ import { Transaction } from '@/components/TransactionCard';
|
||||
import { supabase } from '@/lib/supabase';
|
||||
import { isSyncEnabled } from '@/utils/syncUtils';
|
||||
import { useAuth } from '@/contexts/auth/AuthProvider';
|
||||
import { formatISO, parseISO } from 'date-fns';
|
||||
|
||||
// ISO 형식으로 날짜 변환 (Supabase 저장용)
|
||||
const convertDateToISO = (dateStr: string): string => {
|
||||
try {
|
||||
// 이미 ISO 형식인 경우 그대로 반환
|
||||
if (dateStr.match(/^\d{4}-\d{2}-\d{2}T/)) {
|
||||
return dateStr;
|
||||
}
|
||||
|
||||
// "오늘, 시간" 형식 처리
|
||||
if (dateStr.includes('오늘')) {
|
||||
const today = new Date();
|
||||
|
||||
// 시간 추출 시도
|
||||
const timeMatch = dateStr.match(/(\d{1,2}):(\d{2})/);
|
||||
if (timeMatch) {
|
||||
const hours = parseInt(timeMatch[1], 10);
|
||||
const minutes = parseInt(timeMatch[2], 10);
|
||||
today.setHours(hours, minutes, 0, 0);
|
||||
}
|
||||
|
||||
return formatISO(today);
|
||||
}
|
||||
|
||||
// 일반 날짜 문자열은 그대로 Date 객체로 변환 시도
|
||||
const date = new Date(dateStr);
|
||||
if (!isNaN(date.getTime())) {
|
||||
return formatISO(date);
|
||||
}
|
||||
|
||||
// 변환 실패 시 현재 시간 반환
|
||||
console.warn(`날짜 변환 오류: "${dateStr}"를 ISO 형식으로 변환할 수 없습니다.`);
|
||||
return formatISO(new Date());
|
||||
} catch (error) {
|
||||
console.error(`날짜 변환 오류: "${dateStr}"`, error);
|
||||
return formatISO(new Date());
|
||||
}
|
||||
};
|
||||
|
||||
// Supabase와 트랜잭션 동기화
|
||||
export const syncTransactionsWithSupabase = async (user: any, transactions: Transaction[]): Promise<Transaction[]> => {
|
||||
@@ -56,12 +95,15 @@ export const updateTransactionInSupabase = async (user: any, transaction: Transa
|
||||
if (!user || !isSyncEnabled()) return;
|
||||
|
||||
try {
|
||||
// 날짜를 ISO 형식으로 변환
|
||||
const isoDate = convertDateToISO(transaction.date);
|
||||
|
||||
const { error } = await supabase.from('transactions')
|
||||
.upsert({
|
||||
user_id: user.id,
|
||||
title: transaction.title,
|
||||
amount: transaction.amount,
|
||||
date: transaction.date,
|
||||
date: isoDate, // ISO 형식 사용
|
||||
category: transaction.category,
|
||||
type: transaction.type,
|
||||
transaction_id: transaction.id
|
||||
@@ -69,6 +111,8 @@ export const updateTransactionInSupabase = async (user: any, transaction: Transa
|
||||
|
||||
if (error) {
|
||||
console.error('트랜잭션 업데이트 오류:', error);
|
||||
} else {
|
||||
console.log('Supabase 트랜잭션 업데이트 성공:', transaction.id);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Supabase 업데이트 오류:', error);
|
||||
@@ -86,6 +130,8 @@ export const deleteTransactionFromSupabase = async (user: any, transactionId: st
|
||||
|
||||
if (error) {
|
||||
console.error('트랜잭션 삭제 오류:', error);
|
||||
} else {
|
||||
console.log('Supabase 트랜잭션 삭제 성공:', transactionId);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Supabase 삭제 오류:', error);
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Transaction } from '@/components/TransactionCard';
|
||||
import { saveTransactionsToStorage } from '../../storageUtils';
|
||||
import { deleteTransactionFromSupabase } from '../../supabaseUtils';
|
||||
import { toast } from '@/hooks/useToast.wrapper';
|
||||
import { normalizeDate } from '@/utils/sync/transaction/dateUtils';
|
||||
|
||||
/**
|
||||
* 스토리지 및 Supabase 삭제 처리
|
||||
@@ -31,6 +32,10 @@ export const handleDeleteStorage = (
|
||||
// 동기적 에러를 피하기 위해 setTimeout으로 감싸기
|
||||
setTimeout(() => {
|
||||
try {
|
||||
// ISO 형식으로 날짜 변환
|
||||
const isoDate = normalizeDate(transactionToDelete.date);
|
||||
console.log('삭제 중인 트랜잭션 ISO 날짜:', isoDate);
|
||||
|
||||
deleteTransactionFromSupabase(user, id)
|
||||
.catch(error => {
|
||||
console.error('Supabase 삭제 오류:', error);
|
||||
|
||||
@@ -6,6 +6,7 @@ import { toast } from '@/hooks/useToast.wrapper';
|
||||
import { saveTransactionsToStorage } from '../storageUtils';
|
||||
import { updateTransactionInSupabase } from '../supabaseUtils';
|
||||
import { TransactionOperationProps } from './types';
|
||||
import { normalizeDate } from '@/utils/sync/transaction/dateUtils';
|
||||
|
||||
/**
|
||||
* 트랜잭션 업데이트 기능
|
||||
@@ -28,9 +29,15 @@ export const useUpdateTransaction = (
|
||||
// 상태 업데이트
|
||||
setTransactions(updatedTransactions);
|
||||
|
||||
// Supabase 업데이트 시도
|
||||
// Supabase 업데이트 시도 (날짜 형식 변환 추가)
|
||||
if (user) {
|
||||
updateTransactionInSupabase(user, updatedTransaction);
|
||||
// ISO 형식으로 날짜 변환
|
||||
const transactionWithIsoDate = {
|
||||
...updatedTransaction,
|
||||
dateForSync: normalizeDate(updatedTransaction.date)
|
||||
};
|
||||
|
||||
updateTransactionInSupabase(user, transactionWithIsoDate);
|
||||
}
|
||||
|
||||
// 이벤트 발생
|
||||
|
||||
@@ -43,6 +43,20 @@ export const useTransactionsEvents = (
|
||||
}, 200);
|
||||
};
|
||||
|
||||
// 트랜잭션 변경 이벤트 (통합 이벤트)
|
||||
const handleTransactionChange = (e: CustomEvent) => {
|
||||
console.log('트랜잭션 변경 이벤트 감지:', e.detail?.type);
|
||||
|
||||
// 처리 중 중복 호출 방지
|
||||
if (isProcessing) return;
|
||||
|
||||
isProcessing = true;
|
||||
setTimeout(() => {
|
||||
loadTransactions();
|
||||
isProcessing = false;
|
||||
}, 150);
|
||||
};
|
||||
|
||||
// 스토리지 이벤트
|
||||
const handleStorageEvent = (e: StorageEvent) => {
|
||||
if (e.key === 'transactions' || e.key === null) {
|
||||
@@ -76,6 +90,7 @@ export const useTransactionsEvents = (
|
||||
// 이벤트 리스너 등록
|
||||
window.addEventListener('transactionUpdated', handleTransactionUpdate);
|
||||
window.addEventListener('transactionDeleted', handleTransactionDelete);
|
||||
window.addEventListener('transactionChanged', handleTransactionChange as EventListener);
|
||||
window.addEventListener('storage', handleStorageEvent);
|
||||
window.addEventListener('focus', handleFocus);
|
||||
|
||||
@@ -89,6 +104,7 @@ export const useTransactionsEvents = (
|
||||
console.log('useTransactions - 이벤트 리스너 제거');
|
||||
window.removeEventListener('transactionUpdated', handleTransactionUpdate);
|
||||
window.removeEventListener('transactionDeleted', handleTransactionDelete);
|
||||
window.removeEventListener('transactionChanged', handleTransactionChange as EventListener);
|
||||
window.removeEventListener('storage', handleStorageEvent);
|
||||
window.removeEventListener('focus', handleFocus);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user