From bbf0f75b66bf30779aa8b2a5006fb42b827b1fde Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Sat, 15 Mar 2025 10:54:24 +0000 Subject: [PATCH] Fix type errors in BudgetContext Addresses type errors related to category budgets in BudgetContext and Index page. Specifically, ensures correct type assignment for category budget updates. --- src/components/BudgetProgressCard.tsx | 9 +---- src/components/BudgetTabContent.tsx | 22 ++++------- src/components/CategoryBudgetInputs.tsx | 49 +++++++------------------ src/contexts/BudgetContext.tsx | 20 +++++----- 4 files changed, 35 insertions(+), 65 deletions(-) diff --git a/src/components/BudgetProgressCard.tsx b/src/components/BudgetProgressCard.tsx index e39b481..b8ccfb9 100644 --- a/src/components/BudgetProgressCard.tsx +++ b/src/components/BudgetProgressCard.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import BudgetTabContent from './BudgetTabContent'; +import { BudgetPeriod } from '@/contexts/BudgetContext'; interface BudgetData { targetAmount: number; @@ -9,12 +10,6 @@ interface BudgetData { remainingAmount: number; } -interface CategoryBudget { - 식비: number; - 생활비: number; - 교통비: number; -} - interface BudgetProgressCardProps { budgetData: { daily: BudgetData; @@ -25,7 +20,7 @@ interface BudgetProgressCardProps { setSelectedTab: (value: string) => void; formatCurrency: (amount: number) => string; calculatePercentage: (spent: number, target: number) => number; - onSaveBudget: (type: 'daily' | 'weekly' | 'monthly', amount: number, categoryBudgets?: CategoryBudget) => void; + onSaveBudget: (type: BudgetPeriod, amount: number, newCategoryBudgets?: Record) => void; } const BudgetProgressCard: React.FC = ({ diff --git a/src/components/BudgetTabContent.tsx b/src/components/BudgetTabContent.tsx index e557276..fbc334c 100644 --- a/src/components/BudgetTabContent.tsx +++ b/src/components/BudgetTabContent.tsx @@ -6,6 +6,7 @@ import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/component import BudgetProgress from './BudgetProgress'; import CategoryBudgetInputs from './CategoryBudgetInputs'; import { toast } from '@/components/ui/use-toast'; +import { EXPENSE_CATEGORIES } from '@/constants/categoryIcons'; interface BudgetData { targetAmount: number; @@ -13,17 +14,11 @@ interface BudgetData { remainingAmount: number; } -interface CategoryBudget { - 식비: number; - 생활비: number; - 교통비: number; -} - interface BudgetTabContentProps { data: BudgetData; formatCurrency: (amount: number) => string; calculatePercentage: (spent: number, target: number) => number; - onSaveBudget: (amount: number, categoryBudgets?: CategoryBudget) => void; + onSaveBudget: (amount: number, categoryBudgets?: Record) => void; } const BudgetTabContent: React.FC = ({ @@ -40,13 +35,12 @@ const BudgetTabContent: React.FC = ({ const savedCategoryBudgets = localStorage.getItem('categoryBudgets'); const initialCategoryBudgets = savedCategoryBudgets ? JSON.parse(savedCategoryBudgets) - : { - 식비: Math.round(data.targetAmount * 0.4), - 생활비: Math.round(data.targetAmount * 0.4), - 교통비: Math.round(data.targetAmount * 0.2) - }; + : EXPENSE_CATEGORIES.reduce((acc, category) => { + acc[category] = Math.round(data.targetAmount / EXPENSE_CATEGORIES.length); + return acc; + }, {} as Record); - const [categoryBudgets, setCategoryBudgets] = useState(initialCategoryBudgets); + const [categoryBudgets, setCategoryBudgets] = useState>(initialCategoryBudgets); const handleInputChange = (value: string) => { // Remove all non-numeric characters @@ -54,7 +48,7 @@ const BudgetTabContent: React.FC = ({ setBudgetInput(numericValue); }; - const handleCategoryInputChange = (value: string, category: keyof CategoryBudget) => { + const handleCategoryInputChange = (value: string, category: string) => { // Remove all non-numeric characters const numericValue = value.replace(/[^0-9]/g, ''); setCategoryBudgets(prev => ({ diff --git a/src/components/CategoryBudgetInputs.tsx b/src/components/CategoryBudgetInputs.tsx index c623d2b..5a0f3ff 100644 --- a/src/components/CategoryBudgetInputs.tsx +++ b/src/components/CategoryBudgetInputs.tsx @@ -1,16 +1,11 @@ import React from 'react'; import { Input } from '@/components/ui/input'; - -interface CategoryBudget { - 식비: number; - 생활비: number; - 교통비: number; -} +import { EXPENSE_CATEGORIES } from '@/constants/categoryIcons'; interface CategoryBudgetInputsProps { - categoryBudgets: CategoryBudget; - handleCategoryInputChange: (value: string, category: keyof CategoryBudget) => void; + categoryBudgets: Record; + handleCategoryInputChange: (value: string, category: string) => void; } const CategoryBudgetInputs: React.FC = ({ @@ -23,7 +18,7 @@ const CategoryBudgetInputs: React.FC = ({ }; // Handle input with comma formatting - const handleInput = (e: React.ChangeEvent, category: keyof CategoryBudget) => { + const handleInput = (e: React.ChangeEvent, category: string) => { // Remove all non-numeric characters before passing to parent handler const numericValue = e.target.value.replace(/[^0-9]/g, ''); handleCategoryInputChange(numericValue, category); @@ -31,32 +26,16 @@ const CategoryBudgetInputs: React.FC = ({ return (
-
- - handleInput(e, '식비')} - className="neuro-pressed max-w-[150px]" - /> -
- -
- - handleInput(e, '생활비')} - className="neuro-pressed max-w-[150px]" - /> -
- -
- - handleInput(e, '교통비')} - className="neuro-pressed max-w-[150px]" - /> -
+ {EXPENSE_CATEGORIES.map(category => ( +
+ + handleInput(e, category)} + className="neuro-pressed max-w-[150px]" + /> +
+ ))}
); }; diff --git a/src/contexts/BudgetContext.tsx b/src/contexts/BudgetContext.tsx index f9acfac..f470183 100644 --- a/src/contexts/BudgetContext.tsx +++ b/src/contexts/BudgetContext.tsx @@ -1,7 +1,7 @@ import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react'; import { Transaction } from '@/components/TransactionCard'; -import { DEFAULT_CATEGORY_BUDGETS, DEFAULT_MONTHLY_BUDGET } from '@/constants/categoryIcons'; +import { DEFAULT_CATEGORY_BUDGETS, DEFAULT_MONTHLY_BUDGET, EXPENSE_CATEGORIES } from '@/constants/categoryIcons'; import { toast } from '@/components/ui/use-toast'; // 예산 데이터 타입 정의 @@ -44,7 +44,7 @@ const BudgetContext = createContext(undefined); export const BudgetProvider: React.FC<{ children: ReactNode }> = ({ children }) => { const [selectedTab, setSelectedTab] = useState("daily"); const [transactions, setTransactions] = useState([]); - const [categoryBudgets, setCategoryBudgets] = useState(DEFAULT_CATEGORY_BUDGETS); + const [categoryBudgets, setCategoryBudgets] = useState>(DEFAULT_CATEGORY_BUDGETS); const [budgetData, setBudgetData] = useState({ daily: { targetAmount: Math.round(DEFAULT_MONTHLY_BUDGET / 30), @@ -195,9 +195,12 @@ export const BudgetProvider: React.FC<{ children: ReactNode }> = ({ children }) // 카테고리별 지출 계산 const getCategorySpending = () => { const expenseTransactions = transactions.filter(t => t.type === 'expense'); - const categorySpending: Record = { ...Object.fromEntries( - Object.keys(categoryBudgets).map(key => [key, 0]) - )}; + const categorySpending: Record = {}; + + // 모든 카테고리에 대해 초기값 0 설정 + EXPENSE_CATEGORIES.forEach(category => { + categorySpending[category] = 0; + }); expenseTransactions.forEach(t => { if (t.category in categorySpending) { @@ -227,11 +230,10 @@ export const BudgetProvider: React.FC<{ children: ReactNode }> = ({ children }) // 월간 총 예산이 변경되면 카테고리별 예산도 비례하여 조정 const ratio = amount / budgetData.monthly.targetAmount; - const updatedCategoryBudgets = {...categoryBudgets}; + const updatedCategoryBudgets: Record = {}; - Object.keys(updatedCategoryBudgets).forEach(category => { - updatedCategoryBudgets[category as keyof typeof categoryBudgets] = - Math.round(categoryBudgets[category as keyof typeof categoryBudgets] * ratio); + Object.keys(categoryBudgets).forEach(category => { + updatedCategoryBudgets[category] = Math.round(categoryBudgets[category] * ratio); }); setCategoryBudgets(updatedCategoryBudgets);