Files
zellyy-finance/src/components/BudgetProgressCard.tsx
hansoo 4d9effce41 fix: ESLint 오류 수정 - 사용하지 않는 변수들에 underscore prefix 추가
- AddTransactionButton.tsx: useEffect import 제거
- BudgetProgressCard.tsx: localBudgetData를 _localBudgetData로 변경
- Header.tsx: isMobile을 _isMobile로 변경
- RecentTransactionsSection.tsx: isDeleting을 _isDeleting로 변경
- TransactionCard.tsx: cn import 제거
- ExpenseForm.tsx: useState import 제거
- cacheStrategies.ts: QueryClient, Transaction import 제거
- Analytics.tsx: Separator import 제거, 미사용 변수들에 underscore prefix 추가
- Index.tsx: useMemo import 제거
- Login.tsx: setLoginError를 _setLoginError로 변경
- Register.tsx: useEffect dependency 수정 및 useCallback 추가
- Settings.tsx: toast, handleClick에 underscore prefix 추가
- authStore.ts: setError, setAppwriteInitialized에 underscore prefix 추가
- budgetStore.ts: ranges를 _ranges로 변경
- BudgetProgressCard.test.tsx: waitFor import 제거

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-12 20:49:36 +09:00

112 lines
3.5 KiB
TypeScript

import React, { useEffect, useState, memo, useMemo, useCallback } from "react";
import { logger } from "@/utils/logger";
import BudgetTabContent from "./BudgetTabContent";
import { BudgetPeriod, BudgetData } from "@/contexts/budget/types";
interface BudgetProgressCardProps {
budgetData: BudgetData;
selectedTab: string;
setSelectedTab: (value: string) => void;
formatCurrency: (amount: number) => string;
calculatePercentage: (spent: number, target: number) => number;
onSaveBudget: (
type: BudgetPeriod,
amount: number,
newCategoryBudgets?: Record<string, number>
) => void;
}
const BudgetProgressCard: React.FC<BudgetProgressCardProps> = memo(
({
budgetData,
selectedTab,
setSelectedTab,
formatCurrency,
calculatePercentage,
onSaveBudget,
}) => {
// 데이터 상태 추적 (불일치 감지를 위한 로컬 상태)
const [_localBudgetData, setLocalBudgetData] = useState(budgetData);
// 월간 예산 설정 여부 메모이제이션
const isMonthlyBudgetSet = useMemo(() => {
return budgetData.monthly.targetAmount > 0;
}, [budgetData.monthly.targetAmount]);
// 탭 설정 콜백 메모이제이션
const handleTabSetting = useCallback(() => {
if (!selectedTab || selectedTab !== "monthly") {
logger.info("초기 탭 설정: monthly");
setSelectedTab("monthly");
}
}, [selectedTab, setSelectedTab]);
// 예산 저장 콜백 메모이제이션
const handleSaveBudget = useCallback(
(amount: number, categoryBudgets?: Record<string, number>) => {
onSaveBudget("monthly", amount, categoryBudgets);
},
[onSaveBudget]
);
// budgetDataUpdated 이벤트 핸들러 메모이제이션
const handleBudgetDataUpdated = useCallback(() => {
logger.info("BudgetProgressCard: 예산 데이터 업데이트 이벤트 감지");
}, []);
// 컴포넌트 마운트 및 budgetData 변경 시 업데이트
useEffect(() => {
logger.info(
"BudgetProgressCard 데이터 업데이트 - 예산 데이터:",
budgetData
);
logger.info("월간 예산:", budgetData.monthly.targetAmount);
setLocalBudgetData(budgetData);
// 지연 작업으로 이벤트 발생 (컴포넌트 마운트 후 데이터 갱신)
const timeoutId = setTimeout(() => {
window.dispatchEvent(new Event("budgetDataUpdated"));
}, 300);
return () => clearTimeout(timeoutId);
}, [budgetData]);
// 초기 탭 설정을 위한 효과
useEffect(() => {
handleTabSetting();
}, [handleTabSetting]);
// budgetDataUpdated 이벤트 감지
useEffect(() => {
window.addEventListener("budgetDataUpdated", handleBudgetDataUpdated);
return () =>
window.removeEventListener(
"budgetDataUpdated",
handleBudgetDataUpdated
);
}, [handleBudgetDataUpdated]);
logger.info(`BudgetProgressCard 상태: 월=${isMonthlyBudgetSet}`);
return (
<div
data-testid="budget-progress-card"
className="neuro-card mb-6 overflow-hidden w-full"
>
<div className="text-sm text-gray-600 mb-2 px-3 pt-3"> / </div>
<BudgetTabContent
data={budgetData.monthly}
formatCurrency={formatCurrency}
calculatePercentage={calculatePercentage}
onSaveBudget={handleSaveBudget}
/>
</div>
);
}
);
BudgetProgressCard.displayName = "BudgetProgressCard";
export default BudgetProgressCard;