107 lines
3.4 KiB
JavaScript
107 lines
3.4 KiB
JavaScript
// src/app/App.jsx
|
|
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'
|
|
import { AuthProvider, useAuth } from './providers/AuthProvider'
|
|
import AppLayout from '../layouts/AppLayout'
|
|
import AuthLayout from '../layouts/AuthLayout'
|
|
import Placeholder from './Placeholder'
|
|
import Login from '../auth/pages/Login'
|
|
import Home from '../auth/pages/Home'
|
|
import Admin from '../auth/pages/Admin'
|
|
import ProductsPage from '../features/products/ProductsPage'
|
|
import DriverDailyStatPage from '../features/crm/DriverDailyStat/DriverDailyStatPage'
|
|
import CsHomePage from '../features/crm/CsHome/CsHomePage'
|
|
import { RequireAuth, RequireRole } from '../auth/authGuard'
|
|
import { NAV } from '../lib/navConfig'
|
|
|
|
// 실제 구현된 페이지만 여기에 등록. 나머지 메뉴는 자동으로 Placeholder로 채워진다.
|
|
// key는 navConfig item의 `to`(절대경로)와 일치시킨다.
|
|
const REAL_PAGES = {
|
|
'/crm/home': <CsHomePage />,
|
|
'/crm/driver-daily-stat': <DriverDailyStatPage />,
|
|
'/opr/products': <ProductsPage />,
|
|
}
|
|
|
|
// navConfig.NAV 를 펼쳐 라우트를 생성한다.
|
|
// - element: REAL_PAGES에 있으면 실제 페이지, 없으면 Placeholder
|
|
// - 모듈에 role이 있으면 해당 라우트를 <RequireRole>로 감싼다.
|
|
function buildModuleRoutes() {
|
|
return NAV.map((mod) => {
|
|
const seg = mod.base.replace(/^\//, '') // '/hcm' -> 'hcm'
|
|
const first = mod.items[0]
|
|
const firstSeg = first ? first.to.replace(mod.base + '/', '') : '' // '/hcm/employees' -> 'employees'
|
|
|
|
const children = mod.items.map((it) => {
|
|
const childSeg = it.to.replace(mod.base + '/', '') // 모듈 기준 상대경로
|
|
const page = REAL_PAGES[it.to] ?? <Placeholder title={it.label} />
|
|
const element = mod.role
|
|
? <RequireRole role={mod.role}>{page}</RequireRole>
|
|
: page
|
|
return <Route key={it.to} path={childSeg} element={element} />
|
|
})
|
|
|
|
// /hcm 처럼 모듈 base로 오면 첫 서브메뉴로 보낸다.
|
|
// → 경로가 /hcm/* 로 유지되어 사이드바가 뜨고 탑 탭이 활성화된다.
|
|
// (빈 '모듈 홈' 화면을 원하면 아래 index element를 <Placeholder.../>로 바꾸면 됨)
|
|
return (
|
|
<Route key={mod.key} path={seg}>
|
|
{first && <Route index element={<Navigate to={firstSeg} replace />} />}
|
|
{children}
|
|
</Route>
|
|
)
|
|
})
|
|
}
|
|
|
|
function AppRoutes() {
|
|
const { user } = useAuth()
|
|
|
|
return (
|
|
<Routes>
|
|
<Route
|
|
path="/login"
|
|
element={
|
|
user
|
|
? <Navigate to="/" replace />
|
|
: <AuthLayout><Login /></AuthLayout>
|
|
}
|
|
/>
|
|
|
|
<Route
|
|
path="/"
|
|
element={
|
|
<RequireAuth>
|
|
<AppLayout />
|
|
</RequireAuth>
|
|
}
|
|
>
|
|
<Route index element={<Home />} />
|
|
|
|
{/* navConfig 기반 자동 생성 라우트 (HR/ACC/CS/OPR/SYS/CONFIG) */}
|
|
{buildModuleRoutes()}
|
|
|
|
{/* navConfig에 없지만 유지하는 관리자 전용 라우트 */}
|
|
<Route
|
|
path="admin"
|
|
element={
|
|
<RequireRole role="admin">
|
|
<Admin />
|
|
</RequireRole>
|
|
}
|
|
/>
|
|
|
|
{/* 알 수 없는 경로는 홈으로 */}
|
|
<Route path="*" element={<Navigate to="/" replace />} />
|
|
</Route>
|
|
</Routes>
|
|
)
|
|
}
|
|
|
|
export default function App() {
|
|
return (
|
|
<BrowserRouter>
|
|
<AuthProvider>
|
|
<AppRoutes />
|
|
</AuthProvider>
|
|
</BrowserRouter>
|
|
)
|
|
}
|