Fix budget discrepancies
The budget amounts displayed on the home page were inconsistent with those shown on the transactions and analytics pages. This commit addresses this issue.
This commit is contained in:
@@ -1,45 +1,59 @@
|
||||
|
||||
import React, { useEffect } from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import NavBar from '@/components/NavBar';
|
||||
import TransactionCard from '@/components/TransactionCard';
|
||||
import AddTransactionButton from '@/components/AddTransactionButton';
|
||||
import { Calendar, Search, ChevronLeft, ChevronRight, Loader2 } from 'lucide-react';
|
||||
import { useTransactions } from '@/hooks/useTransactions';
|
||||
import { formatCurrency } from '@/utils/formatters';
|
||||
import { useBudget } from '@/contexts/BudgetContext';
|
||||
import { MONTHS_KR, getCurrentMonth, getPrevMonth, getNextMonth } from '@/utils/dateUtils';
|
||||
|
||||
const Transactions = () => {
|
||||
const {
|
||||
transactions,
|
||||
isLoading,
|
||||
error,
|
||||
totalBudget,
|
||||
selectedMonth,
|
||||
searchQuery,
|
||||
setSearchQuery,
|
||||
handlePrevMonth,
|
||||
handleNextMonth,
|
||||
updateTransaction,
|
||||
totalExpenses,
|
||||
refreshTransactions
|
||||
} = useTransactions();
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const [selectedMonth, setSelectedMonth] = useState(getCurrentMonth());
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [filteredTransactions, setFilteredTransactions] = useState<any[]>([]);
|
||||
|
||||
const {
|
||||
transactions,
|
||||
budgetData,
|
||||
updateTransaction
|
||||
} = useBudget();
|
||||
|
||||
// 페이지 진입/초점 시 새로고침
|
||||
// 월 변경 처리
|
||||
const handlePrevMonth = () => {
|
||||
setSelectedMonth(getPrevMonth(selectedMonth));
|
||||
};
|
||||
|
||||
const handleNextMonth = () => {
|
||||
setSelectedMonth(getNextMonth(selectedMonth));
|
||||
};
|
||||
|
||||
// 트랜잭션 필터링
|
||||
useEffect(() => {
|
||||
const handleFocus = () => {
|
||||
refreshTransactions();
|
||||
};
|
||||
setIsLoading(true);
|
||||
|
||||
window.addEventListener('focus', handleFocus);
|
||||
// 해당 월의 트랜잭션만 필터링
|
||||
let filtered = transactions.filter(t => {
|
||||
return t.date.includes(selectedMonth);
|
||||
});
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('focus', handleFocus);
|
||||
};
|
||||
}, [refreshTransactions]);
|
||||
// 검색어로 필터링
|
||||
if (searchQuery.trim()) {
|
||||
filtered = filtered.filter(t =>
|
||||
t.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
t.category.toLowerCase().includes(searchQuery.toLowerCase())
|
||||
);
|
||||
}
|
||||
|
||||
setFilteredTransactions(filtered);
|
||||
setIsLoading(false);
|
||||
}, [transactions, selectedMonth, searchQuery]);
|
||||
|
||||
// 트랜잭션을 날짜별로 그룹화
|
||||
const groupedTransactions: Record<string, typeof transactions> = {};
|
||||
const groupedTransactions: Record<string, typeof filteredTransactions> = {};
|
||||
|
||||
transactions.forEach(transaction => {
|
||||
filteredTransactions.forEach(transaction => {
|
||||
const datePart = transaction.date.split(',')[0];
|
||||
if (!groupedTransactions[datePart]) {
|
||||
groupedTransactions[datePart] = [];
|
||||
@@ -47,6 +61,11 @@ const Transactions = () => {
|
||||
groupedTransactions[datePart].push(transaction);
|
||||
});
|
||||
|
||||
// 총 지출 계산
|
||||
const totalExpenses = filteredTransactions
|
||||
.filter(t => t.type === 'expense')
|
||||
.reduce((sum, t) => sum + t.amount, 0);
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-neuro-background pb-24">
|
||||
<div className="max-w-md mx-auto px-6">
|
||||
@@ -93,7 +112,7 @@ const Transactions = () => {
|
||||
<div className="neuro-card">
|
||||
<p className="text-sm text-gray-500 mb-1">총 예산</p>
|
||||
<p className="text-lg font-bold text-neuro-income">
|
||||
{formatCurrency(totalBudget)}
|
||||
{formatCurrency(budgetData.monthly.targetAmount)}
|
||||
</p>
|
||||
</div>
|
||||
<div className="neuro-card">
|
||||
@@ -113,21 +132,8 @@ const Transactions = () => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Error State */}
|
||||
{error && (
|
||||
<div className="neuro-card p-4 text-red-500 mb-6">
|
||||
<p>{error}</p>
|
||||
<button
|
||||
className="text-neuro-income mt-2"
|
||||
onClick={refreshTransactions}
|
||||
>
|
||||
다시 시도
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Empty State */}
|
||||
{!isLoading && !error && transactions.length === 0 && (
|
||||
{!isLoading && filteredTransactions.length === 0 && (
|
||||
<div className="text-center py-10">
|
||||
<p className="text-gray-500 mb-3">
|
||||
{searchQuery.trim()
|
||||
@@ -146,7 +152,7 @@ const Transactions = () => {
|
||||
)}
|
||||
|
||||
{/* Transactions By Date */}
|
||||
{!isLoading && !error && (
|
||||
{!isLoading && filteredTransactions.length > 0 && (
|
||||
<div className="space-y-6">
|
||||
{Object.entries(groupedTransactions).map(([date, transactions]) => (
|
||||
<div key={date}>
|
||||
|
||||
Reference in New Issue
Block a user