Refactor BudgetContext file

Refactor BudgetContext.tsx into smaller components and hooks to improve code readability and maintainability.
This commit is contained in:
gpt-engineer-app[bot]
2025-03-15 11:08:35 +00:00
parent 6e02282383
commit 8c403f9761
7 changed files with 404 additions and 323 deletions

View File

@@ -0,0 +1,138 @@
import { useState, useEffect } from 'react';
import { BudgetData, BudgetPeriod, Transaction } from './types';
import { toast } from '@/components/ui/use-toast';
import {
loadTransactionsFromStorage,
saveTransactionsToStorage,
loadCategoryBudgetsFromStorage,
saveCategoryBudgetsToStorage,
loadBudgetDataFromStorage,
saveBudgetDataToStorage
} from './storageUtils';
import {
calculateCategorySpending,
calculateSpentAmounts,
calculateUpdatedBudgetData
} from './budgetUtils';
export const useBudgetState = () => {
// 상태 초기화
const [selectedTab, setSelectedTab] = useState<BudgetPeriod>("daily");
const [transactions, setTransactions] = useState<Transaction[]>([]);
const [categoryBudgets, setCategoryBudgets] = useState<Record<string, number>>(loadCategoryBudgetsFromStorage());
const [budgetData, setBudgetData] = useState<BudgetData>(loadBudgetDataFromStorage());
// 트랜잭션 로드
useEffect(() => {
const loadTransactions = () => {
const storedTransactions = loadTransactionsFromStorage();
setTransactions(storedTransactions);
};
loadTransactions();
// 지출 내역이 변경될 때마다 업데이트되도록 이벤트 리스너를 추가합니다
window.addEventListener('storage', loadTransactions);
return () => {
window.removeEventListener('storage', loadTransactions);
};
}, []);
// 지출 계산 및 업데이트
useEffect(() => {
const updatedBudgetData = calculateSpentAmounts(transactions, budgetData);
setBudgetData(updatedBudgetData);
saveBudgetDataToStorage(updatedBudgetData);
}, [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);
setBudgetData(prev => {
const updatedBudgetData = {
daily: {
targetAmount: totalDailyBudget,
spentAmount: prev.daily.spentAmount,
remainingAmount: totalDailyBudget - prev.daily.spentAmount
},
weekly: {
targetAmount: totalWeeklyBudget,
spentAmount: prev.weekly.spentAmount,
remainingAmount: totalWeeklyBudget - prev.weekly.spentAmount
},
monthly: {
targetAmount: totalMonthlyBudget,
spentAmount: prev.monthly.spentAmount,
remainingAmount: totalMonthlyBudget - prev.monthly.spentAmount
}
};
saveBudgetDataToStorage(updatedBudgetData);
return updatedBudgetData;
});
saveCategoryBudgetsToStorage(categoryBudgets);
}, [categoryBudgets]);
// 카테고리별 지출 계산
const getCategorySpending = () => {
return calculateCategorySpending(transactions, categoryBudgets);
};
// 예산 목표 업데이트 함수
const handleBudgetGoalUpdate = (type: BudgetPeriod, amount: number, newCategoryBudgets?: Record<string, number>) => {
// 카테고리 예산이 직접 업데이트된 경우
if (newCategoryBudgets) {
setCategoryBudgets(newCategoryBudgets);
return; // 카테고리 예산이 변경되면 useEffect에서 자동으로 budgetData가 업데이트됩니다
}
// 월간 예산을 업데이트하고 일일, 주간도 자동 계산
if (type === 'monthly') {
const ratio = amount / budgetData.monthly.targetAmount;
const updatedCategoryBudgets: Record<string, number> = {};
Object.keys(categoryBudgets).forEach(category => {
updatedCategoryBudgets[category] = Math.round(categoryBudgets[category] * ratio);
});
setCategoryBudgets(updatedCategoryBudgets);
} else {
// 일일이나 주간 예산이 직접 업데이트되는 경우
const updatedBudgetData = calculateUpdatedBudgetData(budgetData, type, amount);
setBudgetData(updatedBudgetData);
saveBudgetDataToStorage(updatedBudgetData);
}
toast({
title: "목표 업데이트 완료",
description: `${type === 'daily' ? '일일' : type === 'weekly' ? '주간' : '월간'} 목표가 ${amount.toLocaleString()}원으로 설정되었습니다.`
});
};
// 트랜잭션 업데이트 처리
const updateTransaction = (updatedTransaction: Transaction) => {
setTransactions(prev => {
const updated = prev.map(transaction =>
transaction.id === updatedTransaction.id ? updatedTransaction : transaction
);
saveTransactionsToStorage(updated);
return updated;
});
};
return {
transactions,
categoryBudgets,
budgetData,
selectedTab,
setSelectedTab,
updateTransaction,
handleBudgetGoalUpdate,
getCategorySpending
};
};