Fix budget update issues
Addresses delayed notifications and data loss after budget updates and page transitions.
This commit is contained in:
@@ -34,6 +34,7 @@ const BudgetInputCard: React.FC<BudgetGoalProps> = ({
|
||||
return numericValue.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||
};
|
||||
|
||||
// 초기값 변경시 입력 필드 값 업데이트
|
||||
useEffect(() => {
|
||||
setBudgetInputs({
|
||||
daily: initialBudgets.daily > 0 ? initialBudgets.daily.toString() : '',
|
||||
@@ -53,9 +54,21 @@ const BudgetInputCard: React.FC<BudgetGoalProps> = ({
|
||||
|
||||
const handleSave = () => {
|
||||
const amount = parseInt(budgetInputs[selectedTab].replace(/,/g, ''), 10) || 0;
|
||||
onSave(selectedTab, amount);
|
||||
// Close the collapsible after saving
|
||||
if (amount <= 0) {
|
||||
return; // 0 이하의 금액은 저장하지 않음
|
||||
}
|
||||
|
||||
// 즉시 입력 필드를 업데이트하여 사용자에게 피드백 제공
|
||||
setBudgetInputs(prev => ({
|
||||
...prev,
|
||||
[selectedTab]: amount.toString()
|
||||
}));
|
||||
|
||||
// 즉시 콜랩시블을 닫아 사용자에게 완료 피드백 제공
|
||||
setIsOpen(false);
|
||||
|
||||
// 예산 저장
|
||||
onSave(selectedTab, amount);
|
||||
};
|
||||
|
||||
// 비어있으면 빈 문자열을, 그렇지 않으면 포맷팅된 문자열을 반환
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
|
||||
import React, { useEffect } from 'react';
|
||||
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<string, number>;
|
||||
@@ -14,6 +15,7 @@ const CategoryBudgetInputs: React.FC<CategoryBudgetInputsProps> = ({
|
||||
handleCategoryInputChange
|
||||
}) => {
|
||||
const isMobile = useIsMobile();
|
||||
const previousBudgetsRef = useRef<Record<string, number>>({});
|
||||
|
||||
// Format number with commas for display
|
||||
const formatWithCommas = (value: number): string => {
|
||||
@@ -26,6 +28,12 @@ const CategoryBudgetInputs: React.FC<CategoryBudgetInputsProps> = ({
|
||||
// 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가 로컬 스토리지에서 다시 로드되도록 이벤트 리스너 설정
|
||||
@@ -44,6 +52,24 @@ const CategoryBudgetInputs: React.FC<CategoryBudgetInputsProps> = ({
|
||||
};
|
||||
}, []);
|
||||
|
||||
// 값이 변경될 때마다 토스트 메시지 표시
|
||||
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 (
|
||||
<div className="space-y-2 w-full">
|
||||
{EXPENSE_CATEGORIES.map(category => (
|
||||
@@ -53,7 +79,7 @@ const CategoryBudgetInputs: React.FC<CategoryBudgetInputsProps> = ({
|
||||
value={formatWithCommas(categoryBudgets[category] || 0)}
|
||||
onChange={(e) => handleInput(e, category)}
|
||||
placeholder="예산 입력"
|
||||
className={`neuro-pressed ${isMobile ? 'w-[150px]' : 'max-w-[150px]'} text-xs`}
|
||||
className={`neuro-pressed transition-colors duration-300 ${isMobile ? 'w-[150px]' : 'max-w-[150px]'} text-xs`}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user