diff --git a/src/components/security/DataResetDialog.tsx b/src/components/security/DataResetDialog.tsx new file mode 100644 index 0000000..994061f --- /dev/null +++ b/src/components/security/DataResetDialog.tsx @@ -0,0 +1,74 @@ + +import React from 'react'; +import { CloudOff, Loader2 } from 'lucide-react'; +import { Button } from '@/components/ui/button'; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, + DialogClose +} from '@/components/ui/dialog'; + +interface DataResetDialogProps { + isOpen: boolean; + onOpenChange: (open: boolean) => void; + onConfirm: () => Promise; + isResetting: boolean; + isLoggedIn: boolean; +} + +const DataResetDialog: React.FC = ({ + isOpen, + onOpenChange, + onConfirm, + isResetting, + isLoggedIn +}) => { + return ( + + + + 정말 모든 데이터를 초기화하시겠습니까? + + {isLoggedIn ? ( + <> + 이 작업은 되돌릴 수 없으며, 로컬 및 클라우드에 저장된 모든 예산, 지출 내역이 영구적으로 삭제됩니다. +
+ + 클라우드 데이터도 함께 삭제됩니다. +
+ + ) : ( + "이 작업은 되돌릴 수 없으며, 모든 예산, 지출 내역, 설정이 영구적으로 삭제됩니다." + )} +
+ 단, '환영합니다' 화면 표시 설정과 로그인 상태는 유지됩니다. +
+
+
+ + + + + + +
+
+ ); +}; + +export default DataResetDialog; diff --git a/src/components/security/DataResetSection.tsx b/src/components/security/DataResetSection.tsx index cdaa41f..a3afce0 100644 --- a/src/components/security/DataResetSection.tsx +++ b/src/components/security/DataResetSection.tsx @@ -1,140 +1,19 @@ import React, { useState } from 'react'; -import { Trash2, Loader2, CloudOff } from 'lucide-react'; +import { Trash2 } from 'lucide-react'; import { Button } from '@/components/ui/button'; -import { useToast } from '@/hooks/useToast.wrapper'; -import { useNavigate } from 'react-router-dom'; -import { resetAllStorageData } from '@/utils/storageUtils'; -import { clearCloudData } from '@/utils/syncUtils'; import { useAuth } from '@/contexts/auth/AuthProvider'; -import { - Dialog, - DialogContent, - DialogDescription, - DialogFooter, - DialogHeader, - DialogTitle, - DialogClose -} from '@/components/ui/dialog'; +import { useDataReset } from '@/hooks/useDataReset'; +import DataResetDialog from './DataResetDialog'; const DataResetSection = () => { const [isResetDialogOpen, setIsResetDialogOpen] = useState(false); - const [isResetting, setIsResetting] = useState(false); - const [isCloudResetSuccess, setIsCloudResetSuccess] = useState(null); - const { toast } = useToast(); - const navigate = useNavigate(); const { user } = useAuth(); + const { isResetting, resetAllData } = useDataReset(); const handleResetAllData = async () => { - // 데이터 초기화 수행 - try { - setIsResetting(true); - console.log('모든 데이터 초기화 시작'); - - // 클라우드 데이터 초기화 먼저 시도 (로그인 상태인 경우) - let cloudResetSuccess = false; - if (user) { - console.log('로그인 상태: 클라우드 데이터 초기화 시도'); - cloudResetSuccess = await clearCloudData(user.id); - setIsCloudResetSuccess(cloudResetSuccess); - - if (cloudResetSuccess) { - console.log('클라우드 데이터 초기화 성공'); - } else { - console.warn('클라우드 데이터 초기화 실패 또는 부분 성공'); - } - } else { - console.log('로그인하지 않음: 클라우드 초기화 건너뜀'); - setIsCloudResetSuccess(null); - } - - // 초기화 실행 전에 사용자 설정 백업 - const dontShowWelcomeValue = localStorage.getItem('dontShowWelcome'); - const hasVisitedBefore = localStorage.getItem('hasVisitedBefore'); - - // 로그인 관련 설정 백업 (supabase 관련 모든 설정) - const authBackupItems: Record = {}; - - // 로그인 관련 항목 수집 - for (let i = 0; i < localStorage.length; i++) { - const key = localStorage.key(i); - if (key && ( - key.includes('supabase') || - key.includes('auth') || - key.includes('sb-') || - key.includes('token') || - key.includes('user') || - key.includes('session') - )) { - authBackupItems[key] = localStorage.getItem(key); - console.log(`백업 항목: ${key}`); - } - } - - // 데이터 초기화 - resetAllStorageData(); - - // 사용자 설정 복원 - if (dontShowWelcomeValue) { - localStorage.setItem('dontShowWelcome', dontShowWelcomeValue); - } - - if (hasVisitedBefore) { - localStorage.setItem('hasVisitedBefore', hasVisitedBefore); - } - - // 로그인 관련 설정 복원 (로그인 화면이 나타나지 않도록) - Object.entries(authBackupItems).forEach(([key, value]) => { - if (value) { - localStorage.setItem(key, value); - console.log(`복원 항목: ${key}`); - } - }); - - // 스토리지 이벤트 트리거하여 다른 컴포넌트에 변경 알림 - window.dispatchEvent(new Event('transactionUpdated')); - window.dispatchEvent(new Event('budgetDataUpdated')); - window.dispatchEvent(new Event('categoryBudgetsUpdated')); - window.dispatchEvent(new StorageEvent('storage')); - - setTimeout(() => { - // 클라우드 초기화 상태에 따라 다른 메시지 표시 - if (user) { - if (cloudResetSuccess) { - toast({ - title: "모든 데이터가 초기화되었습니다.", - description: "로컬 및 클라우드의 모든 데이터가 초기화되었습니다.", - }); - } else { - toast({ - title: "로컬 데이터만 초기화됨", - description: "로컬 데이터는 초기화되었지만, 클라우드 데이터 초기화 중 문제가 발생했습니다.", - variant: "destructive" - }); - } - } else { - toast({ - title: "모든 데이터가 초기화되었습니다.", - description: "모든 예산, 지출 내역, 설정이 초기화되었습니다.", - }); - } - - setIsResetDialogOpen(false); - console.log('모든 데이터 초기화 완료'); - - // 초기화 후 설정 페이지로 이동 - setTimeout(() => navigate('/settings'), 500); - }, 500); - } catch (error) { - console.error('데이터 초기화 실패:', error); - toast({ - title: "데이터 초기화 실패", - description: "데이터를 초기화하는 중 문제가 발생했습니다.", - variant: "destructive", - }); - } finally { - setIsResetting(false); - } + await resetAllData(); + setIsResetDialogOpen(false); }; return ( @@ -161,47 +40,13 @@ const DataResetSection = () => { - {/* Reset Dialog */} - - - - 정말 모든 데이터를 초기화하시겠습니까? - - {user ? ( - <> - 이 작업은 되돌릴 수 없으며, 로컬 및 클라우드에 저장된 모든 예산, 지출 내역이 영구적으로 삭제됩니다. -
- - 클라우드 데이터도 함께 삭제됩니다. -
- - ) : ( - "이 작업은 되돌릴 수 없으며, 모든 예산, 지출 내역, 설정이 영구적으로 삭제됩니다." - )} -
- 단, '환영합니다' 화면 표시 설정과 로그인 상태는 유지됩니다. -
-
-
- - - - - - -
-
+ ); }; diff --git a/src/hooks/useDataReset.ts b/src/hooks/useDataReset.ts new file mode 100644 index 0000000..e18b9e0 --- /dev/null +++ b/src/hooks/useDataReset.ts @@ -0,0 +1,136 @@ + +import { useState } from 'react'; +import { useNavigate } from 'react-router-dom'; +import { useToast } from '@/hooks/useToast.wrapper'; +import { resetAllStorageData } from '@/utils/storageUtils'; +import { clearCloudData } from '@/utils/syncUtils'; +import { useAuth } from '@/contexts/auth/AuthProvider'; + +export interface DataResetResult { + isCloudResetSuccess: boolean | null; +} + +export const useDataReset = () => { + const [isResetting, setIsResetting] = useState(false); + const [isCloudResetSuccess, setIsCloudResetSuccess] = useState(null); + const { toast } = useToast(); + const navigate = useNavigate(); + const { user } = useAuth(); + + const resetAllData = async (): Promise => { + try { + setIsResetting(true); + console.log('모든 데이터 초기화 시작'); + + // 클라우드 데이터 초기화 먼저 시도 (로그인 상태인 경우) + let cloudResetSuccess = false; + if (user) { + console.log('로그인 상태: 클라우드 데이터 초기화 시도'); + cloudResetSuccess = await clearCloudData(user.id); + setIsCloudResetSuccess(cloudResetSuccess); + + if (cloudResetSuccess) { + console.log('클라우드 데이터 초기화 성공'); + } else { + console.warn('클라우드 데이터 초기화 실패 또는 부분 성공'); + } + } else { + console.log('로그인하지 않음: 클라우드 초기화 건너뜀'); + setIsCloudResetSuccess(null); + } + + // 초기화 실행 전에 사용자 설정 백업 + const dontShowWelcomeValue = localStorage.getItem('dontShowWelcome'); + const hasVisitedBefore = localStorage.getItem('hasVisitedBefore'); + + // 로그인 관련 설정 백업 (supabase 관련 모든 설정) + const authBackupItems: Record = {}; + + // 로그인 관련 항목 수집 + for (let i = 0; i < localStorage.length; i++) { + const key = localStorage.key(i); + if (key && ( + key.includes('supabase') || + key.includes('auth') || + key.includes('sb-') || + key.includes('token') || + key.includes('user') || + key.includes('session') + )) { + authBackupItems[key] = localStorage.getItem(key); + console.log(`백업 항목: ${key}`); + } + } + + // 데이터 초기화 + resetAllStorageData(); + + // 사용자 설정 복원 + if (dontShowWelcomeValue) { + localStorage.setItem('dontShowWelcome', dontShowWelcomeValue); + } + + if (hasVisitedBefore) { + localStorage.setItem('hasVisitedBefore', hasVisitedBefore); + } + + // 로그인 관련 설정 복원 (로그인 화면이 나타나지 않도록) + Object.entries(authBackupItems).forEach(([key, value]) => { + if (value) { + localStorage.setItem(key, value); + console.log(`복원 항목: ${key}`); + } + }); + + // 스토리지 이벤트 트리거하여 다른 컴포넌트에 변경 알림 + window.dispatchEvent(new Event('transactionUpdated')); + window.dispatchEvent(new Event('budgetDataUpdated')); + window.dispatchEvent(new Event('categoryBudgetsUpdated')); + window.dispatchEvent(new StorageEvent('storage')); + + // 클라우드 초기화 상태에 따라 다른 메시지 표시 + if (user) { + if (cloudResetSuccess) { + toast({ + title: "모든 데이터가 초기화되었습니다.", + description: "로컬 및 클라우드의 모든 데이터가 초기화되었습니다.", + }); + } else { + toast({ + title: "로컬 데이터만 초기화됨", + description: "로컬 데이터는 초기화되었지만, 클라우드 데이터 초기화 중 문제가 발생했습니다.", + variant: "destructive" + }); + } + } else { + toast({ + title: "모든 데이터가 초기화되었습니다.", + description: "모든 예산, 지출 내역, 설정이 초기화되었습니다.", + }); + } + + console.log('모든 데이터 초기화 완료'); + + // 초기화 후 설정 페이지로 이동 (타임아웃으로 약간 지연) + setTimeout(() => navigate('/settings'), 500); + + return { isCloudResetSuccess: cloudResetSuccess }; + } catch (error) { + console.error('데이터 초기화 실패:', error); + toast({ + title: "데이터 초기화 실패", + description: "데이터를 초기화하는 중 문제가 발생했습니다.", + variant: "destructive", + }); + return { isCloudResetSuccess: false }; + } finally { + setIsResetting(false); + } + }; + + return { + isResetting, + isCloudResetSuccess, + resetAllData + }; +};