import React, { createContext, useState, useContext, useEffect } from 'react'; import { BudgetContextType, BudgetData, Transaction, CategoryBudget } from './budget/types'; import { loadTransactionsFromStorage, saveTransactionsToStorage } from '@/hooks/transactions/storageUtils'; import { v4 as uuidv4 } from 'uuid'; // BudgetContext 생성 const BudgetContext = createContext(undefined); export const BudgetProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { // 로컬 스토리지에서 초기 트랜잭션 데이터 로드 const [transactions, setTransactions] = useState([]); const [categoryBudgets, setCategoryBudgets] = useState>({}); const [budgetData, setBudgetData] = useState({ daily: { targetAmount: 0, spentAmount: 0, remainingAmount: 0 }, weekly: { targetAmount: 0, spentAmount: 0, remainingAmount: 0 }, monthly: { targetAmount: 0, spentAmount: 0, remainingAmount: 0 }, }); const [selectedTab, setSelectedTab] = useState<'daily' | 'weekly' | 'monthly'>('monthly'); useEffect(() => { const storedTransactions = loadTransactionsFromStorage(); setTransactions(storedTransactions); }, []); useEffect(() => { // 트랜잭션 변경 시 로컬 스토리지에 저장 saveTransactionsToStorage(transactions); }, [transactions]); // 트랜잭션 추가 const addTransaction = (transaction: Transaction) => { const newTransaction = { ...transaction, id: uuidv4() }; setTransactions(prevTransactions => [...prevTransactions, newTransaction]); }; // 트랜잭션 업데이트 const updateTransaction = (updatedTransaction: Transaction) => { setTransactions(prevTransactions => prevTransactions.map(transaction => transaction.id === updatedTransaction.id ? updatedTransaction : transaction ) ); }; // 트랜잭션 삭제 const deleteTransaction = (id: string) => { setTransactions(prevTransactions => prevTransactions.filter(transaction => transaction.id !== id) ); }; // 예산 목표 업데이트 const handleBudgetGoalUpdate = (type: 'daily' | 'weekly' | 'monthly', amount: number, newCategoryBudgets?: Record) => { setBudgetData(prev => ({ ...prev, [type]: { ...prev[type], targetAmount: amount, }, })); if (newCategoryBudgets) { setCategoryBudgets(newCategoryBudgets); } }; // 카테고리별 지출 계산 const getCategorySpending = () => { const categorySpending: { [key: string]: { total: number; current: number } } = {}; // 초기화 ['음식', '쇼핑', '교통', '기타'].forEach(category => { categorySpending[category] = { total: categoryBudgets[category] || 0, current: 0 }; }); // 지출 합산 transactions.filter(tx => tx.type === 'expense').forEach(tx => { categorySpending[tx.category].current += tx.amount; }); // 배열로 변환 return Object.entries(categorySpending).map(([title, { total, current }]) => ({ title, total, current, })); }; // 결제 방법 통계 계산 함수 추가 const getPaymentMethodStats = () => { // 지출 트랜잭션 필터링 const expenseTransactions = transactions.filter(t => t.type === 'expense'); // 총 지출 계산 const totalExpense = expenseTransactions.reduce((acc, curr) => acc + curr.amount, 0); // 결제 방법별 금액 계산 const cardExpense = expenseTransactions .filter(t => t.paymentMethod === '신용카드' || !t.paymentMethod) // paymentMethod가 없으면 신용카드로 간주 .reduce((acc, curr) => acc + curr.amount, 0); const cashExpense = expenseTransactions .filter(t => t.paymentMethod === '현금') .reduce((acc, curr) => acc + curr.amount, 0); // 결과 배열 생성 - 금액이 큰 순서대로 정렬 const result = [ { method: '신용카드', amount: cardExpense, percentage: totalExpense > 0 ? (cardExpense / totalExpense) * 100 : 0 }, { method: '현금', amount: cashExpense, percentage: totalExpense > 0 ? (cashExpense / totalExpense) * 100 : 0 } ].sort((a, b) => b.amount - a.amount); return result; }; // 예산 데이터 재설정 함수 추가 const resetBudgetData = () => { setBudgetData({ daily: { targetAmount: 0, spentAmount: 0, remainingAmount: 0 }, weekly: { targetAmount: 0, spentAmount: 0, remainingAmount: 0 }, monthly: { targetAmount: 0, spentAmount: 0, remainingAmount: 0 }, }); setCategoryBudgets({}); }; return ( {children} ); }; // useContext Hook export const useBudget = () => { const context = useContext(BudgetContext); if (context === undefined) { throw new Error("useBudget must be used within a BudgetProvider"); } return context; }; // 타입 내보내기를 수정 export type { BudgetContextType }; export type { Transaction } from './budget/types'; export { type BudgetPeriod } from './budget/types';