generated from pricelees/issue-pr-template
refactor: 새로운 API 명세에 맞춘 프론트엔드 코드 수정
This commit is contained in:
parent
24dd2c492f
commit
52230a5ba0
@ -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>
|
||||||
@ -57,25 +43,11 @@ function App() {
|
|||||||
<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>
|
||||||
} />
|
} />
|
||||||
|
|||||||
@ -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">
|
||||||
|
|||||||
@ -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 (
|
||||||
|
|||||||
@ -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 }>();
|
||||||
|
|||||||
82
frontend/src/pages/admin/AdminThemePage.tsx
Normal file
82
frontend/src/pages/admin/AdminThemePage.tsx
Normal 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;
|
||||||
Loading…
x
Reference in New Issue
Block a user