diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 62b831d0..55f77c3e 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -20,6 +20,10 @@ 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 AdminThemeEditPage from './pages/admin/AdminThemeEditPage'; const AdminRoutes = () => ( @@ -28,6 +32,7 @@ const AdminRoutes = () => ( } /> } /> } /> + } /> } /> @@ -53,6 +58,11 @@ function App() { } /> } /> + {/* V2 Pages */} + } /> + } /> + } /> + {/* V2 Reservation Flow */} } /> } /> diff --git a/frontend/src/api/apiClient.ts b/frontend/src/api/apiClient.ts index 6e488ac3..f72d764c 100644 --- a/frontend/src/api/apiClient.ts +++ b/frontend/src/api/apiClient.ts @@ -28,16 +28,16 @@ async function request( }, }; - if (isRequiredAuth) { - const accessToken = localStorage.getItem('accessToken'); - if (accessToken) { - if (!config.headers) { - config.headers = {}; - } - config.headers['Authorization'] = `Bearer ${accessToken}`; + + const accessToken = localStorage.getItem('accessToken'); + if (accessToken) { + if (!config.headers) { + config.headers = {}; } + config.headers['Authorization'] = `Bearer ${accessToken}`; } + if (method.toUpperCase() !== 'GET') { config.data = data; } diff --git a/frontend/src/api/theme/themeAPI.ts b/frontend/src/api/theme/themeAPI.ts index 6cbe5c3d..b36ca302 100644 --- a/frontend/src/api/theme/themeAPI.ts +++ b/frontend/src/api/theme/themeAPI.ts @@ -1,5 +1,13 @@ -import apiClient from "@_api/apiClient"; -import type { ThemeCreateRequest, ThemeCreateResponse, ThemeRetrieveListResponse } from "./themeTypes"; +import apiClient from '@_api/apiClient'; +import type { + AdminThemeDetailRetrieveResponse, + AdminThemeSummaryRetrieveListResponse, + ThemeCreateRequest, + ThemeCreateRequestV2, ThemeCreateResponse, + ThemeCreateResponseV2, ThemeRetrieveListResponse, + ThemeUpdateRequest, + UserThemeRetrieveListResponse +} from './themeTypes'; export const createTheme = async (data: ThemeCreateRequest): Promise => { return await apiClient.post('/themes', data, true); @@ -16,3 +24,27 @@ export const mostReservedThemes = async (count: number = 10): Promise => { return await apiClient.del(`/themes/${id}`, true); }; + +export const fetchAdminThemes = async (): Promise => { + return await apiClient.get('/admin/themes'); +}; + +export const fetchAdminThemeDetail = async (id: string): Promise => { + return await apiClient.get(`/admin/themes/${id}`); +}; + +export const createThemeV2 = async (themeData: ThemeCreateRequestV2): Promise => { + return await apiClient.post('/admin/themes', themeData); +}; + +export const updateTheme = async (id: string, themeData: ThemeUpdateRequest): Promise => { + await apiClient.patch(`/admin/themes/${id}`, themeData); +}; + +export const deleteTheme = async (id: string): Promise => { + await apiClient.del(`/admin/themes/${id}`); +}; + +export const fetchUserThemes = async (): Promise => { + return await apiClient.get('/v2/themes'); +}; diff --git a/frontend/src/api/theme/themeTypes.ts b/frontend/src/api/theme/themeTypes.ts index 129f1fc1..dd24ed8e 100644 --- a/frontend/src/api/theme/themeTypes.ts +++ b/frontend/src/api/theme/themeTypes.ts @@ -21,3 +21,113 @@ export interface ThemeRetrieveResponse { export interface ThemeRetrieveListResponse { themes: ThemeRetrieveResponse[]; } + + +export interface ThemeV2 { + id: string; + name: string; + description: string; + thumbnailUrl: string; + difficulty: Difficulty; + price: number; + minParticipants: number; + maxParticipants: number; + availableMinutes: number; + expectedMinutesFrom: number; + expectedMinutesTo: number; + isOpen: boolean; + createDate: string; // Assuming ISO string format + updatedDate: string; // Assuming ISO string format + createdBy: string; + updatedBy: string; +} + +export interface ThemeCreateRequestV2 { + name: string; + description: string; + thumbnailUrl: string; + difficulty: Difficulty; + price: number; + minParticipants: number; + maxParticipants: number; + availableMinutes: number; + expectedMinutesFrom: number; + expectedMinutesTo: number; + isOpen: boolean; +} + +export interface ThemeCreateResponseV2 { + id: string; +} + +export interface ThemeUpdateRequest { + name?: string; + description?: string; + thumbnailUrl?: string; + difficulty?: Difficulty; + price?: number; + minParticipants?: number; + maxParticipants?: number; + availableMinutes?: number; + expectedMinutesFrom?: number; + expectedMinutesTo?: number; + isOpen?: boolean; +} + +export interface AdminThemeSummaryRetrieveResponse { + id: string; + name: string; + difficulty: Difficulty; + price: number; + isOpen: boolean; +} + +export interface AdminThemeSummaryRetrieveListResponse { + themes: AdminThemeSummaryRetrieveResponse[]; +} + +export interface AdminThemeDetailRetrieveResponse { + id: string; + name: string; + description: string; + thumbnailUrl: string; + difficulty: Difficulty; + price: number; + minParticipants: number; + maxParticipants: number; + availableMinutes: number; + expectedMinutesFrom: number; + expectedMinutesTo: number; + isOpen: boolean; + createdAt: string; // LocalDateTime in Kotlin, map to string (ISO format) + createdBy: string; + updatedAt: string; // LocalDateTime in Kotlin, map to string (ISO format) + updatedBy: string; +} + +export interface UserThemeRetrieveResponse { + id: string; + name: string; + thumbnailUrl: string; + description: string; + difficulty: Difficulty; + price: number; + minParticipants: number; + maxParticipants: number; + availableMinutes: number; + expectedMinutesFrom: number; + expectedMinutesTo: number; +} + +export interface UserThemeRetrieveListResponse { + themes: UserThemeRetrieveResponse[]; +} + +// @ts-ignore +export enum Difficulty { + VERY_EASY = 'VERY_EASY', + EASY = 'EASY', + NORMAL = 'NORMAL', + HARD = 'HARD', + VERY_HARD = 'VERY_HARD', +} \ No newline at end of file diff --git a/frontend/src/components/Navbar.tsx b/frontend/src/components/Navbar.tsx index 8644022f..82168dba 100644 --- a/frontend/src/components/Navbar.tsx +++ b/frontend/src/components/Navbar.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { Link, useNavigate } from 'react-router-dom'; import { useAuth } from 'src/context/AuthContext'; +import 'src/css/navbar.css'; const Navbar: React.FC = () => { const { loggedIn, userName, logout } = useAuth(); @@ -14,42 +15,34 @@ const Navbar: React.FC = () => { } catch (error) { console.error('Logout failed:', error); } - } + }; return ( -