diff --git a/src/app/gathering/[id]/page.tsx b/src/app/gathering/[id]/page.tsx index c2984dbf..69748828 100644 --- a/src/app/gathering/[id]/page.tsx +++ b/src/app/gathering/[id]/page.tsx @@ -1,11 +1,5 @@ import Breadcrumbs from "@/components/common/Breadcrumb"; -import GatheringRecommendationList from "@/components/gathering/read/GatheringRecommendationList"; import GatheringViewerContainer from "@/containers/gathering/read/detail/GatheringViewerContainer"; -import { GatheringDetailResponseDto } from "@/types/GatheringDto"; -import { cookies } from "next/headers"; -import { redirect } from "next/navigation"; -import { NextResponse } from "next/server"; - interface PageProps { params: { id: string }; } @@ -16,85 +10,87 @@ const categories = [ ]; -async function getNewAccessToken(refreshToken: string): Promise { - try { - const response = await fetch( - `${process.env.BACKEND_URL}/api/auth/oauth2/token/refresh`, - { - method: "POST", - headers: { - "Content-Type": "application/json", - Cookie: `refresh_token=${refreshToken}`, - }, - }, - ); - - if (!response.ok) { - throw new Error("리프레시 토큰을 사용한 액세스 토큰 갱신 실패"); - } - const accessToken = response.headers.get("set-cookie"); - return accessToken; - } catch (error) { - console.error("액세스 토큰 갱신 중 오류 발생:", error); - return null; - } -} - -async function getGathering(id: number): Promise { - let accessToken = cookies().get("access_token")?.value; - const refreshToken = cookies().get("refresh_token")?.value; - - if (!accessToken && !refreshToken) { - redirect("/auth/signin"); - } - - - try { - let response = await fetch( - `${process.env.BACKEND_URL}/api/gatherings/${id}`, - { - method: "GET", - headers: { - "Content-Type": "application/json", - Cookie: `access_token=${accessToken}`, - }, - cache: "no-store", - }, - ); - - // 액세스 토큰이 만료된 경우 - if (response.status === 401 && refreshToken) { - const newAccessToken = await getNewAccessToken(refreshToken); - - if (newAccessToken) { - // 새로 발급받은 액세스 토큰으로 다시 요청 - response = await fetch( - `${process.env.BACKEND_URL}/api/gatherings/${id}`, - { - method: "GET", - headers: { - "Content-Type": "application/json", - Cookie: `access_token=${newAccessToken}`, - }, - cache: "no-store", - }, - ); - - } else { - throw new Error("새로운 액세스 토큰 발급 실패"); - } - } - - if (!response.ok) { - throw new Error("네트워크 응답이 좋지 않습니다."); - } - - return await response.json(); - } catch (error) { - console.error("데이터를 가져오는 중 오류 발생:", error); - throw error; - } -} +// async function getNewAccessToken(refreshToken: string): Promise { +// try { +// const response = await fetch( +// `${process.env.BACKEND_URL}/api/auth/oauth2/token/refresh`, +// { +// method: "POST", +// headers: { +// "Content-Type": "application/json", +// Cookie: `refresh_token=${refreshToken}`, +// }, +// }, +// ); + +// if (!response.ok) { +// throw new Error("리프레시 토큰을 사용한 액세스 토큰 갱신 실패"); +// } +// const accessToken = response.headers.get("set-cookie"); +// return accessToken; +// } catch (error) { +// console.error("액세스 토큰 갱신 중 오류 발생:", error); +// return null; +// } +// } + +// async function getGathering(id: number) { +// let accessToken = cookies().get("access_token")?.value; +// const refreshToken = cookies().get("refresh_token")?.value; + +// if (!accessToken && !refreshToken) { +// redirect("/auth/signin"); +// } + +// if (!accessToken) { +// const newAccessToken= await getNewAccessToken(refreshToken as string); +// accessToken = newAccessToken as string; +// } + +// let response = await fetch( +// `${process.env.BACKEND_URL}/api/gatherings/${id}`, +// { +// method: "GET", +// headers: { +// "Content-Type": "application/json", +// Cookie: `access_token=${accessToken}`, +// }, +// cache: "no-store", +// }, +// ); + +// if (response.status != 401 && !response.ok) { +// throw new Error("서버 에러"); +// } + +// // 액세스 토큰이 만료된 경우 +// if (response.status === 401 && refreshToken) { +// const newAccessToken = await getNewAccessToken(refreshToken); + +// if (newAccessToken) { +// // 새로 발급받은 액세스 토큰으로 다시 요청 +// response = await fetch( +// `${process.env.BACKEND_URL}/api/gatherings/${id}`, +// { +// method: "GET", +// headers: { +// "Content-Type": "application/json", +// Cookie: `access_token=${newAccessToken}`, +// }, +// cache: "no-store", +// }, +// ); + +// } else { +// throw new Error("새로운 액세스 토큰 발급 실패"); +// } + +// if (!response.ok) { +// throw new Error("네트워크 응답이 좋지 않습니다."); +// } +// } +// return await response.json(); +// } export async function generateMetadata({ params: { id } }: PageProps) { const postId = Number(id); @@ -108,17 +104,18 @@ export async function generateMetadata({ params: { id } }: PageProps) { }; } + export default async function Page({ params: { id } }: PageProps) { const postId = Number(id); - - if (postId <= 0 || !Number.isSafeInteger(postId)) { - return NextResponse.json( - { message: "페이지를 찾을 수 없습니다." }, - { status: 404 }, - ); - } - const gatheringData = await getGathering(postId); - return ( + // if (postId <= 0 || !Number.isSafeInteger(postId)) { + // return NextResponse.json( + // { message: "페이지를 찾을 수 없습니다." }, + // { status: 404 }, + // ); + // } + // const data = await getGathering(postId); + + return (
{/* 제일 상단 */} - - + + {/* */}
); } diff --git a/src/components/common/modal/Modal.tsx b/src/components/common/modal/Modal.tsx index 6fe84f19..ec78a177 100644 --- a/src/components/common/modal/Modal.tsx +++ b/src/components/common/modal/Modal.tsx @@ -14,7 +14,7 @@ interface ModalProps extends React.PropsWithChildren { export const Modal = ({ isOpen, children, onClose, isHeaderBar, headerBarStyle = "bg-white" }: ModalProps) => { const [documentBody, setDocumentBody] = useState(null); - const ref = useRef(null); + const ref = useRef(null); let flag = isOpen; usePreventBodyScroll(isOpen); @@ -63,9 +63,9 @@ export const Modal = ({ isOpen, children, onClose, isHeaderBar, headerBarStyle = style={{ zIndex: "100" }} >
- + , document.getElementById("modal-root") as HTMLElement, ); diff --git a/src/components/gathering/createUpdate/editor/modal/GatheringParticipantsFilterModal.tsx b/src/components/gathering/createUpdate/editor/modal/GatheringParticipantsFilterModal.tsx index d0f9d75d..0a49f350 100644 --- a/src/components/gathering/createUpdate/editor/modal/GatheringParticipantsFilterModal.tsx +++ b/src/components/gathering/createUpdate/editor/modal/GatheringParticipantsFilterModal.tsx @@ -1,82 +1,60 @@ import { - SETTING_MODAL_SEX + SETTING_MODAL_SEX, } from "@/constants/gathering/GatheringConstant"; import "@/styles/reactDataRange.css"; import Image from "next/image"; -import Slider from "rc-slider"; -import "rc-slider/assets/index.css"; import { useState } from "react"; import { useFormContext } from "react-hook-form"; - interface IGatheringParticipantsFilterModalProps { closeModal: () => void; } +const SETTING_MODAL_AGE = { + 전체: { + startAge: 20, + endAge: 59, + }, + "20대": { + startAge: 20, + endAge: 29, + }, + "30대": { + startAge: 30, + endAge: 39, + }, + "40대": { + startAge: 40, + endAge: 49, + }, + "50대": { + startAge: 50, + endAge: 59, + }, +} -const GatheringParticipantsFilterModal = (props: IGatheringParticipantsFilterModalProps) => { +const GatheringParticipantsFilterModal = ( + props: IGatheringParticipantsFilterModalProps, +) => { const formContext = useFormContext(); - const [peopleCount, setPeopleCount] = useState(formContext.getValues("personCount") || 6); + const [peopleCount, setPeopleCount] = useState( + formContext.getValues("personCount") || 5, + ); const [sex, setSex] = useState(formContext.getValues("allowedSex")); - const [startAge, setStartAge] = useState(formContext.getValues("startAge") ? new Date().getFullYear() - formContext.getValues("startAge") : 20); - const [endAge, setEndAge] = useState(formContext.getValues("endAge") ? new Date().getFullYear() - formContext.getValues("endAge") : 59); - const [values, setValues] = useState([startAge, endAge]); - const markerPositions = [20, 25, 30, 35, 40, 45, 50, 55, 59]; - -const onClickDecreaseMinAge = () => { - let temp = Math.max(20, startAge - 1); - if (temp <= endAge) { - setStartAge(temp); - setValues((prev) => [temp, prev[1]]); - } -}; - -const onClickImproveMinAge = () => { - let temp = Math.min(endAge, startAge + 1); - setStartAge(temp); - setValues((prev) => [temp, prev[1]]); -}; - -const onClickDecreaseMaxAge = () => { - let temp = Math.max(startAge, endAge - 1); - setEndAge(temp); - setValues((prev) => [prev[0], temp]); -}; - -const onClickImproveMaxAge = () => { - let temp = Math.min(59, endAge + 1); - if (temp >= startAge) { - setEndAge(temp); - setValues((prev) => [prev[0], temp]); - } -}; - - const handleChange = (newValues: number[] | number) => { - const valuesArray = newValues as number[]; - setValues(valuesArray); - setStartAge(valuesArray[0]); - setEndAge(valuesArray[1]); - }; - - const handleMarkerClick = (age: number) => { - const distanceToStart = Math.abs(startAge - age); - const distanceToEnd = Math.abs(endAge - age); - - if (distanceToStart < distanceToEnd) { - // Update startAge if it's closer to the clicked age - const newStartAge = age; - setStartAge(newStartAge); - setValues([newStartAge, endAge]); - } else { - // Update endAge if it's closer to the clicked age - const newEndAge = age; - setEndAge(newEndAge); - setValues([startAge, newEndAge]); - } - }; + const [startAge, setStartAge] = useState( + formContext.getValues("startAge") + ? new Date().getFullYear() - formContext.getValues("startAge") + : 20, + ); + const [endAge, setEndAge] = useState( + formContext.getValues("endAge") + ? new Date().getFullYear() - formContext.getValues("endAge") + : 59, + ); + const [directInput, setDirectInput] = useState(false); const submitHandler = () => { - formContext.setValue("startAge", new Date().getFullYear() - startAge); - formContext.setValue("endAge", new Date().getFullYear() - endAge); + formContext.setValue("startAge", new Date().getFullYear() - (startAge || 0)); + formContext.setValue("endAge", new Date().getFullYear() - (endAge || 0)); formContext.setValue("personCount", peopleCount); formContext.setValue("allowedSex", sex); formContext.watch(); @@ -84,11 +62,28 @@ const onClickImproveMaxAge = () => { props.closeModal(); }; + const ageHandler = ({ + _startAge, + _endAge, + }: { + _startAge: number; + _endAge: number; + }) => { + setDirectInput(false); + if ((endAge || 0) + 1 == _startAge) { + setEndAge(_endAge); + } else if ((startAge || 0) - 1 == _endAge) { + setStartAge(_startAge); + } else { + setStartAge(_startAge); + setEndAge(_endAge); + } + }; return (
-

- 참여자 선택 -

-
-
+

참여자 선택

+
+
+
인원
-
인원
-
-
{peopleCount}
명 +
{ + setPeopleCount(peopleCount <= 2 ? 2 : peopleCount - 1); + }} + > + {peopleCount > 2 ? ( + {"minus-icon"} + ) : ( +
+ )}
-
-
- setPeopleCount(value)} - trackStyle={[ - { - backgroundColor: "#0d6efd", - height: 30, - }, - ]} - handleStyle={{ - height: 30, - width: 30, - borderRadius: 50, - borderColor: "#0d6efd00", - backgroundColor: "#ffffff00", - transform: "translate(-50%, 8px)", - opacity: 0, +
+
{peopleCount}
명 +
+
{ + setPeopleCount(peopleCount >= 10 ? 10 : peopleCount + 1); }} - railStyle={{ backgroundColor: "#ddd", height: 32 }} - /> + > + {peopleCount < 10 ? ( + {"plus-icon"} + ) : ( +
+ )} +
-
-
- 나이 -
-
- {new Date().getFullYear() - startAge} 년생 - {`(${startAge} 세)`} -
-
- {new Date().getFullYear() - endAge} 년생 - {`(${endAge} 세)`} -
-
- {/* 화살표 버튼 */} -
-
+
+
나이
+
+
+ {Object.entries(SETTING_MODAL_AGE).map((i) => ( - -
-
- - -
+ ))} +
-
- -
- = 56 - ? `calc(${((startAge - 20) / 39) * 100}% - 2rem)` - : `calc(${((startAge - 20) / 35) * 87.5}% - ${((((startAge - 20) / 35) * 87.5) / 100) * 2}rem)`, - width: - startAge >= 56 - ? endAge >= 56 - ? `calc(100% - (${((startAge - 20) / 39) * 100}% - 2rem - (${((59 - endAge) / 39) * 87.5}%))` - : `calc(100% - (${((startAge - 20) / 39) * 100}% - 2rem - (${((59 - endAge) / 39) * 87.5}%))` // 55 1 , 57 0.5, 59 0 - : endAge >= 55 - ? `calc(100% - (${((startAge - 20) / 35) * 87.5}% - ${((((startAge - 20) / 35) * 87.5) / 100) * 2}rem) - calc(calc(100% - 2rem) / 8 * ${59 - endAge} / 4 )` - : `calc(100% - (${((startAge - 20) / 35) * 87.5}% - ${((((startAge - 20) / 35) * 87.5) / 100) * 2}rem) - calc(calc(100% - 2rem) / 8 * ${55 - endAge + 5} / 5 )`, - }, - ]} - railStyle={{ - backgroundColor: "#ddd", - height: 32, - }} - /> -
- {markerPositions.map((age) => ( - - ))} + {new Date().getFullYear() - (endAge || 0)} 년생 +
+
-
성별 제한
+
+ 성별 제한 +
{Object.entries(SETTING_MODAL_SEX).map((i) => ( @@ -298,10 +285,15 @@ const onClickImproveMaxAge = () => {
-
+
-
-
- 나이 -
-
- {new Date().getFullYear() - startAge} 년생 - {`(${startAge} 세)`} -
-
- {new Date().getFullYear() - endAge} 년생 - {`(${endAge} 세)`} -
-
- {/* 화살표 버튼 */} -
-
- +
+
나이
+
+
+ {Object.entries(SETTING_MODAL_AGE).map((i) => ( -
-
- - -
+ ))} +
-
- -
- = 56 - ? `calc(${((startAge - 20) / 39) * 100}% - 2rem)` - : `calc(${((startAge - 20) / 35) * 87.5}% - ${((((startAge - 20) / 35) * 87.5) / 100) * 2}rem)`, - width: - startAge >= 56 - ? endAge >= 56 - ? `calc(100% - (${((startAge - 20) / 39) * 100}% - 2rem - (${((59 - endAge) / 39) * 87.5}%))` - : `calc(100% - (${((startAge - 20) / 39) * 100}% - 2rem - (${((59 - endAge) / 39) * 87.5}%))` // 55 1 , 57 0.5, 59 0 - : endAge >= 55 - ? `calc(100% - (${((startAge - 20) / 35) * 87.5}% - ${((((startAge - 20) / 35) * 87.5) / 100) * 2}rem) - calc(calc(100% - 2rem) / 8 * ${59 - endAge} / 4 )` - : `calc(100% - (${((startAge - 20) / 35) * 87.5}% - ${((((startAge - 20) / 35) * 87.5) / 100) * 2}rem) - calc(calc(100% - 2rem) / 8 * ${55 - endAge + 5} / 5 )`, - }, - ]} - railStyle={{ - backgroundColor: "#ddd", - height: 32, - }} - /> -
- {markerPositions.map((age, index) => ( - - ))} + {new Date().getFullYear() - (endAge || 0)} 년생 +
+
diff --git a/src/containers/gathering/read/detail/GatheringViewerContainer.tsx b/src/containers/gathering/read/detail/GatheringViewerContainer.tsx index a6395342..c546c88b 100644 --- a/src/containers/gathering/read/detail/GatheringViewerContainer.tsx +++ b/src/containers/gathering/read/detail/GatheringViewerContainer.tsx @@ -1,37 +1,63 @@ "use client" import GatheringViewer from "@/components/gathering/read/detail/GatheringViewer"; +import GatheringRecommendationList from "@/components/gathering/read/GatheringRecommendationList"; import useModalState from "@/hooks/useModalState"; import useGatheringStore from "@/store/gatheringStore"; import { GatheringDetailResponseDto } from "@/types/GatheringDto"; -import { useEffect } from "react"; +import { useParams } from "next/navigation"; +import { useEffect, useState } from "react"; interface IGatheringViewerContainer { - data: GatheringDetailResponseDto; + // data: GatheringDetailResponseDto; postId: number; } -const GatheringViewerContainer = ({ data, postId }: IGatheringViewerContainer) => { +const GatheringViewerContainer = ({ postId }: IGatheringViewerContainer) => { const modalState = useModalState(); const gatheringStore = useGatheringStore(); + const params = useParams(); + const [data, setData] = useState(); useEffect(() => { - gatheringStore.setGathering({ - currentParticipants: data.nowPersonCount, - gatheringApplicantsResponses: data.gatheringApplicantsResponses, - isFinish: data.isFinish, - deadline: data.deadline, - personCount: data.personCount, - }); + + const getGathering = async () => { + const res = await fetch(`/api/gathering/${params.id}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + cache: "no-store", + }); + + const data = await res.json(); + setData(data); + gatheringStore.setGathering({ + currentParticipants: data.nowPersonCount, + gatheringApplicantsResponses: data.gatheringApplicantsResponses, + isFinish: data.isFinish, + deadline: data.deadline, + personCount: data.personCount, + }); + } + getGathering(); },[]) return ( - + <> + { + data != undefined && + <> + + + + } + ); }; export default GatheringViewerContainer \ No newline at end of file