import React, { useEffect, useRef } from 'react'; import { Input } from '@/components/ui/input'; import { EXPENSE_CATEGORIES } from '@/constants/categoryIcons'; import { useIsMobile } from '@/hooks/use-mobile'; import { toast } from '@/components/ui/use-toast'; interface CategoryBudgetInputsProps { categoryBudgets: Record; handleCategoryInputChange: (value: string, category: string) => void; } const CategoryBudgetInputs: React.FC = ({ categoryBudgets, handleCategoryInputChange }) => { const isMobile = useIsMobile(); const previousBudgetsRef = useRef>({}); // Format number with commas for display const formatWithCommas = (value: number): string => { if (value === 0) return ''; return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); }; // Handle input with comma formatting const handleInput = (e: React.ChangeEvent, category: string) => { // Remove all non-numeric characters before passing to parent handler const numericValue = e.target.value.replace(/[^0-9]/g, ''); handleCategoryInputChange(numericValue, category); // 사용자에게 시각적 피드백 제공 e.target.classList.add('border-green-500'); setTimeout(() => { e.target.classList.remove('border-green-500'); }, 300); }; // 컴포넌트가 마운트될 때 categoryBudgets가 로컬 스토리지에서 다시 로드되도록 이벤트 리스너 설정 useEffect(() => { const handleStorageChange = () => { // 부모 컴포넌트에서 데이터가 업데이트되므로 별도 처리 필요 없음 console.log('카테고리 예산 데이터 변경 감지됨'); }; window.addEventListener('categoryBudgetsUpdated', handleStorageChange); window.addEventListener('storage', handleStorageChange); return () => { window.removeEventListener('categoryBudgetsUpdated', handleStorageChange); window.removeEventListener('storage', handleStorageChange); }; }, []); // 값이 변경될 때마다 토스트 메시지 표시 useEffect(() => { const hasChanges = Object.keys(categoryBudgets).some( category => categoryBudgets[category] !== previousBudgetsRef.current[category] ); const totalBudget = Object.values(categoryBudgets).reduce((sum, val) => sum + val, 0); const previousTotal = Object.values(previousBudgetsRef.current).reduce((sum, val) => sum + val, 0); // 이전 값과 다르고, 총 예산이 있는 경우 토스트 표시 if (hasChanges && totalBudget > 0 && totalBudget !== previousTotal) { // 토스트 메시지는 storage에서 처리 } // 현재 값을 이전 값으로 업데이트 previousBudgetsRef.current = { ...categoryBudgets }; }, [categoryBudgets]); return (
{EXPENSE_CATEGORIES.map(category => (
handleInput(e, category)} placeholder="예산 입력" className={`neuro-pressed transition-colors duration-300 ${isMobile ? 'w-[150px]' : 'max-w-[150px]'} text-xs`} />
))}
); }; export default CategoryBudgetInputs;