Refactor useSyncSettings hook

Refactors the useSyncSettings hook into smaller, more manageable modules to improve code organization and maintainability. The functionality of the hook remains unchanged.
This commit is contained in:
gpt-engineer-app[bot]
2025-03-18 01:24:31 +00:00
parent a4533aea70
commit b96e0877b7
5 changed files with 246 additions and 194 deletions

View File

@@ -0,0 +1,41 @@
import { toast } from '@/hooks/useToast.wrapper';
import { SyncResult } from '@/utils/syncUtils';
/**
* 동기화 결과 처리 함수
*/
export const handleSyncResult = (result: SyncResult) => {
if (result.success) {
if (result.downloadSuccess && result.uploadSuccess) {
toast({
title: "동기화 완료",
description: "모든 데이터가 클라우드에 동기화되었습니다.",
});
} else if (result.downloadSuccess) {
toast({
title: "다운로드만 성공",
description: "서버 데이터를 가져왔지만, 업로드에 실패했습니다.",
variant: "destructive"
});
} else if (result.uploadSuccess) {
toast({
title: "업로드만 성공",
description: "로컬 데이터를 업로드했지만, 다운로드에 실패했습니다.",
variant: "destructive"
});
} else if (result.partial) {
toast({
title: "동기화 일부 완료",
description: "일부 데이터만 동기화되었습니다. 다시 시도해보세요.",
variant: "destructive"
});
}
} else {
toast({
title: "일부 동기화 실패",
description: "일부 데이터 동기화 중 문제가 발생했습니다. 다시 시도해주세요.",
variant: "destructive"
});
}
};

View File

@@ -0,0 +1,52 @@
import { useState } from 'react';
import { toast } from '@/hooks/useToast.wrapper';
import { trySyncAllData, SyncResult } from '@/utils/syncUtils';
import { getLastSyncTime, setLastSyncTime } from '@/utils/syncUtils';
import { handleSyncResult } from './syncResultHandler';
/**
* 수동 동기화 기능을 위한 커스텀 훅
*/
export const useManualSync = (user: any) => {
const [syncing, setSyncing] = useState(false);
// 수동 동기화 핸들러
const handleManualSync = async () => {
if (!user) {
toast({
title: "로그인 필요",
description: "데이터 동기화를 위해 로그인이 필요합니다.",
variant: "destructive"
});
return;
}
await performSync(user.id);
};
// 실제 동기화 수행 함수
const performSync = async (userId: string) => {
if (!userId) return;
try {
setSyncing(true);
// 안전한 동기화 함수 사용
const result = await trySyncAllData(userId);
handleSyncResult(result);
setLastSyncTime(getLastSyncTime());
} catch (error) {
console.error('동기화 오류:', error);
toast({
title: "동기화 오류",
description: "동기화 중 문제가 발생했습니다. 다시 시도해주세요.",
variant: "destructive"
});
} finally {
setSyncing(false);
}
};
return { syncing, handleManualSync };
};

View File

@@ -0,0 +1,31 @@
import { useState, useEffect } from 'react';
import { getLastSyncTime } from '@/utils/syncUtils';
/**
* 동기화 상태와 마지막 동기화 시간을 관리하는 커스텀 훅
*/
export const useSyncStatus = () => {
const [lastSync, setLastSync] = useState<string | null>(getLastSyncTime());
// 마지막 동기화 시간 정기적으로 업데이트
useEffect(() => {
const intervalId = setInterval(() => {
setLastSync(getLastSyncTime());
}, 10000); // 10초마다 업데이트
return () => clearInterval(intervalId);
}, []);
// 마지막 동기화 시간 포맷팅
const formatLastSyncTime = () => {
if (!lastSync) return "아직 동기화된 적 없음";
if (lastSync === '부분-다운로드') return "부분 동기화 (다운로드만)";
const date = new Date(lastSync);
return `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
};
return { lastSync, formatLastSyncTime };
};

View File

@@ -0,0 +1,116 @@
import { useState, useEffect } from 'react';
import { useAuth } from '@/contexts/auth';
import { toast } from '@/hooks/useToast.wrapper';
import {
isSyncEnabled,
setSyncEnabled
} from '@/utils/syncUtils';
import { trySyncAllData } from '@/utils/syncUtils';
/**
* 동기화 토글 기능을 위한 커스텀 훅
*/
export const useSyncToggle = () => {
const [enabled, setEnabled] = useState(isSyncEnabled());
const { user } = useAuth();
// 사용자 로그인 상태 변경 감지
useEffect(() => {
// 사용자 로그인 상태에 따라 동기화 설정 업데이트
const updateSyncState = () => {
if (!user && isSyncEnabled()) {
// 사용자가 로그아웃했고 동기화가 활성화되어 있으면 비활성화
setSyncEnabled(false);
setEnabled(false);
console.log('로그아웃으로 인해 동기화 설정이 비활성화되었습니다.');
}
// 동기화 상태 업데이트
setEnabled(isSyncEnabled());
};
// 초기 호출
updateSyncState();
// 인증 상태 변경 이벤트 리스너
window.addEventListener('auth-state-changed', updateSyncState);
return () => {
window.removeEventListener('auth-state-changed', updateSyncState);
};
}, [user]);
// 동기화 토글 핸들러
const handleSyncToggle = async (checked: boolean) => {
if (!user && checked) {
toast({
title: "로그인 필요",
description: "데이터 동기화를 위해 로그인이 필요합니다.",
variant: "destructive"
});
return;
}
// 현재 로컬 데이터 백업
const budgetDataBackup = localStorage.getItem('budgetData');
const categoryBudgetsBackup = localStorage.getItem('categoryBudgets');
const transactionsBackup = localStorage.getItem('transactions');
console.log('동기화 설정 변경 전 로컬 데이터 백업:', {
budgetData: budgetDataBackup ? '있음' : '없음',
categoryBudgets: categoryBudgetsBackup ? '있음' : '없음',
transactions: transactionsBackup ? '있음' : '없음'
});
setEnabled(checked);
setSyncEnabled(checked);
if (checked && user) {
try {
// 동기화 활성화 시 즉시 동기화 실행
await performSync(user.id);
} catch (error) {
console.error('동기화 중 오류, 로컬 데이터 복원 시도:', error);
// 오류 발생 시 백업 데이터 복원
if (budgetDataBackup) {
localStorage.setItem('budgetData', budgetDataBackup);
}
if (categoryBudgetsBackup) {
localStorage.setItem('categoryBudgets', categoryBudgetsBackup);
}
if (transactionsBackup) {
localStorage.setItem('transactions', transactionsBackup);
}
// 이벤트 발생시켜 UI 업데이트
window.dispatchEvent(new Event('budgetDataUpdated'));
window.dispatchEvent(new Event('categoryBudgetsUpdated'));
window.dispatchEvent(new Event('transactionUpdated'));
toast({
title: "동기화 오류",
description: "동기화 중 문제가 발생하여 로컬 데이터가 복원되었습니다.",
variant: "destructive"
});
}
}
};
return { enabled, setEnabled, handleSyncToggle };
};
// 실제 동기화 수행 함수
const performSync = async (userId: string) => {
if (!userId) return;
try {
// 안전한 동기화 함수 사용
const result = await trySyncAllData(userId);
return result;
} catch (error) {
console.error('동기화 오류:', error);
throw error;
}
};

View File

@@ -1,206 +1,18 @@
import { useState, useEffect } from 'react';
import { useAuth } from '@/contexts/auth';
import { toast } from '@/hooks/useToast.wrapper';
import {
isSyncEnabled,
setSyncEnabled,
getLastSyncTime,
trySyncAllData,
SyncResult
} from '@/utils/syncUtils';
import { useSyncToggle } from './sync/useSyncToggle';
import { useManualSync } from './sync/useManualSync';
import { useSyncStatus } from './sync/useSyncStatus';
/**
* 동기화 설정 관리를 위한 커스텀 훅
*/
export const useSyncSettings = () => {
const [enabled, setEnabled] = useState(isSyncEnabled());
const [syncing, setSyncing] = useState(false);
const [lastSync, setLastSync] = useState<string | null>(getLastSyncTime());
const { user } = useAuth();
// 사용자 로그인 상태 변경 감지
useEffect(() => {
// 사용자 로그인 상태에 따라 동기화 설정 업데이트
const updateSyncState = () => {
if (!user && isSyncEnabled()) {
// 사용자가 로그아웃했고 동기화가 활성화되어 있으면 비활성화
setSyncEnabled(false);
setEnabled(false);
setLastSync(null);
console.log('로그아웃으로 인해 동기화 설정이 비활성화되었습니다.');
}
// 동기화 상태 업데이트
setEnabled(isSyncEnabled());
setLastSync(getLastSyncTime());
};
// 초기 호출
updateSyncState();
// 인증 상태 변경 이벤트 리스너
window.addEventListener('auth-state-changed', updateSyncState);
return () => {
window.removeEventListener('auth-state-changed', updateSyncState);
};
}, [user]);
// 마지막 동기화 시간 정기적으로 업데이트
useEffect(() => {
const intervalId = setInterval(() => {
setLastSync(getLastSyncTime());
}, 10000); // 10초마다 업데이트
return () => clearInterval(intervalId);
}, []);
// 동기화 토글 핸들러
const handleSyncToggle = async (checked: boolean) => {
if (!user && checked) {
toast({
title: "로그인 필요",
description: "데이터 동기화를 위해 로그인이 필요합니다.",
variant: "destructive"
});
return;
}
// 현재 로컬 데이터 백업
const budgetDataBackup = localStorage.getItem('budgetData');
const categoryBudgetsBackup = localStorage.getItem('categoryBudgets');
const transactionsBackup = localStorage.getItem('transactions');
console.log('동기화 설정 변경 전 로컬 데이터 백업:', {
budgetData: budgetDataBackup ? '있음' : '없음',
categoryBudgets: categoryBudgetsBackup ? '있음' : '없음',
transactions: transactionsBackup ? '있음' : '없음'
});
setEnabled(checked);
setSyncEnabled(checked);
if (checked && user) {
try {
// 동기화 활성화 시 즉시 동기화 실행
await performSync();
} catch (error) {
console.error('동기화 중 오류, 로컬 데이터 복원 시도:', error);
// 오류 발생 시 백업 데이터 복원
if (budgetDataBackup) {
localStorage.setItem('budgetData', budgetDataBackup);
}
if (categoryBudgetsBackup) {
localStorage.setItem('categoryBudgets', categoryBudgetsBackup);
}
if (transactionsBackup) {
localStorage.setItem('transactions', transactionsBackup);
}
// 이벤트 발생시켜 UI 업데이트
window.dispatchEvent(new Event('budgetDataUpdated'));
window.dispatchEvent(new Event('categoryBudgetsUpdated'));
window.dispatchEvent(new Event('transactionUpdated'));
toast({
title: "동기화 오류",
description: "동기화 중 문제가 발생하여 로컬 데이터가 복원되었습니다.",
variant: "destructive"
});
}
}
};
// 수동 동기화 핸들러
const handleManualSync = async () => {
if (!user) {
toast({
title: "로그인 필요",
description: "데이터 동기화를 위해 로그인이 필요합니다.",
variant: "destructive"
});
return;
}
await performSync();
};
// 실제 동기화 수행 함수
const performSync = async () => {
if (!user) return;
try {
setSyncing(true);
// 안전한 동기화 함수 사용
const result = await trySyncAllData(user.id);
handleSyncResult(result);
setLastSync(getLastSyncTime());
} catch (error) {
console.error('동기화 오류:', error);
toast({
title: "동기화 오류",
description: "동기화 중 문제가 발생했습니다. 다시 시도해주세요.",
variant: "destructive"
});
// 심각한 오류 발생 시 동기화 비활성화
if (!enabled) {
setEnabled(false);
setSyncEnabled(false);
}
} finally {
setSyncing(false);
}
};
// 동기화 결과 처리 함수
const handleSyncResult = (result: SyncResult) => {
if (result.success) {
if (result.downloadSuccess && result.uploadSuccess) {
toast({
title: "동기화 완료",
description: "모든 데이터가 클라우드에 동기화되었습니다.",
});
} else if (result.downloadSuccess) {
toast({
title: "다운로드만 성공",
description: "서버 데이터를 가져왔지만, 업로드에 실패했습니다.",
variant: "destructive"
});
} else if (result.uploadSuccess) {
toast({
title: "업로드만 성공",
description: "로컬 데이터를 업로드했지만, 다운로드에 실패했습니다.",
variant: "destructive"
});
} else if (result.partial) {
toast({
title: "동기화 일부 완료",
description: "일부 데이터만 동기화되었습니다. 다시 시도해보세요.",
variant: "destructive"
});
}
} else {
toast({
title: "일부 동기화 실패",
description: "일부 데이터 동기화 중 문제가 발생했습니다. 다시 시도해주세요.",
variant: "destructive"
});
}
};
// 마지막 동기화 시간 포맷팅
const formatLastSyncTime = () => {
if (!lastSync) return "아직 동기화된 적 없음";
if (lastSync === '부분-다운로드') return "부분 동기화 (다운로드만)";
const date = new Date(lastSync);
return `${date.toLocaleDateString()} ${date.toLocaleTimeString()}`;
};
const { enabled, setEnabled, handleSyncToggle } = useSyncToggle();
const { syncing, handleManualSync } = useManualSync(user);
const { lastSync, formatLastSyncTime } = useSyncStatus();
return {
enabled,