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;