Reverted to edit edt-df6bf84a-482f-4f45-8871-2125b421fdb0: "Add bottom padding to screen
Adds 100px bottom padding to the screen."
This commit is contained in:
@@ -1,65 +1,174 @@
|
||||
|
||||
import React, { useEffect } from 'react';
|
||||
import NavBar from '../components/NavBar';
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import BudgetTabContent from '@/components/BudgetTabContent';
|
||||
import RecentTransactionsSection from '@/components/RecentTransactionsSection';
|
||||
import NavBar from '@/components/NavBar';
|
||||
import AddTransactionButton from '@/components/AddTransactionButton';
|
||||
import Header from '@/components/Header';
|
||||
import { useBudget } from '@/contexts/budget';
|
||||
import SafeAreaContainer from '@/components/SafeAreaContainer';
|
||||
import { formatCurrency } from '@/utils/formatters';
|
||||
import WelcomeDialog from '@/components/onboarding/WelcomeDialog';
|
||||
import HomeContent from '@/components/home/HomeContent';
|
||||
import { useBudget } from '@/contexts/budget/BudgetContext';
|
||||
import { useAuth } from '@/contexts/auth';
|
||||
import { useWelcomeDialog } from '@/hooks/useWelcomeDialog';
|
||||
import { useDataInitialization } from '@/hooks/useDataInitialization';
|
||||
import { useIsMobile } from '@/hooks/use-mobile';
|
||||
import useNotifications from '@/hooks/useNotifications';
|
||||
|
||||
// 메인 컴포넌트
|
||||
const Index = () => {
|
||||
const { transactions, budgetData, handleBudgetGoalUpdate } = useBudget();
|
||||
|
||||
// 데이터 구조 확인용 로깅
|
||||
const {
|
||||
transactions,
|
||||
budgetData,
|
||||
selectedTab,
|
||||
setSelectedTab,
|
||||
handleBudgetGoalUpdate,
|
||||
updateTransaction,
|
||||
getCategorySpending,
|
||||
resetBudgetData
|
||||
} = useBudget();
|
||||
|
||||
const { user } = useAuth();
|
||||
const { showWelcome, checkWelcomeDialogState, handleCloseWelcome } = useWelcomeDialog();
|
||||
const { isInitialized } = useDataInitialization(resetBudgetData);
|
||||
const isMobile = useIsMobile();
|
||||
const { addNotification } = useNotifications();
|
||||
|
||||
// 초기화 후 환영 메시지 표시 상태 확인
|
||||
useEffect(() => {
|
||||
console.info('Index 페이지 마운트, 현재 데이터 상태:');
|
||||
console.info('트랜잭션 수:', transactions?.length);
|
||||
console.info('예산 데이터:', budgetData);
|
||||
}, [transactions, budgetData]);
|
||||
|
||||
// 예산 퍼센트 계산 함수
|
||||
const calculatePercentage = (spent: number, target: number) => {
|
||||
if (target <= 0) return 0;
|
||||
return Math.min(100, Math.round((spent / target) * 100));
|
||||
};
|
||||
|
||||
if (isInitialized) {
|
||||
const timeoutId = setTimeout(checkWelcomeDialogState, 500);
|
||||
return () => clearTimeout(timeoutId);
|
||||
}
|
||||
}, [isInitialized, checkWelcomeDialogState]);
|
||||
|
||||
// 앱 시작시 예시 알림 추가 (실제 앱에서는 필요한 이벤트에 따라 알림 추가)
|
||||
useEffect(() => {
|
||||
// 환영 메시지가 이미 표시되었는지 확인하는 키
|
||||
const welcomeNotificationSent = sessionStorage.getItem('welcomeNotificationSent');
|
||||
|
||||
if (isInitialized && user && !welcomeNotificationSent) {
|
||||
// 사용자 로그인 시 알림 예시 (한 번만 실행)
|
||||
const timeoutId = setTimeout(() => {
|
||||
addNotification(
|
||||
'환영합니다!',
|
||||
'젤리의 적자탈출에 오신 것을 환영합니다. 예산을 설정하고 지출을 기록해보세요.'
|
||||
);
|
||||
// 세션 스토리지에 환영 메시지 표시 여부 저장
|
||||
sessionStorage.setItem('welcomeNotificationSent', 'true');
|
||||
}, 2000);
|
||||
|
||||
return () => clearTimeout(timeoutId);
|
||||
}
|
||||
}, [isInitialized, user, addNotification]);
|
||||
|
||||
// 페이지가 처음 로드될 때 데이터 로딩 확인
|
||||
useEffect(() => {
|
||||
console.log('Index 페이지 마운트, 현재 데이터 상태:');
|
||||
console.log('트랜잭션:', transactions.length);
|
||||
console.log('예산 데이터:', budgetData);
|
||||
|
||||
// 페이지 마운트 시 데이터 동기화 이벤트 수동 발생
|
||||
try {
|
||||
window.dispatchEvent(new Event('transactionUpdated'));
|
||||
window.dispatchEvent(new Event('budgetDataUpdated'));
|
||||
window.dispatchEvent(new Event('categoryBudgetsUpdated'));
|
||||
} catch (e) {
|
||||
console.error('이벤트 발생 오류:', e);
|
||||
}
|
||||
|
||||
// 백업된 데이터 복구 확인 (메인 데이터가 없는 경우만)
|
||||
try {
|
||||
if (!localStorage.getItem('budgetData')) {
|
||||
const budgetBackup = localStorage.getItem('budgetData_backup');
|
||||
if (budgetBackup) {
|
||||
console.log('예산 데이터 백업에서 복구');
|
||||
localStorage.setItem('budgetData', budgetBackup);
|
||||
window.dispatchEvent(new Event('budgetDataUpdated'));
|
||||
}
|
||||
}
|
||||
|
||||
if (!localStorage.getItem('categoryBudgets')) {
|
||||
const categoryBackup = localStorage.getItem('categoryBudgets_backup');
|
||||
if (categoryBackup) {
|
||||
console.log('카테고리 예산 백업에서 복구');
|
||||
localStorage.setItem('categoryBudgets', categoryBackup);
|
||||
window.dispatchEvent(new Event('categoryBudgetsUpdated'));
|
||||
}
|
||||
}
|
||||
|
||||
if (!localStorage.getItem('transactions')) {
|
||||
const transactionBackup = localStorage.getItem('transactions_backup');
|
||||
if (transactionBackup) {
|
||||
console.log('트랜잭션 백업에서 복구');
|
||||
localStorage.setItem('transactions', transactionBackup);
|
||||
window.dispatchEvent(new Event('transactionUpdated'));
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('백업 복구 시도 중 오류:', error);
|
||||
}
|
||||
}, [transactions.length, budgetData]);
|
||||
|
||||
// 앱이 포커스를 얻었을 때 데이터를 새로고침
|
||||
useEffect(() => {
|
||||
const handleFocus = () => {
|
||||
console.log('창이 포커스를 얻음 - 데이터 새로고침');
|
||||
// 이벤트 발생시켜 데이터 새로고침
|
||||
try {
|
||||
window.dispatchEvent(new Event('storage'));
|
||||
window.dispatchEvent(new Event('transactionUpdated'));
|
||||
window.dispatchEvent(new Event('budgetDataUpdated'));
|
||||
window.dispatchEvent(new Event('categoryBudgetsUpdated'));
|
||||
} catch (e) {
|
||||
console.error('이벤트 발생 오류:', e);
|
||||
}
|
||||
};
|
||||
|
||||
// 포커스 이벤트
|
||||
window.addEventListener('focus', handleFocus);
|
||||
|
||||
// 가시성 변경 이벤트 (백그라운드에서 전경으로 돌아올 때)
|
||||
document.addEventListener('visibilitychange', () => {
|
||||
if (document.visibilityState === 'visible') {
|
||||
console.log('페이지가 다시 보임 - 데이터 새로고침');
|
||||
handleFocus();
|
||||
}
|
||||
});
|
||||
|
||||
// 정기적인 데이터 새로고침 (10초마다)
|
||||
const refreshInterval = setInterval(() => {
|
||||
if (document.visibilityState === 'visible') {
|
||||
console.log('정기 새로고침 - 데이터 업데이트');
|
||||
handleFocus();
|
||||
}
|
||||
}, 10000);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('focus', handleFocus);
|
||||
document.removeEventListener('visibilitychange', () => {});
|
||||
clearInterval(refreshInterval);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<SafeAreaContainer className="min-h-screen bg-neuro-background">
|
||||
<div className="min-h-screen bg-neuro-background pb-24">
|
||||
<div className="max-w-md mx-auto px-6">
|
||||
<Header />
|
||||
|
||||
<Tabs defaultValue="budget" className="w-full mt-4">
|
||||
<TabsList className="grid w-full grid-cols-2 mb-8">
|
||||
<TabsTrigger value="budget">예산</TabsTrigger>
|
||||
<TabsTrigger value="recent">최근 거래</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="budget" className="focus-visible:outline-none">
|
||||
{budgetData && budgetData.monthly && (
|
||||
<BudgetTabContent
|
||||
data={budgetData.monthly}
|
||||
formatCurrency={formatCurrency}
|
||||
calculatePercentage={calculatePercentage}
|
||||
onSaveBudget={(amount, categoryBudgets) =>
|
||||
handleBudgetGoalUpdate('monthly', amount, categoryBudgets)
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="recent" className="focus-visible:outline-none">
|
||||
<RecentTransactionsSection
|
||||
transactions={transactions || []}
|
||||
onUpdateTransaction={transaction => console.log('트랜잭션 업데이트', transaction)}
|
||||
/>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
|
||||
<HomeContent
|
||||
transactions={transactions}
|
||||
budgetData={budgetData}
|
||||
selectedTab={selectedTab}
|
||||
setSelectedTab={setSelectedTab}
|
||||
handleBudgetGoalUpdate={handleBudgetGoalUpdate}
|
||||
updateTransaction={updateTransaction}
|
||||
getCategorySpending={getCategorySpending}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<AddTransactionButton />
|
||||
<NavBar />
|
||||
</SafeAreaContainer>
|
||||
|
||||
{/* 첫 사용자 안내 팝업 */}
|
||||
<WelcomeDialog open={showWelcome} onClose={handleCloseWelcome} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
import React from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import NavBar from '@/components/NavBar';
|
||||
@@ -7,7 +8,6 @@ import { User, CreditCard, Bell, Lock, HelpCircle, LogOut, ChevronRight } from '
|
||||
import { cn } from '@/lib/utils';
|
||||
import { useAuth } from '@/contexts/auth';
|
||||
import { useToast } from '@/hooks/useToast.wrapper';
|
||||
import SafeAreaContainer from '@/components/SafeAreaContainer';
|
||||
|
||||
const SettingsOption = ({
|
||||
icon: Icon,
|
||||
@@ -57,8 +57,7 @@ const Settings = () => {
|
||||
navigate(path);
|
||||
};
|
||||
|
||||
return (
|
||||
<SafeAreaContainer className="min-h-screen bg-neuro-background">
|
||||
return <div className="min-h-screen bg-neuro-background pb-24">
|
||||
<div className="max-w-md mx-auto px-6">
|
||||
{/* Header */}
|
||||
<header className="py-4">
|
||||
@@ -122,8 +121,7 @@ const Settings = () => {
|
||||
</div>
|
||||
|
||||
<NavBar />
|
||||
</SafeAreaContainer>
|
||||
);
|
||||
</div>;
|
||||
};
|
||||
|
||||
export default Settings;
|
||||
|
||||
Reference in New Issue
Block a user