Refactor transaction sync module
Refactors the transaction sync module for better organization.
This commit is contained in:
37
src/utils/sync/transaction/dateUtils.ts
Normal file
37
src/utils/sync/transaction/dateUtils.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
import { formatISO } from 'date-fns';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 날짜 문자열을 ISO 형식으로 변환하는 함수
|
||||||
|
* "오늘, 19:00 PM"과 같은 형식을 처리하기 위한 함수
|
||||||
|
*/
|
||||||
|
export const normalizeDate = (dateStr: string): string => {
|
||||||
|
// 이미 ISO 형식인 경우 그대로 반환
|
||||||
|
if (dateStr.match(/^\d{4}-\d{2}-\d{2}T/)) {
|
||||||
|
return dateStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// "오늘"라는 표현이 있으면 현재 날짜로 변환
|
||||||
|
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 객체로 변환 시도
|
||||||
|
return formatISO(new Date(dateStr));
|
||||||
|
} catch (error) {
|
||||||
|
console.warn(`날짜 변환 오류: "${dateStr}"를 ISO 형식으로 변환할 수 없습니다.`, error);
|
||||||
|
// 오류 발생 시 현재 시간 반환 (데이터 손실 방지)
|
||||||
|
return formatISO(new Date());
|
||||||
|
}
|
||||||
|
};
|
||||||
35
src/utils/sync/transaction/deleteTransaction.ts
Normal file
35
src/utils/sync/transaction/deleteTransaction.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
import { supabase } from '@/lib/supabase';
|
||||||
|
import { isSyncEnabled } from '../syncSettings';
|
||||||
|
import { toast } from '@/hooks/useToast.wrapper';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 특정 트랜잭션 ID 삭제 처리
|
||||||
|
*/
|
||||||
|
export const deleteTransactionFromServer = async (userId: string, transactionId: string): Promise<void> => {
|
||||||
|
if (!isSyncEnabled()) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log(`트랜잭션 삭제 요청: ${transactionId}`);
|
||||||
|
const { error } = await supabase
|
||||||
|
.from('transactions')
|
||||||
|
.delete()
|
||||||
|
.eq('transaction_id', transactionId)
|
||||||
|
.eq('user_id', userId);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
console.error('트랜잭션 삭제 실패:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`트랜잭션 ${transactionId} 삭제 완료`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('트랜잭션 삭제 중 오류:', error);
|
||||||
|
// 에러 발생 시 토스트 알림
|
||||||
|
toast({
|
||||||
|
title: "삭제 동기화 실패",
|
||||||
|
description: "서버에서 트랜잭션을 삭제하는데 문제가 발생했습니다.",
|
||||||
|
variant: "destructive"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
72
src/utils/sync/transaction/downloadTransaction.ts
Normal file
72
src/utils/sync/transaction/downloadTransaction.ts
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
|
||||||
|
import { supabase } from '@/lib/supabase';
|
||||||
|
import { Transaction } from '@/components/TransactionCard';
|
||||||
|
import { isSyncEnabled } from '../syncSettings';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Download transaction data from Supabase to local storage
|
||||||
|
* 서버에서 로컬 스토리지로 데이터 다운로드 (병합 방식)
|
||||||
|
*/
|
||||||
|
export const downloadTransactions = async (userId: string): Promise<void> => {
|
||||||
|
if (!isSyncEnabled()) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log('서버에서 트랜잭션 데이터 다운로드 시작');
|
||||||
|
const { data, error } = await supabase
|
||||||
|
.from('transactions')
|
||||||
|
.select('*')
|
||||||
|
.eq('user_id', userId);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
console.error('트랜잭션 다운로드 실패:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data || data.length === 0) {
|
||||||
|
console.log('서버에 저장된 트랜잭션 없음');
|
||||||
|
return; // 서버에 데이터가 없으면 로컬 데이터 유지
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`서버에서 ${data.length}개의 트랜잭션 다운로드`);
|
||||||
|
|
||||||
|
// 서버 데이터를 로컬 형식으로 변환
|
||||||
|
const serverTransactions = data.map(t => ({
|
||||||
|
id: t.transaction_id || t.id,
|
||||||
|
title: t.title,
|
||||||
|
amount: t.amount,
|
||||||
|
date: t.date,
|
||||||
|
category: t.category,
|
||||||
|
type: t.type
|
||||||
|
}));
|
||||||
|
|
||||||
|
// 기존 로컬 데이터 불러오기
|
||||||
|
const localDataStr = localStorage.getItem('transactions');
|
||||||
|
const localTransactions = localDataStr ? JSON.parse(localDataStr) : [];
|
||||||
|
|
||||||
|
// 로컬 데이터와 서버 데이터 병합 (ID 기준)
|
||||||
|
const transactionMap = new Map();
|
||||||
|
|
||||||
|
// 로컬 데이터를 맵에 추가
|
||||||
|
localTransactions.forEach((tx: Transaction) => {
|
||||||
|
transactionMap.set(tx.id, tx);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 서버 데이터로 맵 업데이트 (서버 데이터 우선)
|
||||||
|
serverTransactions.forEach(tx => {
|
||||||
|
transactionMap.set(tx.id, tx);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 최종 병합된 데이터 생성
|
||||||
|
const mergedTransactions = Array.from(transactionMap.values());
|
||||||
|
|
||||||
|
// 로컬 스토리지에 저장
|
||||||
|
localStorage.setItem('transactions', JSON.stringify(mergedTransactions));
|
||||||
|
console.log(`총 ${mergedTransactions.length}개의 트랜잭션 병합 완료`);
|
||||||
|
|
||||||
|
// 이벤트 발생시켜 UI 업데이트
|
||||||
|
window.dispatchEvent(new Event('transactionUpdated'));
|
||||||
|
} catch (error) {
|
||||||
|
console.error('트랜잭션 다운로드 중 오류:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
10
src/utils/sync/transaction/index.ts
Normal file
10
src/utils/sync/transaction/index.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
import { uploadTransactions } from './uploadTransaction';
|
||||||
|
import { downloadTransactions } from './downloadTransaction';
|
||||||
|
import { deleteTransactionFromServer } from './deleteTransaction';
|
||||||
|
|
||||||
|
export {
|
||||||
|
uploadTransactions,
|
||||||
|
downloadTransactions,
|
||||||
|
deleteTransactionFromServer
|
||||||
|
};
|
||||||
98
src/utils/sync/transaction/uploadTransaction.ts
Normal file
98
src/utils/sync/transaction/uploadTransaction.ts
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
|
||||||
|
import { supabase } from '@/lib/supabase';
|
||||||
|
import { Transaction } from '@/components/TransactionCard';
|
||||||
|
import { isSyncEnabled } from '../syncSettings';
|
||||||
|
import { normalizeDate } from './dateUtils';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload transaction data from local storage to Supabase
|
||||||
|
* 로컬 데이터를 서버에 업로드 (새로운 또는 수정된 데이터만)
|
||||||
|
*/
|
||||||
|
export const uploadTransactions = async (userId: string): Promise<void> => {
|
||||||
|
if (!isSyncEnabled()) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const localTransactions = localStorage.getItem('transactions');
|
||||||
|
if (!localTransactions) return;
|
||||||
|
|
||||||
|
const transactions: Transaction[] = JSON.parse(localTransactions);
|
||||||
|
console.log(`로컬 트랜잭션 ${transactions.length}개 동기화 시작`);
|
||||||
|
|
||||||
|
if (transactions.length === 0) return; // 트랜잭션이 없으면 처리하지 않음
|
||||||
|
|
||||||
|
// 먼저 서버에서 현재 트랜잭션 목록 가져오기
|
||||||
|
const { data: existingData, error: fetchError } = await supabase
|
||||||
|
.from('transactions')
|
||||||
|
.select('transaction_id')
|
||||||
|
.eq('user_id', userId);
|
||||||
|
|
||||||
|
if (fetchError) {
|
||||||
|
console.error('기존 트랜잭션 조회 실패:', fetchError);
|
||||||
|
throw fetchError;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 서버에 이미 있는 트랜잭션 ID 맵 생성
|
||||||
|
const existingIds = new Set(existingData?.map(t => t.transaction_id) || []);
|
||||||
|
console.log(`서버에 이미 존재하는 트랜잭션: ${existingIds.size}개`);
|
||||||
|
|
||||||
|
// 삽입할 새 트랜잭션과 업데이트할 기존 트랜잭션 분리
|
||||||
|
const newTransactions = [];
|
||||||
|
const updateTransactions = [];
|
||||||
|
|
||||||
|
for (const t of transactions) {
|
||||||
|
// 날짜 형식 정규화
|
||||||
|
const normalizedDate = normalizeDate(t.date);
|
||||||
|
|
||||||
|
const transactionData = {
|
||||||
|
user_id: userId,
|
||||||
|
title: t.title,
|
||||||
|
amount: t.amount,
|
||||||
|
date: normalizedDate, // 정규화된 날짜 사용
|
||||||
|
category: t.category,
|
||||||
|
type: t.type,
|
||||||
|
transaction_id: t.id
|
||||||
|
};
|
||||||
|
|
||||||
|
if (existingIds.has(t.id)) {
|
||||||
|
updateTransactions.push(transactionData);
|
||||||
|
} else {
|
||||||
|
newTransactions.push(transactionData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 새 트랜잭션 삽입 (있는 경우)
|
||||||
|
if (newTransactions.length > 0) {
|
||||||
|
console.log(`${newTransactions.length}개의 새 트랜잭션 업로드`);
|
||||||
|
const { error: insertError } = await supabase
|
||||||
|
.from('transactions')
|
||||||
|
.insert(newTransactions);
|
||||||
|
|
||||||
|
if (insertError) {
|
||||||
|
console.error('새 트랜잭션 업로드 실패:', insertError);
|
||||||
|
throw insertError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 기존 트랜잭션 업데이트 (있는 경우)
|
||||||
|
if (updateTransactions.length > 0) {
|
||||||
|
console.log(`${updateTransactions.length}개의 기존 트랜잭션 업데이트`);
|
||||||
|
for (const transaction of updateTransactions) {
|
||||||
|
const { error: updateError } = await supabase
|
||||||
|
.from('transactions')
|
||||||
|
.update(transaction)
|
||||||
|
.eq('transaction_id', transaction.transaction_id)
|
||||||
|
.eq('user_id', userId);
|
||||||
|
|
||||||
|
if (updateError) {
|
||||||
|
console.error('트랜잭션 업데이트 실패:', updateError);
|
||||||
|
// 실패해도 계속 진행
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('트랜잭션 업로드 완료');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('트랜잭션 업로드 실패:', error);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,233 +1,13 @@
|
|||||||
|
|
||||||
import { supabase } from '@/lib/supabase';
|
// 트랜잭션 동기화 기능을 내보내는 파일
|
||||||
import { Transaction } from '@/components/TransactionCard';
|
import {
|
||||||
import { isSyncEnabled } from './syncSettings';
|
uploadTransactions,
|
||||||
import { toast } from '@/hooks/useToast.wrapper';
|
downloadTransactions,
|
||||||
import { formatISO } from 'date-fns';
|
deleteTransactionFromServer
|
||||||
|
} from './transaction';
|
||||||
|
|
||||||
/**
|
export {
|
||||||
* 날짜 문자열을 ISO 형식으로 변환하는 함수
|
uploadTransactions,
|
||||||
* "오늘, 19:00 PM"과 같은 형식을 처리하기 위한 함수
|
downloadTransactions,
|
||||||
*/
|
deleteTransactionFromServer
|
||||||
const normalizeDate = (dateStr: string): string => {
|
|
||||||
// 이미 ISO 형식인 경우 그대로 반환
|
|
||||||
if (dateStr.match(/^\d{4}-\d{2}-\d{2}T/)) {
|
|
||||||
return dateStr;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// "오늘"라는 표현이 있으면 현재 날짜로 변환
|
|
||||||
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 객체로 변환 시도
|
|
||||||
return formatISO(new Date(dateStr));
|
|
||||||
} catch (error) {
|
|
||||||
console.warn(`날짜 변환 오류: "${dateStr}"를 ISO 형식으로 변환할 수 없습니다.`, error);
|
|
||||||
// 오류 발생 시 현재 시간 반환 (데이터 손실 방지)
|
|
||||||
return formatISO(new Date());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Upload transaction data from local storage to Supabase
|
|
||||||
* 로컬 데이터를 서버에 업로드 (새로운 또는 수정된 데이터만)
|
|
||||||
*/
|
|
||||||
export const uploadTransactions = async (userId: string): Promise<void> => {
|
|
||||||
if (!isSyncEnabled()) return;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const localTransactions = localStorage.getItem('transactions');
|
|
||||||
if (!localTransactions) return;
|
|
||||||
|
|
||||||
const transactions: Transaction[] = JSON.parse(localTransactions);
|
|
||||||
console.log(`로컬 트랜잭션 ${transactions.length}개 동기화 시작`);
|
|
||||||
|
|
||||||
if (transactions.length === 0) return; // 트랜잭션이 없으면 처리하지 않음
|
|
||||||
|
|
||||||
// 먼저 서버에서 현재 트랜잭션 목록 가져오기
|
|
||||||
const { data: existingData, error: fetchError } = await supabase
|
|
||||||
.from('transactions')
|
|
||||||
.select('transaction_id')
|
|
||||||
.eq('user_id', userId);
|
|
||||||
|
|
||||||
if (fetchError) {
|
|
||||||
console.error('기존 트랜잭션 조회 실패:', fetchError);
|
|
||||||
throw fetchError;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 서버에 이미 있는 트랜잭션 ID 맵 생성
|
|
||||||
const existingIds = new Set(existingData?.map(t => t.transaction_id) || []);
|
|
||||||
console.log(`서버에 이미 존재하는 트랜잭션: ${existingIds.size}개`);
|
|
||||||
|
|
||||||
// 삽입할 새 트랜잭션과 업데이트할 기존 트랜잭션 분리
|
|
||||||
const newTransactions = [];
|
|
||||||
const updateTransactions = [];
|
|
||||||
|
|
||||||
for (const t of transactions) {
|
|
||||||
// 날짜 형식 정규화
|
|
||||||
const normalizedDate = normalizeDate(t.date);
|
|
||||||
|
|
||||||
const transactionData = {
|
|
||||||
user_id: userId,
|
|
||||||
title: t.title,
|
|
||||||
amount: t.amount,
|
|
||||||
date: normalizedDate, // 정규화된 날짜 사용
|
|
||||||
category: t.category,
|
|
||||||
type: t.type,
|
|
||||||
transaction_id: t.id
|
|
||||||
};
|
|
||||||
|
|
||||||
if (existingIds.has(t.id)) {
|
|
||||||
updateTransactions.push(transactionData);
|
|
||||||
} else {
|
|
||||||
newTransactions.push(transactionData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 새 트랜잭션 삽입 (있는 경우)
|
|
||||||
if (newTransactions.length > 0) {
|
|
||||||
console.log(`${newTransactions.length}개의 새 트랜잭션 업로드`);
|
|
||||||
const { error: insertError } = await supabase
|
|
||||||
.from('transactions')
|
|
||||||
.insert(newTransactions);
|
|
||||||
|
|
||||||
if (insertError) {
|
|
||||||
console.error('새 트랜잭션 업로드 실패:', insertError);
|
|
||||||
throw insertError;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 기존 트랜잭션 업데이트 (있는 경우)
|
|
||||||
if (updateTransactions.length > 0) {
|
|
||||||
console.log(`${updateTransactions.length}개의 기존 트랜잭션 업데이트`);
|
|
||||||
for (const transaction of updateTransactions) {
|
|
||||||
const { error: updateError } = await supabase
|
|
||||||
.from('transactions')
|
|
||||||
.update(transaction)
|
|
||||||
.eq('transaction_id', transaction.transaction_id)
|
|
||||||
.eq('user_id', userId);
|
|
||||||
|
|
||||||
if (updateError) {
|
|
||||||
console.error('트랜잭션 업데이트 실패:', updateError);
|
|
||||||
// 실패해도 계속 진행
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log('트랜잭션 업로드 완료');
|
|
||||||
} catch (error) {
|
|
||||||
console.error('트랜잭션 업로드 실패:', error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Download transaction data from Supabase to local storage
|
|
||||||
* 서버에서 로컬 스토리지로 데이터 다운로드 (병합 방식)
|
|
||||||
*/
|
|
||||||
export const downloadTransactions = async (userId: string): Promise<void> => {
|
|
||||||
if (!isSyncEnabled()) return;
|
|
||||||
|
|
||||||
try {
|
|
||||||
console.log('서버에서 트랜잭션 데이터 다운로드 시작');
|
|
||||||
const { data, error } = await supabase
|
|
||||||
.from('transactions')
|
|
||||||
.select('*')
|
|
||||||
.eq('user_id', userId);
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
console.error('트랜잭션 다운로드 실패:', error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!data || data.length === 0) {
|
|
||||||
console.log('서버에 저장된 트랜잭션 없음');
|
|
||||||
return; // 서버에 데이터가 없으면 로컬 데이터 유지
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`서버에서 ${data.length}개의 트랜잭션 다운로드`);
|
|
||||||
|
|
||||||
// 서버 데이터를 로컬 형식으로 변환
|
|
||||||
const serverTransactions = data.map(t => ({
|
|
||||||
id: t.transaction_id || t.id,
|
|
||||||
title: t.title,
|
|
||||||
amount: t.amount,
|
|
||||||
date: t.date,
|
|
||||||
category: t.category,
|
|
||||||
type: t.type
|
|
||||||
}));
|
|
||||||
|
|
||||||
// 기존 로컬 데이터 불러오기
|
|
||||||
const localDataStr = localStorage.getItem('transactions');
|
|
||||||
const localTransactions = localDataStr ? JSON.parse(localDataStr) : [];
|
|
||||||
|
|
||||||
// 로컬 데이터와 서버 데이터 병합 (ID 기준)
|
|
||||||
const transactionMap = new Map();
|
|
||||||
|
|
||||||
// 로컬 데이터를 맵에 추가
|
|
||||||
localTransactions.forEach((tx: Transaction) => {
|
|
||||||
transactionMap.set(tx.id, tx);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 서버 데이터로 맵 업데이트 (서버 데이터 우선)
|
|
||||||
serverTransactions.forEach(tx => {
|
|
||||||
transactionMap.set(tx.id, tx);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 최종 병합된 데이터 생성
|
|
||||||
const mergedTransactions = Array.from(transactionMap.values());
|
|
||||||
|
|
||||||
// 로컬 스토리지에 저장
|
|
||||||
localStorage.setItem('transactions', JSON.stringify(mergedTransactions));
|
|
||||||
console.log(`총 ${mergedTransactions.length}개의 트랜잭션 병합 완료`);
|
|
||||||
|
|
||||||
// 이벤트 발생시켜 UI 업데이트
|
|
||||||
window.dispatchEvent(new Event('transactionUpdated'));
|
|
||||||
} catch (error) {
|
|
||||||
console.error('트랜잭션 다운로드 중 오류:', error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 특정 트랜잭션 ID 삭제 처리
|
|
||||||
*/
|
|
||||||
export const deleteTransactionFromServer = async (userId: string, transactionId: string): Promise<void> => {
|
|
||||||
if (!isSyncEnabled()) return;
|
|
||||||
|
|
||||||
try {
|
|
||||||
console.log(`트랜잭션 삭제 요청: ${transactionId}`);
|
|
||||||
const { error } = await supabase
|
|
||||||
.from('transactions')
|
|
||||||
.delete()
|
|
||||||
.eq('transaction_id', transactionId)
|
|
||||||
.eq('user_id', userId);
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
console.error('트랜잭션 삭제 실패:', error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(`트랜잭션 ${transactionId} 삭제 완료`);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('트랜잭션 삭제 중 오류:', error);
|
|
||||||
// 에러 발생 시 토스트 알림
|
|
||||||
toast({
|
|
||||||
title: "삭제 동기화 실패",
|
|
||||||
description: "서버에서 트랜잭션을 삭제하는데 문제가 발생했습니다.",
|
|
||||||
variant: "destructive"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
import { isSyncEnabled, setSyncEnabled, getLastSyncTime, setLastSyncTime, initSyncSettings } from './sync/syncSettings';
|
import { isSyncEnabled, setSyncEnabled, getLastSyncTime, setLastSyncTime, initSyncSettings } from './sync/syncSettings';
|
||||||
import { uploadTransactions, downloadTransactions } from './sync/transactionSync';
|
import { uploadTransactions, downloadTransactions, deleteTransactionFromServer } from './sync/transactionSync';
|
||||||
import { uploadBudgets, downloadBudgets } from './sync/budgetSync';
|
import { uploadBudgets, downloadBudgets } from './sync/budgetSync';
|
||||||
|
|
||||||
// Export all utility functions to maintain the same public API
|
// Export all utility functions to maintain the same public API
|
||||||
@@ -9,6 +9,7 @@ export {
|
|||||||
setSyncEnabled,
|
setSyncEnabled,
|
||||||
uploadTransactions,
|
uploadTransactions,
|
||||||
downloadTransactions,
|
downloadTransactions,
|
||||||
|
deleteTransactionFromServer,
|
||||||
uploadBudgets,
|
uploadBudgets,
|
||||||
downloadBudgets,
|
downloadBudgets,
|
||||||
getLastSyncTime,
|
getLastSyncTime,
|
||||||
|
|||||||
Reference in New Issue
Block a user