diff --git a/app/(route)/(header)/event/[eventId]/approve/[editId]/_components/EditBox.tsx b/app/(route)/(header)/event/[eventId]/approve/[editId]/_components/EditBox.tsx index 310eb89f..33403532 100644 --- a/app/(route)/(header)/event/[eventId]/approve/[editId]/_components/EditBox.tsx +++ b/app/(route)/(header)/event/[eventId]/approve/[editId]/_components/EditBox.tsx @@ -10,7 +10,9 @@ const EditBox = ({ children, isEdited = false }: Props) => { return (
{isEdited ? "수정 내용" : "기존 내용"} -
{children}
+
+ {children} +
); }; diff --git a/app/(route)/(header)/event/[eventId]/approve/[editId]/page.tsx b/app/(route)/(header)/event/[eventId]/approve/[editId]/page.tsx index 00cf6ded..7a142db8 100644 --- a/app/(route)/(header)/event/[eventId]/approve/[editId]/page.tsx +++ b/app/(route)/(header)/event/[eventId]/approve/[editId]/page.tsx @@ -2,13 +2,17 @@ import { useQuery } from "@tanstack/react-query"; import Link from "next/link"; -import { useParams } from "next/navigation"; +import { useParams, useRouter } from "next/navigation"; import { useEffect, useState } from "react"; import toast from "react-hot-toast"; import { instance } from "@/api/api"; +import { useSession } from "@/store/session/cookies"; +import { EditErrMsgType } from "@/types/errorMsgType"; import { CategoryType, EditContentType, LabelType, PostValueType } from "@/types/index"; import { EDIT_ERR_MSG } from "@/constants/errorMsg"; import { LABEL_BY_CATEGORY, exceptionList } from "@/constants/post"; +import ApproveIcon from "@/public/icon/edit-approve.svg"; +import DeclineIcon from "@/public/icon/edit-reject.svg"; import LinkIcon from "@/public/icon/link.svg"; import IdIcon from "@/public/icon/user.svg"; import BottomDoubleButton from "../../_components/BottomDoubleButton"; @@ -18,14 +22,16 @@ import RenderException from "../_components/RenderException"; import EditBox from "./_components/EditBox"; const EditDetailApprove = () => { + const router = useRouter(); + const { eventId, editId } = useParams(); const [originData, setOriginData] = useState(); - const { editId } = useParams(); const { data, isSuccess, refetch } = useQuery({ queryKey: ["approveDetail", editId], queryFn: async () => { return instance.get(`/event/update/application/${editId}`, { eventUpdateApplicationId: String(editId) }); }, }); + const session = useSession(); useEffect(() => { if (isSuccess) { @@ -42,10 +48,19 @@ const EditDetailApprove = () => { }, [data]); const handleApplicationSubmit = async (isApproved: boolean) => { - const res = await instance.post("/event/update/approval", { eventUpdateApplicationId: String(editId), isApproved, userId: "edit-api" }); - refetch(); - if (res.error) { - toast(EDIT_ERR_MSG[res.statusCode as "409" | "500"], { icon: "⚠️", className: "text-14 !text-red font-600" }); + try { + if (!session) throw Error("Unauthorized"); + if (session.user.userId === data.applicationDetail.userId) throw Error("the applicant is the author"); + const res = await instance.post("/event/update/approval", { eventUpdateApplicationId: String(editId), isApproved, userId: "edit-api" }); + refetch(); + toast(EDIT_ERR_MSG[isApproved ? "approve" : "reject"], { + icon: isApproved ? : , + className: "text-16 font-500", + }); + router.replace(`/event/${eventId}/approve`); + } catch (err: any) { + toast.error(EDIT_ERR_MSG[err.message as EditErrMsgType], { className: "text-16 !text-red font-500" }); + if (err.message === "Unauthorized") router.push("/signin"); } }; @@ -74,6 +89,7 @@ const EditDetailApprove = () => { <>{JSON.parse(data.applicationDetail.updateData)[data.applicationDetail.updateCategory]} )} + {data.applicationDetail.updateCategory === "eventImages" &&

사진을 클릭해 확인해 보세요.

}
승인 현황 diff --git a/app/(route)/(header)/event/[eventId]/approve/_components/EditCard.tsx b/app/(route)/(header)/event/[eventId]/approve/_components/EditCard.tsx index 0ae25ef2..2aaa8743 100644 --- a/app/(route)/(header)/event/[eventId]/approve/_components/EditCard.tsx +++ b/app/(route)/(header)/event/[eventId]/approve/_components/EditCard.tsx @@ -26,30 +26,30 @@ const EditCard = ({ id, type, editContent, count, createdAt, category }: Props) const curPath = usePathname(); return ( -
-
{type}
- {exceptionList.includes(type) ? ( - - ) : ( -
{editContent[category as PostValueType]}
- )} -
-
- 승인 - + +
+
{type}
+ {exceptionList.includes(type) ? ( + + ) : ( +
{editContent[category as PostValueType]}
+ )} +
+
+ 승인 + +
+
+ 거절 + +
+

{formatDate(createdAt, "yyyy.MM.dd")}

-
- 거절 - -
-

{formatDate(createdAt, "yyyy.MM.dd")}

-
- -
+ +
+ ); }; diff --git a/app/(route)/(header)/event/[eventId]/approve/_components/EditFormat.tsx b/app/(route)/(header)/event/[eventId]/approve/_components/EditFormat.tsx index 88da4be9..51757a56 100644 --- a/app/(route)/(header)/event/[eventId]/approve/_components/EditFormat.tsx +++ b/app/(route)/(header)/event/[eventId]/approve/_components/EditFormat.tsx @@ -1,7 +1,9 @@ import classNames from "classnames"; import Image from "next/image"; -import { useParams, usePathname, useRouter } from "next/navigation"; +import { useParams, usePathname } from "next/navigation"; import Chip from "@/components/chip/Chip"; +import ModalPortal from "@/components/modal/ModalPortal"; +import { useModal } from "@/hooks/useModal"; import { GiftType } from "@/types/index"; import { EDIT_ERR_MSG } from "@/constants/errorMsg"; import { SnsIcon } from "@/constants/snsIcon"; @@ -11,20 +13,29 @@ interface ImageEditProps { } export const ImageEdit = ({ imgList }: ImageEditProps) => { - const router = useRouter(); const { eventId, editId } = useParams(); const curPath = usePathname(); const isPreview = curPath === `/event/${eventId}/approve/${editId}`; + const { modal, openModal, closeModal } = useModal(); return (
{imgList.length > 0 ? imgList.map((url: string) => ( -
(isPreview ? router.push(url) : null)}> +
(isPreview ? openModal(url) : null)}> 수정된 행사 이미지
)) : EDIT_ERR_MSG["noInfo"]} + {modal && ( + +
+
+ 크게보기 +
+
+
+ )}
); }; diff --git a/app/(route)/(header)/event/[eventId]/approve/page.tsx b/app/(route)/(header)/event/[eventId]/approve/page.tsx index 8d3adb28..ae8d0fb0 100644 --- a/app/(route)/(header)/event/[eventId]/approve/page.tsx +++ b/app/(route)/(header)/event/[eventId]/approve/page.tsx @@ -1,5 +1,6 @@ "use client"; +import LoadingDot from "@/(route)/(bottom-nav)/signin/_components/LoadingDot"; import { useQuery } from "@tanstack/react-query"; import { useParams } from "next/navigation"; import { instance } from "@/api/api"; @@ -22,18 +23,26 @@ const EditApprove = () => {

수정사항은 사용자 3인 이상의 승인 후에 반영됩니다. 거절이 3회 누적된 수정사항은 자동으로 삭제됩니다.

- {isLoading &&
로딩중
} + {isLoading && ( +
+ +
+ )} {isSuccess && - data.map(({ id, approvalCount, rejectionCount, updateCategory, updateData, createdAt }: EditApplicationType) => ( - + (data.length === 0 ? ( +
요청된 수정사항이 없어요💦
+ ) : ( + data.map(({ id, approvalCount, rejectionCount, updateCategory, updateData, createdAt }: EditApplicationType) => ( + + )) ))}
); diff --git a/app/(route)/(header)/event/[eventId]/edit/_components/EditContent.tsx b/app/(route)/(header)/event/[eventId]/edit/_components/EditContent.tsx index b3f27d4f..798dbd16 100644 --- a/app/(route)/(header)/event/[eventId]/edit/_components/EditContent.tsx +++ b/app/(route)/(header)/event/[eventId]/edit/_components/EditContent.tsx @@ -3,18 +3,21 @@ import MainInput from "@/(route)/post/_components/_inputs/MainInput"; import StarInput from "@/(route)/post/_components/_inputs/StarInput"; import SubInput from "@/(route)/post/_components/_inputs/SubInput"; import { PostType } from "@/(route)/post/page"; +import { useEffect } from "react"; import { useFormContext } from "react-hook-form"; import BottomButton from "@/components/button/BottomButton"; import { useStore } from "@/store/index"; import { checkArrUpdate } from "@/utils/checkArrUpdate"; import { PostValueType } from "@/types/index"; +const ArrCategory = ["artists", "artistNames", "tags", "eventImages"]; + const EditContent = () => { const { watch, formState: { defaultValues }, } = useFormContext(); - const { isCheck } = useStore((state) => ({ isCheck: state.isWarningCheck })); + const { isCheck, setCheck } = useStore((state) => ({ isCheck: state.isWarningCheck, setCheck: state.setIsWarningCheck })); const watchedValue = watch(); const checkUpdated = () => { @@ -26,20 +29,7 @@ const EditContent = () => { if (postTypeGuard(defaultValues, key)) { const prev = defaultValues[key]; const cur = watchedValue[key]; - if (typeof prev === "undefined" || typeof cur === "undefined") { - return false; - } - switch (key) { - case "artists": - case "artistNames": - case "tags": - case "eventImages": - if (typeof prev === "string" || typeof cur === "string") return false; - isUpdated = checkArrUpdate(prev, cur); - break; - default: - isUpdated = prev !== cur; - } + isUpdated = ArrCategory.includes(key) ? checkArrUpdate(prev as any[], cur as any[]) : prev !== cur; if (isUpdated) { return true; } @@ -50,6 +40,10 @@ const EditContent = () => { const isValid = checkUpdated() && isCheck; + useEffect(() => { + setCheck(false); + }, []); + return (
@@ -66,5 +60,5 @@ const EditContent = () => { export default EditContent; const postTypeGuard = (obj: { [a: string]: any }, key: string): key is PostValueType => { - return !!obj[key]; + return typeof obj[key] !== undefined; }; diff --git a/app/(route)/(header)/event/[eventId]/edit/_components/InitButton.tsx b/app/(route)/(header)/event/[eventId]/edit/_components/InitButton.tsx new file mode 100644 index 00000000..a32d3200 --- /dev/null +++ b/app/(route)/(header)/event/[eventId]/edit/_components/InitButton.tsx @@ -0,0 +1,13 @@ +interface Props { + onClick?: () => void; +} + +const InitButton = ({ onClick }: Props) => { + return ( + + ); +}; + +export default InitButton; diff --git a/app/(route)/(header)/event/[eventId]/edit/page.tsx b/app/(route)/(header)/event/[eventId]/edit/page.tsx index 68253369..3ed89a0f 100644 --- a/app/(route)/(header)/event/[eventId]/edit/page.tsx +++ b/app/(route)/(header)/event/[eventId]/edit/page.tsx @@ -4,32 +4,38 @@ import { PostType } from "@/(route)/post/page"; import { instance } from "app/_api/api"; import { format } from "date-fns"; import { useParams } from "next/navigation"; -import { useEffect, useState } from "react"; +import { Suspense, useEffect, useState } from "react"; import GenericFormProvider from "@/components/GenericFormProvider"; +import { useAuth } from "@/hooks/useAuth"; +import { useStore } from "@/store/index"; import EditContent from "./_components/EditContent"; let INITIAL_DATA: PostType; const Edit = () => { + // const session = useAuth("/signin"); const { eventId } = useParams(); const [init, setInit] = useState(false); + const { setWriterId } = useStore((state) => ({ setWriterId: state.setWriterId })); useEffect(() => { const fetchData = async () => { const data = await instance.get(`/event/${eventId}`); - const { address, addressDetail, description, endDate, startDate, eventImages, eventTags, eventUrl, eventType, organizerSns, placeName, snsType, targetArtists } = data; + const { address, addressDetail, description, endDate, startDate, eventImages, eventTags, eventUrl, eventType, organizerSns, placeName, snsType, targetArtists, userId } = + data; const artistNames: string[] = targetArtists.map(({ artistName }: { artistName: string }) => artistName); const artists = targetArtists.map(({ artistId }: { artistId: string }) => artistId); const tags = eventTags.map(({ tagName }: { tagName: string }) => tagName); const imgList = eventImages.map(({ imageUrl }: { imageUrl: string }) => imageUrl); + setWriterId(userId); INITIAL_DATA = { placeName, eventType, - groupId: targetArtists[0].groupId, - groupName: targetArtists[0].groupName, + groupId: targetArtists[0].groupId || "", + groupName: targetArtists[0].groupId ? targetArtists[0].groupName : targetArtists[0].artistName, artists, - artistNames, + artistNames: targetArtists[0].groupId ? artistNames : [], startDate: format(startDate, "yyyy.MM.dd"), endDate: format(endDate, "yyyy.MM.dd"), address, @@ -49,7 +55,7 @@ const Edit = () => { return (
{init && ( - + )} diff --git a/app/(route)/post/_components/DetailInfo.tsx b/app/(route)/post/_components/DetailInfo.tsx index df13cf31..c962e4a8 100644 --- a/app/(route)/post/_components/DetailInfo.tsx +++ b/app/(route)/post/_components/DetailInfo.tsx @@ -19,7 +19,9 @@ const DetailInfo = () => {
- 100}>작성 완료 + 100}> + 작성 완료 + ); }; diff --git a/app/(route)/post/_components/_inputs/DetailInput.tsx b/app/(route)/post/_components/_inputs/DetailInput.tsx index d650100e..224af18a 100644 --- a/app/(route)/post/_components/_inputs/DetailInput.tsx +++ b/app/(route)/post/_components/_inputs/DetailInput.tsx @@ -1,3 +1,4 @@ +import InitButton from "@/(route)/(header)/event/[eventId]/edit/_components/InitButton"; import { useEffect, useState } from "react"; import { useFormContext } from "react-hook-form"; import WarningCheck from "@/components/WarningCheck"; @@ -32,10 +33,10 @@ const DetailInput = () => { return ( <>
-
+
이미지 {validateEdit(typeof defaultValues?.eventImages !== "undefined" && checkArrUpdate(defaultValues?.eventImages, imgList)) && ( -

수정됨

+ setImgList(defaultValues?.eventImages as (string | File)[])} /> )}
@@ -51,6 +52,7 @@ const DetailInput = () => { rules={{ maxLength: 100 }} hasLimit isEdit={validateEdit(defaultValues?.description !== getValues("description"))} + onInit={() => setValue("description", defaultValues?.description || "")} > 상세 내용 diff --git a/app/(route)/post/_components/_inputs/MainInput.tsx b/app/(route)/post/_components/_inputs/MainInput.tsx index 8a136500..cc0bc95c 100644 --- a/app/(route)/post/_components/_inputs/MainInput.tsx +++ b/app/(route)/post/_components/_inputs/MainInput.tsx @@ -1,3 +1,4 @@ +import InitButton from "@/(route)/(header)/event/[eventId]/edit/_components/InitButton"; import { useFormContext } from "react-hook-form"; import AddressBottomSheet from "@/components/bottom-sheet/AddressBottomSheet"; import CalenderBottomSheet from "@/components/bottom-sheet/CalendarBottomSheet"; @@ -19,7 +20,13 @@ const MainInput = () => { return ( <> - + setValue("placeName", defaultValues?.placeName || "")} + > 장소 이름
@@ -30,15 +37,26 @@ const MainInput = () => { onKeyDown={(event) => handleEnterDown(event, () => openBottomSheet("address"))} onClick={() => openBottomSheet("address")} isEdit={validateEdit(defaultValues?.address !== address || defaultValues?.addressDetail !== addressDetail)} + onInit={() => { + setValue("address", defaultValues?.address || ""); + setValue("addressDetail", defaultValues?.addressDetail || ""); + }} > 주소
-
+
기간 - {validateEdit(defaultValues?.startDate !== startDate || defaultValues?.endDate !== endDate) &&

수정됨

} + {validateEdit(defaultValues?.startDate !== startDate || defaultValues?.endDate !== endDate) && ( + { + setValue("startDate", defaultValues?.startDate || ""); + setValue("endDate", defaultValues?.endDate || ""); + }} + /> + )}
diff --git a/app/(route)/post/_components/_inputs/StarInput.tsx b/app/(route)/post/_components/_inputs/StarInput.tsx index 2dcb9678..8d05862f 100644 --- a/app/(route)/post/_components/_inputs/StarInput.tsx +++ b/app/(route)/post/_components/_inputs/StarInput.tsx @@ -1,3 +1,4 @@ +import InitButton from "@/(route)/(header)/event/[eventId]/edit/_components/InitButton"; import { useFormContext } from "react-hook-form"; import EventTypeBottomSheet from "@/components/bottom-sheet/EventTypeBottomSheet"; import StarBottomSheet from "@/components/bottom-sheet/StarBottomSheet"; @@ -12,20 +13,28 @@ const StarInput = () => { const { bottomSheet, openBottomSheet, closeBottomSheet, refs } = useBottomSheet(); const { + setValue, formState: { defaultValues }, watch, } = useFormContext(); const { eventType, groupId, artistNames, artists } = watch(); const isNotMember = groupId && artistNames.length === 0; + const handleArtistInit = () => { + setValue("groupId", defaultValues?.groupId || ""); + setValue("groupName", defaultValues?.groupName || ""); + setValue("artists", defaultValues?.artists as string[]); + setValue("artistNames", defaultValues?.artistNames as string[]); + }; + return ( <>
-
+
@@ -54,6 +63,8 @@ const StarInput = () => { onClick={() => openBottomSheet("event")} onKeyDown={(event) => handleEnterDown(event, () => openBottomSheet("event"))} isEdit={validateEdit(defaultValues?.eventType !== eventType)} + onInit={() => setValue("eventType", defaultValues?.eventType || "카페")} + noButton > 행사 유형 diff --git a/app/(route)/post/_components/_inputs/SubInput.tsx b/app/(route)/post/_components/_inputs/SubInput.tsx index 94728cd5..1007ab8e 100644 --- a/app/(route)/post/_components/_inputs/SubInput.tsx +++ b/app/(route)/post/_components/_inputs/SubInput.tsx @@ -1,3 +1,4 @@ +import InitButton from "@/(route)/(header)/event/[eventId]/edit/_components/InitButton"; import { useEffect, useState } from "react"; import { useFormContext } from "react-hook-form"; import ChipButton from "@/components/chip/ChipButton"; @@ -45,6 +46,10 @@ const SubInput = () => { name="organizerSns" placeholder="sns 계정을 입력해주세요." isEdit={validateEdit(defaultValues?.organizerSns !== organizerSns || defaultValues.snsType !== snsType)} + onInit={() => { + setSnsType(defaultValues?.snsType || "트위터"); + setValue("organizerSns", defaultValues?.organizerSns || ""); + }} > 주최자 @@ -64,13 +69,20 @@ const SubInput = () => { ))}
- + setValue("eventUrl", defaultValues?.eventUrl || "")} + > 링크
-
+
특전 - {validateEdit(typeof defaultValues?.tags !== "undefined" && checkArrUpdate(defaultValues?.tags, giftList)) &&

수정됨

} + {validateEdit(typeof defaultValues?.tags !== "undefined" && checkArrUpdate(defaultValues?.tags, giftList)) && ( + setGiftList(defaultValues?.tags as string[])} /> + )}
    {GIFT_LIST.map((gift) => ( diff --git a/app/(route)/post/page.tsx b/app/(route)/post/page.tsx index 7b0944c2..5be58fdf 100644 --- a/app/(route)/post/page.tsx +++ b/app/(route)/post/page.tsx @@ -2,6 +2,7 @@ import GenericFormProvider from "@/components/GenericFormProvider"; import MobileHeader from "@/components/header/MobileHeader"; +import { useAuth } from "@/hooks/useAuth"; import { useFunnel } from "@/hooks/useFunnel"; import { PostStepNameType } from "@/types/index"; import DetailInfo from "./_components/DetailInfo"; @@ -39,6 +40,7 @@ export type PostType = Omit { + // const session = useAuth("/signin"); const { Funnel, Step, setStep, currentStep } = useFunnel(POST_STEPS); const handlePrevClick = () => { @@ -48,7 +50,7 @@ const Post = () => { return ( <> -
    +
    diff --git a/app/_api/api.ts b/app/_api/api.ts index 3d760fd4..9f7160cc 100644 --- a/app/_api/api.ts +++ b/app/_api/api.ts @@ -8,12 +8,10 @@ const STR_RES_ENDPOINT = ["/file/upload", "/event/update/application"]; export class Api { private baseUrl; private queryString; - private accessToken; - constructor(token?: string) { + constructor() { this.baseUrl = ""; this.queryString = ""; - this.accessToken = token; } private makeError(result: any) { @@ -40,11 +38,7 @@ export class Api { if (queryObj) { this.makeQueryString(queryObj); } - const res = await fetch(queryObj ? this.baseUrl + this.queryString : this.baseUrl, { - headers: { - Authorization: `Bearer ${this.accessToken}`, - }, - }); + const res = await fetch(queryObj ? this.baseUrl + this.queryString : this.baseUrl); const result = await res.json(); this.makeError(result); @@ -61,10 +55,8 @@ export class Api { body: endPoint === "/file/upload" ? (body as any) : JSON.stringify(body), headers: { ...(endPoint === "/file/upload" || endPoint === "/reviews" ? {} : { "Content-Type": "application/json" }), - Authorization: `Bearer ${this.accessToken}`, credentials: "include", }, - credentials: "include", }); const result = STR_RES_ENDPOINT.includes(endPoint) ? await res.text() : await res.json(); this.makeError(result); @@ -79,7 +71,6 @@ export class Api { body: JSON.stringify(body), headers: { "Content-type": "application/json", - Authorization: `Bearer ${this.accessToken}`, }, }); const result = await res.json(); @@ -93,9 +84,6 @@ export class Api { const res = await fetch(this.baseUrl, { method: "DELETE", body: JSON.stringify(body), - headers: { - Authorization: `Bearer ${this.accessToken}`, - }, }); const result = await res.json(); this.makeError(result); diff --git a/app/_components/ArtistList.tsx b/app/_components/ArtistList.tsx deleted file mode 100644 index 0e7d336c..00000000 --- a/app/_components/ArtistList.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { ReactNode } from "react"; - -interface Props { - render: () => ReactNode; -} - -const ArtistList = ({ render }: Props) => { - return
    {render()}
    ; -}; - -export default ArtistList; diff --git a/app/_components/GenericFormProvider.tsx b/app/_components/GenericFormProvider.tsx index f4761a0b..daa6cf08 100644 --- a/app/_components/GenericFormProvider.tsx +++ b/app/_components/GenericFormProvider.tsx @@ -2,9 +2,14 @@ import { instance } from "app/_api/api"; import { useParams, usePathname, useRouter } from "next/navigation"; import React from "react"; import { FieldValues, FormProvider, UseFormProps, useForm } from "react-hook-form"; +import toast from "react-hot-toast"; import { useModal } from "@/hooks/useModal"; +import { useSession } from "@/store/session/cookies"; import { handleSignupSubmit } from "@/utils/handleSignupSubmit"; -import { handlePostSubmit, submitEditApplication } from "@/utils/submitPost"; +import { handlePostSubmit, submitEditApplication, submitEditWriter } from "@/utils/submitPost"; +import { EditErrMsgType, PostErrMsgType } from "@/types/errorMsgType"; +import { EDIT_ERR_MSG, POST_ERR_MSG } from "@/constants/errorMsg"; +import { useStore } from "../_store"; import AlertModal from "./modal/AlertModal"; interface GenericFormProps { @@ -13,26 +18,45 @@ interface GenericFormProps { } const GenericFormProvider = ({ children, formOptions }: GenericFormProps) => { - const { editId, eventId } = useParams(); + const { eventId } = useParams(); const { modal, openModal, closeModal } = useModal(); const router = useRouter(); const methods = useForm(formOptions); const path = usePathname(); + const { writerId } = useStore((state) => ({ writerId: state.writerId })); const onSubmit = async () => { const userInputValue = methods.getValues(); const defaultValue = methods.formState.defaultValues; + const session = useSession(); + if (!session) return; if (path === "/post") { - const res = await handlePostSubmit(userInputValue, instance); - router.push(`/event/${res.eventId}`); + try { + const res = await handlePostSubmit(userInputValue, instance, session.user.userId); + router.push(`/event/${res.eventId}`); + } catch (err: any) { + toast.error(POST_ERR_MSG[err.message as PostErrMsgType], { className: "text-16 font-500 !text-red" }); + if (err.message === "Unauthorized") { + return router.push("/signin"); + } + } } if (path === `/event/${eventId}/edit`) { - //작성 유저 - // const res = await submitEditWriter(methods.getValues(), instance, eventId); - //신청 유저 - await submitEditApplication(instance, defaultValue, userInputValue, eventId); - openModal("endEdit"); + try { + if (writerId === session.user.userId) { + await submitEditWriter(methods.getValues(), instance, session.user.userId, eventId); + openModal("editWriter"); + } else { + await submitEditApplication(instance, defaultValue, userInputValue, session.user.userId, eventId); + openModal("editApprove"); + } + } catch (err: any) { + toast.error(EDIT_ERR_MSG[err.message as EditErrMsgType], { className: "text-16 font-500 !text-red" }); + if (err.message === "Unauthorized") { + return router.push("/signin"); + } + } } if (path === "/signup") { const res = await handleSignupSubmit(userInputValue, instance); @@ -45,16 +69,15 @@ const GenericFormProvider = ({ children, formOptions }: G return (
    {children}
    - {modal === "endEdit" && ( - router.push(`/event/${eventId}`)}> + {modal === "editApprove" && ( + router.replace(`/event/${eventId}/approve`)}> 수정사항은 사용자 3인 이상의
    승인 후에 반영됩니다.
    )} - {modal === "endEdit" && ( - router.push(`/event/${eventId}`)}> - 수정사항은 사용자 3인 이상의 -
    승인 후에 반영됩니다. + {modal === "editWriter" && ( + router.replace(`/event/${eventId}`)}> + 수정이 완료되었습니다. )}
    diff --git a/app/_components/bottom-sheet/EventTypeBottomSheet.tsx b/app/_components/bottom-sheet/EventTypeBottomSheet.tsx index 9fd19493..92cc4c57 100644 --- a/app/_components/bottom-sheet/EventTypeBottomSheet.tsx +++ b/app/_components/bottom-sheet/EventTypeBottomSheet.tsx @@ -16,12 +16,12 @@ const EventTypeBottomSheet = ({ closeBottomSheet, refs }: BottomSheetBaseType) = return ( 행사 유형 선택 -
      +
        {EVENT_TYPE_LIST.map((event) => (
      • handleEventClick(event)} - className="hover:bg-main-pink-50 cursor-pointer border-b border-gray-50 px-24 py-20 text-16 font-500 text-gray-900" + className="cursor-pointer border-b border-gray-50 px-24 py-20 text-16 font-500 text-gray-900 hover:bg-main-pink-50" > {event}
      • diff --git a/app/_components/bottom-sheet/StarBottomSheet.tsx b/app/_components/bottom-sheet/StarBottomSheet.tsx index 5815a088..d742fb5e 100644 --- a/app/_components/bottom-sheet/StarBottomSheet.tsx +++ b/app/_components/bottom-sheet/StarBottomSheet.tsx @@ -1,14 +1,13 @@ +import LoadingDot from "@/(route)/(bottom-nav)/signin/_components/LoadingDot"; import { PostType } from "@/(route)/post/page"; -import { useQuery } from "@tanstack/react-query"; import { instance } from "app/_api/api"; import { Dispatch, SetStateAction, useEffect } from "react"; import { useFormContext } from "react-hook-form"; +import { useFetchGroupSolo } from "@/hooks/useFetchGroupSolo"; import { useFetchMember } from "@/hooks/useFetchMember"; -import { useSearch } from "@/hooks/useSearch"; -import { BottomSheetBaseType } from "@/types/index"; +import { BottomSheetBaseType, GroupAndSoloType, MemberDataType } from "@/types/index"; import BackIcon from "@/public/icon/arrow-left_lg.svg"; import ArtistCard from "../ArtistCard"; -import ArtistList from "../ArtistList"; import SearchInput from "../input/SearchInput"; import BottomSheet from "./BottomSheetMaterial"; @@ -19,18 +18,7 @@ interface Props extends BottomSheetBaseType { const StarBottomSheet = ({ closeBottomSheet, refs, isFirst = false }: Props) => { const { setValue, getValues, watch } = useFormContext(); const { groupName, artistNames } = watch(); - const { - data: groupData, - isSuccess, - isLoading, - refetch: refetchGroup, - } = useQuery({ - queryKey: ["group"], - queryFn: async () => { - return instance.get("/group/solo", { size: 12, page: 1, keyword: keyword }); - }, - }); - const { keyword, setKeyword } = useSearch(refetchGroup); + const { setKeyword, groupList, containerRef, isSuccess, isLoading } = useFetchGroupSolo(instance); const { groupId, setGroupId, isLoading: isMemberLoading, isSuccess: isMemberSuccess, data: memberData } = useFetchMember(instance, getValues, isFirst); const handleFirstDepthClick = (type: string, id: string, name: string) => { @@ -71,49 +59,53 @@ const StarBottomSheet = ({ closeBottomSheet, refs, isFirst = false }: Props) => return ( 아티스트 선택 -
        +
        {groupId ? (
        - {isMemberLoading &&
        멤버 로딩중
        } + {isMemberLoading && ( +
        + +
        + )} {isMemberSuccess && (memberData.length === 0 ? ( -
        데이터가 없어요ㅠㅠ
        +
        아직 데이터가 없어요💦
        ) : ( - ( - <> - {memberData.map(({ id, artistName, artistImage }: any) => ( - handleMemberClick(id, artistName)}> - {artistName} - - ))} - - )} - /> +
        +
        + {memberData.map(({ id, artistName, artistImage }: MemberDataType) => ( + handleMemberClick(id, artistName)}> + {artistName} + + ))} +
        +
        ))}
        ) : ( <> - {isLoading &&
        데이터 로딩중 ~~
        } + {isLoading && ( +
        + +
        + )} {isSuccess && ( - ( - <> - {groupData.groupAndSoloList.map(({ id, image, name, type }: any) => ( - handleFirstDepthClick(type, id, name)} - > - {name} - - ))} - - )} - /> +
        +
        + {groupList.map(({ id, image, name, type }: GroupAndSoloType) => ( + handleFirstDepthClick(type, id, name)} + > + {name} + + ))} +
        +
        )} )} diff --git a/app/_components/input/InputArea.tsx b/app/_components/input/InputArea.tsx index 5a76c7ec..1f2944c5 100644 --- a/app/_components/input/InputArea.tsx +++ b/app/_components/input/InputArea.tsx @@ -1,3 +1,4 @@ +import InitButton from "@/(route)/(header)/event/[eventId]/edit/_components/InitButton"; import classNames from "classnames"; import { KeyboardEvent, ReactNode } from "react"; import { FieldPath, FieldValues, UseControllerProps, useController } from "react-hook-form"; @@ -9,20 +10,21 @@ interface Prop { isEdit?: boolean; height?: number; hasLimit?: boolean; + onInit?: () => void; } type Function = = FieldPath>( prop: UseControllerProps & Prop, ) => ReactNode; -const InputArea: Function = ({ children, placeholder, onKeyDown, isEdit, hasLimit = false, ...control }) => { +const InputArea: Function = ({ children, placeholder, onKeyDown, isEdit, hasLimit = false, onInit, ...control }) => { const { field } = useController(control); return (
        -