diff --git a/src/apis/activities.ts b/src/apis/activities.ts index 27657a81..5833125c 100644 --- a/src/apis/activities.ts +++ b/src/apis/activities.ts @@ -46,6 +46,11 @@ const Activities = { params: { size: DEFAULT_PAGE_SIZE }, }), + /** + * 체험 등록 + * @param value + * @returns + */ create: (value: ActivityCreateBody) => instance.post(ACTIVITIES_API, value), createReservation: (activityId: number, value: ReservationCreateBody) => diff --git a/src/components/createPage/CreatePageContent/index.tsx b/src/components/createPage/CreatePageContent/index.tsx index 74e1789f..ca1ace90 100644 --- a/src/components/createPage/CreatePageContent/index.tsx +++ b/src/components/createPage/CreatePageContent/index.tsx @@ -1,30 +1,13 @@ -import { useRouter } from 'next/router'; - -import { GAME_T0_CATEGORY } from '@/constants'; -import { formatLinkToGame, isValidGameName, redirectToPage } from '@/utils'; +import { CreatePageContentProps } from '@/pages/[game]/create'; import PostForm from '@/components/createPage/PostForm'; import Banner from '@/components/layout/Banner'; -import { Category, GameNameEN, LinkName } from '@/types'; - -const CreatePageContent = () => { - const router = useRouter(); - const { game } = router.query; - - const isValid = isValidGameName(game as string); - - if (!isValid) { - redirectToPage('/landing'); - return null; - } - - const gameName = formatLinkToGame(game as LinkName) as GameNameEN; - +const CreatePageContent = ({ gameName, category }: CreatePageContentProps) => { return ( <> - + ); }; diff --git a/src/components/createPage/PostForm/index.tsx b/src/components/createPage/PostForm/index.tsx index 515919c0..a41c5b7b 100644 --- a/src/components/createPage/PostForm/index.tsx +++ b/src/components/createPage/PostForm/index.tsx @@ -1,10 +1,12 @@ import { useEffect, useState } from 'react'; import { zodResolver } from '@hookform/resolvers/zod'; +import { useMutation } from '@tanstack/react-query'; import classNames from 'classnames/bind'; import { useDaumPostcodePopup } from 'react-daum-postcode'; import { FormProvider, useForm } from 'react-hook-form'; +import Activities from '@/apis/activities'; import { ADDRESS_CUSTOM_THEME, ADDRESS_POPUP_SIZE, @@ -21,6 +23,7 @@ import { formatCategoryToBannerImageURL, joinTitleByDelimiter, navigateBack, + normalizeEndTimes, } from '@/utils'; import { BaseButton } from '@/components/commons/buttons'; @@ -30,16 +33,25 @@ import Schedule from '@/components/createPage/Schedule'; import SelectedSchedule from '@/components/createPage/SelectedSchedule'; import useToggleButton from '@/hooks/useToggleButton'; +import { ActivityCreateBody, Category } from '@/types'; + import styles from './PostForm.module.scss'; const cx = classNames.bind(styles); type PostFormProps = { type: '등록' | '수정'; - category: '스포츠' | '투어' | '관광' | '웰빙'; + category: Category; }; const PostForm = ({ type, category }: PostFormProps) => { + const { mutate } = useMutation({ + mutationFn: (value: ActivityCreateBody) => Activities.create(value), + onSuccess: () => { + handleToggleClick(); + }, + }); + // 모집 유형 관련 const [price, setPrice] = useState(0); @@ -150,6 +162,7 @@ const PostForm = ({ type, category }: PostFormProps) => { const descriptionArray = [description, discord]; const editedTitle = joinTitleByDelimiter(titleArray); const editedDescription = joinTitleByDelimiter(descriptionArray); + const editedScheduleArray = normalizeEndTimes(scheduleArray); const editedRequestBody = { title: editedTitle, @@ -157,14 +170,12 @@ const PostForm = ({ type, category }: PostFormProps) => { description: editedDescription, address: newAddress, price: Number(price), - schedules: scheduleArray, + schedules: editedScheduleArray, bannerImageUrl: newBannerImageUrl, subImageUrls: imageArray.slice(1), }; - // 추후 api 연결할 부분 - console.log(editedRequestBody); - handleToggleClick(); + mutate(editedRequestBody); }; return ( diff --git a/src/pages/[game]/create/index.tsx b/src/pages/[game]/create/index.tsx index c7966c0b..b2e13d66 100644 --- a/src/pages/[game]/create/index.tsx +++ b/src/pages/[game]/create/index.tsx @@ -1,8 +1,44 @@ +import { GetServerSidePropsContext } from 'next'; + +import { GAME_T0_CATEGORY, PAGE_PATHS } from '@/constants'; +import { formatLinkToGame, getAuthCookie, isValidGameName } from '@/utils'; + import CreatePageContent from '@/components/createPage/CreatePageContent'; import Layout from '@/components/layout/Layout'; -const CreatePage = () => { - return ; +import { Category, GameNameEN, LinkName } from '@/types'; + +export function getServerSideProps(context: GetServerSidePropsContext) { + const { accessToken } = getAuthCookie(context); + const isLoggedIn = !!accessToken; + + const game = context.params?.game; + const isValid = isValidGameName(game as string); + + if (!isLoggedIn || !isValid) { + return { + redirect: { + destination: PAGE_PATHS.signin, + permanent: false, + }, + }; + } + + const gameName = formatLinkToGame(game as LinkName) as GameNameEN; + const category = GAME_T0_CATEGORY[gameName]; + + return { + props: { gameName, category }, + }; +} + +export type CreatePageContentProps = { + gameName: GameNameEN; + category: Category; +}; + +const CreatePage = ({ gameName, category }: CreatePageContentProps) => { + return ; }; export default CreatePage;