[어플리케이션 개발] 3. 학원 입지 분석 대시보드 앱 개발 - 아키텍처 및 결과물
아키텍처

앱 구조 (App.js)
HashRouter 기반으로 3개 페이지를 라우팅합니다. / → 스플래시, /home → 홈, /map → 지도 순서로 이동하며, Capacitor의 backButton 이벤트를 감지해 홈/스플래시에서 뒤로 가기 시 앱을 종료합니다.
스플래시 (Splash.js)
앱 진입 시 로고 + 텍스트를 2.5초 동안 페이드인/아웃 애니메이션으로 보여주고 홈으로 이동합니다. 네이티브 앱 빌드 시 Capacitor의 기본 스플래시를 즉시 숨기고 React 애니메이션으로 대체합니다.
지도 (MapPage.js)
Supabase Storage에서 GeoJSON을 fetch해 Deck.gl의 GeoJsonLayer로 행정동 경계를 렌더링합니다. 선택한 컬럼 타입에 따라 색상 로직이 분기됩니다. 클러스터 타입이면 CLUSTER_COLORS 딕셔너리로 고정색을 쓰고, 수치 타입이면 min/max 기준 0~1 비율을 getHeatColorRgb로 파란색→빨간색 히트맵으로 변환합니다.
사이드바는 COLUMN_GROUPS 객체로 7개 카테고리(클러스터, 분석지표, 인구, 학교, 학원 등)를 정의하고, 학원수별·학원경쟁도별처럼 GeoJSON 중첩 객체에서 동적으로 컬럼을 추출하는 카테고리도 별도 처리합니다.
모바일/데스크탑 반응형은 useIsMobile 커스텀 훅으로 분기합니다. 데스크탑은 좌측 사이드바 + 우측 팝업 카드, 모바일은 바텀시트 UI를 사용합니다. 바텀시트는 none / menu / detail 세 가지 모드와 half / full 두 가지 높이를 터치 제스처(onTouchStart / onTouchEnd)로 전환합니다.
동 클릭 시 해당 동의 경계 좌표 평균을 계산해 지도를 자동으로 이동시키고, 상위 20개 랭킹 팝업과 동 이름 검색 기능도 함께 제공합니다.

서비스워커 (index.js / sw.js)
배포 캐시 문제를 방지하기 위해 index.js에서 앱 로드 시 기존 서비스워커를 전부 unregister하고 캐시를 삭제합니다. sw.js는 index.html만 캐싱하는 최소 구성으로 유지합니다.