diff --git a/assets/images/imageUrl.ts b/assets/images/imageUrl.ts index 06824e141..b7a07f85b 100644 --- a/assets/images/imageUrl.ts +++ b/assets/images/imageUrl.ts @@ -2,17 +2,21 @@ export const CHICKEN_IMAGE = "https://user-images.githubusercontent.com/84257439/235454460-07e32553-3be0-41f2-8e3e-801c2ecdf059.png"; export const GATHER_SHARE_IMAGES = [ - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%AA%A8%EC%9E%84+%EA%B3%B5%EC%9C%A0+%EC%9D%B4%EB%AF%B8%EC%A7%80/%EC%88%A0%EC%9E%90%EB%A6%AC.jpg", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%AA%A8%EC%9E%84+%EA%B3%B5%EC%9C%A0+%EC%9D%B4%EB%AF%B8%EC%A7%80/%EB%A7%9B%EC%A7%912.jpg", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%AA%A8%EC%9E%84+%EA%B3%B5%EC%9C%A0+%EC%9D%B4%EB%AF%B8%EC%A7%80/%EB%A7%9B%EC%A7%91.jpg", "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%AA%A8%EC%9E%84+%EA%B3%B5%EC%9C%A0+%EC%9D%B4%EB%AF%B8%EC%A7%80/%EC%9D%91.jpg", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%AA%A8%EC%9E%84+%EA%B3%B5%EC%9C%A0+%EC%9D%B4%EB%AF%B8%EC%A7%80/%EB%A7%A5%EC%A3%BC.jpg", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%AA%A8%EC%9E%84+%EA%B3%B5%EC%9C%A0+%EC%9D%B4%EB%AF%B8%EC%A7%80/%EB%85%B8%ED%8A%B8%EB%B6%81+%EC%B9%B4%EA%B3%B5.jpg", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%AA%A8%EC%9E%84+%EA%B3%B5%EC%9C%A0+%EC%9D%B4%EB%AF%B8%EC%A7%80/%EC%98%81%ED%99%94.jpg", "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%AA%A8%EC%9E%84+%EA%B3%B5%EC%9C%A0+%EC%9D%B4%EB%AF%B8%EC%A7%80/%EB%94%94%EC%A0%80%ED%8A%B8.jpg", "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%AA%A8%EC%9E%84+%EA%B3%B5%EC%9C%A0+%EC%9D%B4%EB%AF%B8%EC%A7%80/%EA%B3%A0%EC%96%91%EC%9D%B4.jpg", "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%AA%A8%EC%9E%84+%EA%B3%B5%EC%9C%A0+%EC%9D%B4%EB%AF%B8%EC%A7%80/%EC%B9%9C%EA%B5%AC%EC%B0%BE%EC%95%84.jpg", "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%AA%A8%EC%9E%84+%EA%B3%B5%EC%9C%A0+%EC%9D%B4%EB%AF%B8%EC%A7%80/%EA%B2%8C%EC%9E%84.jpg", "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%AA%A8%EC%9E%84+%EA%B3%B5%EC%9C%A0+%EC%9D%B4%EB%AF%B8%EC%A7%80/%EC%98%81%ED%99%94%EA%B4%80.jpg", + "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%AA%A8%EC%9E%84+%EA%B3%B5%EC%9C%A0+%EC%9D%B4%EB%AF%B8%EC%A7%80/%EB%B3%B4%EB%93%9C%EA%B2%8C%EC%9E%84.jpg", "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EC%86%8C%EB%AA%A8%EC%9E%84/%EB%A9%94%EC%9D%B8%EC%BB%A4%EB%B2%84/%EC%B6%9C%EC%82%AC.webp", "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%B0%B0%EB%84%88/%ED%8E%AD%EA%B7%842.jpg", "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%B0%B0%EB%84%88/%ED%8E%AD%EA%B7%841.jpg", - "https://studyabout.s3.ap-northeast-2.amazonaws.com/%EB%AA%A8%EC%9E%84+%EA%B3%B5%EC%9C%A0+%EC%9D%B4%EB%AF%B8%EC%A7%80/%EB%85%B8%ED%8A%B8%EB%B6%81+%EC%B9%B4%EA%B3%B5.jpg", ]; export const DEFAULT_IMAGE_URL = diff --git a/components/molecules/NewTwoButtonRow.tsx b/components/molecules/NewTwoButtonRow.tsx index dc1cff1a8..343436f10 100644 --- a/components/molecules/NewTwoButtonRow.tsx +++ b/components/molecules/NewTwoButtonRow.tsx @@ -1,4 +1,5 @@ import { Button, Flex } from "@chakra-ui/react"; +import Link from "next/link"; import { JSXElementConstructor, ReactElement } from "react"; interface NewTwoButtonRowProps { @@ -6,12 +7,14 @@ interface NewTwoButtonRowProps { // eslint-disable-next-line @typescript-eslint/no-explicit-any icon?: ReactElement>; children?: React.ReactNode; + url: string; }; rightProps: { // eslint-disable-next-line @typescript-eslint/no-explicit-any icon?: ReactElement>; children?: React.ReactNode; isDisabled?: boolean; + func: () => void; }; } @@ -19,10 +22,10 @@ function NewTwoButtonRow({ leftProps, rightProps }: NewTwoButtonRowProps) { return ( + diff --git a/components/organisms/drawer/BottomFlexDrawer.tsx b/components/organisms/drawer/BottomFlexDrawer.tsx index e303d9433..95694fac8 100644 --- a/components/organisms/drawer/BottomFlexDrawer.tsx +++ b/components/organisms/drawer/BottomFlexDrawer.tsx @@ -49,7 +49,7 @@ export default function BottomFlexDrawer({ const [drawerHeight, setDrawerHeight] = useState(isDrawerUp ? maxHeight : DRAWER_MIN_HEIGHT); // 초기 높이 const startYRef = useRef(0); // 드래그 시작 위치 저장 const currentHeightRef = useRef(drawerHeight); // 현재 높이 저장 - + useEffect(() => { if (isDrawerUp) setDrawerHeight(maxHeight); else setDrawerHeight(DRAWER_MIN_HEIGHT); diff --git a/components/services/studyVote/StudyVoteDrawer.tsx b/components/services/studyVote/StudyPlacePickerDrawer.tsx similarity index 50% rename from components/services/studyVote/StudyVoteDrawer.tsx rename to components/services/studyVote/StudyPlacePickerDrawer.tsx index e166ad93c..ca8c0ccc2 100644 --- a/components/services/studyVote/StudyVoteDrawer.tsx +++ b/components/services/studyVote/StudyPlacePickerDrawer.tsx @@ -1,8 +1,144 @@ -function StudyVoteDrawer() { - return <>; +import { Box, Flex } from "@chakra-ui/react"; +import { useEffect, useState } from "react"; + +import { useCurrentLocation } from "../../../hooks/custom/CurrentLocationHook"; +import { setStudyToThumbnailInfo } from "../../../libs/study/setStudyToThumbnailInfo"; +import { + DEFAULT_SUB_PLACE_CNT, + RECOMMENDATION_KM, + sortByDistanceSub, + SubPlaceProps, +} from "../../../pageTemplates/vote/VoteDrawer"; +import { DispatchType } from "../../../types/hooks/reactTypes"; +import { + StudyDailyInfoProps, + StudyParticipationProps, +} from "../../../types/models/studyTypes/studyDetails"; +import { StudyThumbnailCardProps } from "../../molecules/cards/StudyThumbnailCard"; +import PickerRowButton from "../../molecules/PickerRowButton"; +import BottomFlexDrawer, { BottomFlexDrawerOptions } from "../../organisms/drawer/BottomFlexDrawer"; + +interface StudyPlacePickerDrawerProps { + studyVoteData: StudyDailyInfoProps; + setModalType: (type: "timeSelect") => void; + id: string; + + subArr: SubPlaceProps[]; + setSubArr: DispatchType; + findMyPickMainPlace: StudyParticipationProps; +} + +function StudyPlacePickerDrawer({ + setModalType, + studyVoteData, + id, + subArr, + setSubArr, + findMyPickMainPlace, +}: StudyPlacePickerDrawerProps) { + const { currentLocation } = useCurrentLocation(); + + const [defaultPlaceArr, setDefaultPlaceArr] = useState([]); + + useEffect(() => { + if (!studyVoteData) return; + const temp: SubPlaceProps[] = []; + const temp2: SubPlaceProps[] = []; + const sortedSub = sortByDistanceSub(studyVoteData, findMyPickMainPlace); + sortedSub.forEach((par, idx) => { + if (idx < DEFAULT_SUB_PLACE_CNT && par.place.distance <= RECOMMENDATION_KM) temp.push(par); + else temp2.push(par); + }); + setSubArr(temp); + setDefaultPlaceArr(temp2); + }, [studyVoteData]); + + const drawerOptions2: BottomFlexDrawerOptions = { + header: { + title: "스터디 장소 투표", + subTitle: "참여 가능한 스터디 장소를 모두 선택해 주세요¡", + }, + footer: { + text: "다 음", + func: () => setModalType("timeSelect"), + // loading: isLoading1 || isLoading2, + }, + }; + + const convertData = (data: StudyParticipationProps): StudyThumbnailCardProps => { + const isMain = id === data.place._id; + return setStudyToThumbnailInfo( + [data], + null, + isMain + ? currentLocation + : { lat: findMyPickMainPlace?.place.latitude, lon: findMyPickMainPlace?.place?.longitude }, + null, + true, + null, + null, + null, + )[0]; + }; + + return ( + <> + setModalType(null)} + drawerOptions={drawerOptions2} + > + + + setModalType(null)} + pickType="main" + /> + + {subArr?.map((props, idx) => { + const id = props.place._id; + const par = defaultPlaceArr.find((par) => par.place._id === id); + return ( + + + subArr.some((sub) => sub.place._id === id) + ? setSubArr((old) => old.filter((old) => old.place._id !== id)) + : setSubArr((old) => [...old, par]) + } + pickType="second" + isNoSelect={!subArr.some((par) => par.place._id === id)} + /> + + ); + })} + {defaultPlaceArr?.map((props, idx) => { + const id = props.place._id; + const par = defaultPlaceArr.find((par) => par.place._id === id); + return ( + + setSubArr((old) => [...old, par])} + pickType={null} + isNoSelect={!subArr.some((par) => par.place._id === id)} + /> + + ); + })} + + + + ); } -export default StudyVoteDrawer; +export default StudyPlacePickerDrawer; // import { Box } from "@chakra-ui/react"; // import dayjs from "dayjs"; @@ -17,7 +153,7 @@ export default StudyVoteDrawer; // dayjs.locale("ko"); -// interface IStudyVoteDrawer extends IModal { +// interface IStudyPlacePickerDrawer extends IModal { // imagePropsArr: { // id: string; // name: string; @@ -29,13 +165,13 @@ export default StudyVoteDrawer; // hasPlace?: boolean; // } -// export default function StudyVoteDrawer({ +// export default function StudyPlacePickerDrawer({ // setIsModal, // date, // hasPlace, // handleSubmit, // isLoading, -// }: IStudyVoteDrawer) { +// }: IStudyPlacePickerDrawer) { // // const { date, id } = useParams<{ date: string; id: string }>(); // // const router = useRouter(); diff --git a/constants/serviceConstants/pointSystemConstants.ts b/constants/serviceConstants/pointSystemConstants.ts index 163fadfff..9df1b0681 100644 --- a/constants/serviceConstants/pointSystemConstants.ts +++ b/constants/serviceConstants/pointSystemConstants.ts @@ -18,7 +18,7 @@ export const POINT_SYSTEM_PLUS = { STUDY_INVITE: { value: 2, message: "친구 초대 보너스" }, DAILY_ATTEND: { value: 2, message: "일일 출석" }, PROMOTION: { value: 100, message: "홍보 리워드" }, - LIKE: { value: 2, message: "좋아요" }, + LIKE: { value: 1, message: "좋아요" }, }; export const POINT_SYSTEM_DEPOSIT = { diff --git a/libs/study/getStudyTime.ts b/libs/study/getStudyTime.ts index dae0c6598..c90e8df32 100644 --- a/libs/study/getStudyTime.ts +++ b/libs/study/getStudyTime.ts @@ -5,8 +5,8 @@ import { dayjsToFormat } from "../../utils/dateTimeUtils"; export const getStudyTime = (users: StudyMemberProps[]): { start: string; end: string } => { if (!users) return null; - let startTime; - let endTime; + let startTime = dayjs(); + let endTime = dayjs(); users.forEach((user) => { const userStart = dayjs(user.time.start); @@ -16,6 +16,6 @@ export const getStudyTime = (users: StudyMemberProps[]): { start: string; end: s if (userStart.isBefore(startTime)) startTime = userStart; if (userEnd.isAfter(endTime)) endTime = userEnd; }); - + return { start: dayjsToFormat(startTime, "HH:mm"), end: dayjsToFormat(endTime, "HH:mm") }; }; diff --git a/modals/study/StudySimpleVoteModal.tsx b/modals/study/StudySimpleVoteModal.tsx index d15de92ae..485722046 100644 --- a/modals/study/StudySimpleVoteModal.tsx +++ b/modals/study/StudySimpleVoteModal.tsx @@ -209,8 +209,8 @@ function StudySimpleVoteModal({ studyVoteData, setIsModal }: StudySimpleVoteModa {studyDateStatus === "today" ? mainPlaceFullName || "장소를 선택해 주세요" : mainPlaceFullName - ? `${mainPlaceFullName} 외 ${myVote?.subPlace?.length + 1}곳` - : "등록된 장소가 없습니다."} + ? `${mainPlaceFullName} 외 ${myVote?.subPlace?.length + 1}곳` + : "등록된 장소가 없습니다."} - {modalType === "timeRullet" && ( - setModalType(null)} - drawerOptions={drawerOptions} - /> - )} - {alertModalInfo && ( - setAlertModalInfo(null)} - /> - )} + {isAbsentModal && } {isCancelModal && ( @@ -364,58 +279,38 @@ function StudyNavigation({ 스터디 장소를 변경해 보는 건 어떨까요? )} - {isSubVoteDrawer && ( - - - - setIsSubVoteDrawer(false)} - pickType="main" - /> - - {subArr?.map((props, idx) => { - const id = props.place._id; - const par = defaultPlaceArr.find((par) => par.place._id === id); - return ( - - - subArr.some((sub) => sub.place._id === id) - ? setSubArr((old) => old.filter((old) => old.place._id !== id)) - : setSubArr((old) => [...old, par]) - } - pickType="second" - isNoSelect={!subArr.some((par) => par.place._id === id)} - /> - - ); - })} - {defaultPlaceArr?.map((props, idx) => { - const id = props.place._id; - const par = defaultPlaceArr.find((par) => par.place._id === id); - return ( - - setSubArr((old) => [...old, par])} - pickType={null} - isNoSelect={!subArr.some((par) => par.place._id === id)} - /> - - ); - })} - - + {alertModalInfo && ( + setAlertModalInfo(null)} + /> + )} + {modalType === "placePicker" && ( + + )} + {modalType === "timeSelect" && ( + setModalType(null)} + drawerOptions={drawerOptions} + /> )} ); diff --git a/pageTemplates/studyPage/StudyInfoDrawer.tsx b/pageTemplates/studyPage/StudyInfoDrawer.tsx index 98d36ffde..c09f4d6b2 100644 --- a/pageTemplates/studyPage/StudyInfoDrawer.tsx +++ b/pageTemplates/studyPage/StudyInfoDrawer.tsx @@ -1,7 +1,6 @@ import { Box, Flex } from "@chakra-ui/react"; import dayjs from "dayjs"; import Image from "next/image"; -import Link from "next/link"; import { useRouter, useSearchParams } from "next/navigation"; import { useState } from "react"; import { useRecoilValue } from "recoil"; @@ -14,6 +13,7 @@ import NewTwoButtonRow from "../../components/molecules/NewTwoButtonRow"; import BottomFlexDrawer, { BottomFlexDrawerOptions, } from "../../components/organisms/drawer/BottomFlexDrawer"; +import StudyPlacePickerDrawer from "../../components/services/studyVote/StudyPlacePickerDrawer"; import StudyVoteTimeRulletDrawer from "../../components/services/studyVote/StudyVoteTimeRulletDrawer"; import { useResetStudyQuery } from "../../hooks/custom/CustomHooks"; import { useToast, useTypeToast } from "../../hooks/custom/CustomToast"; @@ -26,13 +26,18 @@ import { useUserInfoQuery } from "../../hooks/user/queries"; import { ModalLayout } from "../../modals/Modals"; import { myStudyParticipationState } from "../../recoils/studyRecoils"; import { DispatchType } from "../../types/hooks/reactTypes"; -import { StudyPlaceProps, StudyStatus } from "../../types/models/studyTypes/studyDetails"; +import { + StudyDailyInfoProps, + StudyPlaceProps, + StudyStatus, +} from "../../types/models/studyTypes/studyDetails"; import { IStudyVoteTime } from "../../types/models/studyTypes/studyInterActions"; import { IAvatar } from "../../types/models/userTypes/userInfoTypes"; import { PlaceInfoProps } from "../../types/models/utilTypes"; import { ActiveLocation } from "../../types/services/locationTypes"; import { convertLocationLangTo } from "../../utils/convertUtils/convertDatas"; import { dayjsToStr } from "../../utils/dateTimeUtils"; +import { SubPlaceProps } from "../vote/VoteDrawer"; export interface StudyInfoProps { id: string; @@ -60,9 +65,10 @@ interface StudyInFoDrawerProps { detailInfo: StudyInfoProps; setDetailInfo: DispatchType; date: string; + studyVoteData: StudyDailyInfoProps; } -function StudyInFoDrawer({ detailInfo, setDetailInfo, date }: StudyInFoDrawerProps) { +function StudyInFoDrawer({ detailInfo, setDetailInfo, studyVoteData, date }: StudyInFoDrawerProps) { const resetStudy = useResetStudyQuery(); const searchParams = useSearchParams(); const router = useRouter(); @@ -72,6 +78,7 @@ function StudyInFoDrawer({ detailInfo, setDetailInfo, date }: StudyInFoDrawerPro const myStudyParticipation = useRecoilValue(myStudyParticipationState); const { data: userInfo } = useUserInfoQuery({ enabled: detailInfo.status === "solo" }); + const [subArr, setSubArr] = useState([]); const { mutate: studyVote, isLoading: isLoading1 } = useStudyParticipationMutation( dayjs(), @@ -101,7 +108,8 @@ function StudyInFoDrawer({ detailInfo, setDetailInfo, date }: StudyInFoDrawerPro const [commentValue, setCommentValue] = useState(detailInfo?.comment?.text); const [commentText, setCommentText] = useState(detailInfo?.comment?.text); const [voteTime, setVoteTime] = useState(); - const [isVoteDrawer, setIsVoteDrawer] = useState(false); + + const [modalType, setModalType] = useState<"timeSelect" | "placeSelect">(); const [isAlertMoal, setIsAlertModal] = useState(false); const handleStudyActionButton = (type: "vote" | "comment" | "attend") => { @@ -111,15 +119,15 @@ function StudyInFoDrawer({ detailInfo, setDetailInfo, date }: StudyInFoDrawerPro if (type === "vote") { if (detailInfo.status === "solo") { if (userInfo?.friend?.includes(detailInfo?.firstUserUid)) { - setIsVoteDrawer(true); + setModalType("timeSelect"); } else { toast("warning", "친구로 등록된 인원만 참여 가능합니다"); } return; } - - setIsVoteDrawer(true); + if (dayjsToStr(dayjs()) === date) setModalType("timeSelect"); + else setModalType("placeSelect"); } if (type === "attend") { const isOpenStudy = detailInfo.status === "open"; @@ -134,7 +142,7 @@ function StudyInFoDrawer({ detailInfo, setDetailInfo, date }: StudyInFoDrawerPro const handleSuccess = () => { typeToast("vote"); resetStudy(); - setIsVoteDrawer(false); + setModalType(null); setDetailInfo(null); }; @@ -155,6 +163,7 @@ function StudyInFoDrawer({ detailInfo, setDetailInfo, date }: StudyInFoDrawerPro if (!detailInfo.isPrivate) { studyVote({ place: detailInfo?.id, + subPlace: subArr.map((sub) => sub.place._id), start: time?.start || voteTime?.start, end: time?.end || voteTime?.end, }); @@ -183,6 +192,9 @@ function StudyInFoDrawer({ detailInfo, setDetailInfo, date }: StudyInFoDrawerPro }, }; + const findMyPickMainPlace = studyVoteData?.participations.find( + (par) => par.place._id === detailInfo.id, + ); return ( <> ), - children: ( - - 자세히 보기 - - ), + url: `/study/${detailInfo.place._id}/${dayjsToStr( + dayjs(date), + )}?location=${convertLocationLangTo(detailInfo.location, "en")}`, + children: "자세히 보기", }} rightProps={{ icon: @@ -253,27 +262,28 @@ function StudyInFoDrawer({ detailInfo, setDetailInfo, date }: StudyInFoDrawerPro ) : ( ), - isDisabled: dayjsToStr(dayjs()) !== date, + isDisabled: dayjs().startOf("day").isAfter(dayjs(date)), + func: dayjs().startOf("day").isAfter(dayjs(date)) + ? null + : () => + handleStudyActionButton( + status === "attendance" + ? "comment" + : status === "notParticipation" + ? "vote" + : "attend", + ), children: ( -
- handleStudyActionButton( - status === "attendance" - ? "comment" - : status === "notParticipation" - ? "vote" - : "attend", - ) - } - > +
{status === "attendance" ? "한줄 코멘트 변경" : status === "notParticipation" - ? "스터디 합류" - : "스터디 출석"} + ? date === dayjsToStr(dayjs()) + ? detailInfo.participantCnt > 0 + ? "스터디 합류" + : "스터디 참여" + : "스터디 투표" + : "스터디 출석"}
), }} @@ -292,14 +302,25 @@ function StudyInFoDrawer({ detailInfo, setDetailInfo, date }: StudyInFoDrawerPro setCommentValue(e.target.value)} /> )} - {isVoteDrawer && ( + {modalType === "timeSelect" && ( setModalType(null)} zIndex={900} /> )} + {modalType === "placeSelect" && ( + + )} + {isAlertMoal && ( )} diff --git a/pageTemplates/studyPage/StudyMapTopNav.tsx b/pageTemplates/studyPage/StudyMapTopNav.tsx index 9d04513e4..c32a0b5c8 100644 --- a/pageTemplates/studyPage/StudyMapTopNav.tsx +++ b/pageTemplates/studyPage/StudyMapTopNav.tsx @@ -26,7 +26,6 @@ function StudyMapTopNav({ setCenterLocation, }: StudyMapTopNavProps) { const toast = useToast(); - const { data: userInfo } = useUserInfoQuery(); const userPlace = userInfo?.locationDetail; @@ -42,9 +41,10 @@ function StudyMapTopNav({ lat: myStudyParticipation ? latitude : userPlace?.lat, lon: myStudyParticipation ? longitude : userPlace?.lon, }; - const changeLocation = getLocationByCoordinates(lat, lon); + const changeLocation = getLocationByCoordinates(lat, lon) as ActiveLocation | null; if (changeLocation) { setLocation(changeLocation as ActiveLocation); + setCenterLocation({ lat, lon }); } }; diff --git a/pageTemplates/studyPage/studyPageDrawer/StudyPageDrawerHeader.tsx b/pageTemplates/studyPage/studyPageDrawer/StudyPageDrawerHeader.tsx index fa1932b79..f6019f891 100644 --- a/pageTemplates/studyPage/studyPageDrawer/StudyPageDrawerHeader.tsx +++ b/pageTemplates/studyPage/studyPageDrawer/StudyPageDrawerHeader.tsx @@ -1,5 +1,6 @@ import { Box, Button, Flex } from "@chakra-ui/react"; import dayjs from "dayjs"; +import { useRouter, useSearchParams } from "next/navigation"; import { useState } from "react"; import ButtonWrapper from "../../../components/atoms/ButtonWrapper"; @@ -17,11 +18,17 @@ interface StudyPageDrawerHeaderProps { function StudyPageDrawerHeader({ date, setDate, isDrawerUp }: StudyPageDrawerHeaderProps) { const [isCalendarModal, setIsCalendarModal] = useState(false); + const router = useRouter(); + const searchParams = useSearchParams(); + const newSearchParams = new URLSearchParams(searchParams); const englishDayjs = dayjs(date).locale("en"); const navigateNextDay = () => { - setDate((old) => dayjsToStr(dayjs(old).add(1, "day"))); + const newDate = dayjsToStr(dayjs(date).add(1, "day")); + setDate(newDate); + newSearchParams.set("date", newDate); + router.replace(`/studyPage?${newSearchParams.toString()}`); }; return ( diff --git a/pageTemplates/vote/VoteDrawer.tsx b/pageTemplates/vote/VoteDrawer.tsx index 0aadf4b54..cec5a7800 100644 --- a/pageTemplates/vote/VoteDrawer.tsx +++ b/pageTemplates/vote/VoteDrawer.tsx @@ -127,6 +127,7 @@ function VoteDrawer({ }); } else { //즐겨찾기 메인 장소를 투표한 경우 + if (myVote?.main === findMyPreferMainPlace?.place._id) { const findMyPreferSubPlaceArr = studyVoteData?.participations .filter((par) => preference?.subPlace.includes(par.place._id)) @@ -189,6 +190,14 @@ function VoteDrawer({ useEffect(() => { if (!myVote?.main) setIsFirstPage(true); else { + if (date !== dayjsToStr(dayjs())) { + const temp = []; + const sortedSub = sortByDistanceSub(studyVoteData, findMyPickMainPlace); + sortedSub.forEach((par) => { + if (par.place.distance <= RECOMMENDATION_KM) temp.push(par.place._id); + }); + setMyVote((old) => ({ ...old, sub: temp })); + } setCenterLocation({ lat: findMyPickMainPlace?.place?.latitude, lon: findMyPickMainPlace?.place?.longitude, @@ -346,10 +355,10 @@ function VoteDrawer({ !isFirstPage && myVote?.sub.includes(id) ? "second" : myVote?.main !== id - ? null - : isFirstPage - ? "first" - : "main" + ? null + : isFirstPage + ? "first" + : "main" } /> diff --git a/pages/admin/response/suggest.tsx b/pages/admin/response/suggest.tsx index 3d48faff5..64de4001b 100644 --- a/pages/admin/response/suggest.tsx +++ b/pages/admin/response/suggest.tsx @@ -14,7 +14,7 @@ function AdminSuggest() { const { data: data1 } = useUserRequestQuery("건의"); const { data: data2, isLoading } = useUserRequestQuery("신고"); - console.log(4, data2); + useEffect(() => { if (isLoading || !data1) return; const sortedData = [...data1, ...data2].sort((a, b) => diff --git a/pages/api/auth/[...nextauth].ts b/pages/api/auth/[...nextauth].ts index 7591588fe..c8bc2f790 100644 --- a/pages/api/auth/[...nextauth].ts +++ b/pages/api/auth/[...nextauth].ts @@ -92,7 +92,7 @@ export const authOptions: NextAuthOptions = { callbacks: { async signIn({ account, user, profile, credentials }) { try { - console.log(23); + if (account.provider === "guest") return true; if (account.provider === "credentials") return true; if (!account.access_token) return false; diff --git a/pages/api/store/index.ts b/pages/api/store/index.ts index 8653bada6..704c5e5da 100644 --- a/pages/api/store/index.ts +++ b/pages/api/store/index.ts @@ -45,7 +45,7 @@ export default async function giftController(req: NextApiRequest, res: NextApiRe const giftUsers = await GiftModel.find({}) .sort("createdAt") .select("-_id -createdAt -updatedAt -__v"); - console.log(24, giftUsers); + return res.status(200).json({ users: giftUsers }); } catch (error) { console.error(error); diff --git a/pages/group/[id]/index.tsx b/pages/group/[id]/index.tsx index 72d7962e8..302d98349 100644 --- a/pages/group/[id]/index.tsx +++ b/pages/group/[id]/index.tsx @@ -40,7 +40,7 @@ function GroupDetail() { const [group, setTransferGroup] = useRecoilState(transferGroupDataState); const { data: groupData, refetch } = useGroupIdQuery(id, { enabled: !!id && !group }); - console.log(4, groupData); + useEffect(() => { if (groupData) { setTransferGroup(groupData); diff --git a/pages/ranking/index.tsx b/pages/ranking/index.tsx index 66f492d4e..32c2b7ad7 100644 --- a/pages/ranking/index.tsx +++ b/pages/ranking/index.tsx @@ -18,14 +18,14 @@ import StatisticsFilterBar from "../../pageTemplates/ranking/StatisticsFilterBar import StatisticsMine from "../../pageTemplates/ranking/StatisticsMine"; import StatisticsTabNav from "../../pageTemplates/ranking/StatisticsTabNav"; -export type RankingCategoryProp = "주간 랭킹" | "활동 랭킹" | "스터디 랭킹" | "누적 랭킹"; +export type RankingCategoryProp = "주간 랭킹" | "월간 랭킹" | "스터디 랭킹" | "누적 랭킹"; export type RankingCategorySource = "monthScore" | "cnt" | "score" | "weekStudyAccumulationMinutes"; -const CATEGORY_ARR: RankingCategoryProp[] = ["주간 랭킹", "활동 랭킹", "스터디 랭킹", "누적 랭킹"]; +const CATEGORY_ARR: RankingCategoryProp[] = ["주간 랭킹", "월간 랭킹", "스터디 랭킹", "누적 랭킹"]; const CATEGORY_SOURCE: { [key in RankingCategoryProp]: RankingCategorySource } = { "주간 랭킹": "weekStudyAccumulationMinutes", - "활동 랭킹": "monthScore", + "월간 랭킹": "monthScore", "스터디 랭킹": "cnt", "누적 랭킹": "score", }; @@ -44,7 +44,7 @@ const CONTENT: IRuleModalContent = { { title: "카테고리 설명", texts: [ - "활동 랭킹은 이번 달 동아리 활동 점수입니다. 매달 초기화 됩니다.", + "월간 랭킹은 이번 달 동아리 활동 점수입니다. 매달 초기화 됩니다.", "스터디 랭킹은 이번 달 스터디 참여 횟수입니다. 매달 초기화 됩니다.", "누적 랭킹은 동아리 점수입니다. 등급을 나타내는 지표입니다.", ], @@ -63,13 +63,13 @@ function Ranking() { const [usersRanking, setUsersRanking] = useState({ users: [], mine: null }); const [tabValue, setTabValue] = useState<"전체 랭킹" | "내 통계">("전체 랭킹"); const [filterOptions, setFilterOptions] = useState({ - category: "주간 랭킹", + category: "월간 랭킹", isLocationFilter: false, }); const [isModal, setIsModal] = useState(false); const categorySource = CATEGORY_SOURCE[filterOptions.category]; - + const { data: attendRecords } = useUserAttendRateQuery( dayjs().startOf("month"), dayjs(), @@ -90,7 +90,7 @@ function Ranking() { enabled: !!session, }, ); - + useEffect(() => { if (filterOptions.category === "스터디 랭킹" && !attendRecords) return; diff --git a/pages/store/index.tsx b/pages/store/index.tsx index 54f599e9c..10ca8c55f 100644 --- a/pages/store/index.tsx +++ b/pages/store/index.tsx @@ -66,7 +66,6 @@ function Event() { const { data: storeGiftEntries } = useStoreGiftEntryQuery({ onError: errorToast, }); - console.log(4, storeGiftEntries); useEffect(() => { setIsPrevBoolean(isShowActive); diff --git a/pages/studyPage.tsx b/pages/studyPage.tsx index c81cfb3d6..abf9ed0ec 100644 --- a/pages/studyPage.tsx +++ b/pages/studyPage.tsx @@ -7,6 +7,7 @@ import { useRecoilState } from "recoil"; import { STUDY_MAIN_IMAGES } from "../assets/images/studyMain"; import ArrowBackButton from "../components/atoms/buttons/ArrowBackButton"; +import { MainLoadingAbsolute } from "../components/atoms/loaders/MainLoading"; import { DRAWER_MIN_HEIGHT } from "../components/organisms/drawer/BottomFlexDrawer"; import VoteMap from "../components/organisms/VoteMap"; import { USER_LOCATION } from "../constants/keys/localStorage"; @@ -82,13 +83,14 @@ export default function StudyPage() { const [isDrawerUp, setIsDrawerUp] = useState(false); const { data: userInfo } = useUserInfoQuery(); - const { data: studyVoteData } = useStudyVoteQuery(date, locationValue, { + const { data: studyVoteData, isLoading } = useStudyVoteQuery(date, locationValue, { enabled: !!locationValue && !!date, }); //초기 param 값들 설정 //locationValue와 date는 초기부터 존재 (+ useEffect의 의존 인자x) //내 스터디 투표 정보가 있는지에 따라 분류 + useEffect(() => { if (!locationValue) return; @@ -97,7 +99,7 @@ export default function StudyPage() { newSearchParams.set("date", `${getStudyViewDate(dayjs(date))}`); router.replace(`/studyPage?${newSearchParams.toString()}`); - + if (myStudyParticipation) { const lat = myStudyParticipation.place.latitude; const lon = myStudyParticipation.place.longitude; @@ -105,12 +107,14 @@ export default function StudyPage() { if (changeLocation !== locationValue) { setLocationValue(changeLocation as ActiveLocation); } + setCenterLocation({ lat: lat, lon: lon, }); } else { const locationCenter = LOCATION_CENTER_DOT[userLocation]; + setCenterLocation({ lat: locationCenter.latitude, lon: locationCenter.longitude }); } }, [myStudyParticipation]); @@ -120,14 +124,16 @@ export default function StudyPage() { let isChangeLocation = false; if (!isVoteDrawer) { const findMyStudyParticipation = getMyStudyParticipation(studyVoteData, session.user.uid); - setMyStudyParticipation(findMyStudyParticipation); - if (findMyStudyParticipation) { + + if (findMyStudyParticipation && !myStudyParticipation) { + setMyStudyParticipation(findMyStudyParticipation); const changeLocation = getLocationByCoordinates( findMyStudyParticipation.place.latitude, findMyStudyParticipation.place.longitude, ); if (!changeLocation) return; + if (changeLocation === locationValue) { setCenterLocation({ lat: findMyStudyParticipation.place.latitude, @@ -141,17 +147,26 @@ export default function StudyPage() { lon: findMyStudyParticipation.place.longitude, }); } + } else { + if (locationValue) { + const centerCoordination = LOCATION_CENTER_DOT[locationValue]; + setCenterLocation({ + lat: centerCoordination.latitude, + lon: centerCoordination.longitude, + }); + } } setIsVoteDrawerFirst(true); } if (!isChangeLocation) { + setMarkersOptions( getMarkersOptions( studyVoteData, currentLocation, isVoteDrawer ? myVote : null, - isVoteDrawer ? isVoteDrawerFirst : null, + !isVoteDrawer ? isVoteDrawerFirst : null, ), ); } @@ -163,6 +178,7 @@ export default function StudyPage() { setIsLocationRefetch(false); navigator.geolocation.getCurrentPosition( function (position) { + const lat = position.coords.latitude; const lon = position.coords.longitude; setCurrentLocation({ lat, lon }); @@ -201,7 +217,7 @@ export default function StudyPage() { if (!centerLocation || !locationValue) return; if (isVoteDrawer) return; - setMapOptions(getMapOptions(centerLocation, locationValue, centerParam === "votePlace" && 15)); + setMapOptions(getMapOptions(centerLocation, locationValue, centerParam === "votePlace" && 13)); if (voteDrawerParam === "up") { setIsDrawerUp(false); setIsVoteDrawer(true); @@ -242,7 +258,16 @@ export default function StudyPage() { {!isVoteDrawer ? ( { + newSearchParams.set("center", "locationPlace"); + newSearchParams.set( + "location", + convertLocationLangTo(location as ActiveLocation, "en"), + ); + + setLocationValue(location); + router.replace(`/studyPage?${newSearchParams.toString()}`); + }} setCenterLocation={setCenterLocation} setIsLocationFetch={setIsLocationRefetch} /> @@ -262,6 +287,7 @@ export default function StudyPage() { handleMarker={handleMarker} resizeToggle={isVoteDrawer} /> + {isLoading && } )} {detailInfo && ( - + )} ); @@ -323,54 +354,52 @@ const getMarkersOptions = ( }); } - studyVoteData.participations - .filter((par) => (myVote ? true : par.members.length >= 1)) - .forEach((par) => { - if (myVote) { - const mainPlace = studyVoteData?.participations?.find( - (par) => par.place._id === myVote?.main, - )?.place; - const placeId = par.place._id; - - const iconType = - placeId === myVote?.main - ? "main" - : onlyFirst - ? "default" - : myVote?.sub?.includes(placeId) - ? "sub" - : "default"; - - const polyline = - mainPlace && myVote?.sub?.includes(placeId) - ? getPolyline(mainPlace, par.place, myVote?.sub?.includes(placeId)) - : null; - - temp.push({ - isPicked: myVote?.main === placeId, - id: par.place._id, - position: new naver.maps.LatLng(par.place.latitude, par.place.longitude), - title: par.place.brand, - icon: { - content: getStudyVoteIcon(iconType, par.place.branch), - size: new naver.maps.Size(72, 72), - anchor: new naver.maps.Point(36, 44), - }, - type: "vote", - polyline, - }); - } else { - temp.push({ - id: par.place._id, - position: new naver.maps.LatLng(par.place.latitude, par.place.longitude), - icon: { - content: getStudyIcon(null, par.members.length), - size: new naver.maps.Size(72, 72), - anchor: new naver.maps.Point(36, 44), - }, - }); - } - }); + studyVoteData.participations.forEach((par) => { + if (myVote) { + const mainPlace = studyVoteData?.participations?.find( + (par) => par.place._id === myVote?.main, + )?.place; + const placeId = par.place._id; + + const iconType = + placeId === myVote?.main + ? "main" + : onlyFirst + ? "default" + : myVote?.sub?.includes(placeId) + ? "sub" + : "default"; + + const polyline = + mainPlace && myVote?.sub?.includes(placeId) + ? getPolyline(mainPlace, par.place, myVote?.sub?.includes(placeId)) + : null; + + temp.push({ + isPicked: myVote?.main === placeId, + id: par.place._id, + position: new naver.maps.LatLng(par.place.latitude, par.place.longitude), + title: par.place.brand, + icon: { + content: getStudyVoteIcon(iconType, par.place.branch), + size: new naver.maps.Size(72, 72), + anchor: new naver.maps.Point(36, 44), + }, + type: "vote", + polyline, + }); + } else { + temp.push({ + id: par.place._id, + position: new naver.maps.LatLng(par.place.latitude, par.place.longitude), + icon: { + content: getStudyIcon(null, par.members.length), + size: new naver.maps.Size(72, 72), + anchor: new naver.maps.Point(36, 44), + }, + }); + } + }); // if (myVote) return temp; @@ -536,11 +565,13 @@ export const getDetailInfo = ( status: findStudy.status, location: location, comment: { - user: { - uid: commentUser.uid, - avatar: commentUser.avatar, - image: commentUser.profileImage, - }, + user: commentUser + ? { + uid: commentUser.uid, + avatar: commentUser.avatar, + image: commentUser.profileImage, + } + : null, text: sortedCommentUserArr?.[0]?.comment?.text || STUDY_COMMENT_ARR[getRandomIdx(STUDY_COMMENT_ARR.length - 1)],