Refactor useBudgetState hook
Refactor useBudgetState to use separate hooks for different concerns, similar to useBudgetDataState.ts.
This commit is contained in:
@@ -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;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user