네트워크 알림 OFF 및 ts 오류 수정

This commit is contained in:
hansoo
2025-03-21 17:09:26 +09:00
parent 3d246176ad
commit b3cc189493
6 changed files with 30 additions and 155 deletions

View File

@@ -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>

View File

@@ -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;

View File

@@ -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;

View File

@@ -32,4 +32,5 @@ export interface RetryOptions<T> {
retryDelay?: number;
onRetry?: (attempt: number, error: Error | unknown) => void;
shouldRetry?: (error: Error | unknown) => boolean;
entityType?: string; // 동기화 작업 유형 (예: '트랜잭션 업로드', '예산 다운로드' 등)
}

View File

@@ -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; // 동기화 작업 유형 (예: '트랜잭션 업로드', '예산 다운로드' 등)
};

View File

@@ -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('[네트워크 상태 변경] 오프라인 상태로 변경되었습니다.');
}
});