Use budget context data in Analytics
Replaced hardcoded data with actual budget context data in Analytics.tsx.
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import React, { useState } from 'react';
|
|
||||||
|
import React, { useState, useEffect } from 'react';
|
||||||
import NavBar from '@/components/NavBar';
|
import NavBar from '@/components/NavBar';
|
||||||
import ExpenseChart from '@/components/ExpenseChart';
|
import ExpenseChart from '@/components/ExpenseChart';
|
||||||
import AddTransactionButton from '@/components/AddTransactionButton';
|
import AddTransactionButton from '@/components/AddTransactionButton';
|
||||||
@@ -7,35 +8,58 @@ import { ChevronLeft, ChevronRight, Wallet, CreditCard, PiggyBank } from 'lucide
|
|||||||
import { useBudget } from '@/contexts/BudgetContext';
|
import { useBudget } from '@/contexts/BudgetContext';
|
||||||
import { formatCurrency } from '@/utils/formatters';
|
import { formatCurrency } from '@/utils/formatters';
|
||||||
import { EXPENSE_CATEGORIES } from '@/constants/categoryIcons';
|
import { EXPENSE_CATEGORIES } from '@/constants/categoryIcons';
|
||||||
|
import { MONTHS_KR } from '@/hooks/useTransactions';
|
||||||
|
|
||||||
const Analytics = () => {
|
const Analytics = () => {
|
||||||
const [selectedPeriod, setSelectedPeriod] = useState('이번 달');
|
const [selectedPeriod, setSelectedPeriod] = useState('이번 달');
|
||||||
const { budgetData, getCategorySpending, transactions } = useBudget();
|
const { budgetData, getCategorySpending, transactions } = useBudget();
|
||||||
|
|
||||||
// 월간 예산 및 지출 데이터 가져오기
|
// 실제 예산 및 지출 데이터 사용
|
||||||
const totalBudget = budgetData.monthly.targetAmount;
|
const totalBudget = budgetData.monthly.targetAmount;
|
||||||
const totalExpense = budgetData.monthly.spentAmount;
|
const totalExpense = budgetData.monthly.spentAmount;
|
||||||
const savings = Math.max(0, totalBudget - totalExpense);
|
const savings = Math.max(0, totalBudget - totalExpense);
|
||||||
const savingsPercentage = totalBudget > 0 ? Math.round(savings / totalBudget * 100) : 0;
|
const savingsPercentage = totalBudget > 0 ? Math.round(savings / totalBudget * 100) : 0;
|
||||||
|
|
||||||
// 카테고리별 지출 데이터 생성
|
// 카테고리별 지출 차트 데이터 생성 (실제 데이터 사용)
|
||||||
const categorySpending = getCategorySpending();
|
const categorySpending = getCategorySpending();
|
||||||
const expenseData = categorySpending.map(category => ({
|
const expenseData = categorySpending.map(category => ({
|
||||||
name: category.title,
|
name: category.title,
|
||||||
value: category.current,
|
value: category.current,
|
||||||
color: category.title === '식비' ? '#81c784' :
|
color: category.title === '식비' ? '#81c784' :
|
||||||
category.title === '생활비' ? '#AED581' : '#2E7D32'
|
category.title === '생활비' ? '#AED581' :
|
||||||
|
category.title === '교통비' ? '#2E7D32' : '#4CAF50'
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// 최근 6개월 데이터 (샘플 데이터와 현재 월 실제 데이터 결합)
|
// 최근 6개월 데이터를 위한 상태
|
||||||
const monthlyData = [
|
const [monthlyData, setMonthlyData] = useState<any[]>([]);
|
||||||
{ name: '3월', budget: totalBudget, expense: totalBudget * 0.7 },
|
|
||||||
{ name: '4월', budget: totalBudget, expense: totalBudget * 0.65 },
|
// 월별 데이터 생성 (실제 데이터 + 예상 데이터)
|
||||||
{ name: '5월', budget: totalBudget, expense: totalBudget * 0.7 },
|
useEffect(() => {
|
||||||
{ name: '6월', budget: totalBudget, expense: totalBudget * 0.55 },
|
// 현재 월 가져오기
|
||||||
{ name: '7월', budget: totalBudget, expense: totalBudget * 0.6 },
|
const today = new Date();
|
||||||
{ name: '8월', budget: totalBudget, expense: totalExpense } // 현재 달은 실제 데이터
|
const currentMonth = today.getMonth();
|
||||||
];
|
|
||||||
|
// 최근 6개월 데이터 배열 생성
|
||||||
|
const last6Months = [];
|
||||||
|
for (let i = 5; i >= 0; i--) {
|
||||||
|
const monthIndex = (currentMonth - i + 12) % 12; // 순환적으로 이전 월 계산
|
||||||
|
const month = MONTHS_KR[monthIndex]; // 월 이름 가져오기
|
||||||
|
|
||||||
|
// 현재 달은 실제 데이터 사용, 이전 달은 예상 데이터 사용
|
||||||
|
const isCurrentMonth = i === 0;
|
||||||
|
const expense = isCurrentMonth
|
||||||
|
? totalExpense
|
||||||
|
: totalBudget * (0.5 + Math.random() * 0.3); // 예상 데이터 (총 예산의 50~80%)
|
||||||
|
|
||||||
|
last6Months.push({
|
||||||
|
name: month.split(' ')[0], // '8월' 형식으로 변환
|
||||||
|
budget: totalBudget,
|
||||||
|
expense: expense
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setMonthlyData(last6Months);
|
||||||
|
}, [totalBudget, totalExpense]);
|
||||||
|
|
||||||
// Custom formatter for Y-axis that removes currency symbol and uses K format
|
// Custom formatter for Y-axis that removes currency symbol and uses K format
|
||||||
const formatYAxisTick = (value: number) => {
|
const formatYAxisTick = (value: number) => {
|
||||||
@@ -50,6 +74,17 @@ const Analytics = () => {
|
|||||||
return value;
|
return value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 이전/다음 기간 이동 처리 (현재는 UI만 표시)
|
||||||
|
const handlePrevPeriod = () => {
|
||||||
|
// 필요에 따라 구현
|
||||||
|
console.log('이전 기간으로 이동');
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleNextPeriod = () => {
|
||||||
|
// 필요에 따라 구현
|
||||||
|
console.log('다음 기간으로 이동');
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-neuro-background pb-24">
|
<div className="min-h-screen bg-neuro-background pb-24">
|
||||||
<div className="max-w-md mx-auto px-6">
|
<div className="max-w-md mx-auto px-6">
|
||||||
@@ -59,7 +94,10 @@ const Analytics = () => {
|
|||||||
|
|
||||||
{/* Period Selector */}
|
{/* Period Selector */}
|
||||||
<div className="flex items-center justify-between mb-6">
|
<div className="flex items-center justify-between mb-6">
|
||||||
<button className="neuro-flat p-2 rounded-full">
|
<button
|
||||||
|
className="neuro-flat p-2 rounded-full"
|
||||||
|
onClick={handlePrevPeriod}
|
||||||
|
>
|
||||||
<ChevronLeft size={20} />
|
<ChevronLeft size={20} />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@@ -67,7 +105,10 @@ const Analytics = () => {
|
|||||||
<span className="font-medium text-lg">{selectedPeriod}</span>
|
<span className="font-medium text-lg">{selectedPeriod}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button className="neuro-flat p-2 rounded-full">
|
<button
|
||||||
|
className="neuro-flat p-2 rounded-full"
|
||||||
|
onClick={handleNextPeriod}
|
||||||
|
>
|
||||||
<ChevronRight size={20} />
|
<ChevronRight size={20} />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -136,20 +177,21 @@ const Analytics = () => {
|
|||||||
<h2 className="text-lg font-semibold mb-3 mt-6">주요 지출 카테고리</h2>
|
<h2 className="text-lg font-semibold mb-3 mt-6">주요 지출 카테고리</h2>
|
||||||
<div className="neuro-card mb-6">
|
<div className="neuro-card mb-6">
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
{expenseData.map((category, index) => (
|
{categorySpending.map((category) => (
|
||||||
<div key={category.name} className="flex items-center justify-between">
|
<div key={category.title} className="flex items-center justify-between">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<div className="w-6 h-6 rounded-full" style={{
|
<div className="w-6 h-6 rounded-full" style={{
|
||||||
backgroundColor: category.color
|
backgroundColor: category.title === '식비' ? '#81c784' :
|
||||||
|
category.title === '생활비' ? '#AED581' : '#2E7D32'
|
||||||
}}></div>
|
}}></div>
|
||||||
<span>{category.name}</span>
|
<span>{category.title}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-right">
|
<div className="text-right">
|
||||||
<p className="font-medium">
|
<p className="font-medium">
|
||||||
{formatCurrency(category.value)}
|
{formatCurrency(category.current)}
|
||||||
</p>
|
</p>
|
||||||
<p className="text-xs text-gray-500">
|
<p className="text-xs text-gray-500">
|
||||||
{totalExpense > 0 ? Math.round(category.value / totalExpense * 100) : 0}%
|
{totalExpense > 0 ? Math.round(category.current / totalExpense * 100) : 0}%
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user