Fix budget display and category issues
- Fix budget amount not displaying outside the homepage. - Remove unexpected categories and revert to the original 3 categories.
This commit is contained in:
@@ -6,7 +6,7 @@ import { UseFormReturn } from 'react-hook-form';
|
|||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
import { categoryIcons, EXPENSE_CATEGORIES } from '@/constants/categoryIcons';
|
import { categoryIcons, EXPENSE_CATEGORIES } from '@/constants/categoryIcons';
|
||||||
|
|
||||||
// Form schema for validation - 카테고리를 3개로 축소
|
// Form schema for validation - 카테고리를 3개로 제한
|
||||||
export const transactionFormSchema = z.object({
|
export const transactionFormSchema = z.object({
|
||||||
title: z.string().min(1, '제목을 입력해주세요'),
|
title: z.string().min(1, '제목을 입력해주세요'),
|
||||||
amount: z.string().min(1, '금액을 입력해주세요'),
|
amount: z.string().min(1, '금액을 입력해주세요'),
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export const categoryIcons: Record<string, React.ReactNode> = {
|
|||||||
수입: <Banknote size={18} />,
|
수입: <Banknote size={18} />,
|
||||||
};
|
};
|
||||||
|
|
||||||
// 지출 카테고리 목록 - 다시 3개로 축소
|
// 지출 카테고리 목록 - 3개로 제한
|
||||||
export const EXPENSE_CATEGORIES = ['식비', '생활비', '교통비'];
|
export const EXPENSE_CATEGORIES = ['식비', '생활비', '교통비'];
|
||||||
|
|
||||||
// 기본 카테고리 예산 설정
|
// 기본 카테고리 예산 설정
|
||||||
|
|||||||
@@ -21,7 +21,10 @@ export const calculateCategorySpending = (
|
|||||||
|
|
||||||
// 모든 카테고리에 대해 초기값 0 설정
|
// 모든 카테고리에 대해 초기값 0 설정
|
||||||
Object.keys(categoryBudgets).forEach(category => {
|
Object.keys(categoryBudgets).forEach(category => {
|
||||||
categorySpending[category] = 0;
|
// 3개 카테고리만 유지
|
||||||
|
if (EXPENSE_CATEGORIES.includes(category)) {
|
||||||
|
categorySpending[category] = 0;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
expenseTransactions.forEach(t => {
|
expenseTransactions.forEach(t => {
|
||||||
@@ -30,10 +33,10 @@ export const calculateCategorySpending = (
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return Object.keys(categoryBudgets).map(category => ({
|
return EXPENSE_CATEGORIES.map(category => ({
|
||||||
title: category,
|
title: category,
|
||||||
current: categorySpending[category] || 0,
|
current: categorySpending[category] || 0,
|
||||||
total: categoryBudgets[category]
|
total: categoryBudgets[category] || 0
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
import { DEFAULT_CATEGORY_BUDGETS } from '../budgetUtils';
|
import { DEFAULT_CATEGORY_BUDGETS } from '../budgetUtils';
|
||||||
|
import { EXPENSE_CATEGORIES } from '@/constants/categoryIcons';
|
||||||
import { toast } from '@/components/ui/use-toast';
|
import { toast } from '@/components/ui/use-toast';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -12,7 +12,14 @@ export const loadCategoryBudgetsFromStorage = (): Record<string, number> => {
|
|||||||
if (storedCategoryBudgets) {
|
if (storedCategoryBudgets) {
|
||||||
const parsed = JSON.parse(storedCategoryBudgets);
|
const parsed = JSON.parse(storedCategoryBudgets);
|
||||||
console.log('카테고리 예산 로드 완료:', parsed);
|
console.log('카테고리 예산 로드 완료:', parsed);
|
||||||
return parsed;
|
|
||||||
|
// 3개 카테고리만 유지
|
||||||
|
const filteredBudgets: Record<string, number> = {};
|
||||||
|
EXPENSE_CATEGORIES.forEach(category => {
|
||||||
|
filteredBudgets[category] = parsed[category] || 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
return filteredBudgets;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 백업에서 시도
|
// 백업에서 시도
|
||||||
@@ -20,9 +27,16 @@ export const loadCategoryBudgetsFromStorage = (): Record<string, number> => {
|
|||||||
if (backupCategoryBudgets) {
|
if (backupCategoryBudgets) {
|
||||||
const parsedBackup = JSON.parse(backupCategoryBudgets);
|
const parsedBackup = JSON.parse(backupCategoryBudgets);
|
||||||
console.log('백업에서 카테고리 예산 복구:', parsedBackup);
|
console.log('백업에서 카테고리 예산 복구:', parsedBackup);
|
||||||
|
|
||||||
|
// 3개 카테고리만 유지
|
||||||
|
const filteredBudgets: Record<string, number> = {};
|
||||||
|
EXPENSE_CATEGORIES.forEach(category => {
|
||||||
|
filteredBudgets[category] = parsedBackup[category] || 0;
|
||||||
|
});
|
||||||
|
|
||||||
// 메인 스토리지도 복구
|
// 메인 스토리지도 복구
|
||||||
localStorage.setItem('categoryBudgets', backupCategoryBudgets);
|
localStorage.setItem('categoryBudgets', JSON.stringify(filteredBudgets));
|
||||||
return parsedBackup;
|
return filteredBudgets;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('카테고리 예산 데이터 파싱 오류:', error);
|
console.error('카테고리 예산 데이터 파싱 오류:', error);
|
||||||
@@ -39,15 +53,21 @@ export const loadCategoryBudgetsFromStorage = (): Record<string, number> => {
|
|||||||
*/
|
*/
|
||||||
export const saveCategoryBudgetsToStorage = (categoryBudgets: Record<string, number>): void => {
|
export const saveCategoryBudgetsToStorage = (categoryBudgets: Record<string, number>): void => {
|
||||||
try {
|
try {
|
||||||
|
// 3개 카테고리만 유지하고 나머지는 제거
|
||||||
|
const filteredBudgets: Record<string, number> = {};
|
||||||
|
EXPENSE_CATEGORIES.forEach(category => {
|
||||||
|
filteredBudgets[category] = categoryBudgets[category] || 0;
|
||||||
|
});
|
||||||
|
|
||||||
// 데이터 문자열로 변환
|
// 데이터 문자열로 변환
|
||||||
const dataString = JSON.stringify(categoryBudgets);
|
const dataString = JSON.stringify(filteredBudgets);
|
||||||
|
|
||||||
// 로컬 스토리지에 저장
|
// 로컬 스토리지에 저장
|
||||||
localStorage.setItem('categoryBudgets', dataString);
|
localStorage.setItem('categoryBudgets', dataString);
|
||||||
// 백업 저장
|
// 백업 저장
|
||||||
localStorage.setItem('categoryBudgets_backup', dataString);
|
localStorage.setItem('categoryBudgets_backup', dataString);
|
||||||
|
|
||||||
console.log('카테고리 예산 저장 완료:', categoryBudgets);
|
console.log('카테고리 예산 저장 완료:', filteredBudgets);
|
||||||
|
|
||||||
// 스토리지 이벤트 수동 트리거 (동일 창에서도 감지하기 위함)
|
// 스토리지 이벤트 수동 트리거 (동일 창에서도 감지하기 위함)
|
||||||
try {
|
try {
|
||||||
@@ -64,7 +84,7 @@ export const saveCategoryBudgetsToStorage = (categoryBudgets: Record<string, num
|
|||||||
localStorage.setItem('lastCategoryBudgetSaveTime', new Date().toISOString());
|
localStorage.setItem('lastCategoryBudgetSaveTime', new Date().toISOString());
|
||||||
|
|
||||||
// 토스트 알림
|
// 토스트 알림
|
||||||
const totalBudget = Object.values(categoryBudgets).reduce((sum, val) => sum + val, 0);
|
const totalBudget = Object.values(filteredBudgets).reduce((sum, val) => sum + val, 0);
|
||||||
if (totalBudget > 0) {
|
if (totalBudget > 0) {
|
||||||
toast({
|
toast({
|
||||||
title: "카테고리 예산 저장 완료",
|
title: "카테고리 예산 저장 완료",
|
||||||
@@ -91,7 +111,7 @@ export const clearAllCategoryBudgets = (): void => {
|
|||||||
localStorage.removeItem('categoryBudgets');
|
localStorage.removeItem('categoryBudgets');
|
||||||
localStorage.removeItem('categoryBudgets_backup');
|
localStorage.removeItem('categoryBudgets_backup');
|
||||||
|
|
||||||
// 기본값으로 재설정
|
// 기본값으로 재설정 (3개 카테고리만)
|
||||||
const dataString = JSON.stringify(DEFAULT_CATEGORY_BUDGETS);
|
const dataString = JSON.stringify(DEFAULT_CATEGORY_BUDGETS);
|
||||||
localStorage.setItem('categoryBudgets', dataString);
|
localStorage.setItem('categoryBudgets', dataString);
|
||||||
localStorage.setItem('categoryBudgets_backup', dataString);
|
localStorage.setItem('categoryBudgets_backup', dataString);
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import {
|
|||||||
updateTransactionInSupabase,
|
updateTransactionInSupabase,
|
||||||
deleteTransactionFromSupabase
|
deleteTransactionFromSupabase
|
||||||
} from '@/utils/supabaseTransactionUtils';
|
} from '@/utils/supabaseTransactionUtils';
|
||||||
|
import { EXPENSE_CATEGORIES } from '@/constants/categoryIcons';
|
||||||
|
|
||||||
// 월 이름 재노출
|
// 월 이름 재노출
|
||||||
export { MONTHS_KR };
|
export { MONTHS_KR };
|
||||||
@@ -52,8 +53,20 @@ export const useTransactions = () => {
|
|||||||
// 로컬 스토리지에서 트랜잭션 데이터 가져오기
|
// 로컬 스토리지에서 트랜잭션 데이터 가져오기
|
||||||
const localData = loadTransactionsFromStorage();
|
const localData = loadTransactionsFromStorage();
|
||||||
|
|
||||||
|
// 지원되는 카테고리로 필터링
|
||||||
|
const filteredData = localData.map(transaction => {
|
||||||
|
// 트랜잭션의 카테고리가 현재 지원되는 카테고리가 아니면 '기타'로 변경
|
||||||
|
if (transaction.type === 'expense' && !EXPENSE_CATEGORIES.includes(transaction.category)) {
|
||||||
|
return {
|
||||||
|
...transaction,
|
||||||
|
category: '생활비' // 기본값으로 '생활비' 사용
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return transaction;
|
||||||
|
});
|
||||||
|
|
||||||
// 로컬 데이터가 있으면 사용
|
// 로컬 데이터가 있으면 사용
|
||||||
setTransactions(localData);
|
setTransactions(filteredData);
|
||||||
|
|
||||||
// 예산 가져오기
|
// 예산 가져오기
|
||||||
const budget = loadBudgetFromStorage();
|
const budget = loadBudgetFromStorage();
|
||||||
|
|||||||
Reference in New Issue
Block a user