diff --git a/src/components/Header.tsx b/src/components/Header.tsx index cc3b9ea..102180c 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -21,7 +21,17 @@ const Header: React.FC = () => { // 플랫폼 감지 useEffect(() => { - setIsIOS(isIOSPlatform()); + const checkPlatform = async () => { + try { + const isiOS = isIOSPlatform(); + console.log('Header: iOS 플랫폼 감지 결과:', isiOS); + setIsIOS(isiOS); + } catch (error) { + console.error('플랫폼 감지 중 오류:', error); + } + }; + + checkPlatform(); }, []); // 이미지 프리로딩 처리 @@ -37,7 +47,8 @@ const Header: React.FC = () => { }; }, []); - const headerClass = isIOS ? 'has-safe-area-top' : 'py-4'; + // iOS 전용 헤더 클래스 - 안전 영역 적용 + const headerClass = isIOS ? 'ios-notch-padding' : 'py-4'; return (
diff --git a/src/components/SafeAreaContainer.tsx b/src/components/SafeAreaContainer.tsx index c7bd905..11628f4 100644 --- a/src/components/SafeAreaContainer.tsx +++ b/src/components/SafeAreaContainer.tsx @@ -25,15 +25,22 @@ const SafeAreaContainer: React.FC = ({ // 마운트 시 플랫폼 확인 useEffect(() => { - setIsIOS(isIOSPlatform()); + const checkPlatform = async () => { + const isiOS = isIOSPlatform(); + console.log('SafeAreaContainer: 플랫폼 확인 - iOS:', isiOS); + setIsIOS(isiOS); + }; + + checkPlatform(); }, []); // 플랫폼에 따른 클래스 결정 - let safeAreaClass = ''; + let safeAreaClass = 'safe-area-container'; if (isIOS) { if (!bottomOnly) safeAreaClass += ' has-safe-area-top'; // iOS 상단 안전 영역 if (!topOnly) safeAreaClass += ' has-safe-area-bottom'; // iOS 하단 안전 영역 + safeAreaClass += ' ios-safe-area'; // iOS 전용 클래스 추가 } else { if (!bottomOnly) safeAreaClass += ' pt-4'; // 안드로이드 상단 여백 if (!topOnly) safeAreaClass += ' pb-4'; // 안드로이드 하단 여백 @@ -42,6 +49,30 @@ const SafeAreaContainer: React.FC = ({ // 추가 하단 여백 적용 const extraBottomClass = extraBottomPadding ? 'pb-[80px]' : ''; + // 디버그용 로그 추가 + useEffect(() => { + if (isIOS) { + console.log('SafeAreaContainer: iOS 안전 영역 적용됨', { + topOnly, + bottomOnly, + extraBottomPadding + }); + + // 안전 영역 값 확인 (CSS 변수) + try { + const computedStyle = getComputedStyle(document.documentElement); + console.log('Safe area 변수 값:', { + top: computedStyle.getPropertyValue('--safe-area-top'), + bottom: computedStyle.getPropertyValue('--safe-area-bottom'), + left: computedStyle.getPropertyValue('--safe-area-left'), + right: computedStyle.getPropertyValue('--safe-area-right') + }); + } catch (error) { + console.error('CSS 변수 확인 중 오류:', error); + } + } + }, [isIOS, topOnly, bottomOnly]); + return (
{children} diff --git a/src/index.css b/src/index.css index 26eb83c..cd9d8c3 100644 --- a/src/index.css +++ b/src/index.css @@ -52,11 +52,11 @@ --sidebar-ring: 217.2 91.2% 59.8%; - /* Safe area 값 */ - --safe-area-top: env(safe-area-inset-top, 0px); - --safe-area-bottom: env(safe-area-inset-bottom, 0px); - --safe-area-left: env(safe-area-inset-left, 0px); - --safe-area-right: env(safe-area-inset-right, 0px); + /* Safe area 값 - !important 추가하여 우선 적용 */ + --safe-area-top: env(safe-area-inset-top, 0px) !important; + --safe-area-bottom: env(safe-area-inset-bottom, 0px) !important; + --safe-area-left: env(safe-area-inset-left, 0px) !important; + --safe-area-right: env(safe-area-inset-right, 0px) !important; } .dark { @@ -150,17 +150,29 @@ @apply neuro-pressed px-4 py-3 w-full focus:outline-none focus:ring-2 focus:ring-neuro-accent/30; } - /* 안전 영역 관련 클래스 */ + /* 안전 영역 관련 클래스 - 강화된 버전 */ + .safe-area-container { + width: 100%; + position: relative; + box-sizing: border-box; + } + + .ios-safe-area { + /* iOS 전용 안전 영역 처리 */ + position: relative; + box-sizing: border-box; + } + .has-safe-area-top { - padding-top: max(1rem, var(--safe-area-top)); + padding-top: max(1rem, var(--safe-area-top)) !important; } .has-safe-area-bottom { - padding-bottom: max(1rem, var(--safe-area-bottom)); + padding-bottom: max(1rem, var(--safe-area-bottom)) !important; } .ios-header { - padding-top: max(1rem, var(--safe-area-top)); + padding-top: max(1rem, var(--safe-area-top)) !important; } /* 모바일 화면에서의 추가 스타일 */ @@ -186,6 +198,11 @@ .SheetContent { @apply rounded-xl overflow-hidden; } + + /* iOS 고유 노치/다이나믹 아일랜드 영역 고려한 추가 스타일 */ + .ios-safe-area-screen { + padding: var(--safe-area-top) var(--safe-area-right) var(--safe-area-bottom) var(--safe-area-left) !important; + } } /* 데스크탑 화면에서의 추가 스타일 */ @@ -260,11 +277,21 @@ /* iOS 전용 스타일 */ @supports (-webkit-touch-callout: none) { .ios-safe-area-top { - padding-top: var(--safe-area-top); + padding-top: var(--safe-area-top) !important; } .ios-safe-area-bottom { - padding-bottom: var(--safe-area-bottom); + padding-bottom: var(--safe-area-bottom) !important; + } + + /* iOS에서 노치/다이나믹 아일랜드 영역 처리를 위한 추가 클래스 */ + .ios-notch-padding { + padding-top: max(1.5rem, var(--safe-area-top)) !important; + } + + /* iOS에서 하단 홈 인디케이터 영역을 위한 추가 클래스 */ + .ios-bottom-padding { + padding-bottom: max(1.5rem, var(--safe-area-bottom)) !important; } } diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index 30acee6..ee879cb 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -12,6 +12,26 @@ import { useDataInitialization } from '@/hooks/useDataInitialization'; import { useIsMobile } from '@/hooks/use-mobile'; import useNotifications from '@/hooks/useNotifications'; import SafeAreaContainer from '@/components/SafeAreaContainer'; +import { BudgetData } from '@/contexts/budget/types'; + +// 기본 예산 데이터 (빈 객체 대신 사용할 더미 데이터) +const defaultBudgetData: BudgetData = { + daily: { + targetAmount: 0, + spentAmount: 0, + remainingAmount: 0 + }, + weekly: { + targetAmount: 0, + spentAmount: 0, + remainingAmount: 0 + }, + monthly: { + targetAmount: 0, + spentAmount: 0, + remainingAmount: 0 + } +}; // 메인 컴포넌트 const Index = () => { @@ -69,7 +89,7 @@ const Index = () => { try { console.log('Index 페이지 마운트, 현재 데이터 상태:'); console.log('트랜잭션:', transactions?.length || 0); - console.log('예산 데이터:', budgetData); + console.log('예산 데이터:', budgetData || defaultBudgetData); // 페이지 첫 마운트 시에만 실행되는 로직으로 수정 const isFirstMount = sessionStorage.getItem('initialDataLoaded') !== 'true'; @@ -194,7 +214,7 @@ const Index = () => {