Fix budget input and display

- Fix issue where budget input for transportation and other categories were not saved correctly.
- Fix issue where total budget amount was calculated incorrectly.
- Fix issue where daily and weekly budgets were not displayed correctly.
This commit is contained in:
gpt-engineer-app[bot]
2025-03-22 07:35:55 +00:00
parent 22aae75d13
commit b79c6b2314
6 changed files with 66 additions and 65 deletions

View File

@@ -1,3 +1,4 @@
import React from 'react';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import BudgetTabContent from './BudgetTabContent';

View File

@@ -1,4 +1,3 @@
import React, { useState, useEffect } from 'react';
import { CirclePlus, Save, Check } from 'lucide-react';
import BudgetInputCard from './BudgetInputCard';
@@ -15,6 +14,7 @@ interface BudgetTabContentProps {
calculatePercentage: (spent: number, target: number) => number;
onSaveBudget: (amount: number, categoryBudgets?: Record<string, number>) => void;
}
const BudgetTabContent: React.FC<BudgetTabContentProps> = ({
data,
formatCurrency,
@@ -94,19 +94,25 @@ const BudgetTabContent: React.FC<BudgetTabContentProps> = ({
// 예산 여부에 따른 텍스트 결정
const budgetButtonText = targetAmount > 0 ? "예산 수정하기" : "예산 입력하기";
return <div>
{targetAmount > 0 ? <>
return (
<div>
{targetAmount > 0 ? (
<>
<div className="flex justify-between items-center mb-3">
<div className="text-base font-bold">{formatCurrency(spentAmount)}</div>
<div className="text-sm text-gray-500">/ {formatCurrency(targetAmount)}</div>
</div>
<div className="w-full h-2 neuro-pressed overflow-hidden mb-3">
<div className={`h-full ${progressBarColor} transition-all duration-700 ease-out`} style={{
width: `${Math.min(percentage, 100)}%`
}} />
<div
className={`h-full ${progressBarColor} transition-all duration-700 ease-out`}
style={{
width: `${Math.min(percentage, 100)}%`,
}}
/>
</div>
<div className="flex justify-between items-center">
<div className={`text-sm font-medium ${isOverBudget ? 'text-red-500' : 'text-gray-500'}`}>
{budgetStatusText}{budgetAmount}
@@ -115,34 +121,41 @@ const BudgetTabContent: React.FC<BudgetTabContentProps> = ({
{percentage}%
</div>
</div>
<div className="mt-6">
<button onClick={toggleBudgetInput} className="text-neuro-income hover:underline flex items-center text-base font-semibold group">
<button
onClick={toggleBudgetInput}
className="text-neuro-income hover:underline flex items-center text-base font-semibold group"
>
<CirclePlus size={26} className="mr-2 text-neuro-income transition-transform group-hover:scale-110" />
<span className="text-base font-semibold">{budgetButtonText}</span>
</button>
</div>
</> : <div className="py-4 text-center">
</>
) : (
<div className="py-4 text-center">
<div className="text-gray-400 mb-4"> </div>
<Button onClick={toggleBudgetInput} variant="default" className="bg-neuro-income hover:bg-neuro-income/90 animate-pulse shadow-lg">
<CirclePlus className="mr-2" size={24} />
<span className="animate-pulse">{budgetButtonText}</span>
</Button>
</div>}
{showBudgetInput && <div className="mt-4">
</div>
)}
{showBudgetInput && (
<div className="mt-4">
<div className="neuro-card p-4">
<div>
<h3 className="text-base font-medium mb-3"> </h3>
<p className="text-sm text-gray-500 mb-4"> . , .</p>
<CategoryBudgetInputs categoryBudgets={categoryBudgets} handleCategoryInputChange={handleCategoryInputChange} />
<div className="mt-4 border-t border-gray-300 pt-3">
<div className="flex justify-between items-center mb-4">
<h3 className="font-medium text-sm px-[34px]"> :</h3>
<p className="font-bold text-neuro-income text-base px-[10px]">{formatCurrency(calculateTotalBudget())}</p>
</div>
<div className="flex justify-end">
<Button onClick={handleSaveCategoryBudgets} size="sm" className="bg-neuro-income hover:bg-neuro-income/90 text-white mx-[6px]">
<Check size={18} className="mr-1" />
@@ -152,7 +165,10 @@ const BudgetTabContent: React.FC<BudgetTabContentProps> = ({
</div>
</div>
</div>
</div>}
</div>;
</div>
)}
</div>
);
};
export default BudgetTabContent;

View File

@@ -1,45 +1,31 @@
import React from 'react';
import { Coffee, Home, Car, Package, Banknote } from 'lucide-react';
import { ShoppingBag, Coffee, Bus, Landmark, MoreHorizontal } from 'lucide-react';
// 카테고리와 아이콘 매핑 정의
// 지출 카테고리 정의
export const EXPENSE_CATEGORIES = [
'음식',
'쇼핑',
'교통비',
'교통',
'기타'
];
// 카테고리별 아이콘 매핑
export const categoryIcons: Record<string, React.ReactNode> = {
: <Coffee size={18} />,
: <Home size={18} />,
: <Car size={18} />,
: <Package size={18} />,
: <Banknote size={18} />,
'음식': <Coffee className="h-4 w-4" />,
'쇼핑': <ShoppingBag className="h-4 w-4" />,
'교통비': <Bus className="h-4 w-4" />,
'교통': <Bus className="h-4 w-4" />,
'기타': <MoreHorizontal className="h-4 w-4" />,
'수입': <Landmark className="h-4 w-4" />
};
// 지출 카테고리 목록 - 4개로 확장
export const EXPENSE_CATEGORIES = ['음식', '쇼핑', '교통', '기타'];
// 카테고리 부가 설명 정의
export const CATEGORY_DESCRIPTIONS: Record<string, string> = {
: '(식비, 음료)',
: '',
: '(차량 유지비)',
: '(기타 지출)',
: '(식비, 음료)', // 이전 이름과의 호환성 유지
: '', // 이전 이름과의 호환성 유지
: '(차량 유지비)', // 이전 이름과의 호환성 유지
};
// 기본 카테고리 예산 설정
export const DEFAULT_CATEGORY_BUDGETS = {
음식: 400000,
쇼핑: 600000,
교통: 200000,
기타: 100000
};
// 기본 월간 예산
export const DEFAULT_MONTHLY_BUDGET = 1300000;
// 카테고리별 대표 제목 목록 정의 - 자주 사용하는 순서로 재정렬
export const CATEGORY_TITLE_SUGGESTIONS: Record<string, string[]> = {
: ['점심', '저녁', '간식', '아침', '음료', '외식'],
: ['생활용품', '의류', '화장품', '가전제품', '운동용품'],
: ['택시', '주유', '지하철', '버스', '주차', '교통카드'],
: ['통신비', '구독', '관리비', '의료비', '전기요금', '취미']
// 기본 카테고리 설정 (신규 사용자용)
export const DEFAULT_CATEGORIES = {
'음식': 0,
'쇼핑': 0,
'교통비': 0,
'교통': 0,
'기타': 0
};

View File

@@ -6,7 +6,9 @@ import { EXPENSE_CATEGORIES } from '@/constants/categoryIcons';
export const DEFAULT_CATEGORY_BUDGETS: Record<string, number> = {
음식: 0,
쇼핑: 0,
교통비: 0
교통비: 0,
교통: 0,
기타: 0
};
export const DEFAULT_MONTHLY_BUDGET = 0;

View File

@@ -26,11 +26,7 @@ export const useExtendedBudgetUpdate = (
const totalAmount = Object.values(newCategoryBudgets).reduce((sum, val) => sum + val, 0);
console.log('카테고리 총액:', totalAmount);
// 일/주/월 모든 예산 업데이트를 위해 monthly로 처리
// (monthly 타입은 모든 예산을 계산해 줌)
const updatedBudgetData = calculateUpdatedBudgetData(budgetData, 'monthly', totalAmount);
// 각 기간별 예산 업데이트
// 예산 데이터 업데이트를 위해 월간 금액으로 처리 (type은 'monthly'설정)
handleBudgetGoalUpdate('monthly', totalAmount);
} else {
// 카테고리 예산이 없는 경우, 기존 로직 사용

View File

@@ -14,7 +14,7 @@ export const loadCategoryBudgetsFromStorage = (): Record<string, number> => {
const parsed = JSON.parse(storedCategoryBudgets);
console.log('카테고리 예산 로드 완료:', parsed);
// 4개 카테고리만 유지
// 모든 허용된 카테고리 포함
const filteredBudgets: Record<string, number> = {};
EXPENSE_CATEGORIES.forEach(category => {
// 이전 카테고리명이 있을 경우 새 카테고리명으로 값 이전
@@ -36,7 +36,7 @@ export const loadCategoryBudgetsFromStorage = (): Record<string, number> => {
const parsedBackup = JSON.parse(backupCategoryBudgets);
console.log('백업에서 카테고리 예산 복구:', parsedBackup);
// 4개 카테고리만 유지
// 모든 허용된 카테고리 포함
const filteredBudgets: Record<string, number> = {};
EXPENSE_CATEGORIES.forEach(category => {
// 이전 카테고리명이 있을 경우 새 카테고리명으로 값 이전
@@ -83,7 +83,7 @@ export const saveCategoryBudgetsToStorage = (categoryBudgets: Record<string, num
console.error('이전 카테고리 예산 비교 오류:', e);
}
// 4개 카테고리만 유지하고 나머지는 제거
// 모든 허용된 카테고리 포함하여 유지
const filteredBudgets: Record<string, number> = {};
EXPENSE_CATEGORIES.forEach(category => {
filteredBudgets[category] = categoryBudgets[category] || 0;