Refactor DataResetSection component

Refactor DataResetSection component into smaller components and extract logic into a separate hook for better maintainability.
This commit is contained in:
gpt-engineer-app[bot]
2025-03-16 10:20:42 +00:00
parent cbe931ecb3
commit 8b7defb576
3 changed files with 223 additions and 168 deletions

View File

@@ -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<void>;
isResetting: boolean;
isLoggedIn: boolean;
}
const DataResetDialog: React.FC<DataResetDialogProps> = ({
isOpen,
onOpenChange,
onConfirm,
isResetting,
isLoggedIn
}) => {
return (
<Dialog open={isOpen} onOpenChange={onOpenChange}>
<DialogContent>
<DialogHeader>
<DialogTitle> ?</DialogTitle>
<DialogDescription>
{isLoggedIn ? (
<>
, , .
<div className="flex items-center mt-2 text-amber-600">
<CloudOff size={16} className="mr-2" />
.
</div>
</>
) : (
"이 작업은 되돌릴 수 없으며, 모든 예산, 지출 내역, 설정이 영구적으로 삭제됩니다."
)}
<div className="mt-2">
, '환영합니다' .
</div>
</DialogDescription>
</DialogHeader>
<DialogFooter className="flex flex-col sm:flex-row gap-2 sm:gap-0">
<DialogClose asChild>
<Button variant="outline" className="sm:mr-2" disabled={isResetting}></Button>
</DialogClose>
<Button
variant="destructive"
onClick={onConfirm}
disabled={isResetting}
>
{isResetting ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
...
</>
) : isLoggedIn ? '확인, 로컬 및 클라우드 데이터 초기화' : '확인, 모든 데이터 초기화'}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
);
};
export default DataResetDialog;

View File

@@ -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<boolean | null>(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<string, string | null> = {};
// 로그인 관련 항목 수집
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: "모든 예산, 지출 내역, 설정이 초기화되었습니다.",
});
}
await resetAllData();
setIsResetDialogOpen(false);
console.log('모든 데이터 초기화 완료');
// 초기화 후 설정 페이지로 이동
setTimeout(() => navigate('/settings'), 500);
}, 500);
} catch (error) {
console.error('데이터 초기화 실패:', error);
toast({
title: "데이터 초기화 실패",
description: "데이터를 초기화하는 중 문제가 발생했습니다.",
variant: "destructive",
});
} finally {
setIsResetting(false);
}
};
return (
@@ -161,47 +40,13 @@ const DataResetSection = () => {
</Button>
</div>
{/* Reset Dialog */}
<Dialog open={isResetDialogOpen} onOpenChange={setIsResetDialogOpen}>
<DialogContent>
<DialogHeader>
<DialogTitle> ?</DialogTitle>
<DialogDescription>
{user ? (
<>
, , .
<div className="flex items-center mt-2 text-amber-600">
<CloudOff size={16} className="mr-2" />
.
</div>
</>
) : (
"이 작업은 되돌릴 수 없으며, 모든 예산, 지출 내역, 설정이 영구적으로 삭제됩니다."
)}
<div className="mt-2">
, '환영합니다' .
</div>
</DialogDescription>
</DialogHeader>
<DialogFooter className="flex flex-col sm:flex-row gap-2 sm:gap-0">
<DialogClose asChild>
<Button variant="outline" className="sm:mr-2" disabled={isResetting}></Button>
</DialogClose>
<Button
variant="destructive"
onClick={handleResetAllData}
disabled={isResetting}
>
{isResetting ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
...
</>
) : user ? '확인, 로컬 및 클라우드 데이터 초기화' : '확인, 모든 데이터 초기화'}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
<DataResetDialog
isOpen={isResetDialogOpen}
onOpenChange={setIsResetDialogOpen}
onConfirm={handleResetAllData}
isResetting={isResetting}
isLoggedIn={!!user}
/>
</>
);
};

136
src/hooks/useDataReset.ts Normal file
View File

@@ -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<boolean | null>(null);
const { toast } = useToast();
const navigate = useNavigate();
const { user } = useAuth();
const resetAllData = async (): Promise<DataResetResult> => {
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<string, string | null> = {};
// 로그인 관련 항목 수집
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
};
};