[#34] 회원 / 인증 도메인 재정의 #43

Merged
pricelees merged 73 commits from refactor/#34 into main 2025-09-13 10:13:45 +00:00
5 changed files with 104 additions and 53 deletions
Showing only changes of commit 52230a5ba0 - Show all commits

View File

@ -1,41 +1,27 @@
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; import { Route, BrowserRouter as Router, Routes } from 'react-router-dom';
import AdminRoute from './components/AdminRoute';
import Layout from './components/Layout'; import Layout from './components/Layout';
import HomePage from './pages/HomePage'; import { AuthProvider } from './context/AuthContext';
import LoginPage from './pages/LoginPage';
import SignupPage from './pages/SignupPage';
import ReservationPage from './pages/ReservationPage';
import MyReservationPage from './pages/MyReservationPage';
import AdminLayout from './pages/admin/AdminLayout'; import AdminLayout from './pages/admin/AdminLayout';
import AdminPage from './pages/admin/AdminPage'; import AdminPage from './pages/admin/AdminPage';
import AdminReservationPage from './pages/admin/ReservationPage';
import AdminTimePage from './pages/admin/TimePage';
import AdminThemePage from './pages/admin/ThemePage';
import AdminWaitingPage from './pages/admin/WaitingPage';
import { AuthProvider } from './context/AuthContext';
import AdminRoute from './components/AdminRoute';
import ReservationStep1Page from './pages/v2/ReservationStep1Page';
import ReservationStep2Page from './pages/v2/ReservationStep2Page';
import ReservationSuccessPage from './pages/v2/ReservationSuccessPage';
import MyReservationPageV2 from './pages/v2/MyReservationPageV2';
import ReservationStep1PageV21 from './pages/v2/ReservationStep1PageV21';
import ReservationStep2PageV21 from './pages/v2/ReservationStep2PageV21';
import ReservationSuccessPageV21 from './pages/v2/ReservationSuccessPageV21';
import HomePageV2 from './pages/v2/HomePageV2';
import LoginPageV2 from './pages/v2/LoginPageV2';
import SignupPageV2 from './pages/v2/SignupPageV2';
import ReservationFormPage from './pages/v2/ReservationFormPage';
import AdminThemeEditPage from './pages/admin/AdminThemeEditPage';
import AdminSchedulePage from './pages/admin/AdminSchedulePage'; import AdminSchedulePage from './pages/admin/AdminSchedulePage';
import AdminThemeEditPage from './pages/admin/AdminThemeEditPage';
import AdminThemePage from './pages/admin/AdminThemePage';
import HomePage from '@_pages/HomePage';
import LoginPage from '@_pages/LoginPage';
import MyReservationPage from '@_pages/MyReservationPage';
import ReservationFormPage from '@_pages/ReservationFormPage';
import ReservationStep1Page from '@_pages/ReservationStep1Page';
import ReservationStep2Page from '@_pages/ReservationStep2Page';
import ReservationSuccessPage from '@_pages/ReservationSuccessPage';
import SignupPage from '@_pages/SignupPage';
const AdminRoutes = () => ( const AdminRoutes = () => (
<AdminLayout> <AdminLayout>
<Routes> <Routes>
<Route path="/" element={<AdminPage />} /> <Route path="/" element={<AdminPage />} />
<Route path="/reservation" element={<AdminReservationPage />} />
<Route path="/time" element={<AdminTimePage />} />
<Route path="/theme" element={<AdminThemePage />} /> <Route path="/theme" element={<AdminThemePage />} />
<Route path="/theme/edit/:themeId" element={<AdminThemeEditPage />} /> <Route path="/theme/edit/:themeId" element={<AdminThemeEditPage />} />
<Route path="/waiting" element={<AdminWaitingPage />} />
<Route path="/schedule" element={<AdminSchedulePage />} /> <Route path="/schedule" element={<AdminSchedulePage />} />
</Routes> </Routes>
</AdminLayout> </AdminLayout>
@ -54,28 +40,14 @@ function App() {
<Route path="/*" element={ <Route path="/*" element={
<Layout> <Layout>
<Routes> <Routes>
<Route path="/" element={<HomePage />} /> <Route path="/" element={<HomePage/>} />
<Route path="/login" element={<LoginPage />} /> <Route path="/login" element={<LoginPage />} />
<Route path="/signup" element={<SignupPage />} /> <Route path="/signup" element={<SignupPage />} />
<Route path="/reservation" element={<ReservationPage />} /> <Route path="/reservation" element={<ReservationStep1Page />} />
<Route path="/reservation/form" element={<ReservationFormPage />} />
<Route path="/reservation/payment" element={<ReservationStep2Page />} />
<Route path="/reservation/success" element={<ReservationSuccessPage />} />
<Route path="/my-reservation" element={<MyReservationPage />} /> <Route path="/my-reservation" element={<MyReservationPage />} />
<Route path="/my-reservation/v2" element={<MyReservationPageV2 />} />
{/* V2 Pages */}
<Route path="/v2/home" element={<HomePageV2 />} />
<Route path="/v2/login" element={<LoginPageV2 />} />
<Route path="/v2/signup" element={<SignupPageV2 />} />
{/* V2 Reservation Flow */}
<Route path="/v2/reservation" element={<ReservationStep1Page />} />
<Route path="/v2/reservation/payment" element={<ReservationStep2Page />} />
<Route path="/v2/reservation/success" element={<ReservationSuccessPage />} />
{/* V2.1 Reservation Flow */}
<Route path="/v2-1/reservation" element={<ReservationStep1PageV21 />} />
<Route path="/v2/reservation/form" element={<ReservationFormPage />} />
<Route path="/v2-1/reservation/payment" element={<ReservationStep2PageV21 />} />
<Route path="/v2-1/reservation/success" element={<ReservationSuccessPageV21 />} />
</Routes> </Routes>
</Layout> </Layout>
} /> } />

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { Link, useNavigate } from 'react-router-dom'; import { Link, useNavigate } from 'react-router-dom';
import { useAuth } from '../../context/AuthContext'; import { useAuth } from '@_context/AuthContext';
import '../../css/navbar.css'; import '@_css/navbar.css';
const AdminNavbar: React.FC = () => { const AdminNavbar: React.FC = () => {
const { loggedIn, userName, logout } = useAuth(); const { loggedIn, userName, logout } = useAuth();
@ -21,10 +21,7 @@ const AdminNavbar: React.FC = () => {
<nav className="navbar-container"> <nav className="navbar-container">
<div className="nav-links"> <div className="nav-links">
<Link className="nav-link" to="/admin"></Link> <Link className="nav-link" to="/admin"></Link>
<Link className="nav-link" to="/admin/reservation"></Link>
<Link className="nav-link" to="/admin/waiting"></Link>
<Link className="nav-link" to="/admin/theme"></Link> <Link className="nav-link" to="/admin/theme"></Link>
<Link className="nav-link" to="/admin/time"></Link>
<Link className="nav-link" to="/admin/schedule"></Link> <Link className="nav-link" to="/admin/schedule"></Link>
</div> </div>
<div className="nav-actions"> <div className="nav-actions">

View File

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import '../../css/admin-page.css'; import '@_css/admin-page.css';
const AdminPage: React.FC = () => { const AdminPage: React.FC = () => {
return ( return (

View File

@ -8,7 +8,7 @@ import {
import { Difficulty, type ThemeCreateRequestV2, type ThemeUpdateRequest, type ThemeV2 } from '@_api/theme/themeTypes'; import { Difficulty, type ThemeCreateRequestV2, type ThemeUpdateRequest, type ThemeV2 } from '@_api/theme/themeTypes';
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { useLocation, useNavigate, useParams } from 'react-router-dom'; import { useLocation, useNavigate, useParams } from 'react-router-dom';
import '../../css/admin-theme-edit-page.css'; import '@_css/admin-theme-edit-page.css';
const AdminThemeEditPage: React.FC = () => { const AdminThemeEditPage: React.FC = () => {
const { themeId } = useParams<{ themeId: string }>(); const { themeId } = useParams<{ themeId: string }>();

View File

@ -0,0 +1,82 @@
import React, { useEffect, useState } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
import { fetchAdminThemes } from '@_api/theme/themeAPI';
import type {AdminThemeSummaryRetrieveResponse} from '@_api/theme/themeTypes';
import { isLoginRequiredError } from '@_api/apiClient';
import '@_css/admin-theme-page.css';
const AdminThemePage: React.FC = () => {
const [themes, setThemes] = useState<AdminThemeSummaryRetrieveResponse[]>([]);
const navigate = useNavigate();
const location = useLocation();
const handleError = (err: any) => {
if (isLoginRequiredError(err)) {
alert('로그인이 필요해요.');
navigate('/login', { state: { from: location } });
} else {
const message = err.response?.data?.message || '알 수 없는 오류가 발생했습니다.';
alert(message);
console.error(err);
}
};
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetchAdminThemes();
setThemes(response.themes);
} catch (error) {
handleError(error);
}
};
fetchData();
}, []);
const handleAddClick = () => {
navigate('/admin/theme/edit/new');
};
const handleManageClick = (themeId: string) => {
navigate(`/admin/theme/edit/${themeId}`);
};
return (
<div className="admin-theme-container">
<h2 className="page-title"> </h2>
<div className="section-card">
<div className="table-header">
<button className="btn btn-primary" onClick={handleAddClick}> </button>
</div>
<div className="table-container">
<table>
<thead>
<tr>
<th></th>
<th></th>
<th>1 </th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{themes.map(theme => (
<tr key={theme.id}>
<td>{theme.name}</td>
<td>{theme.difficulty}</td>
<td>{theme.price.toLocaleString()}</td>
<td>{theme.isOpen ? '공개' : '비공개'}</td>
<td>
<button className="btn btn-secondary" onClick={() => handleManageClick(theme.id)}></button>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
);
};
export default AdminThemePage;