Refactor: Review and address code issues
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import BudgetTabContent from './BudgetTabContent';
|
import BudgetTabContent from './BudgetTabContent';
|
||||||
import { BudgetPeriod, BudgetData } from '@/contexts/budget/BudgetContext';
|
import { BudgetPeriod, BudgetData } from '@/contexts/budget/types';
|
||||||
|
|
||||||
interface BudgetProgressCardProps {
|
interface BudgetProgressCardProps {
|
||||||
budgetData: BudgetData;
|
budgetData: BudgetData;
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import BudgetProgressCard from '@/components/BudgetProgressCard';
|
|||||||
import BudgetCategoriesSection from '@/components/BudgetCategoriesSection';
|
import BudgetCategoriesSection from '@/components/BudgetCategoriesSection';
|
||||||
import RecentTransactionsSection from '@/components/RecentTransactionsSection';
|
import RecentTransactionsSection from '@/components/RecentTransactionsSection';
|
||||||
import EmptyState from './EmptyState';
|
import EmptyState from './EmptyState';
|
||||||
import { BudgetPeriod, BudgetData } from '@/contexts/budget/BudgetContext';
|
import { BudgetPeriod } from '@/contexts/budget/BudgetContext';
|
||||||
import { formatCurrency, calculatePercentage } from '@/utils/formatters';
|
import { formatCurrency, calculatePercentage } from '@/utils/formatters';
|
||||||
import { Transaction } from '@/contexts/budget/types';
|
import { Transaction, BudgetData } from '@/contexts/budget/types';
|
||||||
|
|
||||||
interface HomeContentProps {
|
interface HomeContentProps {
|
||||||
transactions: Transaction[];
|
transactions: Transaction[];
|
||||||
|
|||||||
@@ -1,24 +1,154 @@
|
|||||||
|
|
||||||
// 분리된 유틸리티 파일들에서 함수와 상수를 재내보내기
|
import { BudgetData, Transaction } from './types';
|
||||||
export {
|
import { format } from 'date-fns';
|
||||||
DEFAULT_CATEGORY_BUDGETS,
|
|
||||||
DEFAULT_MONTHLY_BUDGET,
|
|
||||||
getInitialBudgetData
|
|
||||||
} from './utils/constants';
|
|
||||||
|
|
||||||
export {
|
// 기본 예산 데이터
|
||||||
calculateCategorySpending
|
export const getInitialBudgetData = (): BudgetData => ({
|
||||||
} from './utils/categoryUtils';
|
daily: {
|
||||||
|
targetAmount: 0,
|
||||||
|
spentAmount: 0,
|
||||||
|
remainingAmount: 0
|
||||||
|
},
|
||||||
|
weekly: {
|
||||||
|
targetAmount: 0,
|
||||||
|
spentAmount: 0,
|
||||||
|
remainingAmount: 0
|
||||||
|
},
|
||||||
|
monthly: {
|
||||||
|
targetAmount: 0,
|
||||||
|
spentAmount: 0,
|
||||||
|
remainingAmount: 0
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
export {
|
// 예산 데이터 스토리지에서 로드
|
||||||
calculateUpdatedBudgetData
|
export const safelyLoadBudgetData = (): BudgetData => {
|
||||||
} from './utils/budgetCalculation';
|
try {
|
||||||
|
const budgetDataStr = localStorage.getItem('budgetData');
|
||||||
|
|
||||||
|
if (budgetDataStr) {
|
||||||
|
const parsedData = JSON.parse(budgetDataStr);
|
||||||
|
|
||||||
|
// 데이터 구조 검증 (필요한 키가 있는지 확인)
|
||||||
|
if (parsedData &&
|
||||||
|
typeof parsedData === 'object' &&
|
||||||
|
'daily' in parsedData &&
|
||||||
|
'weekly' in parsedData &&
|
||||||
|
'monthly' in parsedData) {
|
||||||
|
return parsedData;
|
||||||
|
} else {
|
||||||
|
console.warn('저장된 예산 데이터 구조가 유효하지 않습니다. 기본값을 반환합니다.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('예산 데이터 로드 중 오류:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 오류 발생 또는 유효하지 않은 데이터인 경우 기본값 반환
|
||||||
|
return getInitialBudgetData();
|
||||||
|
};
|
||||||
|
|
||||||
export {
|
// 지출 금액 계산 함수
|
||||||
calculateSpentAmounts
|
export const calculateSpentAmounts = (transactions: Transaction[], budgetData: BudgetData): BudgetData => {
|
||||||
} from './utils/spendingCalculation';
|
// 기존 예산 데이터 복사
|
||||||
|
const newBudgetData = JSON.parse(JSON.stringify(budgetData));
|
||||||
|
|
||||||
|
// 지출 트랜잭션만 필터링
|
||||||
|
const expenseTransactions = transactions.filter(t => t.type === 'expense');
|
||||||
|
|
||||||
|
// 현재 날짜 정보
|
||||||
|
const now = new Date();
|
||||||
|
const currentDay = now.getDate();
|
||||||
|
const currentMonth = now.getMonth();
|
||||||
|
const currentYear = now.getFullYear();
|
||||||
|
const todayStr = format(now, 'yyyy-MM-dd');
|
||||||
|
|
||||||
|
// 월간 지출 합계 (현재 월의 모든 지출)
|
||||||
|
const monthlyExpenses = expenseTransactions.filter(t => {
|
||||||
|
try {
|
||||||
|
const transactionDate = new Date(t.date);
|
||||||
|
return (
|
||||||
|
transactionDate.getMonth() === currentMonth &&
|
||||||
|
transactionDate.getFullYear() === currentYear
|
||||||
|
);
|
||||||
|
} catch (e) {
|
||||||
|
return false; // 날짜 파싱 오류 시 포함하지 않음
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 주간 지출 합계 (최근 7일)
|
||||||
|
const weeklyExpenses = expenseTransactions.filter(t => {
|
||||||
|
try {
|
||||||
|
const transactionDate = new Date(t.date);
|
||||||
|
const diffTime = now.getTime() - transactionDate.getTime();
|
||||||
|
const diffDays = diffTime / (1000 * 3600 * 24);
|
||||||
|
return diffDays <= 7;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 일일 지출 합계 (오늘)
|
||||||
|
const dailyExpenses = expenseTransactions.filter(t => {
|
||||||
|
try {
|
||||||
|
const transactionDateStr = format(new Date(t.date), 'yyyy-MM-dd');
|
||||||
|
return transactionDateStr === todayStr;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 계산된 지출 금액
|
||||||
|
const dailyTotal = dailyExpenses.reduce((sum, t) => sum + t.amount, 0);
|
||||||
|
const weeklyTotal = weeklyExpenses.reduce((sum, t) => sum + t.amount, 0);
|
||||||
|
const monthlyTotal = monthlyExpenses.reduce((sum, t) => sum + t.amount, 0);
|
||||||
|
|
||||||
|
// 예산 데이터에 적용
|
||||||
|
newBudgetData.daily.spentAmount = dailyTotal;
|
||||||
|
newBudgetData.daily.remainingAmount = Math.max(0, newBudgetData.daily.targetAmount - dailyTotal);
|
||||||
|
|
||||||
|
newBudgetData.weekly.spentAmount = weeklyTotal;
|
||||||
|
newBudgetData.weekly.remainingAmount = Math.max(0, newBudgetData.weekly.targetAmount - weeklyTotal);
|
||||||
|
|
||||||
|
newBudgetData.monthly.spentAmount = monthlyTotal;
|
||||||
|
newBudgetData.monthly.remainingAmount = Math.max(0, newBudgetData.monthly.targetAmount - monthlyTotal);
|
||||||
|
|
||||||
|
return newBudgetData;
|
||||||
|
};
|
||||||
|
|
||||||
export {
|
// 예산 목표 업데이트 함수
|
||||||
safelyLoadBudgetData,
|
export const calculateUpdatedBudgetData = (
|
||||||
safeStorage
|
budgetData: BudgetData,
|
||||||
} from './utils/storageUtils';
|
type: 'daily' | 'weekly' | 'monthly',
|
||||||
|
amount: number
|
||||||
|
): BudgetData => {
|
||||||
|
const newBudgetData = JSON.parse(JSON.stringify(budgetData));
|
||||||
|
|
||||||
|
// 새로운 예산 목표 설정 및 남은 금액 계산
|
||||||
|
newBudgetData[type].targetAmount = amount;
|
||||||
|
newBudgetData[type].remainingAmount = Math.max(0, amount - newBudgetData[type].spentAmount);
|
||||||
|
|
||||||
|
// 월간 예산 기준으로 일일/주간 예산 자동 계산 (월간 예산이 설정된 경우만)
|
||||||
|
if (type === 'monthly' && amount > 0) {
|
||||||
|
// 현재 날짜 기준으로 이번 달 남은 일수 계산
|
||||||
|
const today = new Date();
|
||||||
|
const lastDayOfMonth = new Date(today.getFullYear(), today.getMonth() + 1, 0).getDate();
|
||||||
|
const remainingDays = lastDayOfMonth - today.getDate() + 1;
|
||||||
|
|
||||||
|
// 일일 예산 계산 (남은 금액 / 남은 일수)
|
||||||
|
if (newBudgetData.daily.targetAmount === 0) {
|
||||||
|
const dailyBudget = Math.round(amount / lastDayOfMonth);
|
||||||
|
newBudgetData.daily.targetAmount = dailyBudget;
|
||||||
|
newBudgetData.daily.remainingAmount = Math.max(0, dailyBudget - newBudgetData.daily.spentAmount);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 주간 예산 계산 (월간 예산 / 4.3주)
|
||||||
|
if (newBudgetData.weekly.targetAmount === 0) {
|
||||||
|
const weeklyBudget = Math.round(amount / 4.3);
|
||||||
|
newBudgetData.weekly.targetAmount = weeklyBudget;
|
||||||
|
newBudgetData.weekly.remainingAmount = Math.max(0, weeklyBudget - newBudgetData.weekly.spentAmount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return newBudgetData;
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user