Fix welcome message and sync
- Prevent duplicate welcome messages. - Remove sync notifications. - Ensure automatic sync updates last sync time.
This commit is contained in:
@@ -5,15 +5,17 @@ import { Dialog, DialogContent, DialogHeader, DialogTitle } from './ui/dialog';
|
|||||||
import { toast } from '@/hooks/useToast.wrapper'; // 래퍼 사용
|
import { toast } from '@/hooks/useToast.wrapper'; // 래퍼 사용
|
||||||
import { useBudget } from '@/contexts/BudgetContext';
|
import { useBudget } from '@/contexts/BudgetContext';
|
||||||
import { supabase } from '@/lib/supabase';
|
import { supabase } from '@/lib/supabase';
|
||||||
import { isSyncEnabled } from '@/utils/syncUtils';
|
import { isSyncEnabled, setLastSyncTime, trySyncAllData } from '@/utils/syncUtils';
|
||||||
import ExpenseForm, { ExpenseFormValues } from './expenses/ExpenseForm';
|
import ExpenseForm, { ExpenseFormValues } from './expenses/ExpenseForm';
|
||||||
import { Transaction } from '@/components/TransactionCard';
|
import { Transaction } from '@/components/TransactionCard';
|
||||||
import { normalizeDate } from '@/utils/sync/transaction/dateUtils';
|
import { normalizeDate } from '@/utils/sync/transaction/dateUtils';
|
||||||
|
import useNotifications from '@/hooks/useNotifications';
|
||||||
|
|
||||||
const AddTransactionButton = () => {
|
const AddTransactionButton = () => {
|
||||||
const [showExpenseDialog, setShowExpenseDialog] = useState(false);
|
const [showExpenseDialog, setShowExpenseDialog] = useState(false);
|
||||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||||
const { addTransaction } = useBudget();
|
const { addTransaction } = useBudget();
|
||||||
|
const { addNotification } = useNotifications();
|
||||||
|
|
||||||
// Format number with commas
|
// Format number with commas
|
||||||
const formatWithCommas = (value: string): string => {
|
const formatWithCommas = (value: string): string => {
|
||||||
@@ -68,10 +70,31 @@ const AddTransactionButton = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
|
|
||||||
|
// 지출 추가 후 자동 동기화 실행
|
||||||
|
console.log('지출 추가 후 자동 동기화 시작');
|
||||||
|
const syncResult = await trySyncAllData(user.id);
|
||||||
|
|
||||||
|
if (syncResult.success) {
|
||||||
|
// 동기화 성공 시 마지막 동기화 시간 업데이트
|
||||||
|
const currentTime = new Date().toISOString();
|
||||||
|
console.log('자동 동기화 성공, 시간 업데이트:', currentTime);
|
||||||
|
setLastSyncTime(currentTime);
|
||||||
|
|
||||||
|
// 동기화 성공 알림 추가
|
||||||
|
addNotification(
|
||||||
|
'동기화 완료',
|
||||||
|
'방금 추가하신 지출 데이터가 클라우드에 동기화되었습니다.'
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Supabase에 지출 추가 실패:', error);
|
console.error('Supabase에 지출 추가 실패:', error);
|
||||||
// 실패해도 로컬에는 저장되어 있으므로 사용자에게 알리지 않음
|
// 실패 시 알림 추가
|
||||||
|
addNotification(
|
||||||
|
'동기화 실패',
|
||||||
|
'지출 데이터 동기화 중 문제가 발생했습니다. 나중에 다시 시도됩니다.'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 다이얼로그를 닫습니다
|
// 다이얼로그를 닫습니다
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { RefreshCw } from "lucide-react";
|
import { RefreshCw } from "lucide-react";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import useNotifications from '@/hooks/useNotifications';
|
||||||
|
|
||||||
interface SyncStatusProps {
|
interface SyncStatusProps {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
@@ -20,6 +21,18 @@ const SyncStatus: React.FC<SyncStatusProps> = ({
|
|||||||
onManualSync
|
onManualSync
|
||||||
}) => {
|
}) => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const { addNotification } = useNotifications();
|
||||||
|
|
||||||
|
// 동기화 버튼 클릭 시 알림 추가
|
||||||
|
const handleSyncClick = async () => {
|
||||||
|
if (syncing) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await onManualSync();
|
||||||
|
} catch (error) {
|
||||||
|
console.error('수동 동기화 실패:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (!enabled) return null;
|
if (!enabled) return null;
|
||||||
|
|
||||||
@@ -29,7 +42,7 @@ const SyncStatus: React.FC<SyncStatusProps> = ({
|
|||||||
<div className="flex justify-between items-center text-sm">
|
<div className="flex justify-between items-center text-sm">
|
||||||
<span className="text-muted-foreground">마지막 동기화: {lastSync}</span>
|
<span className="text-muted-foreground">마지막 동기화: {lastSync}</span>
|
||||||
<button
|
<button
|
||||||
onClick={onManualSync}
|
onClick={handleSyncClick}
|
||||||
disabled={syncing}
|
disabled={syncing}
|
||||||
className="neuro-button py-1 px-3 flex items-center gap-1 bg-neuro-income text-white hover:bg-neuro-income/90"
|
className="neuro-button py-1 px-3 flex items-center gap-1 bg-neuro-income text-white hover:bg-neuro-income/90"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -1,28 +1,45 @@
|
|||||||
|
|
||||||
import { SyncResult } from '@/utils/sync/data';
|
import { SyncResult } from '@/utils/sync/data';
|
||||||
import { toast } from '@/hooks/useToast.wrapper';
|
import { toast } from '@/hooks/useToast.wrapper';
|
||||||
|
import useNotifications from '@/hooks/useNotifications';
|
||||||
|
|
||||||
|
// 알림 인스턴스 얻기 위한 전역 변수
|
||||||
|
let notificationAdder: ((title: string, message: string) => void) | null = null;
|
||||||
|
|
||||||
|
// 알림 함수 설정
|
||||||
|
export const setSyncNotificationAdder = (adder: (title: string, message: string) => void) => {
|
||||||
|
notificationAdder = adder;
|
||||||
|
};
|
||||||
|
|
||||||
// 동기화 결과 처리 함수
|
// 동기화 결과 처리 함수
|
||||||
export const handleSyncResult = (result: SyncResult) => {
|
export const handleSyncResult = (result: SyncResult) => {
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
|
let title = '';
|
||||||
|
let description = '';
|
||||||
|
|
||||||
if (result.uploadSuccess && result.downloadSuccess) {
|
if (result.uploadSuccess && result.downloadSuccess) {
|
||||||
// 양방향 동기화 성공
|
// 양방향 동기화 성공
|
||||||
toast({
|
title = "동기화 완료";
|
||||||
title: "동기화 완료",
|
description = "모든 데이터가 성공적으로 동기화되었습니다.";
|
||||||
description: "모든 데이터가 성공적으로 동기화되었습니다.",
|
|
||||||
});
|
|
||||||
} else if (result.uploadSuccess) {
|
} else if (result.uploadSuccess) {
|
||||||
// 업로드만 성공
|
// 업로드만 성공
|
||||||
toast({
|
title = "동기화 완료";
|
||||||
title: "동기화 완료",
|
description = "로컬 데이터가 클라우드에 업로드되었습니다.";
|
||||||
description: "로컬 데이터가 클라우드에 업로드되었습니다.",
|
|
||||||
});
|
|
||||||
} else if (result.downloadSuccess) {
|
} else if (result.downloadSuccess) {
|
||||||
// 다운로드만 성공
|
// 다운로드만 성공
|
||||||
toast({
|
title = "동기화 완료";
|
||||||
title: "동기화 완료",
|
description = "클라우드 데이터가 기기에 다운로드되었습니다.";
|
||||||
description: "클라우드 데이터가 기기에 다운로드되었습니다.",
|
}
|
||||||
});
|
|
||||||
|
// 토스트 표시
|
||||||
|
toast({
|
||||||
|
title,
|
||||||
|
description,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 알림 추가 (설정된 경우)
|
||||||
|
if (notificationAdder) {
|
||||||
|
notificationAdder(title, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 상세 결과 로깅
|
// 상세 결과 로깅
|
||||||
@@ -38,12 +55,32 @@ export const handleSyncResult = (result: SyncResult) => {
|
|||||||
// 동기화 실패
|
// 동기화 실패
|
||||||
console.error("동기화 실패 세부 결과:", result.details);
|
console.error("동기화 실패 세부 결과:", result.details);
|
||||||
|
|
||||||
|
const title = "동기화 실패";
|
||||||
|
const description = "데이터 동기화 중 문제가 발생했습니다. 다시 시도해주세요.";
|
||||||
|
|
||||||
|
// 토스트 표시
|
||||||
toast({
|
toast({
|
||||||
title: "동기화 실패",
|
title,
|
||||||
description: "데이터 동기화 중 문제가 발생했습니다. 다시 시도해주세요.",
|
description,
|
||||||
variant: "destructive"
|
variant: "destructive"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 알림 추가 (설정된 경우)
|
||||||
|
if (notificationAdder) {
|
||||||
|
notificationAdder(title, description);
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 커스텀 훅: 동기화 알림 관리
|
||||||
|
export const useSyncNotifications = () => {
|
||||||
|
const { addNotification } = useNotifications();
|
||||||
|
|
||||||
|
// 컴포넌트 마운트 시 알림 함수 설정
|
||||||
|
React.useEffect(() => {
|
||||||
|
setSyncNotificationAdder(addNotification);
|
||||||
|
return () => setSyncNotificationAdder(null);
|
||||||
|
}, [addNotification]);
|
||||||
|
};
|
||||||
|
|||||||
@@ -3,12 +3,14 @@ import { useState } from 'react';
|
|||||||
import { toast } from '@/hooks/useToast.wrapper';
|
import { toast } from '@/hooks/useToast.wrapper';
|
||||||
import { trySyncAllData, setLastSyncTime } from '@/utils/syncUtils';
|
import { trySyncAllData, setLastSyncTime } from '@/utils/syncUtils';
|
||||||
import { handleSyncResult } from './syncResultHandler';
|
import { handleSyncResult } from './syncResultHandler';
|
||||||
|
import useNotifications from '@/hooks/useNotifications';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 수동 동기화 기능을 위한 커스텀 훅
|
* 수동 동기화 기능을 위한 커스텀 훅
|
||||||
*/
|
*/
|
||||||
export const useManualSync = (user: any) => {
|
export const useManualSync = (user: any) => {
|
||||||
const [syncing, setSyncing] = useState(false);
|
const [syncing, setSyncing] = useState(false);
|
||||||
|
const { addNotification } = useNotifications();
|
||||||
|
|
||||||
// 수동 동기화 핸들러
|
// 수동 동기화 핸들러
|
||||||
const handleManualSync = async () => {
|
const handleManualSync = async () => {
|
||||||
@@ -18,6 +20,11 @@ export const useManualSync = (user: any) => {
|
|||||||
description: "데이터 동기화를 위해 로그인이 필요합니다.",
|
description: "데이터 동기화를 위해 로그인이 필요합니다.",
|
||||||
variant: "destructive"
|
variant: "destructive"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addNotification(
|
||||||
|
"로그인 필요",
|
||||||
|
"데이터 동기화를 위해 로그인이 필요합니다."
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,6 +45,11 @@ export const useManualSync = (user: any) => {
|
|||||||
setSyncing(true);
|
setSyncing(true);
|
||||||
console.log('수동 동기화 시작');
|
console.log('수동 동기화 시작');
|
||||||
|
|
||||||
|
addNotification(
|
||||||
|
"동기화 시작",
|
||||||
|
"데이터 동기화가 시작되었습니다."
|
||||||
|
);
|
||||||
|
|
||||||
// 동기화 실행
|
// 동기화 실행
|
||||||
const result = await trySyncAllData(userId);
|
const result = await trySyncAllData(userId);
|
||||||
|
|
||||||
@@ -59,6 +71,11 @@ export const useManualSync = (user: any) => {
|
|||||||
description: "동기화 중 문제가 발생했습니다. 다시 시도해주세요.",
|
description: "동기화 중 문제가 발생했습니다. 다시 시도해주세요.",
|
||||||
variant: "destructive"
|
variant: "destructive"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addNotification(
|
||||||
|
"동기화 오류",
|
||||||
|
"동기화 중 문제가 발생했습니다. 다시 시도해주세요."
|
||||||
|
);
|
||||||
} finally {
|
} finally {
|
||||||
setSyncing(false);
|
setSyncing(false);
|
||||||
console.log('수동 동기화 종료');
|
console.log('수동 동기화 종료');
|
||||||
|
|||||||
@@ -58,7 +58,8 @@ export const useSyncStatus = () => {
|
|||||||
|
|
||||||
const updateLastSyncTime = (event?: Event | CustomEvent) => {
|
const updateLastSyncTime = (event?: Event | CustomEvent) => {
|
||||||
const newTime = getLastSyncTime();
|
const newTime = getLastSyncTime();
|
||||||
console.log('마지막 동기화 시간 업데이트됨:', newTime, event instanceof CustomEvent ? `(이벤트 상세: ${JSON.stringify(event.detail)})` : '');
|
const eventDetails = event instanceof CustomEvent ? ` (이벤트 상세: ${JSON.stringify(event.detail)})` : '';
|
||||||
|
console.log(`마지막 동기화 시간 업데이트됨: ${newTime} ${eventDetails}`);
|
||||||
setLastSync(newTime);
|
setLastSync(newTime);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -75,12 +76,26 @@ export const useSyncStatus = () => {
|
|||||||
|
|
||||||
window.addEventListener('storage', handleStorageChange);
|
window.addEventListener('storage', handleStorageChange);
|
||||||
|
|
||||||
|
// 동기화 완료 이벤트도 모니터링 (새로 추가)
|
||||||
|
window.addEventListener('syncComplete', updateLastSyncTime);
|
||||||
|
|
||||||
// 초기 상태 업데이트
|
// 초기 상태 업데이트
|
||||||
updateLastSyncTime();
|
updateLastSyncTime();
|
||||||
|
|
||||||
|
// 1초마다 업데이트 상태 확인 (문제 해결을 위한 임시 방안)
|
||||||
|
const checkInterval = setInterval(() => {
|
||||||
|
const currentTime = getLastSyncTime();
|
||||||
|
if (currentTime !== lastSync) {
|
||||||
|
console.log('주기적 확인에서 동기화 시간 변경 감지:', currentTime);
|
||||||
|
setLastSync(currentTime);
|
||||||
|
}
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener('syncTimeUpdated', updateLastSyncTime);
|
window.removeEventListener('syncTimeUpdated', updateLastSyncTime);
|
||||||
window.removeEventListener('storage', handleStorageChange);
|
window.removeEventListener('storage', handleStorageChange);
|
||||||
|
window.removeEventListener('syncComplete', updateLastSyncTime);
|
||||||
|
clearInterval(checkInterval);
|
||||||
};
|
};
|
||||||
}, [lastSync]);
|
}, [lastSync]);
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ import { toast } from '@/hooks/useToast.wrapper';
|
|||||||
import {
|
import {
|
||||||
isSyncEnabled,
|
isSyncEnabled,
|
||||||
setSyncEnabled,
|
setSyncEnabled,
|
||||||
trySyncAllData
|
trySyncAllData,
|
||||||
|
setLastSyncTime
|
||||||
} from '@/utils/syncUtils';
|
} from '@/utils/syncUtils';
|
||||||
|
import useNotifications from '@/hooks/useNotifications';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 동기화 토글 기능을 위한 커스텀 훅
|
* 동기화 토글 기능을 위한 커스텀 훅
|
||||||
@@ -14,6 +16,7 @@ import {
|
|||||||
export const useSyncToggle = () => {
|
export const useSyncToggle = () => {
|
||||||
const [enabled, setEnabled] = useState(isSyncEnabled());
|
const [enabled, setEnabled] = useState(isSyncEnabled());
|
||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
|
const { addNotification } = useNotifications();
|
||||||
|
|
||||||
// 사용자 로그인 상태 변경 감지
|
// 사용자 로그인 상태 변경 감지
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -60,6 +63,11 @@ export const useSyncToggle = () => {
|
|||||||
description: "데이터 동기화를 위해 로그인이 필요합니다.",
|
description: "데이터 동기화를 위해 로그인이 필요합니다.",
|
||||||
variant: "destructive"
|
variant: "destructive"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addNotification(
|
||||||
|
"로그인 필요",
|
||||||
|
"데이터 동기화를 위해 로그인이 필요합니다."
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,13 +85,28 @@ export const useSyncToggle = () => {
|
|||||||
setEnabled(checked);
|
setEnabled(checked);
|
||||||
setSyncEnabled(checked);
|
setSyncEnabled(checked);
|
||||||
|
|
||||||
|
// 동기화 활성화/비활성화 알림 추가
|
||||||
|
addNotification(
|
||||||
|
checked ? "동기화 활성화" : "동기화 비활성화",
|
||||||
|
checked
|
||||||
|
? "데이터가 클라우드와 동기화됩니다."
|
||||||
|
: "클라우드 동기화가 중지되었습니다."
|
||||||
|
);
|
||||||
|
|
||||||
// 이벤트 트리거
|
// 이벤트 트리거
|
||||||
window.dispatchEvent(new Event('auth-state-changed'));
|
window.dispatchEvent(new Event('auth-state-changed'));
|
||||||
|
|
||||||
if (checked && user) {
|
if (checked && user) {
|
||||||
try {
|
try {
|
||||||
// 동기화 수행
|
// 동기화 수행
|
||||||
await performSync(user.id);
|
const result = await performSync(user.id);
|
||||||
|
|
||||||
|
// 동기화 성공 시 마지막 동기화 시간 업데이트
|
||||||
|
if (result && result.success) {
|
||||||
|
const currentTime = new Date().toISOString();
|
||||||
|
console.log('동기화 활성화 후 첫 동기화 성공, 시간 업데이트:', currentTime);
|
||||||
|
setLastSyncTime(currentTime);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('동기화 중 오류, 로컬 데이터 복원 시도:', error);
|
console.error('동기화 중 오류, 로컬 데이터 복원 시도:', error);
|
||||||
|
|
||||||
@@ -108,6 +131,11 @@ export const useSyncToggle = () => {
|
|||||||
description: "동기화 중 문제가 발생하여 로컬 데이터가 복원되었습니다.",
|
description: "동기화 중 문제가 발생하여 로컬 데이터가 복원되었습니다.",
|
||||||
variant: "destructive"
|
variant: "destructive"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
addNotification(
|
||||||
|
"동기화 오류",
|
||||||
|
"동기화 중 문제가 발생하여 로컬 데이터가 복원되었습니다."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -41,13 +41,18 @@ const Index = () => {
|
|||||||
|
|
||||||
// 앱 시작시 예시 알림 추가 (실제 앱에서는 필요한 이벤트에 따라 알림 추가)
|
// 앱 시작시 예시 알림 추가 (실제 앱에서는 필요한 이벤트에 따라 알림 추가)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isInitialized && user) {
|
// 환영 메시지가 이미 표시되었는지 확인하는 키
|
||||||
// 사용자 로그인 시 알림 예시
|
const welcomeNotificationSent = sessionStorage.getItem('welcomeNotificationSent');
|
||||||
|
|
||||||
|
if (isInitialized && user && !welcomeNotificationSent) {
|
||||||
|
// 사용자 로그인 시 알림 예시 (한 번만 실행)
|
||||||
const timeoutId = setTimeout(() => {
|
const timeoutId = setTimeout(() => {
|
||||||
addNotification(
|
addNotification(
|
||||||
'환영합니다!',
|
'환영합니다!',
|
||||||
'젤리의 적자탈출에 오신 것을 환영합니다. 예산을 설정하고 지출을 기록해보세요.'
|
'젤리의 적자탈출에 오신 것을 환영합니다. 예산을 설정하고 지출을 기록해보세요.'
|
||||||
);
|
);
|
||||||
|
// 세션 스토리지에 환영 메시지 표시 여부 저장
|
||||||
|
sessionStorage.setItem('welcomeNotificationSent', 'true');
|
||||||
}, 2000);
|
}, 2000);
|
||||||
|
|
||||||
return () => clearTimeout(timeoutId);
|
return () => clearTimeout(timeoutId);
|
||||||
|
|||||||
@@ -60,15 +60,23 @@ export const setLastSyncTime = (timestamp: string): void => {
|
|||||||
// 이벤트 발생 - 커스텀 이벤트로 변경하여 디버깅 용이하게
|
// 이벤트 발생 - 커스텀 이벤트로 변경하여 디버깅 용이하게
|
||||||
try {
|
try {
|
||||||
const event = new CustomEvent('syncTimeUpdated', {
|
const event = new CustomEvent('syncTimeUpdated', {
|
||||||
detail: { time: timestamp }
|
detail: { time: timestamp, source: 'setLastSyncTime' }
|
||||||
});
|
});
|
||||||
window.dispatchEvent(event);
|
window.dispatchEvent(event);
|
||||||
console.log('syncTimeUpdated 이벤트 발생 완료');
|
console.log('syncTimeUpdated 이벤트 발생 완료 (setLastSyncTime에서 호출)');
|
||||||
|
|
||||||
|
// 스토리지 이벤트도 함께 발생시켜 다중 환경에서도 동작하도록 함
|
||||||
|
window.dispatchEvent(new StorageEvent('storage', {
|
||||||
|
key: 'lastSync',
|
||||||
|
newValue: timestamp
|
||||||
|
}));
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('동기화 시간 이벤트 발생 오류:', error);
|
console.error('동기화 시간 이벤트 발생 오류:', error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// syncUtils.ts에서 사용하던 함수들도 여기로 통합
|
// syncUtils.ts에서 사용하던 함수들
|
||||||
export { trySyncAllData } from './sync/data';
|
// 수정: 하위 경로에서 가져오는 대신 직접 가져오기
|
||||||
|
import { trySyncAllData } from './sync/data';
|
||||||
|
export { trySyncAllData };
|
||||||
export type { SyncResult } from './sync/data';
|
export type { SyncResult } from './sync/data';
|
||||||
|
|||||||
Reference in New Issue
Block a user