네트워크 알림 OFF 및 ts 오류 수정
This commit is contained in:
@@ -20,7 +20,6 @@ import PaymentMethods from './pages/PaymentMethods';
|
||||
import Settings from './pages/Settings';
|
||||
import { BudgetProvider } from './contexts/BudgetContext';
|
||||
import PrivateRoute from './components/auth/PrivateRoute';
|
||||
import NetworkStatusIndicator from './components/NetworkStatusIndicator';
|
||||
import { initSyncState, startNetworkMonitoring } from './utils/syncUtils';
|
||||
|
||||
// 전역 오류 핸들러
|
||||
@@ -152,7 +151,6 @@ function App() {
|
||||
</Routes>
|
||||
</div>
|
||||
<Toaster />
|
||||
<NetworkStatusIndicator />
|
||||
</div>
|
||||
</Router>
|
||||
</BudgetProvider>
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { getNetworkStatus, onNetworkStatusChange, NetworkStatus } from '../utils/networkUtils';
|
||||
import { getSyncState, onSyncStateChange, SyncState } from '../utils/syncUtils';
|
||||
import { toast } from '../hooks/toast';
|
||||
|
||||
/**
|
||||
* 네트워크 상태 표시기 컴포넌트 속성
|
||||
*/
|
||||
interface NetworkStatusIndicatorProps {
|
||||
showToast?: boolean;
|
||||
showIndicator?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 네트워크 상태 및 동기화 상태를 표시하는 컴포넌트
|
||||
*/
|
||||
const NetworkStatusIndicator: React.FC<NetworkStatusIndicatorProps> = ({
|
||||
showToast = true,
|
||||
showIndicator = true
|
||||
}) => {
|
||||
// 네트워크 상태
|
||||
const [networkStatus, setNetworkStatus] = useState<NetworkStatus>(getNetworkStatus());
|
||||
// 동기화 상태
|
||||
const [syncState, setSyncState] = useState<SyncState>(getSyncState());
|
||||
|
||||
useEffect(() => {
|
||||
// 네트워크 상태 변경 감지
|
||||
const unsubscribeNetwork = onNetworkStatusChange((status) => {
|
||||
setNetworkStatus(status);
|
||||
|
||||
// 오프라인 상태가 되면 토스트 표시
|
||||
if (status === 'offline' && showToast) {
|
||||
toast({
|
||||
title: '네트워크 연결 끊김',
|
||||
description: '네트워크 연결이 끊겼습니다. 오프라인 모드로 전환됩니다.',
|
||||
variant: 'destructive',
|
||||
});
|
||||
}
|
||||
|
||||
// 온라인 상태로 돌아오면 토스트 표시
|
||||
if (status === 'online' && showToast) {
|
||||
toast({
|
||||
title: '네트워크 연결 복구',
|
||||
description: '네트워크 연결이 복구되었습니다. 데이터 동기화가 재개됩니다.',
|
||||
variant: 'default',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// 동기화 상태 변경 감지
|
||||
const unsubscribeSync = onSyncStateChange((state) => {
|
||||
setSyncState(state);
|
||||
|
||||
// 동기화 오류가 발생하면 토스트 표시
|
||||
if (state.error && showToast) {
|
||||
toast({
|
||||
title: '동기화 오류',
|
||||
description: `동기화 중 오류가 발생했습니다: ${state.error}`,
|
||||
variant: 'destructive',
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return () => {
|
||||
// 구독 해제
|
||||
unsubscribeNetwork();
|
||||
unsubscribeSync();
|
||||
};
|
||||
}, [showToast]);
|
||||
|
||||
// 네트워크 상태에 따른 스타일 및 메시지
|
||||
const getNetworkStatusStyle = () => {
|
||||
switch (networkStatus) {
|
||||
case 'online':
|
||||
return { color: '#4caf50', message: '온라인' };
|
||||
case 'offline':
|
||||
return { color: '#f44336', message: '오프라인' };
|
||||
case 'reconnecting':
|
||||
return { color: '#ff9800', message: '재연결 중' };
|
||||
default:
|
||||
return { color: '#9e9e9e', message: '알 수 없음' };
|
||||
}
|
||||
};
|
||||
|
||||
// 동기화 상태에 따른 스타일 및 메시지
|
||||
const getSyncStatusStyle = () => {
|
||||
if (syncState.isSyncing) {
|
||||
return { color: '#2196f3', message: '동기화 중...' };
|
||||
}
|
||||
|
||||
if (syncState.error) {
|
||||
return { color: '#f44336', message: '동기화 오류' };
|
||||
}
|
||||
|
||||
if (!syncState.isEnabled) {
|
||||
return { color: '#9e9e9e', message: '동기화 비활성화' };
|
||||
}
|
||||
|
||||
return { color: '#4caf50', message: '동기화됨' };
|
||||
};
|
||||
|
||||
// 인디케이터 스타일
|
||||
const networkStyle = getNetworkStatusStyle();
|
||||
const syncStyle = getSyncStatusStyle();
|
||||
|
||||
// 인디케이터 컴포넌트
|
||||
const indicatorStyle = {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
padding: '4px 8px',
|
||||
borderRadius: '4px',
|
||||
fontSize: '12px',
|
||||
fontWeight: 'bold',
|
||||
margin: '0 4px'
|
||||
};
|
||||
|
||||
if (!showIndicator) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{
|
||||
position: 'fixed',
|
||||
bottom: '10px',
|
||||
right: '10px',
|
||||
zIndex: 1000,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '5px'
|
||||
}}>
|
||||
<div style={{
|
||||
...indicatorStyle,
|
||||
backgroundColor: networkStyle.color,
|
||||
color: 'white'
|
||||
}}>
|
||||
{networkStyle.message}
|
||||
</div>
|
||||
|
||||
<div style={{
|
||||
...indicatorStyle,
|
||||
backgroundColor: syncStyle.color,
|
||||
color: 'white'
|
||||
}}>
|
||||
{syncStyle.message}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default NetworkStatusIndicator;
|
||||
@@ -18,7 +18,8 @@ export const withRetry = async <T>(
|
||||
maxRetries = MAX_RETRY_COUNT,
|
||||
retryDelay = INITIAL_RETRY_DELAY,
|
||||
onRetry = () => {},
|
||||
shouldRetry = () => true
|
||||
shouldRetry = () => true,
|
||||
entityType
|
||||
} = options;
|
||||
|
||||
let lastError: Error | unknown;
|
||||
|
||||
@@ -32,4 +32,5 @@ export interface RetryOptions<T> {
|
||||
retryDelay?: number;
|
||||
onRetry?: (attempt: number, error: Error | unknown) => void;
|
||||
shouldRetry?: (error: Error | unknown) => boolean;
|
||||
entityType?: string; // 동기화 작업 유형 (예: '트랜잭션 업로드', '예산 다운로드' 등)
|
||||
}
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
/**
|
||||
* 네트워크 유틸리티 모듈
|
||||
*
|
||||
* 이 파일은 하위 모듈로 리팩토링되었습니다.
|
||||
* 기존 코드와의 호환성을 위해 새 모듈에서 모든 기능을 재내보냅니다.
|
||||
*/
|
||||
|
||||
// 모든 네트워크 유틸리티 기능을 새 모듈에서 가져와 재내보내기
|
||||
export * from './network';
|
||||
|
||||
/**
|
||||
* 네트워크 상태 관리 및 오류 처리를 위한 유틸리티
|
||||
*/
|
||||
@@ -457,6 +467,7 @@ export const withRetry = async <T>(
|
||||
retryDelay?: number;
|
||||
onRetry?: (attempt: number, error: Error | unknown) => void;
|
||||
shouldRetry?: (error: Error | unknown) => boolean;
|
||||
entityType?: string; // 동기화 작업 유형 (예: '트랜잭션 업로드', '예산 다운로드' 등)
|
||||
} = {}
|
||||
): Promise<T> => {
|
||||
const {
|
||||
@@ -536,3 +547,14 @@ export const onNetworkStatusChange = (callback: (status: NetworkStatus) => void)
|
||||
window.removeEventListener('networkStatusChange', handler);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* 재시도 옵션 타입
|
||||
*/
|
||||
export type RetryOptions = {
|
||||
maxRetries?: number;
|
||||
retryDelay?: number;
|
||||
onRetry?: (attempt: number, error: Error | unknown) => void;
|
||||
shouldRetry?: (error: Error | unknown) => boolean;
|
||||
entityType?: string; // 동기화 작업 유형 (예: '트랜잭션 업로드', '예산 다운로드' 등)
|
||||
};
|
||||
|
||||
@@ -12,7 +12,8 @@ import {
|
||||
addToSyncQueue,
|
||||
processPendingSyncQueue,
|
||||
onNetworkStatusChange,
|
||||
NetworkStatus
|
||||
NetworkStatus,
|
||||
RetryOptions
|
||||
} from './networkUtils';
|
||||
|
||||
// Export all utility functions to maintain the same public API
|
||||
@@ -80,6 +81,9 @@ export const initSyncState = async (): Promise<void> => {
|
||||
// 온라인 상태로 변경되면 보류 중인 동기화 작업 처리
|
||||
if (status === 'online') {
|
||||
processPendingSyncQueue();
|
||||
console.log('[네트워크 상태 변경] 온라인 상태로 변경되었습니다.');
|
||||
} else {
|
||||
console.log('[네트워크 상태 변경] 오프라인 상태로 변경되었습니다.');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user