diff --git a/components/molecules/DateVoteBlock.tsx b/components/molecules/DateVoteBlock.tsx index 13c17e8f8..0f42a2637 100644 --- a/components/molecules/DateVoteBlock.tsx +++ b/components/molecules/DateVoteBlock.tsx @@ -1,4 +1,6 @@ import { Box, Button, Flex } from "@chakra-ui/react"; +import { useSearchParams } from "next/navigation"; +import { useRouter } from "next/router"; import { useRecoilValue } from "recoil"; import { DateVoteButtonProps } from "../../pageTemplates/home/studyController/StudyControllerVoteButton"; @@ -11,18 +13,30 @@ interface DateVoteBlockProps { } function DateVoteBlock({ buttonProps, func, cnt }: DateVoteBlockProps) { + const router = useRouter(); + const searchParams = useSearchParams(); + const date = searchParams.get("date"); + const locationEn = searchParams.get("location"); + const myStudy = useRecoilValue(myStudyState); + return ( 현재 참여 인원: + - - {cnt === undefined ? "- " : cnt} - - 명 + {cnt !== undefined ? ( + + ) : ( + + - + + )} diff --git a/components/molecules/layouts/ImageTileFlexLayout.tsx b/components/molecules/layouts/ImageTileFlexLayout.tsx new file mode 100644 index 000000000..0a82af449 --- /dev/null +++ b/components/molecules/layouts/ImageTileFlexLayout.tsx @@ -0,0 +1,67 @@ +import { Box, Flex } from "@chakra-ui/react"; +import Image from "next/image"; +import styled from "styled-components"; + +export interface IImageTileData { + imageUrl: string; + text: string; + url?: string; + func?: () => void; + id?: string; +} + +interface IImageTileGridLayout { + imageDataArr: IImageTileData[]; + selectedId?: string[]; + selectedSubId?: string[]; +} +export default function ImageTileFlexLayout({ + imageDataArr, + + selectedId, + selectedSubId, +}: IImageTileGridLayout) { + function ImageTileLayout({ url, text }: { url: string; text: string }) { + return ( + + + studyPlaceImage + + {text} + + ); + } + + return ( + + {imageDataArr.map((imageData, idx) => ( + + ))} + + ); +} + +const Button = styled.button<{ $isSelected: "main" | "sub" | null }>` + background-color: ${(props) => + props.$isSelected === "main" + ? "var(--color-mint)" + : props.$isSelected === "sub" + ? "var(--color-orange)" + : null}; + color: ${(props) => (props.$isSelected ? "white" : "inherit")}; + border-radius: var(--rounded); + margin-right: 12px; + height: 100px; +`; diff --git a/components/services/studyVote/StudyVoteTimeRulletDrawer.tsx b/components/services/studyVote/StudyVoteTimeRulletDrawer.tsx index cf9160453..81ecd9107 100644 --- a/components/services/studyVote/StudyVoteTimeRulletDrawer.tsx +++ b/components/services/studyVote/StudyVoteTimeRulletDrawer.tsx @@ -17,6 +17,20 @@ export default function StudyVoteTimeRulletDrawer({ drawerOptions, setIsModal, }: IStudyVoteTimeRulletDrawer) { + return ( + <> + + + + + ); +} + +interface StudyVoteTimeRulletsProps { + setVoteTime: Dispatch<{ start: Dayjs; end: Dayjs }>; +} + +export function StudyVoteTimeRullets({ setVoteTime }: StudyVoteTimeRulletsProps) { const leftDefaultIdx = 8; const rightDefaultIdx = 10; @@ -43,16 +57,12 @@ export default function StudyVoteTimeRulletDrawer({ }, [rulletValue]); return ( - <> - - - - + ); } diff --git a/constants/serviceConstants/pointSystemConstants.ts b/constants/serviceConstants/pointSystemConstants.ts index 8a327b1ce..69f2ec2c0 100644 --- a/constants/serviceConstants/pointSystemConstants.ts +++ b/constants/serviceConstants/pointSystemConstants.ts @@ -14,6 +14,7 @@ export const POINT_SYSTEM_PLUS = { second: { value: 5, message: "스터디 두번째 투표" }, third: { value: 2, message: "스터디 세번째 투표" }, }, + STUDY_VOTE_DAILY: { value: 2, message: "당일 스터디 참여" }, STUDY_INVITE: { value: 2, message: "친구 초대 보너스" }, DAILY_ATTEND: { value: 3, message: "일일 출석" }, PROMOTION: { value: 100, message: "홍보 리워드" }, diff --git a/libs/study/getMyStudy.ts b/libs/study/getMyStudy.ts index b3bcd71bf..872bc233a 100644 --- a/libs/study/getMyStudy.ts +++ b/libs/study/getMyStudy.ts @@ -14,7 +14,7 @@ export const getMyStudy = ( } }), ); - + console.log(34, participations, myStudy); return myStudy; }; diff --git a/libs/study/getStudyVoteCnt.ts b/libs/study/getStudyVoteCnt.ts index 3116fe883..714f4c20e 100644 --- a/libs/study/getStudyVoteCnt.ts +++ b/libs/study/getStudyVoteCnt.ts @@ -1,6 +1,7 @@ import { IParticipation } from "../../types/models/studyTypes/studyDetails"; export const getStudyVoteCnt = (studyVoteData: IParticipation[], filterUid?: string) => { + if (!studyVoteData) return undefined; const temp = new Set(); studyVoteData?.forEach((par) => { @@ -10,5 +11,6 @@ export const getStudyVoteCnt = (studyVoteData: IParticipation[], filterUid?: str temp.add(who.user.uid); }); }); + return temp.size; }; diff --git a/modals/study/StudyPointGuideModal.tsx b/modals/study/StudyPointGuideModal.tsx new file mode 100644 index 000000000..f95d62fe5 --- /dev/null +++ b/modals/study/StudyPointGuideModal.tsx @@ -0,0 +1,25 @@ +import CheckList from "../../components/atoms/CheckList"; +import { IModal } from "../../types/components/modalTypes"; +import { IFooterOptions, ModalLayout } from "../Modals"; + +function StudyPointGuideModal({ setIsModal }: IModal) { + const footerOptions: IFooterOptions = { + main: { + text: "확인", + }, + }; + + const STUDY_CONTENTS = [ + "결과 발표 이전에 신청한 경우 5 POINT + 선택한 서브 장소 만큼 추가 포인트 획득!", + "가장 먼저 신청한 인원은 +10 POINT, 두번째 인원은 +5 POINT, 세번째 인원은 +2 POINT를 추가 획득!", + "당일 참여나 자유 스터디의 경우 +2 POINT", + ]; + + return ( + + + + ); +} + +export default StudyPointGuideModal; diff --git a/modals/study/StudySimpleVoteModal.tsx b/modals/study/StudySimpleVoteModal.tsx new file mode 100644 index 000000000..58996032a --- /dev/null +++ b/modals/study/StudySimpleVoteModal.tsx @@ -0,0 +1,157 @@ +import { Box } from "@chakra-ui/react"; +import dayjs, { Dayjs } from "dayjs"; +import { useSearchParams } from "next/navigation"; +import { useEffect, useState } from "react"; +import { useQueryClient } from "react-query"; +import { useRecoilValue } from "recoil"; + +import Selector from "../../components/atoms/Selector"; +import ImageTileFlexLayout from "../../components/molecules/layouts/ImageTileFlexLayout"; +import { IImageTileData } from "../../components/molecules/layouts/ImageTitleGridLayout"; +import { StudyVoteTimeRullets } from "../../components/services/studyVote/StudyVoteTimeRulletDrawer"; +import { STUDY_VOTE } from "../../constants/keys/queryKeys"; +import { POINT_SYSTEM_PLUS } from "../../constants/serviceConstants/pointSystemConstants"; +import { useToast } from "../../hooks/custom/CustomToast"; +import { + useStudyOpenFreeMutation, + useStudyParticipationMutation, +} from "../../hooks/study/mutations"; +import { usePointSystemMutation } from "../../hooks/user/mutations"; +import { usePointSystemLogQuery } from "../../hooks/user/queries"; +import { myStudyState } from "../../recoils/studyRecoils"; +import { ModalSubtitle } from "../../styles/layout/modal"; +import { IModal } from "../../types/components/modalTypes"; +import { IParticipation } from "../../types/models/studyTypes/studyDetails"; +import { IStudyVote } from "../../types/models/studyTypes/studyInterActions"; +import { LocationEn } from "../../types/services/locationTypes"; +import { convertLocationLangTo } from "../../utils/convertUtils/convertDatas"; +import { dayjsToStr } from "../../utils/dateTimeUtils"; +import { IFooterOptions, ModalLayout } from "../Modals"; + +interface StudySimpleVoteModalProps extends IModal { + studyVoteData: IParticipation[]; +} + +function StudySimpleVoteModal({ studyVoteData, setIsModal }: StudySimpleVoteModalProps) { + const toast = useToast(); + const searchParams = useSearchParams(); + const date = searchParams.get("date"); + const locationEn = searchParams.get("location") as LocationEn; + const location = convertLocationLangTo(locationEn, "kr"); + + const myStudy = useRecoilValue(myStudyState); + const [selectedPlace, setSelectedPlace] = useState(); + const [isFirstPage, setIsFirstPage] = useState(true); + const [myVote, setMyVote] = useState(); + const [voteTime, setVoteTime] = useState<{ start: Dayjs; end: Dayjs }>(); + + const { data: pointLog } = usePointSystemLogQuery("point", true, { + enabled: !!myStudy, + }); + const { mutate: getPoint } = usePointSystemMutation("point"); + + const { mutateAsync: openFree } = useStudyOpenFreeMutation(date, {}); + + const { mutate: patchAttend, isLoading } = useStudyParticipationMutation(dayjs(date), "post", { + onSuccess() { + handleSuccess(); + }, + }); + + useEffect(() => { + setMyVote((old) => ({ + ...old, + place: selectedPlace, + start: voteTime?.start, + end: voteTime?.end, + })); + }, [selectedPlace, voteTime]); + + const queryClient = useQueryClient(); + + const handleSuccess = async () => { + queryClient.invalidateQueries([STUDY_VOTE, date, location]); + if (myPrevVotePoint) { + await getPoint({ + message: "스터디 투표 취소", + value: -myPrevVotePoint, + }); + } + await getPoint({ + ...POINT_SYSTEM_PLUS.STUDY_VOTE_DAILY, + sub: date, + }); + toast( + "success", + `참여 완료! ${POINT_SYSTEM_PLUS.STUDY_VOTE_DAILY.value} 포인트가 적립되었습니다."}`, + ); + setIsModal(false); + }; + + const myPrevVotePoint = pointLog?.find( + (item) => item.message === "스터디 투표" && item.meta.sub === dayjsToStr(dayjs(date)), + )?.meta.value; + + const handleVote = async () => { + if (!myVote?.place || !myVote?.start || !myVote?.end) { + toast("error", "누락된 정보가 있습니다."); + return; + } + const findPlace = studyVoteData?.find((par) => par.place._id === myVote.place); + + if (findPlace.status === "dismissed") { + await openFree(myVote?.place); + setTimeout(() => { + patchAttend(myVote); + }, 500); + } else patchAttend(myVote); + }; + + const imageDataArr: IImageTileData[] = studyVoteData + ?.filter((par) => par.status === "dismissed") + .map((par) => ({ + imageUrl: par.place.image, + text: par.place.branch, + id: par.place._id, + func: () => setSelectedPlace(par.place._id), + })) + .sort((a) => (a.text === "개인 스터디" ? 1 : -1)); + + const dismissedPlaces = studyVoteData + ?.filter((par) => par.status === "dismissed") + .map((par) => par.place.branch); + + const footerOptions: IFooterOptions = { + main: { + text: isFirstPage ? "선택 완료" : "참여 신청", + func: isFirstPage ? () => setIsFirstPage(false) : handleVote, + isLoading, + }, + }; + + return ( + + + {isFirstPage ? ( + <> + + 오픈된 스터디에 참여하거나 자유 스터디로 오픈할 수 있습니다. + + + + + + + ) : ( + + )} + + + ); +} + +export default StudySimpleVoteModal; diff --git a/modals/userRequest/StudyPresetModal.tsx b/modals/userRequest/StudyPresetModal.tsx index 8a58913e2..588129e1f 100644 --- a/modals/userRequest/StudyPresetModal.tsx +++ b/modals/userRequest/StudyPresetModal.tsx @@ -39,7 +39,7 @@ function StudyPresetModal() { const { data: studyPreference } = useStudyPreferenceQuery(); - const { data: studyPlaces } = useStudyPlacesQuery(location, { + const { data: studyPlaces } = useStudyPlacesQuery(location, "active", { enabled: !!location, onSuccess(data) { if (data.length === 0) { diff --git a/pageTemplates/home/HomeStudySection.tsx b/pageTemplates/home/HomeStudySection.tsx index 42a36578e..6453f31f9 100644 --- a/pageTemplates/home/HomeStudySection.tsx +++ b/pageTemplates/home/HomeStudySection.tsx @@ -25,8 +25,6 @@ import { studyDateStatusState, } from "../../recoils/studyRecoils"; import { IParticipation, StudyStatus } from "../../types/models/studyTypes/studyDetails"; -import { StudyWaitingUser } from "../../types/models/studyTypes/studyInterActions"; -import { IUserSummary } from "../../types/models/userTypes/userInfoTypes"; import { LocationEn } from "../../types/services/locationTypes"; import { convertLocationLangTo } from "../../utils/convertUtils/convertDatas"; import { dayjsToStr } from "../../utils/dateTimeUtils"; @@ -50,7 +48,7 @@ export default function HomeStudySection() { const { data: studyVoteData, isLoading } = useStudyVoteQuery(date as string, location, { enabled: !!date && !!location, }); - + console.log(11, studyVoteData); const { mutate: decideStudyResult } = useStudyResultDecideMutation(date); useEffect(() => { @@ -61,20 +59,19 @@ export default function HomeStudySection() { } const sortedData = sortStudyVoteData(studyVoteData, studyDateStatus !== "not passed"); - const waiting = studyDateStatus === "not passed" && getWaitingSpaceProps(studyVoteData); + // const waiting = studyDateStatus === "not passed" && getWaitingSpaceProps(studyVoteData); const cardList = setStudyDataToCardCol( sortedData, date as string, session?.user.uid, - studyDateStatus === "not passed" ? waiting.map((obj) => obj.user) : null, - `${locationEn}/${date}`, + // studyDateStatus === "not passed" ? waiting.map((obj) => obj.user) : null, ); setStudyCardColData(cardList.slice(0, 3)); setSortedStudyCardList(cardList); const myStudy = getMyStudy(studyVoteData, myUid); - + console.log(5, myStudy); setMyStudy(myStudy); if (date === dayjsToStr(dayjs())) { @@ -137,42 +134,15 @@ export default function HomeStudySection() { ); } -export const getWaitingSpaceProps = (studyData: IParticipation[]) => { - const userArr: StudyWaitingUser[] = []; - - studyData.forEach((par) => { - par.attendences.forEach((who) => { - const user = who.user; - const place = { id: par.place._id, branch: par.place.branch }; - const findUser = userArr.find((obj) => obj.user.uid === user.uid); - if (!findUser) { - if (who.firstChoice) { - userArr.push({ user, place, subPlace: [], createdAt: who.createdAt }); - } else userArr.push({ user, place: null, subPlace: [place], createdAt: who.createdAt }); - } else { - if (who.firstChoice) { - findUser.place = place; // 첫 선택인 경우 place를 업데이트 - } else { - if (!findUser.subPlace.includes(place)) { - findUser.subPlace.push(place); // subPlace 배열에 place를 추가 - } - } - } - }); - }); - return userArr.sort((a, b) => (dayjs(a.createdAt).isAfter(dayjs(b.createdAt)) ? 1 : -1)); -}; + export const setStudyDataToCardCol = ( studyData: IParticipation[], urlDateParam: string, uid: string, - waitingUser?: IUserSummary[], - param?: string, ): IPostThumbnailCard[] => { const privateStudy = studyData.find((par) => par.place.brand === "자유 신청"); const filteredData = studyData.filter((par) => par.place.brand !== "자유 신청"); - const isNotPassed = !privateStudy; if (privateStudy) filteredData.splice(2, 0, privateStudy); @@ -192,22 +162,6 @@ export const setStudyDataToCardCol = ( data.status === "pending" && data.attendences.some((who) => who.user.uid === uid) && "GOOD", })); - if (isNotPassed) { - cardColData.unshift({ - title: "스터디 대기소", - subtitle: "스터디", - participants: waitingUser, - url: `/study/waiting/${param}`, - maxCnt: 8, - image: { - url: "/", - priority: true, - }, - badge: null, - type: "study", - }); - } - return cardColData; }; diff --git a/pageTemplates/home/studyController/StudyController.tsx b/pageTemplates/home/studyController/StudyController.tsx index 58821641d..65f288bc1 100644 --- a/pageTemplates/home/studyController/StudyController.tsx +++ b/pageTemplates/home/studyController/StudyController.tsx @@ -12,6 +12,7 @@ import { useStudyDailyVoteCntQuery, useStudyVoteQuery } from "../../../hooks/stu import { getStudyVoteCnt } from "../../../libs/study/getStudyVoteCnt"; import DateCalendarModal from "../../../modals/aboutHeader/DateCalendarModal"; import StudyAttendCheckModal from "../../../modals/study/StudyAttendCheckModal"; +import StudySimpleVoteModal from "../../../modals/study/StudySimpleVoteModal"; import { studyDateStatusState } from "../../../recoils/studyRecoils"; import { ActiveLocation, LocationEn } from "../../../types/services/locationTypes"; import { convertLocationLangTo } from "../../../utils/convertUtils/convertDatas"; @@ -126,6 +127,12 @@ function StudyController() { {modalType === "monthCalendar" && ( setModalType(null)} /> )} + {modalType === "todayVote" && ( + setModalType(null)} + /> + )} ); } diff --git a/pageTemplates/home/studyController/StudyControllerVoteButton.tsx b/pageTemplates/home/studyController/StudyControllerVoteButton.tsx index ed1c318a1..3a3f7a96d 100644 --- a/pageTemplates/home/studyController/StudyControllerVoteButton.tsx +++ b/pageTemplates/home/studyController/StudyControllerVoteButton.tsx @@ -54,7 +54,7 @@ function StudyControllerVoteButton({ setModalType, memberCnt }: IStudyController return; } const type = buttonProps.text; - if (type === "참여 신청" || type === "투표 변경" || type === "당일 참여") { + if (type === "참여 신청" || type === "투표 변경") { router.push(`/vote?${newSearchParams.toString()}`); return; } diff --git a/pageTemplates/study/StudyWaitingOverview.tsx b/pageTemplates/study/StudyWaitingOverview.tsx index 98d8ce134..aa5696ec8 100644 --- a/pageTemplates/study/StudyWaitingOverview.tsx +++ b/pageTemplates/study/StudyWaitingOverview.tsx @@ -2,11 +2,12 @@ import { Box, Button } from "@chakra-ui/react"; import styled from "styled-components"; import InfoBox, { InfoBoxProp } from "../../components/molecules/InfoBox"; +import { DispatchBoolean } from "../../types/hooks/reactTypes"; interface StudyWaitingOverviewProps { - title: string; + setIsModal: DispatchBoolean; } -function StudyWaitingOverview({ title }: StudyWaitingOverviewProps) { +function StudyWaitingOverview({ setIsModal }: StudyWaitingOverviewProps) { const infos: InfoBoxProp[] = [ { text: "오후 11시에 스터디 결과가 발표됩니다.", @@ -23,7 +24,12 @@ function StudyWaitingOverview({ title }: StudyWaitingOverviewProps) { - diff --git a/pageTemplates/study/StudyWaitingPlaces.tsx b/pageTemplates/study/StudyWaitingPlaces.tsx index e72201ad7..7c06dae64 100644 --- a/pageTemplates/study/StudyWaitingPlaces.tsx +++ b/pageTemplates/study/StudyWaitingPlaces.tsx @@ -16,15 +16,15 @@ function StudyWaitingPlaces({ studyWaitingPlaces }: StudyWaitingPlacesProps) { image: place.image, name: place.brand, text: place.branch, - leftComponent: - idx < 8 ? ( - - ) : ( - - ), + leftComponent: ( + + {idx < 8 ? ( + + ) : ( + + )} + + ), rightComponent: ( {par.attendences.length}명 신청중 diff --git a/pageTemplates/study/StudyWaitingUsers.tsx b/pageTemplates/study/StudyWaitingUsers.tsx index c0d866e2b..f83d6cdff 100644 --- a/pageTemplates/study/StudyWaitingUsers.tsx +++ b/pageTemplates/study/StudyWaitingUsers.tsx @@ -1,38 +1,48 @@ import { Box, Flex } from "@chakra-ui/react"; +import dayjs from "dayjs"; +import { useParams } from "next/navigation"; +import { useRecoilValue } from "recoil"; import { IProfileCommentCard } from "../../components/molecules/cards/ProfileCommentCard"; import ProfileCardColumn from "../../components/organisms/ProfileCardColumn"; import { POINT_SYSTEM_PLUS } from "../../constants/serviceConstants/pointSystemConstants"; +import { studyDateStatusState } from "../../recoils/studyRecoils"; import { StudyWaitingUser } from "../../types/models/studyTypes/studyInterActions"; interface StudyWaitingUsersProps { studyWaitingUsers: StudyWaitingUser[]; } function StudyWaitingUsers({ studyWaitingUsers }: StudyWaitingUsersProps) { + const { date } = useParams<{ location: string; date: string }>() || {}; + const studyDateStatus = useRecoilValue(studyDateStatusState); + let index = 0; const userCardArr: IProfileCommentCard[] = studyWaitingUsers.map((par, idx) => { const text = par.place.branch + " " + par.subPlace.map((place) => place.branch).join(" "); - + + const isLate = dayjs(par.createdAt).isAfter(dayjs(date).subtract(1, "day").hour(23)); + if (!isLate) index++; + return { user: par.user, comment: text, - leftComponent: - idx < 8 ? ( - - ) : ( - - ), - rightComponent: ( + leftComponent: ( + + {idx < 8 ? ( + + ) : ( + + )} + + ), + rightComponent: studyDateStatus === "not passed" && ( - + {getPoint(idx, par.subPlace.length)} POINT + + {getPoint(index - 1, isLate, par)} POINT ), }; }); - c + return ( <> {userCardArr.length ? ( @@ -61,13 +71,17 @@ function StudyWaitingUsers({ studyWaitingUsers }: StudyWaitingUsersProps) { ); } -const getPoint = (idx: number, subPlaceCnt: number) => { - let value = POINT_SYSTEM_PLUS.STUDY_VOTE.basic.value; +const getPoint = (idx: number, isLate: boolean, par: StudyWaitingUser) => { + let value = isLate ? 2 : POINT_SYSTEM_PLUS.STUDY_VOTE.basic.value; + + const subPlaceCnt = par.subPlace.length; const subCntValue = subPlaceCnt >= 5 ? 5 : subPlaceCnt; - if (idx === 0) value += POINT_SYSTEM_PLUS.STUDY_VOTE.first.value; - if (idx === 1) value += POINT_SYSTEM_PLUS.STUDY_VOTE.second.value; - if (idx === 2) value += POINT_SYSTEM_PLUS.STUDY_VOTE.third.value; + if (!isLate) { + if (idx === 0) value += POINT_SYSTEM_PLUS.STUDY_VOTE.first.value; + if (idx === 1) value += POINT_SYSTEM_PLUS.STUDY_VOTE.second.value; + if (idx === 2) value += POINT_SYSTEM_PLUS.STUDY_VOTE.third.value; + } return value + subCntValue; }; diff --git a/pages/study/waiting/[location]/[date]/index.tsx b/pages/study/waiting/[location]/[date]/index.tsx index 0f2a8c13b..1ae37a1f8 100644 --- a/pages/study/waiting/[location]/[date]/index.tsx +++ b/pages/study/waiting/[location]/[date]/index.tsx @@ -1,8 +1,9 @@ import { Box, Flex } from "@chakra-ui/react"; -import { useParams } from "next/navigation"; +import dayjs from "dayjs"; import { useSession } from "next-auth/react"; +import { useParams } from "next/navigation"; import { useEffect, useState } from "react"; -import { useRecoilState, useSetRecoilState } from "recoil"; +import { useSetRecoilState } from "recoil"; import styled from "styled-components"; import HighlightedTextButton from "../../../../../components/atoms/buttons/HighlightedTextButton"; @@ -13,7 +14,7 @@ import { useStudyVoteQuery } from "../../../../../hooks/study/queries"; import { getStudyDateStatus } from "../../../../../libs/study/date/getStudyDateStatus"; import { getMyStudy } from "../../../../../libs/study/getMyStudy"; import { sortStudyVoteData } from "../../../../../libs/study/sortStudyVoteData"; -import { getWaitingSpaceProps } from "../../../../../pageTemplates/home/HomeStudySection"; +import StudyPointGuideModal from "../../../../../modals/study/StudyPointGuideModal"; import StudyCover from "../../../../../pageTemplates/study/StudyCover"; import StudyDateBar from "../../../../../pageTemplates/study/StudyDateBar"; import StudyHeader from "../../../../../pageTemplates/study/StudyHeader"; @@ -21,6 +22,8 @@ import StudyWaitingOverview from "../../../../../pageTemplates/study/StudyWaitin import StudyWaitingPlaces from "../../../../../pageTemplates/study/StudyWaitingPlaces"; import StudyWaitingUsers from "../../../../../pageTemplates/study/StudyWaitingUsers"; import { myStudyState, studyDateStatusState } from "../../../../../recoils/studyRecoils"; +import { IParticipation } from "../../../../../types/models/studyTypes/studyDetails"; +import { StudyWaitingUser } from "../../../../../types/models/studyTypes/studyInterActions"; import { ActiveLocation } from "../../../../../types/services/locationTypes"; import { convertLocationLangTo } from "../../../../../utils/convertUtils/convertDatas"; @@ -40,7 +43,7 @@ export default function Page() { const [isHidden, setIsHidden] = useState(true); - const [studyDateStatus, setStudyDateStatus] = useRecoilState(studyDateStatusState); + const setStudyDateStatus = useSetRecoilState(studyDateStatusState); useEffect(() => { setStudyDateStatus(getStudyDateStatus(date)); @@ -55,6 +58,7 @@ export default function Page() { const sortedStudyPlaces = studyAll && sortStudyVoteData(studyAll, false); const [category, setCategory] = useState("참여 멤버"); + const [isPointModal, setIsPointModal] = useState(false); const categoryArr = ["참여 멤버", "스터디"]; @@ -65,56 +69,93 @@ export default function Page() { })); return ( - - {studyWaitingUsers && ( - <> - - - + + {studyWaitingUsers && ( + <> + + + - + - + - - - - {category === "참여 멤버" ? ( - - ) : ( - - )} - {category === "스터디" && sortedStudyPlaces.length >= 8 && ( - - setIsHidden(false)} /> - - )} - - - )} - + + + {category === "참여 멤버" ? ( + + who.place.branch !== "개인 스터디" || + (who.place.branch === "개인 스터디" && + who.user.location === + convertLocationLangTo(location as ActiveLocation, "kr")), + )} + /> + ) : ( + + )} + {category === "스터디" && sortedStudyPlaces.length >= 8 && isHidden && ( + + setIsHidden(false)} /> + + )} + + + )} + + {isPointModal && } + ); } +const getWaitingSpaceProps = (studyData: IParticipation[]) => { + const userArr: StudyWaitingUser[] = []; + + studyData.forEach((par) => { + par.attendences.forEach((who) => { + const user = who.user; + const place = { id: par.place._id, branch: par.place.branch }; + const findUser = userArr.find((obj) => obj.user.uid === user.uid); + if (!findUser) { + if (who.firstChoice) { + userArr.push({ user, place, subPlace: [], createdAt: who.createdAt }); + } else userArr.push({ user, place: null, subPlace: [place], createdAt: who.createdAt }); + } else { + if (who.firstChoice) { + findUser.place = place; + } else { + if (!findUser.subPlace.includes(place)) { + findUser.subPlace.push(place); + } + } + } + }); + }); + return userArr.sort((a, b) => (dayjs(a.createdAt).isAfter(dayjs(b.createdAt)) ? 1 : -1)); +}; + const Layout = styled.div` padding-bottom: 161px; `; diff --git a/pages/study/writing/complete.tsx b/pages/study/writing/complete.tsx index 192ce9dbc..8f6f61c02 100644 --- a/pages/study/writing/complete.tsx +++ b/pages/study/writing/complete.tsx @@ -9,7 +9,7 @@ import BottomNav from "../../../components/layouts/BottomNav"; import Header from "../../../components/layouts/Header"; import Slide from "../../../components/layouts/PageSlide"; import ProgressStatus from "../../../components/molecules/ProgressStatus"; -import { useFailToast, useToast } from "../../../hooks/custom/CustomToast"; +import { useToast } from "../../../hooks/custom/CustomToast"; import { useStudyAdditionMutation } from "../../../hooks/study/mutations"; import { useUserRequestMutation } from "../../../hooks/user/sub/request/mutations"; import RegisterLayout from "../../../pageTemplates/register/RegisterLayout"; @@ -19,7 +19,7 @@ import { sharedStudyWritingState } from "../../../recoils/sharedDataAtoms"; function WritingStudyComplete() { const { data: session } = useSession(); const router = useRouter(); - const failToast = useFailToast(); + const toast = useToast(); const studyWriting = useRecoilValue(sharedStudyWritingState); diff --git a/pages/study/writing/image.tsx b/pages/study/writing/image.tsx index 6d24f0a30..ab0355c68 100644 --- a/pages/study/writing/image.tsx +++ b/pages/study/writing/image.tsx @@ -20,7 +20,10 @@ function WritingStudyImage() { const [studyWriting, setStudyWriting] = useRecoilState(sharedStudyWritingState); - const [imageProps, setImageProps] = useState<{ mainImage: string; coverImage: string }>(null); + const [imageProps, setImageProps] = useState<{ mainImage: string; coverImage: string }>({ + mainImage: studyWriting?.image, + coverImage: studyWriting?.coverImage, + }); const onClickNext = () => { if (!imageProps?.mainImage || !imageProps?.coverImage) { diff --git a/types/models/studyTypes/studyInterActions.ts b/types/models/studyTypes/studyInterActions.ts index cdb034184..d123b5c8e 100644 --- a/types/models/studyTypes/studyInterActions.ts +++ b/types/models/studyTypes/studyInterActions.ts @@ -44,4 +44,5 @@ export interface StudyWaitingUser { place: StudyWaitingPlaceProps; subPlace: StudyWaitingPlaceProps[]; createdAt?: string; + point?: number; }