Investigate budget display issue

Examine why budget data is not displaying correctly on the expense and analytics screens, despite being saved successfully.
This commit is contained in:
gpt-engineer-app[bot]
2025-03-22 10:53:56 +00:00
parent c92d41e8f0
commit ab86d9b5f9
5 changed files with 223 additions and 75 deletions

View File

@@ -1,5 +1,5 @@
import React, { useEffect } from 'react'; import React, { useEffect, useState } from 'react';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import BudgetTabContent from './BudgetTabContent'; import BudgetTabContent from './BudgetTabContent';
import { BudgetPeriod } from '@/contexts/budget/BudgetContext'; import { BudgetPeriod } from '@/contexts/budget/BudgetContext';
@@ -31,21 +31,52 @@ const BudgetProgressCard: React.FC<BudgetProgressCardProps> = ({
calculatePercentage, calculatePercentage,
onSaveBudget onSaveBudget
}) => { }) => {
// 컴포넌트 마운트 시 예산 데이터 업데이트 이벤트 발생 // 데이터 상태 추적 (불일치 감지를 위한 로컬 상태)
const [localBudgetData, setLocalBudgetData] = useState(budgetData);
// 컴포넌트 마운트 및 budgetData 변경 시 업데이트
useEffect(() => { useEffect(() => {
console.log("BudgetProgressCard 마운트 - 예산 데이터:", budgetData); console.log("BudgetProgressCard 데이터 업데이트 - 예산 데이터:", budgetData);
setLocalBudgetData(budgetData);
// 지연 작업으로 이벤트 발생 (컴포넌트 마운트 후 데이터 갱신) // 지연 작업으로 이벤트 발생 (컴포넌트 마운트 후 데이터 갱신)
const timeoutId = setTimeout(() => { const timeoutId = setTimeout(() => {
window.dispatchEvent(new Event('budgetDataUpdated')); window.dispatchEvent(new Event('budgetDataUpdated'));
}, 500); }, 300);
return () => clearTimeout(timeoutId); return () => clearTimeout(timeoutId);
}, [budgetData]);
// budgetDataUpdated 이벤트 감지
useEffect(() => {
const handleBudgetDataUpdated = () => {
console.log("BudgetProgressCard: 예산 데이터 업데이트 이벤트 감지");
};
window.addEventListener('budgetDataUpdated', handleBudgetDataUpdated);
return () => window.removeEventListener('budgetDataUpdated', handleBudgetDataUpdated);
}, []); }, []);
// 탭 변경 처리 - 예산 데이터 확인
const handleTabChange = (value: string) => {
console.log(`탭 변경: ${value}, 현재 예산 데이터:`, {
daily: budgetData.daily.targetAmount,
weekly: budgetData.weekly.targetAmount,
monthly: budgetData.monthly.targetAmount
});
setSelectedTab(value);
};
// 각 탭에 대한 현재 예산 설정 여부 계산
const isDailyBudgetSet = budgetData.daily.targetAmount > 0;
const isWeeklyBudgetSet = budgetData.weekly.targetAmount > 0;
const isMonthlyBudgetSet = budgetData.monthly.targetAmount > 0;
console.log(`BudgetProgressCard 상태: 일=${isDailyBudgetSet}, 주=${isWeeklyBudgetSet}, 월=${isMonthlyBudgetSet}`);
return ( return (
<div className="neuro-card mb-6 overflow-hidden w-full"> <div className="neuro-card mb-6 overflow-hidden w-full">
<Tabs defaultValue="daily" value={selectedTab} onValueChange={setSelectedTab} className="w-full"> <Tabs defaultValue="daily" value={selectedTab} onValueChange={handleTabChange} className="w-full">
<TabsList className="grid grid-cols-3 mb-4 bg-transparent"> <TabsList className="grid grid-cols-3 mb-4 bg-transparent">
<TabsTrigger <TabsTrigger
value="daily" value="daily"

View File

@@ -29,13 +29,35 @@ const BudgetTabContent: React.FC<BudgetTabContentProps> = ({
const spentAmount = data.spentAmount; const spentAmount = data.spentAmount;
const targetAmount = data.targetAmount; const targetAmount = data.targetAmount;
// 예산 설정 여부 확인 (수정: 0보다 큰지만 확인) // 로그 추가 - 받은 데이터 확인
useEffect(() => {
console.log(`BudgetTabContent 수신 데이터:`, data);
}, [data]);
// 전역 예산 데이터가 변경되었을 때 로컬 상태 갱신
useEffect(() => {
const handleBudgetDataUpdated = () => {
console.log(`BudgetTabContent: 전역 예산 데이터 이벤트 감지, 현재 targetAmount=${targetAmount}`);
// 입력 폼이 열려있고 예산이 설정된 경우 폼 닫기
if (showBudgetInput && targetAmount > 0) {
console.log('예산이 설정되어 입력 폼을 닫습니다.');
setShowBudgetInput(false);
}
};
window.addEventListener('budgetDataUpdated', handleBudgetDataUpdated);
return () => window.removeEventListener('budgetDataUpdated', handleBudgetDataUpdated);
}, [showBudgetInput, targetAmount]);
// 예산 설정 여부 확인 - 데이터 targetAmount가 실제로 0보다 큰지 확인
const isBudgetSet = targetAmount > 0; const isBudgetSet = targetAmount > 0;
// 디버깅을 위한 로그 추가
useEffect(() => { useEffect(() => {
console.log(`BudgetTabContent 렌더링: targetAmount=${targetAmount}, isBudgetSet=${isBudgetSet}`); if (isBudgetSet && showBudgetInput) {
}, [targetAmount, isBudgetSet]); console.log('예산이 설정되었으므로 입력 폼을 닫습니다.');
setShowBudgetInput(false);
}
}, [isBudgetSet, showBudgetInput]);
// 실제 백분율 계산 (초과해도 실제 퍼센트로 표시) // 실제 백분율 계산 (초과해도 실제 퍼센트로 표시)
const actualPercentage = targetAmount > 0 ? Math.round((spentAmount / targetAmount) * 100) : 0; const actualPercentage = targetAmount > 0 ? Math.round((spentAmount / targetAmount) * 100) : 0;
@@ -116,12 +138,16 @@ const BudgetTabContent: React.FC<BudgetTabContentProps> = ({
// 예산 버튼 클릭 핸들러 - 토글 기능 추가 // 예산 버튼 클릭 핸들러 - 토글 기능 추가
const toggleBudgetInput = () => { const toggleBudgetInput = () => {
console.log('예산 입력 폼 토글. 현재 상태:', showBudgetInput, '예산 설정 여부:', isBudgetSet);
setShowBudgetInput(prev => !prev); setShowBudgetInput(prev => !prev);
}; };
// 예산 여부에 따른 텍스트 결정 // 예산 여부에 따른 텍스트 결정
const budgetButtonText = isBudgetSet ? "예산 수정하기" : "예산 입력하기"; const budgetButtonText = isBudgetSet ? "예산 수정하기" : "예산 입력하기";
// 화면에 표시할 내용 - 디버깅을 위한 로그 추가
console.log(`BudgetTabContent 렌더링: targetAmount=${targetAmount}, isBudgetSet=${isBudgetSet}, 표시될 화면:`, isBudgetSet ? "예산 진행 상황" : "예산 입력하기 버튼");
return ( return (
<div> <div>
{isBudgetSet ? ( {isBudgetSet ? (

View File

@@ -63,7 +63,13 @@ export const calculateUpdatedBudgetData = (
type: BudgetPeriod, type: BudgetPeriod,
amount: number amount: number
): BudgetData => { ): BudgetData => {
console.log(`예산 업데이트 계산: 타입=${type}, 금액=${amount}`); console.log(`예산 업데이트 계산 시작: 타입=${type}, 금액=${amount}`);
// 값이 없거나 유효하지 않은 경우 로깅
if (!prevBudgetData) {
console.error('이전 예산 데이터가 없습니다. 기본값 사용.');
prevBudgetData = getInitialBudgetData();
}
// 선택된 타입에 따라 다른 타입의 예산도 자동으로 계산 // 선택된 타입에 따라 다른 타입의 예산도 자동으로 계산
let monthlyAmount: number, weeklyAmount: number, dailyAmount: number; let monthlyAmount: number, weeklyAmount: number, dailyAmount: number;
@@ -71,7 +77,9 @@ export const calculateUpdatedBudgetData = (
if (type === 'monthly') { if (type === 'monthly') {
// 월간 예산이 직접 입력된 경우 // 월간 예산이 직접 입력된 경우
monthlyAmount = amount; monthlyAmount = amount;
// 월 30일 기준 (실제 사용 시 값 확인)
dailyAmount = Math.round(monthlyAmount / 30); dailyAmount = Math.round(monthlyAmount / 30);
// 월 4.3주 기준 (실제 사용 시 값 확인)
weeklyAmount = Math.round(monthlyAmount / 4.3); weeklyAmount = Math.round(monthlyAmount / 4.3);
} else if (type === 'weekly') { } else if (type === 'weekly') {
// 주간 예산이 직접 입력된 경우 // 주간 예산이 직접 입력된 경우
@@ -90,29 +98,38 @@ export const calculateUpdatedBudgetData = (
weeklyAmount = Math.max(0, weeklyAmount); weeklyAmount = Math.max(0, weeklyAmount);
dailyAmount = Math.max(0, dailyAmount); dailyAmount = Math.max(0, dailyAmount);
console.log(`최종 예산 계산: 월간=${monthlyAmount}원, 주간=${weeklyAmount}원, 일일=${dailyAmount}`); console.log(`최종 예산 계산 결과: 월간=${monthlyAmount}원, 주간=${weeklyAmount}원, 일일=${dailyAmount}`);
// prevBudgetData 출력하여 디버깅 // 로그에 이전 예산 데이터 출력
console.log("이전 예산 데이터:", JSON.stringify(prevBudgetData)); console.log("이전 예산 데이터:", JSON.stringify(prevBudgetData));
// 이전 지출 데이터 보존
const dailySpent = prevBudgetData.daily?.spentAmount || 0;
const weeklySpent = prevBudgetData.weekly?.spentAmount || 0;
const monthlySpent = prevBudgetData.monthly?.spentAmount || 0;
// 새 예산 데이터 생성 (spentAmount는 이전 값 유지) // 새 예산 데이터 생성 (spentAmount는 이전 값 유지)
return { const updatedBudgetData = {
daily: { daily: {
targetAmount: dailyAmount, targetAmount: dailyAmount,
spentAmount: prevBudgetData.daily.spentAmount, spentAmount: dailySpent,
remainingAmount: Math.max(0, dailyAmount - prevBudgetData.daily.spentAmount) remainingAmount: Math.max(0, dailyAmount - dailySpent)
}, },
weekly: { weekly: {
targetAmount: weeklyAmount, targetAmount: weeklyAmount,
spentAmount: prevBudgetData.weekly.spentAmount, spentAmount: weeklySpent,
remainingAmount: Math.max(0, weeklyAmount - prevBudgetData.weekly.spentAmount) remainingAmount: Math.max(0, weeklyAmount - weeklySpent)
}, },
monthly: { monthly: {
targetAmount: monthlyAmount, targetAmount: monthlyAmount,
spentAmount: prevBudgetData.monthly.spentAmount, spentAmount: monthlySpent,
remainingAmount: Math.max(0, monthlyAmount - prevBudgetData.monthly.spentAmount) remainingAmount: Math.max(0, monthlyAmount - monthlySpent)
} }
}; };
console.log("새 예산 데이터:", JSON.stringify(updatedBudgetData));
return updatedBudgetData;
}; };
// 지출액 계산 (일일, 주간, 월간) - 문제 수정 // 지출액 계산 (일일, 주간, 월간) - 문제 수정
@@ -120,6 +137,8 @@ export const calculateSpentAmounts = (
transactions: Transaction[], transactions: Transaction[],
prevBudgetData: BudgetData prevBudgetData: BudgetData
): BudgetData => { ): BudgetData => {
console.log("지출액 계산 시작, 트랜잭션 수:", transactions.length);
// 지출 거래 필터링 // 지출 거래 필터링
const expenseTransactions = transactions.filter(t => t.type === 'expense'); const expenseTransactions = transactions.filter(t => t.type === 'expense');
@@ -140,13 +159,13 @@ export const calculateSpentAmounts = (
// 이번 달 총 지출 계산 // 이번 달 총 지출 계산
const monthlySpent = expenseTransactions.reduce((sum, t) => sum + t.amount, 0); const monthlySpent = expenseTransactions.reduce((sum, t) => sum + t.amount, 0);
// 기존 예산 목표 유지 // 기존 예산 목표 유지 (없으면 기본값 0)
const dailyTarget = prevBudgetData.daily.targetAmount; const dailyTarget = prevBudgetData?.daily?.targetAmount || 0;
const weeklyTarget = prevBudgetData.weekly.targetAmount; const weeklyTarget = prevBudgetData?.weekly?.targetAmount || 0;
const monthlyTarget = prevBudgetData.monthly.targetAmount; const monthlyTarget = prevBudgetData?.monthly?.targetAmount || 0;
// 예산 데이터 업데이트 // 예산 데이터 업데이트
return { const updatedBudget = {
daily: { daily: {
targetAmount: dailyTarget, targetAmount: dailyTarget,
spentAmount: dailySpent, spentAmount: dailySpent,
@@ -163,6 +182,10 @@ export const calculateSpentAmounts = (
remainingAmount: Math.max(0, monthlyTarget - monthlySpent) remainingAmount: Math.max(0, monthlyTarget - monthlySpent)
} }
}; };
console.log("지출액 계산 결과:", updatedBudget);
return updatedBudget;
}; };
// 초기 예산 데이터 생성 // 초기 예산 데이터 생성
@@ -185,3 +208,25 @@ export const getInitialBudgetData = (): BudgetData => {
} }
}; };
}; };
// 스토리지에서 안전하게 예산 데이터 가져오기
export const safelyLoadBudgetData = (defaultData: BudgetData = getInitialBudgetData()): BudgetData => {
try {
const budgetDataStr = localStorage.getItem('budgetData');
if (budgetDataStr) {
const parsed = JSON.parse(budgetDataStr);
// 데이터 구조 검증 (daily, weekly, monthly 키 존재 확인)
if (parsed && parsed.daily && parsed.weekly && parsed.monthly) {
return parsed;
} else {
console.warn('저장된 예산 데이터 구조가 유효하지 않습니다. 기본값 사용.');
}
}
} catch (error) {
console.error('예산 데이터 로드 오류:', error);
}
// 오류 발생 또는 데이터 없음 시 기본값 반환
return defaultData;
};

View File

@@ -9,16 +9,19 @@ import {
import { toast } from '@/components/ui/use-toast'; import { toast } from '@/components/ui/use-toast';
import { import {
calculateUpdatedBudgetData, calculateUpdatedBudgetData,
calculateSpentAmounts calculateSpentAmounts,
safelyLoadBudgetData
} from '../budgetUtils'; } from '../budgetUtils';
import { Transaction } from '../types'; import { Transaction } from '../types';
// 예산 데이터 상태 관리 훅 // 예산 데이터 상태 관리 훅
export const useBudgetDataState = (transactions: Transaction[]) => { export const useBudgetDataState = (transactions: Transaction[]) => {
const [budgetData, setBudgetData] = useState<BudgetData>(loadBudgetDataFromStorage()); // 초기 데이터 로드 시 safelyLoadBudgetData 함수 사용
const [budgetData, setBudgetData] = useState<BudgetData>(safelyLoadBudgetData());
const [selectedTab, setSelectedTab] = useState<BudgetPeriod>("daily"); const [selectedTab, setSelectedTab] = useState<BudgetPeriod>("daily");
const [isInitialized, setIsInitialized] = useState(false); const [isInitialized, setIsInitialized] = useState(false);
const [lastUpdateTime, setLastUpdateTime] = useState(0);
// 초기 로드 및 이벤트 리스너 설정 - 최적화된 버전 // 초기 로드 및 이벤트 리스너 설정 - 최적화된 버전
useEffect(() => { useEffect(() => {
@@ -30,54 +33,51 @@ export const useBudgetDataState = (transactions: Transaction[]) => {
// 비동기 작업을 마이크로태스크로 지연 // 비동기 작업을 마이크로태스크로 지연
await new Promise<void>(resolve => queueMicrotask(() => resolve())); await new Promise<void>(resolve => queueMicrotask(() => resolve()));
const loadedData = loadBudgetDataFromStorage(); // 안전하게 데이터 로드
const loadedData = safelyLoadBudgetData();
console.log('로드된 예산 데이터:', JSON.stringify(loadedData)); console.log('로드된 예산 데이터:', JSON.stringify(loadedData));
// 새로 로드한 데이터와 현재 데이터가 다를 때만 업데이트 // 새로 로드한 데이터와 현재 데이터가 다를 때만 업데이트
if (JSON.stringify(loadedData) !== JSON.stringify(budgetData)) { if (JSON.stringify(loadedData) !== JSON.stringify(budgetData)) {
// 상태 업데이트를 마이크로태스크로 지연 console.log('새 예산 데이터 감지됨, 상태 업데이트');
queueMicrotask(() => {
setBudgetData(loadedData); setBudgetData(loadedData);
console.log('예산 데이터 업데이트 완료'); setLastUpdateTime(Date.now());
});
} }
// 초기화 상태 업데이트 // 초기화 상태 업데이트
if (!isInitialized) { if (!isInitialized) {
queueMicrotask(() => {
setIsInitialized(true); setIsInitialized(true);
});
} }
} catch (error) { } catch (error) {
console.error('예산 데이터 로드 중 오류:', error); console.error('예산 데이터 로드 중 오류:', error);
} }
}; };
// 초기 로드 - 지연 시간 추가 // 초기 로드 - 직접 호출
setTimeout(() => {
loadBudget(); loadBudget();
}, 100); // 지연된 초기 로드
// 필수 이벤트 등록 // 필수 이벤트 등록
const handleBudgetUpdate = () => loadBudget(); const handleBudgetUpdate = () => {
console.log('예산 데이터 업데이트 이벤트 감지');
loadBudget();
};
// 필수 이벤트만 등록 window.addEventListener('budgetDataUpdated', handleBudgetUpdate);
const budgetUpdateHandler = () => handleBudgetUpdate();
window.addEventListener('budgetDataUpdated', budgetUpdateHandler);
// 스토리지 이벤트도 함께 처리 (다른 탭/창에서의 업데이트 감지) // 스토리지 이벤트도 함께 처리 (다른 탭/창에서의 업데이트 감지)
const storageUpdateHandler = (e: StorageEvent) => { const storageUpdateHandler = (e: StorageEvent) => {
if (e.key === 'budgetData' || e.key === null) { if (e.key === 'budgetData' || e.key === null) {
console.log('스토리지 이벤트 감지 - 예산 데이터 업데이트');
handleBudgetUpdate(); handleBudgetUpdate();
} }
}; };
window.addEventListener('storage', storageUpdateHandler); window.addEventListener('storage', storageUpdateHandler);
return () => { return () => {
window.removeEventListener('budgetDataUpdated', budgetUpdateHandler); window.removeEventListener('budgetDataUpdated', handleBudgetUpdate);
window.removeEventListener('storage', storageUpdateHandler); window.removeEventListener('storage', storageUpdateHandler);
}; };
}, [isInitialized, budgetData]); }, [isInitialized]);
// 트랜잭션 변경 시 지출 금액 업데이트 // 트랜잭션 변경 시 지출 금액 업데이트
useEffect(() => { useEffect(() => {
@@ -85,19 +85,18 @@ export const useBudgetDataState = (transactions: Transaction[]) => {
console.log('트랜잭션 변경으로 인한 예산 데이터 업데이트. 트랜잭션 수:', transactions.length); console.log('트랜잭션 변경으로 인한 예산 데이터 업데이트. 트랜잭션 수:', transactions.length);
try { try {
// 현재 예산 데이터 다시 로드 (최신 상태 확보) // 현재 예산 데이터 다시 로드 (최신 상태 확보)
const currentBudgetData = loadBudgetDataFromStorage(); const currentBudgetData = safelyLoadBudgetData();
// 지출 금액 업데이트 // 지출 금액 업데이트
const updatedBudgetData = calculateSpentAmounts(transactions, currentBudgetData); const updatedBudgetData = calculateSpentAmounts(transactions, currentBudgetData);
// 변경이 있을 때만 저장 // 변경이 있을 때만 저장
if (JSON.stringify(updatedBudgetData) !== JSON.stringify(currentBudgetData)) { if (JSON.stringify(updatedBudgetData) !== JSON.stringify(currentBudgetData)) {
console.log('예산 지출액 업데이트 감지 - 데이터 저장');
// 상태 및 스토리지 모두 업데이트 // 상태 및 스토리지 모두 업데이트
setBudgetData(updatedBudgetData); setBudgetData(updatedBudgetData);
saveBudgetDataToStorage(updatedBudgetData); saveBudgetDataToStorage(updatedBudgetData);
setLastUpdateTime(Date.now());
// 저장 시간 업데이트
localStorage.setItem('lastBudgetSaveTime', new Date().toISOString());
// 기타 컴포넌트에 이벤트 알림 // 기타 컴포넌트에 이벤트 알림
window.dispatchEvent(new Event('budgetDataUpdated')); window.dispatchEvent(new Event('budgetDataUpdated'));
@@ -128,7 +127,7 @@ export const useBudgetDataState = (transactions: Transaction[]) => {
} }
// 현재 최신 예산 데이터 로드 (다른 곳에서 변경되었을 수 있음) // 현재 최신 예산 데이터 로드 (다른 곳에서 변경되었을 수 있음)
const currentBudgetData = loadBudgetDataFromStorage(); const currentBudgetData = safelyLoadBudgetData();
// 예산 데이터 업데이트 - 일간, 주간, 월간 예산이 모두 자동으로 계산됨 // 예산 데이터 업데이트 - 일간, 주간, 월간 예산이 모두 자동으로 계산됨
const updatedBudgetData = calculateUpdatedBudgetData(currentBudgetData, type, amount); const updatedBudgetData = calculateUpdatedBudgetData(currentBudgetData, type, amount);
@@ -137,9 +136,7 @@ export const useBudgetDataState = (transactions: Transaction[]) => {
// 상태 및 스토리지 둘 다 업데이트 // 상태 및 스토리지 둘 다 업데이트
setBudgetData(updatedBudgetData); setBudgetData(updatedBudgetData);
saveBudgetDataToStorage(updatedBudgetData); saveBudgetDataToStorage(updatedBudgetData);
setLastUpdateTime(Date.now());
// 저장 시간 업데이트
localStorage.setItem('lastBudgetSaveTime', new Date().toISOString());
// 이벤트 발생시켜 다른 컴포넌트에 알림 // 이벤트 발생시켜 다른 컴포넌트에 알림
window.dispatchEvent(new Event('budgetDataUpdated')); window.dispatchEvent(new Event('budgetDataUpdated'));
@@ -151,7 +148,16 @@ export const useBudgetDataState = (transactions: Transaction[]) => {
key: 'budgetData', key: 'budgetData',
newValue: JSON.stringify(updatedBudgetData) newValue: JSON.stringify(updatedBudgetData)
})); }));
}, 1000); }, 500);
// 2초 후 데이터 갱신 이벤트 한 번 더 발생
setTimeout(() => {
window.dispatchEvent(new Event('budgetDataUpdated'));
window.dispatchEvent(new StorageEvent('storage', {
key: 'budgetData',
newValue: JSON.stringify(updatedBudgetData)
}));
}, 2000);
console.log('예산 목표 업데이트 완료:', updatedBudgetData); console.log('예산 목표 업데이트 완료:', updatedBudgetData);
@@ -178,8 +184,9 @@ export const useBudgetDataState = (transactions: Transaction[]) => {
clearAllBudgetData(); clearAllBudgetData();
// 로컬스토리지에서 다시 로드 // 로컬스토리지에서 다시 로드
const freshData = loadBudgetDataFromStorage(); const freshData = safelyLoadBudgetData();
setBudgetData(freshData); setBudgetData(freshData);
setLastUpdateTime(Date.now());
// 이벤트 발생시켜 다른 컴포넌트에 알림 // 이벤트 발생시켜 다른 컴포넌트에 알림
window.dispatchEvent(new Event('budgetDataUpdated')); window.dispatchEvent(new Event('budgetDataUpdated'));
@@ -195,8 +202,8 @@ export const useBudgetDataState = (transactions: Transaction[]) => {
// 디버깅 로그 추가 // 디버깅 로그 추가
useEffect(() => { useEffect(() => {
console.log('최신 예산 데이터:', JSON.stringify(budgetData)); console.log('최신 예산 데이터:', JSON.stringify(budgetData), '마지막 업데이트:', new Date(lastUpdateTime).toISOString());
}, [budgetData]); }, [budgetData, lastUpdateTime]);
return { return {
budgetData, budgetData,

View File

@@ -17,7 +17,7 @@ export const useExtendedBudgetUpdate = (
amount: number, amount: number,
newCategoryBudgets?: Record<string, number> newCategoryBudgets?: Record<string, number>
) => { ) => {
console.log(`확장된 예산 목표 업데이트: ${type}, 금액: ${amount}, 카테고리 예산:`, newCategoryBudgets); console.log(`확장된 예산 목표 업데이트 호출: ${type}, 금액: ${amount}, 카테고리 예산:`, newCategoryBudgets);
// 카테고리 예산이 제공된 경우 업데이트 // 카테고리 예산이 제공된 경우 업데이트
if (newCategoryBudgets) { if (newCategoryBudgets) {
@@ -48,7 +48,7 @@ export const useExtendedBudgetUpdate = (
// 총액 계산 (0 확인) // 총액 계산 (0 확인)
const totalAmount = Object.values(updatedCategoryBudgets).reduce((sum, val) => sum + val, 0); const totalAmount = Object.values(updatedCategoryBudgets).reduce((sum, val) => sum + val, 0);
console.log('카테고리 총액:', totalAmount); console.log('카테고리 예산 총합:', totalAmount, updatedCategoryBudgets);
if (totalAmount <= 0) { if (totalAmount <= 0) {
toast({ toast({
@@ -71,19 +71,39 @@ export const useExtendedBudgetUpdate = (
description: `월간 총 예산이 ${totalAmount.toLocaleString()}원으로 설정되었습니다.` description: `월간 총 예산이 ${totalAmount.toLocaleString()}원으로 설정되었습니다.`
}); });
// 여러 번의 이벤트 발생으로 UI 업데이트 보장 (타이밍 문제 해결) // 다중 이벤트 발생으로 UI 업데이트 보장
// 0.5초 후 1차 업데이트
setTimeout(() => { setTimeout(() => {
console.log("예산 UI 업데이트 이벤트 발생 (1차)");
window.dispatchEvent(new Event('budgetDataUpdated')); window.dispatchEvent(new Event('budgetDataUpdated'));
}, 300); }, 500);
// 1.5초 후 2차 업데이트
setTimeout(() => { setTimeout(() => {
console.log("예산 UI 업데이트 이벤트 발생 (2차)");
window.dispatchEvent(new Event('budgetDataUpdated')); window.dispatchEvent(new Event('budgetDataUpdated'));
// 스토리지 이벤트도 발생시켜 데이터 로드 보장 // 스토리지 이벤트도 발생시켜 데이터 로드 보장
const savedData = localStorage.getItem('budgetData');
if (savedData) {
window.dispatchEvent(new StorageEvent('storage', { window.dispatchEvent(new StorageEvent('storage', {
key: 'budgetData', key: 'budgetData',
newValue: localStorage.getItem('budgetData') newValue: savedData
})); }));
}, 1000); }
}, 1500);
// 3초 후 3차 업데이트 (최종 보장)
setTimeout(() => {
console.log("예산 UI 업데이트 이벤트 발생 (3차/최종)");
window.dispatchEvent(new Event('budgetDataUpdated'));
const savedData = localStorage.getItem('budgetData');
if (savedData) {
window.dispatchEvent(new StorageEvent('storage', {
key: 'budgetData',
newValue: savedData
}));
}
}, 3000);
} catch (error) { } catch (error) {
console.error('카테고리 예산 업데이트 오류:', error); console.error('카테고리 예산 업데이트 오류:', error);
toast({ toast({
@@ -132,19 +152,38 @@ export const useExtendedBudgetUpdate = (
description: `${periodText} 예산이 ${amount.toLocaleString()}원으로 설정되었습니다.` description: `${periodText} 예산이 ${amount.toLocaleString()}원으로 설정되었습니다.`
}); });
// 데이터 표시 강제 갱신 (타이밍 문제 해결을 위한 여러 이벤트 발생) // 다중 이벤트 발생
// 0.5초 후 1차 업데이트
setTimeout(() => { setTimeout(() => {
console.log("예산 UI 업데이트 이벤트 발생 (1차)");
window.dispatchEvent(new Event('budgetDataUpdated')); window.dispatchEvent(new Event('budgetDataUpdated'));
}, 300); }, 500);
// 1.5초 후 2차 업데이트
setTimeout(() => { setTimeout(() => {
console.log("예산 UI 업데이트 이벤트 발생 (2차)");
window.dispatchEvent(new Event('budgetDataUpdated')); window.dispatchEvent(new Event('budgetDataUpdated'));
// 스토리지 이벤트도 발생시켜 데이터 로드 보장 const savedData = localStorage.getItem('budgetData');
if (savedData) {
window.dispatchEvent(new StorageEvent('storage', { window.dispatchEvent(new StorageEvent('storage', {
key: 'budgetData', key: 'budgetData',
newValue: localStorage.getItem('budgetData') newValue: savedData
})); }));
}, 1000); }
}, 1500);
// 3초 후 3차 업데이트 (최종 보장)
setTimeout(() => {
console.log("예산 UI 업데이트 이벤트 발생 (3차/최종)");
window.dispatchEvent(new Event('budgetDataUpdated'));
const savedData = localStorage.getItem('budgetData');
if (savedData) {
window.dispatchEvent(new StorageEvent('storage', {
key: 'budgetData',
newValue: savedData
}));
}
}, 3000);
} }
}, [categoryBudgets, handleBudgetGoalUpdate, updateCategoryBudgets]); }, [categoryBudgets, handleBudgetGoalUpdate, updateCategoryBudgets]);