Refactor useBudgetState hook

Refactor useBudgetState to use separate hooks for different concerns, similar to useBudgetDataState.ts.
This commit is contained in:
gpt-engineer-app[bot]
2025-03-22 11:03:55 +00:00
parent d1a9b9f89f
commit e900fa77a1
3 changed files with 116 additions and 463 deletions

View File

@@ -1,191 +1,29 @@
import { useCallback } from 'react';
import { BudgetData, BudgetPeriod } from '../types';
import { calculateUpdatedBudgetData } from '../budgetUtils';
import { toast } from '@/components/ui/use-toast';
import { BudgetPeriod } from '../types';
// 확장된 예산 업데이트 로직을 제공하는 훅
/**
* 예산 목표 업데이트 확장 함수를 제공하는 훅
* 예산 목표 업데이트와 카테고리 예산 업데이트를 통합합니다.
*/
export const useExtendedBudgetUpdate = (
budgetData: BudgetData,
categoryBudgets: Record<string, number>,
handleBudgetGoalUpdate: (type: BudgetPeriod, amount: number) => void,
updateCategoryBudgets: (budgets: Record<string, number>) => void
handleBudgetUpdate: (type: BudgetPeriod, amount: number) => void,
setCategoryBudgets: (budgets: Record<string, number>) => void
) => {
// 확장된 예산 업데이트 로직
const extendedBudgetGoalUpdate = useCallback((
type: BudgetPeriod,
amount: number,
// 예산 목표 업데이트 확장 함수
const extendedBudgetUpdate = (
type: BudgetPeriod,
amount: number,
newCategoryBudgets?: Record<string, number>
) => {
console.log(`확장된 예산 목표 업데이트 호출: ${type}, 금액: ${amount}, 카테고리 예산:`, newCategoryBudgets);
// 기본 예산 목표 업데이트
handleBudgetUpdate(type, amount);
// 카테고리 예산 제공된 경우 업데이트
// 카테고리 예산 업데이트 (제공된 경우)
if (newCategoryBudgets) {
try {
// 카테고리명 표준화 처리
let updatedCategoryBudgets = { ...newCategoryBudgets };
// 교통비 값이 있으면 교통으로 통합
if (updatedCategoryBudgets['교통비'] && !updatedCategoryBudgets['교통']) {
updatedCategoryBudgets['교통'] = updatedCategoryBudgets['교통비'];
delete updatedCategoryBudgets['교통비'];
}
// 식비 값이 있으면 음식으로 통합
if (updatedCategoryBudgets['식비'] && !updatedCategoryBudgets['음식']) {
updatedCategoryBudgets['음식'] = updatedCategoryBudgets['식비'];
delete updatedCategoryBudgets['식비'];
}
// 생활비 값이 있으면 쇼핑으로 통합
if (updatedCategoryBudgets['생활비'] && !updatedCategoryBudgets['쇼핑']) {
updatedCategoryBudgets['쇼핑'] = updatedCategoryBudgets['생활비'];
delete updatedCategoryBudgets['생활비'];
}
// 카테고리 예산 저장
updateCategoryBudgets(updatedCategoryBudgets);
// 총액 계산 (0 확인)
const totalAmount = Object.values(updatedCategoryBudgets).reduce((sum, val) => sum + val, 0);
console.log('카테고리 예산 총합:', totalAmount, updatedCategoryBudgets);
if (totalAmount <= 0) {
toast({
title: "예산 설정 오류",
description: "유효한 예산 금액을 입력해주세요.",
variant: "destructive"
});
return;
}
// 항상 월간 예산으로 처리하여 일/주간 자동계산 보장
handleBudgetGoalUpdate('monthly', totalAmount);
// 명시적으로 BudgetData 업데이트 이벤트 발생
window.dispatchEvent(new Event('budgetDataUpdated'));
// 성공 토스트 표시
toast({
title: "카테고리 예산 설정 완료",
description: `월간 총 예산이 ${totalAmount.toLocaleString()}원으로 설정되었습니다.`
});
// 다중 이벤트 발생으로 UI 업데이트 보장
// 0.5초 후 1차 업데이트
setTimeout(() => {
console.log("예산 UI 업데이트 이벤트 발생 (1차)");
window.dispatchEvent(new Event('budgetDataUpdated'));
}, 500);
// 1.5초 후 2차 업데이트
setTimeout(() => {
console.log("예산 UI 업데이트 이벤트 발생 (2차)");
window.dispatchEvent(new Event('budgetDataUpdated'));
// 스토리지 이벤트도 발생시켜 데이터 로드 보장
const savedData = localStorage.getItem('budgetData');
if (savedData) {
window.dispatchEvent(new StorageEvent('storage', {
key: 'budgetData',
newValue: savedData
}));
}
}, 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) {
console.error('카테고리 예산 업데이트 오류:', error);
toast({
title: "예산 설정 오류",
description: "카테고리 예산을 업데이트하는 중 오류가 발생했습니다.",
variant: "destructive"
});
}
} else {
// 카테고리 예산이 없는 경우, 선택된 기간 유형에 맞게 예산 설정
if (amount <= 0) {
toast({
title: "예산 설정 오류",
description: "유효한 예산 금액을 입력해주세요.",
variant: "destructive"
});
return;
}
// 어떤 타입이 들어오더라도 항상 월간으로 처리하고 일/주간은 자동계산
if (type !== 'monthly') {
console.log(`${type} 입력을 월간 예산으로 변환합니다.`);
// 일간 입력인 경우 월간으로 변환 (30배)
if (type === 'daily') {
amount = amount * 30;
}
// 주간 입력인 경우 월간으로 변환 (4.3배)
else if (type === 'weekly') {
amount = Math.round(amount * 4.3);
}
// 변환된 금액으로 월간 예산 설정
handleBudgetGoalUpdate('monthly', amount);
} else {
// 원래 월간이면 그대로 설정
handleBudgetGoalUpdate('monthly', amount);
}
// 명시적으로 BudgetData 업데이트 이벤트 발생
window.dispatchEvent(new Event('budgetDataUpdated'));
// 성공 토스트 표시
const periodText = type === 'daily' ? '일일' : type === 'weekly' ? '주간' : '월간';
toast({
title: "예산 설정 완료",
description: `${periodText} 예산이 ${amount.toLocaleString()}원으로 설정되었습니다.`
});
// 다중 이벤트 발생
// 0.5초 후 1차 업데이트
setTimeout(() => {
console.log("예산 UI 업데이트 이벤트 발생 (1차)");
window.dispatchEvent(new Event('budgetDataUpdated'));
}, 500);
// 1.5초 후 2차 업데이트
setTimeout(() => {
console.log("예산 UI 업데이트 이벤트 발생 (2차)");
window.dispatchEvent(new Event('budgetDataUpdated'));
const savedData = localStorage.getItem('budgetData');
if (savedData) {
window.dispatchEvent(new StorageEvent('storage', {
key: 'budgetData',
newValue: savedData
}));
}
}, 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);
console.log('카테고리 예산 업데이트:', newCategoryBudgets);
setCategoryBudgets(newCategoryBudgets);
}
}, [categoryBudgets, handleBudgetGoalUpdate, updateCategoryBudgets]);
};
return { extendedBudgetGoalUpdate };
return extendedBudgetUpdate;
};