import React, { useState, useEffect, Suspense, lazy } from "react";
import { logger } from "@/utils/logger";
import NavBar from "@/components/NavBar";
import { useBudget } from "@/stores";
import { MONTHS_KR } from "@/hooks/useTransactions";
import { useIsMobile } from "@/hooks/use-mobile";
import { getCategoryColor } from "@/utils/categoryColorUtils";
import { MonthlyData } from "@/types";
// 차트 관련 컴포넌트들을 동적 import로 변경
const ExpenseChart = lazy(() => import("@/components/ExpenseChart"));
const PeriodSelector = lazy(
() => import("@/components/analytics/PeriodSelector")
);
const SummaryCards = lazy(() => import("@/components/analytics/SummaryCards"));
const MonthlyComparisonChart = lazy(
() => import("@/components/analytics/MonthlyComparisonChart")
);
const CategorySpendingList = lazy(
() => import("@/components/analytics/CategorySpendingList")
);
const PaymentMethodChart = lazy(
() => import("@/components/analytics/PaymentMethodChart")
);
const AddTransactionButton = lazy(
() => import("@/components/AddTransactionButton")
);
// 로딩 스피너 컴포넌트
const ChartLoadingSpinner = () => (
);
const Analytics = () => {
const [_selectedPeriod, _setSelectedPeriod] = useState("이번 달");
const {
budgetData,
getCategorySpending,
getPaymentMethodStats,
// 새로 추가된 메서드
transactions: _transactions,
} = useBudget();
const _isMobile = useIsMobile();
const [refreshTrigger, setRefreshTrigger] = useState(0);
const [monthlyData, setMonthlyData] = useState([]);
// 페이지 가시성 변경시 데이터 새로고침
useEffect(() => {
const handleVisibilityChange = () => {
if (document.visibilityState === "visible") {
logger.info("분석 페이지 보임 - 데이터 새로고침");
setRefreshTrigger((prev) => prev + 1);
// 이벤트 발생시켜 데이터 새로고침
try {
window.dispatchEvent(new Event("storage"));
window.dispatchEvent(new Event("transactionUpdated"));
window.dispatchEvent(new Event("budgetDataUpdated"));
window.dispatchEvent(new Event("categoryBudgetsUpdated"));
} catch (e) {
logger.error("이벤트 발생 오류:", e);
}
}
};
const handleFocus = () => {
logger.info("분석 페이지 포커스 - 데이터 새로고침");
setRefreshTrigger((prev) => prev + 1);
// 이벤트 발생시켜 데이터 새로고침
try {
window.dispatchEvent(new Event("storage"));
window.dispatchEvent(new Event("transactionUpdated"));
window.dispatchEvent(new Event("budgetDataUpdated"));
window.dispatchEvent(new Event("categoryBudgetsUpdated"));
} catch (e) {
logger.error("이벤트 발생 오류:", e);
}
};
document.addEventListener("visibilitychange", handleVisibilityChange);
window.addEventListener("focus", handleFocus);
window.addEventListener("transactionUpdated", () =>
setRefreshTrigger((prev) => prev + 1)
);
window.addEventListener("budgetDataUpdated", () =>
setRefreshTrigger((prev) => prev + 1)
);
window.addEventListener("categoryBudgetsUpdated", () =>
setRefreshTrigger((prev) => prev + 1)
);
// 컴포넌트 마운트 시 초기 데이터 로드 이벤트 트리거
handleFocus();
return () => {
document.removeEventListener("visibilitychange", handleVisibilityChange);
window.removeEventListener("focus", handleFocus);
window.removeEventListener("transactionUpdated", () => {});
window.removeEventListener("budgetDataUpdated", () => {});
window.removeEventListener("categoryBudgetsUpdated", () => {});
};
}, []);
// 실제 예산 및 지출 데이터 사용
const totalBudget = budgetData?.monthly?.targetAmount || 0;
const totalExpense = budgetData?.monthly?.spentAmount || 0;
const savings = Math.max(0, totalBudget - totalExpense);
const savingsPercentage =
totalBudget > 0 ? Math.round((savings / totalBudget) * 100) : 0;
// 카테고리별 지출 차트 데이터 생성 - 색상 유틸리티 사용
const categorySpending = getCategorySpending();
const expenseData = categorySpending.map((category) => ({
name: category.title,
value: category.current,
color: getCategoryColor(category.title), // 일관된 색상 적용
}));
// 결제 방법 데이터 가져오기
const paymentMethodData = getPaymentMethodStats();
const hasPaymentData = paymentMethodData.some((method) => method.amount > 0);
// 월별 데이터 생성 - 샘플 데이터 제거하고 현재 달만 실제 데이터 사용
useEffect(() => {
logger.info("Analytics 페이지: 월별 데이터 생성", {
totalBudget,
totalExpense,
});
// 현재 월 가져오기
const today = new Date();
const currentMonth = today.getMonth();
// 현재 달만 실제 데이터 사용하는 배열 생성
const monthlyDataArray = [
{
name: MONTHS_KR[currentMonth].split(" ")[0],
// '8월' 형식으로 변환
budget: totalBudget,
expense: totalExpense,
},
];
setMonthlyData(monthlyDataArray);
logger.info("Analytics 페이지: 월별 데이터 생성 완료", monthlyDataArray);
}, [totalBudget, totalExpense, refreshTrigger]);
// 이전/다음 기간 이동 처리
const handlePrevPeriod = () => {
logger.info("이전 기간으로 이동");
};
const handleNextPeriod = () => {
logger.info("다음 기간으로 이동");
};
return (
{/* Header */}
지출 분석
{/* Period Selector */}
}>
{/* Summary Cards */}
}>
{/* Monthly Comparison Chart */}
월별 그래프
}>
{/* 카테고리 비율과 지출을 하나의 카드로 합침 */}
카테고리 비율
{expenseData.some((item) => item.value > 0) ? (
<>
}>
{/* 원그래프 아래에 카테고리 지출 목록 추가 */}
}>
>
) : (
)}
{/* 결제 방법 차트 추가 */}
결제 방법 비율
}>
{/* 결제 방법 차트 아래 80px 여유 공간 추가 */}
}
>
);
};
export default Analytics;