import {createBrowserRouter, Navigate} from 'react-router'; import {Loader2} from 'lucide-react'; import {AccountPage} from '@/pages/AccountPage'; import {BuilderPage} from '@/pages/BuilderPage'; import {DevShowcasePage} from '@/pages/DevShowcasePage'; import {LandingPage} from '@/pages/LandingPage'; import {LoginPage} from '@/pages/LoginPage'; import {NotFoundPage} from '@/pages/NotFoundPage'; import {PricingPage} from '@/pages/PricingPage'; import {ShowcasePage} from '@/pages/ShowcasePage'; import {SignupPage} from '@/pages/SignupPage'; import {SitesPage} from '@/pages/SitesPage'; import {RequireAuth} from '@/components/layout/RequireAuth'; import {useAuthStore} from '@/stores/auth'; /** * 첫 화면은 로그인 여부로 갈린다 — 이미 사이트를 가진 사장님의 용건은 "새로 만들기"가 아니라 * "내 것 고치기"다. 비로그인은 **랜딩**을 본다. * * ★ 예전엔 비로그인을 곧장 위저드로 보냈다. 그러면 이 제품이 무엇을 파는 물건인지 말할 자리가 * 한 곳도 없다 — 처음 온 사람이 업종 선택 화면부터 만난다. * ★ 복구가 끝나기 전에 판단하면 새로고침할 때마다 화면이 한 번 번쩍이고 목록으로 튄다. */ function Home() { const isRestoring = useAuthStore((s) => s.isRestoring); const user = useAuthStore((s) => s.user); if (isRestoring) { return (
); } /* * ★ 로그인해도 랜딩을 보여 준다 (2026-09-04, 사장님 지적) * 예전엔 여기서 /sites 로 튕겼다. 그러면 **로그인한 사장님은 랜딩·요금에 갈 길이 없다** — * 로고가 '/' 를 걸고 있어도 눌리는 순간 목록으로 돌아온다. * "로그인 직후엔 내 사이트로" 는 로그인·가입 화면이 직접 보낸다(LoginPage homePath). */ void user; return ; } export const router = createBrowserRouter([ {path: '/login', element: }, // 로그인 화면의 [회원가입] 이 여기로 온다. 이 줄이 없으면 링크는 있고 목적지만 404 다. {path: '/signup', element: }, // 비로그인 = 랜딩, 로그인 = 내 사이트. Home 이 그걸 가른다. {path: '/', element: }, // 로그인 전 화면. ★ 랜딩과 같은 껍데기(MarketingShell)를 쓴다 — 사이드바 없는 문서형이다. {path: '/pricing', element: }, {path: '/showcase', element: }, // 로그인한 사장님의 홈. 만든 사이트를 열고 고치는 자리다. { path: '/sites', element: ( ), }, { path: '/account', element: ( ), }, /** * 빌더는 로그인 화면을 앞에 세우지 않는다 — 위저드를 열자마자 로그인부터 만나면 * 만들어 보기도 전에 막힌다. * * 대신 세션은 조용히 확보한다 — VITE_AUTO_LOGIN_ID·PW 가 주입돼 있으면 useAutoLogin() 이 * 그 계정으로 붙고, 없으면 서버가 필요한 순간(2단계 검색)에만 알린다. * * 에디터(6단계)는 전체 화면이 필요해 AppShell 을 스스로 끄고 켠다 — BuilderPage 참조. */ {path: '/builder', element: }, /** * ★ 내부 운영 화면(/places, /local-content, /seo)은 여기 없다 — 최상단 `admin/` 앱으로 나갔다. * 라우트 가드는 화면을 가리지 **번들은 못 가린다**: 한 앱이면 내부 라우트 이름과 코드가 * 사장님 브라우저에 그대로 내려간다. `UserRole.DEVELOPER` 주석의 * "고객사에 존재를 노출하지 않는다"를 지키려면 번들 자체가 갈라져야 한다. * (ARCHITECTURE.md 4절) */ // 개발 빌드에서만 열리는 컴포넌트 쇼케이스. 운영 번들에서는 라우트 자체가 없다. ...(import.meta.env.DEV ? [{path: '/dev/showcase', element: }] : []), {path: '*', element: }, ]);