네트워크 알림 OFF 및 ts 오류 수정
This commit is contained in:
@@ -20,7 +20,6 @@ import PaymentMethods from './pages/PaymentMethods';
|
|||||||
import Settings from './pages/Settings';
|
import Settings from './pages/Settings';
|
||||||
import { BudgetProvider } from './contexts/BudgetContext';
|
import { BudgetProvider } from './contexts/BudgetContext';
|
||||||
import PrivateRoute from './components/auth/PrivateRoute';
|
import PrivateRoute from './components/auth/PrivateRoute';
|
||||||
import NetworkStatusIndicator from './components/NetworkStatusIndicator';
|
|
||||||
import { initSyncState, startNetworkMonitoring } from './utils/syncUtils';
|
import { initSyncState, startNetworkMonitoring } from './utils/syncUtils';
|
||||||
|
|
||||||
// 전역 오류 핸들러
|
// 전역 오류 핸들러
|
||||||
@@ -152,7 +151,6 @@ function App() {
|
|||||||
</Routes>
|
</Routes>
|
||||||
</div>
|
</div>
|
||||||
<Toaster />
|
<Toaster />
|
||||||
<NetworkStatusIndicator />
|
|
||||||
</div>
|
</div>
|
||||||
</Router>
|
</Router>
|
||||||
</BudgetProvider>
|
</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,
|
maxRetries = MAX_RETRY_COUNT,
|
||||||
retryDelay = INITIAL_RETRY_DELAY,
|
retryDelay = INITIAL_RETRY_DELAY,
|
||||||
onRetry = () => {},
|
onRetry = () => {},
|
||||||
shouldRetry = () => true
|
shouldRetry = () => true,
|
||||||
|
entityType
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
let lastError: Error | unknown;
|
let lastError: Error | unknown;
|
||||||
|
|||||||
@@ -32,4 +32,5 @@ export interface RetryOptions<T> {
|
|||||||
retryDelay?: number;
|
retryDelay?: number;
|
||||||
onRetry?: (attempt: number, error: Error | unknown) => void;
|
onRetry?: (attempt: number, error: Error | unknown) => void;
|
||||||
shouldRetry?: (error: Error | unknown) => boolean;
|
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;
|
retryDelay?: number;
|
||||||
onRetry?: (attempt: number, error: Error | unknown) => void;
|
onRetry?: (attempt: number, error: Error | unknown) => void;
|
||||||
shouldRetry?: (error: Error | unknown) => boolean;
|
shouldRetry?: (error: Error | unknown) => boolean;
|
||||||
|
entityType?: string; // 동기화 작업 유형 (예: '트랜잭션 업로드', '예산 다운로드' 등)
|
||||||
} = {}
|
} = {}
|
||||||
): Promise<T> => {
|
): Promise<T> => {
|
||||||
const {
|
const {
|
||||||
@@ -536,3 +547,14 @@ export const onNetworkStatusChange = (callback: (status: NetworkStatus) => void)
|
|||||||
window.removeEventListener('networkStatusChange', handler);
|
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,
|
addToSyncQueue,
|
||||||
processPendingSyncQueue,
|
processPendingSyncQueue,
|
||||||
onNetworkStatusChange,
|
onNetworkStatusChange,
|
||||||
NetworkStatus
|
NetworkStatus,
|
||||||
|
RetryOptions
|
||||||
} from './networkUtils';
|
} from './networkUtils';
|
||||||
|
|
||||||
// Export all utility functions to maintain the same public API
|
// Export all utility functions to maintain the same public API
|
||||||
@@ -80,6 +81,9 @@ export const initSyncState = async (): Promise<void> => {
|
|||||||
// 온라인 상태로 변경되면 보류 중인 동기화 작업 처리
|
// 온라인 상태로 변경되면 보류 중인 동기화 작업 처리
|
||||||
if (status === 'online') {
|
if (status === 'online') {
|
||||||
processPendingSyncQueue();
|
processPendingSyncQueue();
|
||||||
|
console.log('[네트워크 상태 변경] 온라인 상태로 변경되었습니다.');
|
||||||
|
} else {
|
||||||
|
console.log('[네트워크 상태 변경] 오프라인 상태로 변경되었습니다.');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user