Fix data initialization and toast issues
- Ensure toast notifications disappear after data initialization. - Resolve issues with expense items not displaying on the expense page. - Fix graph display issues on the analytics screen. - Prevent login screen from appearing after data initialization.
This commit is contained in:
@@ -31,7 +31,10 @@ const MonthlyComparisonChart: React.FC<MonthlyComparisonChartProps> = ({
|
|||||||
return value;
|
return value;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Empty state component
|
// 데이터 확인 로깅
|
||||||
|
console.log('MonthlyComparisonChart 데이터:', monthlyData);
|
||||||
|
|
||||||
|
// EmptyGraphState 컴포넌트: 데이터가 없을 때 표시
|
||||||
const EmptyGraphState = () => (
|
const EmptyGraphState = () => (
|
||||||
<div className="flex flex-col items-center justify-center h-48 text-gray-400">
|
<div className="flex flex-col items-center justify-center h-48 text-gray-400">
|
||||||
<p>데이터가 없습니다</p>
|
<p>데이터가 없습니다</p>
|
||||||
@@ -39,9 +42,14 @@ const MonthlyComparisonChart: React.FC<MonthlyComparisonChartProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 데이터 여부 확인 로직 개선 - 데이터가 비어있거나 모든 값이 0인 경우도 고려
|
||||||
|
const hasValidData = monthlyData &&
|
||||||
|
monthlyData.length > 0 &&
|
||||||
|
monthlyData.some(item => item.budget > 0 || item.expense > 0);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="neuro-card h-72 w-full">
|
<div className="neuro-card h-72 w-full">
|
||||||
{!isEmpty && monthlyData.length > 0 && monthlyData.some(item => item.budget > 0 || item.expense > 0) ? (
|
{hasValidData ? (
|
||||||
<ResponsiveContainer width="100%" height="100%">
|
<ResponsiveContainer width="100%" height="100%">
|
||||||
<BarChart data={monthlyData} margin={{
|
<BarChart data={monthlyData} margin={{
|
||||||
top: 20,
|
top: 20,
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { Trash2 } from 'lucide-react';
|
import { Trash2 } from 'lucide-react';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
@@ -28,6 +27,9 @@ const DataResetSection = () => {
|
|||||||
// 초기화 실행 전에 사용자 설정 백업
|
// 초기화 실행 전에 사용자 설정 백업
|
||||||
const dontShowWelcomeValue = localStorage.getItem('dontShowWelcome');
|
const dontShowWelcomeValue = localStorage.getItem('dontShowWelcome');
|
||||||
const hasVisitedBefore = localStorage.getItem('hasVisitedBefore');
|
const hasVisitedBefore = localStorage.getItem('hasVisitedBefore');
|
||||||
|
// 로그인 관련 설정도 백업
|
||||||
|
const authSession = localStorage.getItem('authSession');
|
||||||
|
const sb_auth = localStorage.getItem('sb-auth-token');
|
||||||
|
|
||||||
// 데이터 초기화
|
// 데이터 초기화
|
||||||
resetAllStorageData();
|
resetAllStorageData();
|
||||||
@@ -41,6 +43,15 @@ const DataResetSection = () => {
|
|||||||
localStorage.setItem('hasVisitedBefore', hasVisitedBefore);
|
localStorage.setItem('hasVisitedBefore', hasVisitedBefore);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 로그인 관련 설정 복원 (로그인 화면이 나타나지 않도록)
|
||||||
|
if (authSession) {
|
||||||
|
localStorage.setItem('authSession', authSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sb_auth) {
|
||||||
|
localStorage.setItem('sb-auth-token', sb_auth);
|
||||||
|
}
|
||||||
|
|
||||||
// 스토리지 이벤트 트리거하여 다른 컴포넌트에 변경 알림
|
// 스토리지 이벤트 트리거하여 다른 컴포넌트에 변경 알림
|
||||||
window.dispatchEvent(new Event('transactionUpdated'));
|
window.dispatchEvent(new Event('transactionUpdated'));
|
||||||
window.dispatchEvent(new Event('budgetDataUpdated'));
|
window.dispatchEvent(new Event('budgetDataUpdated'));
|
||||||
@@ -94,7 +105,7 @@ const DataResetSection = () => {
|
|||||||
<DialogTitle>정말 모든 데이터를 초기화하시겠습니까?</DialogTitle>
|
<DialogTitle>정말 모든 데이터를 초기화하시겠습니까?</DialogTitle>
|
||||||
<DialogDescription>
|
<DialogDescription>
|
||||||
이 작업은 되돌릴 수 없으며, 모든 예산, 지출 내역, 설정이 영구적으로 삭제됩니다.
|
이 작업은 되돌릴 수 없으며, 모든 예산, 지출 내역, 설정이 영구적으로 삭제됩니다.
|
||||||
단, '환영합니다' 화면 표시 설정은 유지됩니다.
|
단, '환영합니다' 화면 표시 설정과 로그인 상태는 유지됩니다.
|
||||||
</DialogDescription>
|
</DialogDescription>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<DialogFooter className="flex flex-col sm:flex-row gap-2 sm:gap-0">
|
<DialogFooter className="flex flex-col sm:flex-row gap-2 sm:gap-0">
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import type {
|
|||||||
|
|
||||||
// 토스트 알림 표시 제한 및 자동 사라짐 시간(ms) 설정
|
// 토스트 알림 표시 제한 및 자동 사라짐 시간(ms) 설정
|
||||||
const TOAST_LIMIT = 1
|
const TOAST_LIMIT = 1
|
||||||
const TOAST_REMOVE_DELAY = 3000 // 3초 후 자동으로 사라지도록 수정
|
const TOAST_REMOVE_DELAY = 3000 // 3초 후 자동으로 사라지도록 설정
|
||||||
|
|
||||||
type ToasterToast = ToastProps & {
|
type ToasterToast = ToastProps & {
|
||||||
id: string
|
id: string
|
||||||
@@ -163,6 +163,11 @@ function toast({ ...props }: Toast) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// 토스트 생성 후 자동으로 3초 후에 사라지도록 설정
|
||||||
|
setTimeout(() => {
|
||||||
|
dismiss()
|
||||||
|
}, TOAST_REMOVE_DELAY)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: id,
|
id: id,
|
||||||
dismiss,
|
dismiss,
|
||||||
|
|||||||
@@ -1,29 +1,93 @@
|
|||||||
|
|
||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect, useCallback } from 'react';
|
||||||
import { Transaction } from '@/components/TransactionCard';
|
import { Transaction } from '@/components/TransactionCard';
|
||||||
import { useAuth } from '@/contexts/auth/AuthProvider';
|
import { useAuth } from '@/contexts/auth/AuthProvider';
|
||||||
import { toast } from '@/hooks/useToast.wrapper';
|
import { toast } from '@/hooks/useToast.wrapper';
|
||||||
import { isSyncEnabled } from '@/utils/syncUtils';
|
import { isSyncEnabled } from '@/utils/syncUtils';
|
||||||
import { MONTHS_KR, getCurrentMonth, getPrevMonth, getNextMonth } from '@/utils/dateUtils';
|
|
||||||
import {
|
|
||||||
loadTransactionsFromStorage,
|
|
||||||
saveTransactionsToStorage
|
|
||||||
} from '@/utils/storageUtils';
|
|
||||||
import {
|
|
||||||
filterTransactionsByMonth,
|
|
||||||
filterTransactionsByQuery,
|
|
||||||
calculateTotalExpenses
|
|
||||||
} from '@/utils/transactionUtils';
|
|
||||||
import {
|
|
||||||
syncTransactionsWithSupabase,
|
|
||||||
updateTransactionInSupabase,
|
|
||||||
deleteTransactionFromSupabase
|
|
||||||
} from '@/utils/supabaseTransactionUtils';
|
|
||||||
import { EXPENSE_CATEGORIES } from '@/constants/categoryIcons';
|
import { EXPENSE_CATEGORIES } from '@/constants/categoryIcons';
|
||||||
|
|
||||||
// 월 이름 재노출
|
// 월 이름 상수
|
||||||
export { MONTHS_KR };
|
export const MONTHS_KR = ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'];
|
||||||
|
|
||||||
|
// 현재 월 가져오기
|
||||||
|
export const getCurrentMonth = () => {
|
||||||
|
const today = new Date();
|
||||||
|
return MONTHS_KR[today.getMonth()];
|
||||||
|
};
|
||||||
|
|
||||||
|
// 이전 월 가져오기
|
||||||
|
export const getPrevMonth = (currentMonth: string) => {
|
||||||
|
const index = MONTHS_KR.indexOf(currentMonth);
|
||||||
|
return index > 0 ? MONTHS_KR[index - 1] : MONTHS_KR[11];
|
||||||
|
};
|
||||||
|
|
||||||
|
// 다음 월 가져오기
|
||||||
|
export const getNextMonth = (currentMonth: string) => {
|
||||||
|
const index = MONTHS_KR.indexOf(currentMonth);
|
||||||
|
return index < 11 ? MONTHS_KR[index + 1] : MONTHS_KR[0];
|
||||||
|
};
|
||||||
|
|
||||||
|
// 월별 거래 필터링
|
||||||
|
export const filterTransactionsByMonth = (transactions: Transaction[], selectedMonth: string): Transaction[] => {
|
||||||
|
console.log('월별 필터링:', selectedMonth, '트랜잭션 수:', transactions.length);
|
||||||
|
|
||||||
|
// 현재 날짜 정보
|
||||||
|
const now = new Date();
|
||||||
|
const currentYear = now.getFullYear();
|
||||||
|
const currentMonth = now.getMonth() + 1; // JavaScript 월은 0부터 시작
|
||||||
|
|
||||||
|
// 선택된 월의 인덱스 (0-11)
|
||||||
|
const selectedMonthIndex = MONTHS_KR.findIndex(month => month === selectedMonth);
|
||||||
|
|
||||||
|
// 특수 케이스 처리: '이번 달', '오늘', '이번 주' 등
|
||||||
|
if (transactions.some(t => t.date.includes('오늘') || t.date.includes('어제') || t.date.includes('이번주'))) {
|
||||||
|
return transactions;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 실제 필터링
|
||||||
|
return transactions.filter(transaction => {
|
||||||
|
// 날짜 형식이 '2023-05-15' 또는 '2023/05/15' 등의 형식인 경우
|
||||||
|
if (transaction.date.includes('-') || transaction.date.includes('/')) {
|
||||||
|
const parts = transaction.date.split(/[-\/]/);
|
||||||
|
if (parts.length >= 2) {
|
||||||
|
const transactionMonth = parseInt(parts[1]);
|
||||||
|
const monthIndex = transactionMonth - 1; // 0-11 인덱스로 변환
|
||||||
|
return monthIndex === selectedMonthIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 날짜에 월이 포함된 경우 (예: '5월 15일')
|
||||||
|
for (let i = 0; i < MONTHS_KR.length; i++) {
|
||||||
|
if (transaction.date.includes(MONTHS_KR[i])) {
|
||||||
|
return MONTHS_KR[i] === selectedMonth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 기본적으로 모든 트랜잭션 표시 (필터링 실패 시)
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 검색어로 거래 필터링
|
||||||
|
export const filterTransactionsByQuery = (transactions: Transaction[], query: string): Transaction[] => {
|
||||||
|
if (!query.trim()) return transactions;
|
||||||
|
|
||||||
|
const lowercaseQuery = query.toLowerCase();
|
||||||
|
return transactions.filter(transaction =>
|
||||||
|
transaction.title.toLowerCase().includes(lowercaseQuery) ||
|
||||||
|
transaction.category.toLowerCase().includes(lowercaseQuery) ||
|
||||||
|
transaction.amount.toString().includes(lowercaseQuery)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 총 지출 계산
|
||||||
|
export const calculateTotalExpenses = (transactions: Transaction[]): number => {
|
||||||
|
return transactions
|
||||||
|
.filter(t => t.type === 'expense')
|
||||||
|
.reduce((total, transaction) => total + transaction.amount, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// useTransactions 훅
|
||||||
export const useTransactions = () => {
|
export const useTransactions = () => {
|
||||||
const [transactions, setTransactions] = useState<Transaction[]>([]);
|
const [transactions, setTransactions] = useState<Transaction[]>([]);
|
||||||
const [filteredTransactions, setFilteredTransactions] = useState<Transaction[]>([]);
|
const [filteredTransactions, setFilteredTransactions] = useState<Transaction[]>([]);
|
||||||
@@ -45,28 +109,41 @@ export const useTransactions = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// 트랜잭션 로드
|
// 트랜잭션 로드
|
||||||
const loadTransactions = () => {
|
const loadTransactions = useCallback(() => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
setError(null);
|
setError(null);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 로컬 스토리지에서 트랜잭션 데이터 가져오기
|
// 로컬 스토리지에서 트랜잭션 데이터 가져오기
|
||||||
const localData = loadTransactionsFromStorage();
|
const localDataStr = localStorage.getItem('transactions');
|
||||||
|
console.log('로컬 트랜잭션 데이터:', localDataStr);
|
||||||
|
|
||||||
// 지원되는 카테고리로 필터링
|
if (localDataStr) {
|
||||||
const filteredData = localData.map(transaction => {
|
try {
|
||||||
// 트랜잭션의 카테고리가 현재 지원되는 카테고리가 아니면 '기타'로 변경
|
const localData = JSON.parse(localDataStr);
|
||||||
if (transaction.type === 'expense' && !EXPENSE_CATEGORIES.includes(transaction.category)) {
|
|
||||||
return {
|
// 지원되는 카테고리로 필터링
|
||||||
...transaction,
|
const filteredData = localData.map((transaction: Transaction) => {
|
||||||
category: '생활비' // 기본값으로 '생활비' 사용
|
// 트랜잭션의 카테고리가 현재 지원되는 카테고리가 아니면 '생활비'로 변경
|
||||||
};
|
if (transaction.type === 'expense' && !EXPENSE_CATEGORIES.includes(transaction.category)) {
|
||||||
|
return {
|
||||||
|
...transaction,
|
||||||
|
category: '생활비' // 기본값으로 '생활비' 사용
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return transaction;
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('필터링된 트랜잭션:', filteredData.length);
|
||||||
|
setTransactions(filteredData);
|
||||||
|
} catch (parseError) {
|
||||||
|
console.error('트랜잭션 데이터 파싱 오류:', parseError);
|
||||||
|
setTransactions([]);
|
||||||
}
|
}
|
||||||
return transaction;
|
} else {
|
||||||
});
|
console.log('로컬 트랜잭션 데이터 없음');
|
||||||
|
setTransactions([]);
|
||||||
// 로컬 데이터가 있으면 사용
|
}
|
||||||
setTransactions(filteredData);
|
|
||||||
|
|
||||||
// 예산 가져오기
|
// 예산 가져오기
|
||||||
const budgetDataStr = localStorage.getItem('budgetData');
|
const budgetDataStr = localStorage.getItem('budgetData');
|
||||||
@@ -90,7 +167,7 @@ export const useTransactions = () => {
|
|||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
};
|
}, []);
|
||||||
|
|
||||||
// 필터 적용
|
// 필터 적용
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -102,70 +179,58 @@ export const useTransactions = () => {
|
|||||||
filtered = filterTransactionsByQuery(filtered, searchQuery);
|
filtered = filterTransactionsByQuery(filtered, searchQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('필터링 결과:', filtered.length, '트랜잭션');
|
||||||
setFilteredTransactions(filtered);
|
setFilteredTransactions(filtered);
|
||||||
}, [transactions, selectedMonth, searchQuery]);
|
}, [transactions, selectedMonth, searchQuery]);
|
||||||
|
|
||||||
// 초기 데이터 로드
|
// 초기 데이터 로드 및 이벤트 리스너 설정
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
console.log('useTransactions - 초기 데이터 로드');
|
||||||
loadTransactions();
|
loadTransactions();
|
||||||
|
|
||||||
// Supabase 동기화 (로그인 상태인 경우)
|
// 트랜잭션 업데이트 이벤트 리스너
|
||||||
const syncWithSupabase = async () => {
|
const handleTransactionUpdated = () => {
|
||||||
if (user) {
|
console.log('트랜잭션 업데이트 이벤트 감지됨');
|
||||||
const syncedTransactions = await syncTransactionsWithSupabase(user, transactions);
|
|
||||||
if (syncedTransactions !== transactions) {
|
|
||||||
setTransactions(syncedTransactions);
|
|
||||||
saveTransactionsToStorage(syncedTransactions);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
syncWithSupabase();
|
|
||||||
|
|
||||||
// 예산 데이터 변경 이벤트 리스너
|
|
||||||
const handleBudgetUpdate = () => {
|
|
||||||
const budgetDataStr = localStorage.getItem('budgetData');
|
|
||||||
if (budgetDataStr) {
|
|
||||||
try {
|
|
||||||
const budgetData = JSON.parse(budgetDataStr);
|
|
||||||
setTotalBudget(budgetData.monthly.targetAmount);
|
|
||||||
} catch (e) {
|
|
||||||
console.error('예산 데이터 파싱 오류:', e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
window.addEventListener('budgetDataUpdated', handleBudgetUpdate);
|
|
||||||
window.addEventListener('storage', (e) => {
|
|
||||||
if (e.key === 'budgetData') {
|
|
||||||
handleBudgetUpdate();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
window.removeEventListener('budgetDataUpdated', handleBudgetUpdate);
|
|
||||||
window.removeEventListener('storage', () => {});
|
|
||||||
};
|
|
||||||
}, [user, refreshKey]);
|
|
||||||
|
|
||||||
// 정기적으로 데이터 새로고침
|
|
||||||
useEffect(() => {
|
|
||||||
const refreshInterval = setInterval(() => {
|
|
||||||
loadTransactions();
|
loadTransactions();
|
||||||
}, 5000); // 5초마다 데이터 새로고침
|
};
|
||||||
|
|
||||||
// 페이지 포커스 시 새로고침
|
// 스토리지 변경 이벤트 리스너
|
||||||
|
const handleStorageChange = (e: StorageEvent) => {
|
||||||
|
if (e.key === 'transactions' || e.key === null) {
|
||||||
|
console.log('로컬 스토리지 변경 감지됨:', e.key);
|
||||||
|
loadTransactions();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 페이지 포커스/가시성 이벤트 리스너
|
||||||
const handleFocus = () => {
|
const handleFocus = () => {
|
||||||
|
console.log('창 포커스 - 트랜잭션 새로고침');
|
||||||
loadTransactions();
|
loadTransactions();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleVisibilityChange = () => {
|
||||||
|
if (document.visibilityState === 'visible') {
|
||||||
|
console.log('페이지 가시성 변경 - 트랜잭션 새로고침');
|
||||||
|
loadTransactions();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 이벤트 리스너 등록
|
||||||
|
window.addEventListener('transactionUpdated', handleTransactionUpdated);
|
||||||
|
window.addEventListener('storage', handleStorageChange);
|
||||||
window.addEventListener('focus', handleFocus);
|
window.addEventListener('focus', handleFocus);
|
||||||
|
document.addEventListener('visibilitychange', handleVisibilityChange);
|
||||||
|
|
||||||
|
// 컴포넌트 마운트시에만 수동으로 트랜잭션 업데이트 이벤트 발생
|
||||||
|
window.dispatchEvent(new Event('transactionUpdated'));
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
clearInterval(refreshInterval);
|
window.removeEventListener('transactionUpdated', handleTransactionUpdated);
|
||||||
|
window.removeEventListener('storage', handleStorageChange);
|
||||||
window.removeEventListener('focus', handleFocus);
|
window.removeEventListener('focus', handleFocus);
|
||||||
|
document.removeEventListener('visibilitychange', handleVisibilityChange);
|
||||||
};
|
};
|
||||||
}, []);
|
}, [loadTransactions, refreshKey]);
|
||||||
|
|
||||||
// 트랜잭션 업데이트
|
// 트랜잭션 업데이트
|
||||||
const updateTransaction = (updatedTransaction: Transaction) => {
|
const updateTransaction = (updatedTransaction: Transaction) => {
|
||||||
@@ -173,11 +238,17 @@ export const useTransactions = () => {
|
|||||||
transaction.id === updatedTransaction.id ? updatedTransaction : transaction
|
transaction.id === updatedTransaction.id ? updatedTransaction : transaction
|
||||||
);
|
);
|
||||||
|
|
||||||
setTransactions(updatedTransactions);
|
// 로컬 스토리지 업데이트
|
||||||
saveTransactionsToStorage(updatedTransactions);
|
localStorage.setItem('transactions', JSON.stringify(updatedTransactions));
|
||||||
|
|
||||||
// Supabase에도 업데이트
|
// 백업도 업데이트
|
||||||
updateTransactionInSupabase(user, updatedTransaction);
|
localStorage.setItem('transactions_backup', JSON.stringify(updatedTransactions));
|
||||||
|
|
||||||
|
// 상태 업데이트
|
||||||
|
setTransactions(updatedTransactions);
|
||||||
|
|
||||||
|
// 이벤트 발생
|
||||||
|
window.dispatchEvent(new Event('transactionUpdated'));
|
||||||
|
|
||||||
toast({
|
toast({
|
||||||
title: "지출이 수정되었습니다",
|
title: "지출이 수정되었습니다",
|
||||||
@@ -189,11 +260,17 @@ export const useTransactions = () => {
|
|||||||
const deleteTransaction = (id: string) => {
|
const deleteTransaction = (id: string) => {
|
||||||
const updatedTransactions = transactions.filter(transaction => transaction.id !== id);
|
const updatedTransactions = transactions.filter(transaction => transaction.id !== id);
|
||||||
|
|
||||||
setTransactions(updatedTransactions);
|
// 로컬 스토리지 업데이트
|
||||||
saveTransactionsToStorage(updatedTransactions);
|
localStorage.setItem('transactions', JSON.stringify(updatedTransactions));
|
||||||
|
|
||||||
// Supabase에서도 삭제
|
// 백업도 업데이트
|
||||||
deleteTransactionFromSupabase(user, id);
|
localStorage.setItem('transactions_backup', JSON.stringify(updatedTransactions));
|
||||||
|
|
||||||
|
// 상태 업데이트
|
||||||
|
setTransactions(updatedTransactions);
|
||||||
|
|
||||||
|
// 이벤트 발생
|
||||||
|
window.dispatchEvent(new Event('transactionUpdated'));
|
||||||
|
|
||||||
toast({
|
toast({
|
||||||
title: "지출이 삭제되었습니다",
|
title: "지출이 삭제되었습니다",
|
||||||
@@ -209,6 +286,7 @@ export const useTransactions = () => {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
transactions: filteredTransactions,
|
transactions: filteredTransactions,
|
||||||
|
allTransactions: transactions,
|
||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
totalBudget,
|
totalBudget,
|
||||||
|
|||||||
@@ -73,8 +73,12 @@ export const resetAllStorageData = (): void => {
|
|||||||
// 중요: 사용자 설정 값 백업
|
// 중요: 사용자 설정 값 백업
|
||||||
const dontShowWelcomeValue = localStorage.getItem('dontShowWelcome');
|
const dontShowWelcomeValue = localStorage.getItem('dontShowWelcome');
|
||||||
const hasVisitedBefore = localStorage.getItem('hasVisitedBefore');
|
const hasVisitedBefore = localStorage.getItem('hasVisitedBefore');
|
||||||
|
// 로그인 상태 관련 데이터 백업
|
||||||
|
const authSession = localStorage.getItem('authSession');
|
||||||
|
const sbAuth = localStorage.getItem('sb-auth-token');
|
||||||
|
const supabase = localStorage.getItem('supabase.auth.token');
|
||||||
|
|
||||||
// 모든 Storage 키 목록
|
// 모든 Storage 키 목록 (로그인 관련 항목 제외)
|
||||||
const keysToRemove = [
|
const keysToRemove = [
|
||||||
'transactions',
|
'transactions',
|
||||||
'budget',
|
'budget',
|
||||||
@@ -120,12 +124,7 @@ export const resetAllStorageData = (): void => {
|
|||||||
localStorage.setItem('categoryBudgets', JSON.stringify({
|
localStorage.setItem('categoryBudgets', JSON.stringify({
|
||||||
식비: 0,
|
식비: 0,
|
||||||
교통비: 0,
|
교통비: 0,
|
||||||
생활비: 0,
|
생활비: 0
|
||||||
쇼핑: 0,
|
|
||||||
의료: 0,
|
|
||||||
여가: 0,
|
|
||||||
교육: 0,
|
|
||||||
기타: 0
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// 백업 생성
|
// 백업 생성
|
||||||
@@ -142,13 +141,26 @@ export const resetAllStorageData = (): void => {
|
|||||||
localStorage.setItem('hasVisitedBefore', hasVisitedBefore);
|
localStorage.setItem('hasVisitedBefore', hasVisitedBefore);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 로그인 상태 복원
|
||||||
|
if (authSession) {
|
||||||
|
localStorage.setItem('authSession', authSession);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sbAuth) {
|
||||||
|
localStorage.setItem('sb-auth-token', sbAuth);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (supabase) {
|
||||||
|
localStorage.setItem('supabase.auth.token', supabase);
|
||||||
|
}
|
||||||
|
|
||||||
// 이벤트 발생
|
// 이벤트 발생
|
||||||
window.dispatchEvent(new Event('transactionUpdated'));
|
window.dispatchEvent(new Event('transactionUpdated'));
|
||||||
window.dispatchEvent(new Event('budgetDataUpdated'));
|
window.dispatchEvent(new Event('budgetDataUpdated'));
|
||||||
window.dispatchEvent(new Event('categoryBudgetsUpdated'));
|
window.dispatchEvent(new Event('categoryBudgetsUpdated'));
|
||||||
window.dispatchEvent(new StorageEvent('storage'));
|
window.dispatchEvent(new StorageEvent('storage'));
|
||||||
|
|
||||||
console.log('모든 저장소 데이터가 완전히 초기화되었습니다.');
|
console.log('모든 저장소 데이터가 완전히 초기화되었습니다. (로그인 상태는 유지)');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('데이터 초기화 중 오류:', error);
|
console.error('데이터 초기화 중 오류:', error);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user