diff --git a/src/contexts/budget/hooks/useBudgetDataState.ts b/src/contexts/budget/hooks/useBudgetDataState.ts index 5a811cc..967aa47 100644 --- a/src/contexts/budget/hooks/useBudgetDataState.ts +++ b/src/contexts/budget/hooks/useBudgetDataState.ts @@ -17,72 +17,61 @@ export const useBudgetDataState = (transactions: any[]) => { const [budgetData, setBudgetData] = useState(loadBudgetDataFromStorage()); const [selectedTab, setSelectedTab] = useState("daily"); - // 지출 금액 업데이트 - 트랜잭션이 변경될 때마다 실행 + // 초기 로드 및 이벤트 리스너 설정 useEffect(() => { - // 지출 금액 업데이트 - const updatedBudgetData = calculateSpentAmounts(transactions, budgetData); - - // 상태 및 스토리지 모두 업데이트 - setBudgetData(updatedBudgetData); - saveBudgetDataToStorage(updatedBudgetData); - }, [transactions, budgetData]); + const loadBudget = () => { + console.log('예산 데이터 로드 시도'); + const loadedData = loadBudgetDataFromStorage(); + setBudgetData(loadedData); + console.log('예산 데이터 로드됨:', loadedData); + }; - // 이벤트 리스너 설정 - useEffect(() => { + // 초기 로드 + loadBudget(); + + // 이벤트 리스너 설정 const handleBudgetUpdate = () => { - const loadedBudgetData = loadBudgetDataFromStorage(); - setBudgetData(prevData => { - // 예산 목표는 로드된 데이터에서 가져오고, 지출 금액은 유지 - const updatedData = { - daily: { - ...loadedBudgetData.daily, - spentAmount: prevData.daily.spentAmount, - }, - weekly: { - ...loadedBudgetData.weekly, - spentAmount: prevData.weekly.spentAmount, - }, - monthly: { - ...loadedBudgetData.monthly, - spentAmount: prevData.monthly.spentAmount, - } - }; - - // 남은 금액 재계산 - updatedData.daily.remainingAmount = updatedData.daily.targetAmount - updatedData.daily.spentAmount; - updatedData.weekly.remainingAmount = updatedData.weekly.targetAmount - updatedData.weekly.spentAmount; - updatedData.monthly.remainingAmount = updatedData.monthly.targetAmount - updatedData.monthly.spentAmount; - - return updatedData; - }); + console.log('예산 데이터 업데이트 이벤트 감지'); + loadBudget(); }; window.addEventListener('budgetDataUpdated', handleBudgetUpdate); - window.addEventListener('categoryBudgetsUpdated', handleBudgetUpdate); window.addEventListener('storage', handleBudgetUpdate); + window.addEventListener('focus', handleBudgetUpdate); return () => { window.removeEventListener('budgetDataUpdated', handleBudgetUpdate); - window.removeEventListener('categoryBudgetsUpdated', handleBudgetUpdate); window.removeEventListener('storage', handleBudgetUpdate); + window.removeEventListener('focus', handleBudgetUpdate); }; }, []); + // 지출 금액 업데이트 - 트랜잭션이 변경될 때마다 실행 + useEffect(() => { + if (transactions.length > 0) { + console.log('트랜잭션 변경으로 인한 예산 데이터 업데이트'); + // 지출 금액 업데이트 + const updatedBudgetData = calculateSpentAmounts(transactions, budgetData); + + // 상태 및 스토리지 모두 업데이트 + setBudgetData(updatedBudgetData); + saveBudgetDataToStorage(updatedBudgetData); + } + }, [transactions]); + // 예산 목표 업데이트 함수 const handleBudgetGoalUpdate = useCallback(( type: BudgetPeriod, amount: number, newCategoryBudgets?: Record ) => { + console.log(`예산 목표 업데이트: ${type}, 금액: ${amount}`); // 월간 예산 직접 업데이트 (카테고리 예산이 없는 경우) if (!newCategoryBudgets) { const updatedBudgetData = calculateUpdatedBudgetData(budgetData, type, amount); setBudgetData(updatedBudgetData); saveBudgetDataToStorage(updatedBudgetData); - // 이벤트 발생시키기 - window.dispatchEvent(new Event('budgetDataUpdated')); - toast({ title: "목표 업데이트 완료", description: `${type === 'daily' ? '일일' : type === 'weekly' ? '주간' : '월간'} 목표가 ${amount.toLocaleString()}원으로 설정되었습니다.` diff --git a/src/contexts/budget/hooks/useCategoryBudgetState.ts b/src/contexts/budget/hooks/useCategoryBudgetState.ts index 6178ba4..ceed427 100644 --- a/src/contexts/budget/hooks/useCategoryBudgetState.ts +++ b/src/contexts/budget/hooks/useCategoryBudgetState.ts @@ -12,28 +12,40 @@ export const useCategoryBudgetState = () => { loadCategoryBudgetsFromStorage() ); - // 이벤트 리스너 설정 + // 초기 로드 및 이벤트 리스너 설정 useEffect(() => { + const loadCategories = () => { + console.log('카테고리 예산 로드 시도'); + const loaded = loadCategoryBudgetsFromStorage(); + setCategoryBudgets(loaded); + console.log('카테고리 예산 로드됨:', loaded); + }; + + // 초기 로드 + loadCategories(); + + // 이벤트 리스너 설정 const handleCategoryUpdate = () => { - setCategoryBudgets(loadCategoryBudgetsFromStorage()); + console.log('카테고리 예산 업데이트 이벤트 감지'); + loadCategories(); }; window.addEventListener('categoryBudgetsUpdated', handleCategoryUpdate); window.addEventListener('storage', handleCategoryUpdate); + window.addEventListener('focus', handleCategoryUpdate); return () => { window.removeEventListener('categoryBudgetsUpdated', handleCategoryUpdate); window.removeEventListener('storage', handleCategoryUpdate); + window.removeEventListener('focus', handleCategoryUpdate); }; }, []); // 카테고리 예산 업데이트 함수 const updateCategoryBudgets = useCallback((newCategoryBudgets: Record) => { + console.log('카테고리 예산 업데이트:', newCategoryBudgets); setCategoryBudgets(newCategoryBudgets); saveCategoryBudgetsToStorage(newCategoryBudgets); - - // 로컬 이벤트 발생 (다른 컴포넌트에서 변경 감지하도록) - window.dispatchEvent(new Event('categoryBudgetsUpdated')); }, []); // 카테고리 예산 초기화 함수 @@ -45,7 +57,7 @@ export const useCategoryBudgetState = () => { return { categoryBudgets, - setCategoryBudgets, + setCategoryBudgets: updateCategoryBudgets, updateCategoryBudgets, resetCategoryBudgets }; diff --git a/src/contexts/budget/hooks/useTransactionState.ts b/src/contexts/budget/hooks/useTransactionState.ts index a85377f..c6f3579 100644 --- a/src/contexts/budget/hooks/useTransactionState.ts +++ b/src/contexts/budget/hooks/useTransactionState.ts @@ -16,23 +16,32 @@ export const useTransactionState = () => { useEffect(() => { const loadTransactions = () => { const storedTransactions = loadTransactionsFromStorage(); + console.log('트랜잭션 로드됨:', storedTransactions.length, '개'); setTransactions(storedTransactions); }; loadTransactions(); // 이벤트 리스너를 추가하여 다른 컴포넌트에서 변경 시 업데이트 - const handleTransactionUpdate = () => loadTransactions(); + const handleTransactionUpdate = () => { + console.log('트랜잭션 업데이트 이벤트 감지'); + loadTransactions(); + }; + window.addEventListener('transactionUpdated', handleTransactionUpdate); window.addEventListener('transactionDeleted', handleTransactionUpdate); window.addEventListener('transactionAdded', handleTransactionUpdate); window.addEventListener('storage', handleTransactionUpdate); + // 페이지 포커스 시 데이터 갱신 + window.addEventListener('focus', handleTransactionUpdate); + return () => { window.removeEventListener('transactionUpdated', handleTransactionUpdate); window.removeEventListener('transactionDeleted', handleTransactionUpdate); window.removeEventListener('transactionAdded', handleTransactionUpdate); window.removeEventListener('storage', handleTransactionUpdate); + window.removeEventListener('focus', handleTransactionUpdate); }; }, []); diff --git a/src/contexts/budget/storage/budgetStorage.ts b/src/contexts/budget/storage/budgetStorage.ts index 2f911ee..ec2c429 100644 --- a/src/contexts/budget/storage/budgetStorage.ts +++ b/src/contexts/budget/storage/budgetStorage.ts @@ -33,6 +33,7 @@ export const saveBudgetDataToStorage = (budgetData: BudgetData): void => { console.log('예산 데이터 저장 완료'); // 스토리지 이벤트 수동 트리거 (동일 창에서도 감지하기 위함) + window.dispatchEvent(new Event('budgetDataUpdated')); window.dispatchEvent(new StorageEvent('storage', { key: 'budgetData' })); @@ -51,6 +52,9 @@ export const clearAllBudgetData = (): void => { const initialData = getInitialBudgetData(); saveBudgetDataToStorage(initialData); console.log('예산 데이터가 초기화되었습니다.'); + + // 스토리지 이벤트 수동 트리거 + window.dispatchEvent(new Event('budgetDataUpdated')); } catch (error) { console.error('예산 데이터 삭제 오류:', error); } diff --git a/src/contexts/budget/storage/categoryStorage.ts b/src/contexts/budget/storage/categoryStorage.ts index 8a8f22b..5078882 100644 --- a/src/contexts/budget/storage/categoryStorage.ts +++ b/src/contexts/budget/storage/categoryStorage.ts @@ -31,6 +31,7 @@ export const saveCategoryBudgetsToStorage = (categoryBudgets: Record { // 기본값으로 재설정 saveCategoryBudgetsToStorage(DEFAULT_CATEGORY_BUDGETS); console.log('카테고리 예산이 초기화되었습니다.'); + + // 이벤트 발생 + window.dispatchEvent(new Event('categoryBudgetsUpdated')); } catch (error) { console.error('카테고리 예산 삭제 오류:', error); } diff --git a/src/contexts/budget/storage/transactionStorage.ts b/src/contexts/budget/storage/transactionStorage.ts index 76b9a9c..72510c9 100644 --- a/src/contexts/budget/storage/transactionStorage.ts +++ b/src/contexts/budget/storage/transactionStorage.ts @@ -8,7 +8,9 @@ export const loadTransactionsFromStorage = (): Transaction[] => { try { const storedTransactions = localStorage.getItem('transactions'); if (storedTransactions) { - return JSON.parse(storedTransactions); + const parsedData = JSON.parse(storedTransactions); + console.log('트랜잭션 로드 완료, 항목 수:', parsedData.length); + return parsedData; } } catch (error) { console.error('트랜잭션 데이터 파싱 오류:', error); @@ -25,6 +27,7 @@ export const saveTransactionsToStorage = (transactions: Transaction[]): void => console.log('트랜잭션 저장 완료, 항목 수:', transactions.length); // 스토리지 이벤트 수동 트리거 (동일 창에서도 감지하기 위함) + window.dispatchEvent(new Event('transactionUpdated')); window.dispatchEvent(new StorageEvent('storage', { key: 'transactions' })); @@ -44,6 +47,7 @@ export const clearAllTransactions = (): void => { console.log('모든 트랜잭션이 삭제되었습니다.'); // 스토리지 이벤트 수동 트리거 + window.dispatchEvent(new Event('transactionUpdated')); window.dispatchEvent(new StorageEvent('storage', { key: 'transactions' })); diff --git a/src/contexts/budget/useBudgetState.ts b/src/contexts/budget/useBudgetState.ts index 12bac76..a083b99 100644 --- a/src/contexts/budget/useBudgetState.ts +++ b/src/contexts/budget/useBudgetState.ts @@ -6,11 +6,6 @@ import { useTransactionState } from './hooks/useTransactionState'; import { useCategoryBudgetState } from './hooks/useCategoryBudgetState'; import { useBudgetDataState } from './hooks/useBudgetDataState'; import { useCategorySpending } from './hooks/useCategorySpending'; -import { - clearAllTransactions, - clearAllCategoryBudgets, - clearAllBudgetData -} from './storage'; export const useBudgetState = () => { // 각 상태 관리 훅 사용 @@ -39,33 +34,45 @@ export const useBudgetState = () => { const { getCategorySpending } = useCategorySpending(transactions, categoryBudgets); + // 디버깅을 위한 로그 + useEffect(() => { + console.log('현재 예산 데이터:', budgetData); + console.log('현재 카테고리 예산:', categoryBudgets); + console.log('현재 거래 수:', transactions.length); + }, [budgetData, categoryBudgets, transactions]); + // 카테고리별 예산 및 지출 계산 useEffect(() => { const totalMonthlyBudget = Object.values(categoryBudgets).reduce((sum, value) => sum + value, 0); - const totalDailyBudget = Math.round(totalMonthlyBudget / 30); - const totalWeeklyBudget = Math.round(totalMonthlyBudget / 4.3); - - const updatedBudgetData = { - daily: { - targetAmount: totalDailyBudget, - spentAmount: budgetData.daily.spentAmount, - remainingAmount: totalDailyBudget - budgetData.daily.spentAmount - }, - weekly: { - targetAmount: totalWeeklyBudget, - spentAmount: budgetData.weekly.spentAmount, - remainingAmount: totalWeeklyBudget - budgetData.weekly.spentAmount - }, - monthly: { - targetAmount: totalMonthlyBudget, - spentAmount: budgetData.monthly.spentAmount, - remainingAmount: totalMonthlyBudget - budgetData.monthly.spentAmount - } - }; + console.log('카테고리 예산 합계:', totalMonthlyBudget); - // 로컬 이벤트 발생 (다른 컴포넌트에서 변경 감지하도록) - window.dispatchEvent(new Event('budgetDataUpdated')); - }, [categoryBudgets, budgetData]); + if (totalMonthlyBudget > 0) { + const totalDailyBudget = Math.round(totalMonthlyBudget / 30); + const totalWeeklyBudget = Math.round(totalMonthlyBudget / 4.3); + + const updatedBudgetData = { + daily: { + targetAmount: totalDailyBudget, + spentAmount: budgetData.daily.spentAmount, + remainingAmount: totalDailyBudget - budgetData.daily.spentAmount + }, + weekly: { + targetAmount: totalWeeklyBudget, + spentAmount: budgetData.weekly.spentAmount, + remainingAmount: totalWeeklyBudget - budgetData.weekly.spentAmount + }, + monthly: { + targetAmount: totalMonthlyBudget, + spentAmount: budgetData.monthly.spentAmount, + remainingAmount: totalMonthlyBudget - budgetData.monthly.spentAmount + } + }; + + // 로컬 상태 업데이트 + handleBudgetGoalUpdate('monthly', totalMonthlyBudget); + console.log('예산 데이터 자동 업데이트:', updatedBudgetData); + } + }, [categoryBudgets, handleBudgetGoalUpdate]); // 모든 데이터 리셋 함수 const resetBudgetData = useCallback(() => { @@ -80,11 +87,13 @@ export const useBudgetState = () => { }, [resetTransactions, resetCategoryBudgets, resetBudgetDataInternal]); // 확장된 예산 목표 업데이트 함수 - const extendedBudgetGoalUpdate = ( + const extendedBudgetGoalUpdate = useCallback(( type: BudgetPeriod, amount: number, newCategoryBudgets?: Record ) => { + console.log(`확장된 예산 목표 업데이트: ${type}, 금액: ${amount}, 카테고리 예산:`, newCategoryBudgets); + // 카테고리 예산이 직접 업데이트된 경우 if (newCategoryBudgets) { updateCategoryBudgets(newCategoryBudgets); @@ -111,7 +120,7 @@ export const useBudgetState = () => { // 일일이나 주간 예산이 직접 업데이트되는 경우 handleBudgetGoalUpdate(type, amount); } - }; + }, [budgetData, categoryBudgets, handleBudgetGoalUpdate, updateCategoryBudgets]); return { transactions, diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index b79a102..6cfdb2e 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -37,11 +37,28 @@ const Index = () => { } }, [isInitialized, checkWelcomeDialogState]); + // 페이지가 처음 로드될 때 데이터 로딩 확인 + useEffect(() => { + // 데이터 로드 상태 확인 + console.log('Index 페이지 마운트, 현재 데이터 상태:'); + console.log('트랜잭션:', transactions.length); + console.log('예산 데이터:', budgetData); + + // 수동으로 이벤트 발생시켜 데이터 갱신 + window.dispatchEvent(new Event('transactionUpdated')); + window.dispatchEvent(new Event('budgetDataUpdated')); + window.dispatchEvent(new Event('categoryBudgetsUpdated')); + }, []); + // 앱이 포커스를 얻었을 때 데이터를 새로고침 useEffect(() => { const handleFocus = () => { + console.log('창이 포커스를 얻음 - 데이터 새로고침'); // 이벤트 발생시켜 데이터 새로고침 window.dispatchEvent(new Event('storage')); + window.dispatchEvent(new Event('transactionUpdated')); + window.dispatchEvent(new Event('budgetDataUpdated')); + window.dispatchEvent(new Event('categoryBudgetsUpdated')); }; window.addEventListener('focus', handleFocus);