- Spring Security + JWT 인증 (8시간 토큰) - AdminUser / Recruit 엔터티 추가 - AdminController: 로그인, 대시보드, 뉴스/문의/채용 CRUD - React 어드민 SPA: /admin/* 라우트 (Header/Footer 없음) - 로그인, 대시보드, 뉴스 관리, 문의 관리, 채용공고 관리, 설정 - Jenkinsfile: 서버 환경 맞춤 CI/CD 파이프라인 - .gitignore 추가 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
85 lines
3.4 KiB
JavaScript
85 lines
3.4 KiB
JavaScript
import React, { Suspense, lazy } from 'react';
|
|
import { Routes, Route, Navigate, useLocation } from 'react-router-dom';
|
|
import Header from './components/layout/Header';
|
|
import Footer from './components/layout/Footer';
|
|
|
|
const Home = lazy(() => import('./pages/Home'));
|
|
const GuardiaDetail = lazy(() => import('./pages/GuardiaDetail'));
|
|
const SolutionPage = lazy(() => import('./pages/SolutionPage'));
|
|
const Company = lazy(() => import('./pages/Company'));
|
|
const Business = lazy(() => import('./pages/Business'));
|
|
const Contact = lazy(() => import('./pages/Contact'));
|
|
const Support = lazy(() => import('./pages/Support'));
|
|
const NewsPage = lazy(() => import('./pages/NewsPage'));
|
|
const Recruit = lazy(() => import('./pages/Recruit'));
|
|
const NotFound = lazy(() => import('./pages/NotFound'));
|
|
|
|
// Admin
|
|
const AdminLogin = lazy(() => import('./pages/admin/AdminLogin'));
|
|
const AdminLayout = lazy(() => import('./pages/admin/AdminLayout'));
|
|
const AdminDashboard = lazy(() => import('./pages/admin/AdminDashboard'));
|
|
const AdminNews = lazy(() => import('./pages/admin/AdminNews'));
|
|
const AdminInquiry = lazy(() => import('./pages/admin/AdminInquiry'));
|
|
const AdminRecruit = lazy(() => import('./pages/admin/AdminRecruit'));
|
|
const AdminSettings = lazy(() => import('./pages/admin/AdminSettings'));
|
|
|
|
function Loading() {
|
|
return (
|
|
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center',
|
|
height: '60vh', color: 'var(--gray-400)', fontSize: '14px' }}>
|
|
로딩 중...
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function PublicLayout({ children }) {
|
|
return (
|
|
<>
|
|
<Header />
|
|
<Suspense fallback={<Loading />}>{children}</Suspense>
|
|
<Footer />
|
|
</>
|
|
);
|
|
}
|
|
|
|
export default function App() {
|
|
const location = useLocation();
|
|
const isAdmin = location.pathname.startsWith('/admin');
|
|
|
|
if (isAdmin) {
|
|
return (
|
|
<Suspense fallback={<Loading />}>
|
|
<Routes>
|
|
<Route path="/admin/login" element={<AdminLogin />} />
|
|
<Route path="/admin" element={<AdminLayout />}>
|
|
<Route index element={<Navigate to="/admin/dashboard" replace />} />
|
|
<Route path="dashboard" element={<AdminDashboard />} />
|
|
<Route path="news" element={<AdminNews />} />
|
|
<Route path="inquiries" element={<AdminInquiry />} />
|
|
<Route path="recruit" element={<AdminRecruit />} />
|
|
<Route path="settings" element={<AdminSettings />} />
|
|
</Route>
|
|
<Route path="*" element={<Navigate to="/admin/login" replace />} />
|
|
</Routes>
|
|
</Suspense>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<PublicLayout>
|
|
<Routes>
|
|
<Route path="/" element={<Home />} />
|
|
<Route path="/solution/guardia" element={<GuardiaDetail />} />
|
|
<Route path="/solution/*" element={<SolutionPage />} />
|
|
<Route path="/company/*" element={<Company />} />
|
|
<Route path="/business/*" element={<Business />} />
|
|
<Route path="/support/contact" element={<Contact />} />
|
|
<Route path="/support/*" element={<Support />} />
|
|
<Route path="/recruit/*" element={<Recruit />} />
|
|
<Route path="/news/*" element={<NewsPage />} />
|
|
<Route path="*" element={<NotFound />} />
|
|
</Routes>
|
|
</PublicLayout>
|
|
);
|
|
}
|