From 561ff52d762605bb760d1348165150a8b73a11eb Mon Sep 17 00:00:00 2001 From: seungju Date: Tue, 16 Apr 2024 23:52:56 +0900 Subject: [PATCH 01/10] fix: show study free open --- pageTemplates/home/HomeStudySection.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pageTemplates/home/HomeStudySection.tsx b/pageTemplates/home/HomeStudySection.tsx index 765b790a3..4db74c242 100644 --- a/pageTemplates/home/HomeStudySection.tsx +++ b/pageTemplates/home/HomeStudySection.tsx @@ -1,7 +1,7 @@ import dayjs from "dayjs"; import { AnimatePresence, motion, PanInfo } from "framer-motion"; -import { useRouter, useSearchParams } from "next/navigation"; import { useSession } from "next-auth/react"; +import { useRouter, useSearchParams } from "next/navigation"; import { useEffect, useState } from "react"; import { useRecoilValue, useSetRecoilState } from "recoil"; import styled from "styled-components"; @@ -53,8 +53,7 @@ export default function HomeStudySection() { useEffect(() => { if (!studyVoteData || !studyVoteData.length || !session?.user) return; - const sortedData = sortStudyVoteData(studyVoteData, studyDateStatus !== "not passed"); - + const sortedData = sortStudyVoteData(studyVoteData, studyVoteData[0].status !== "pending"); const cardList = setStudyDataToCardCol(sortedData, date as string, session?.user.uid); setStudyCardColData(cardList.slice(0, 3)); setSortedStudyCardList(cardList); From 84cecb1ee2dcff17d52296edd76d651f58e62f0f Mon Sep 17 00:00:00 2001 From: seungju Date: Wed, 17 Apr 2024 00:12:54 +0900 Subject: [PATCH 02/10] fix: resolve studyDate error at 23:00-00:00 --- libs/study/date/getStudyDateStatus.ts | 10 ++++++++-- pageTemplates/home/HomeStudySection.tsx | 3 ++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/libs/study/date/getStudyDateStatus.ts b/libs/study/date/getStudyDateStatus.ts index 8a39f49ae..63d0d0e46 100644 --- a/libs/study/date/getStudyDateStatus.ts +++ b/libs/study/date/getStudyDateStatus.ts @@ -1,7 +1,7 @@ import dayjs from "dayjs"; import { STUDY_RESULT_HOUR } from "../../../constants/serviceConstants/studyConstants/studyTimeConstant"; -import { getHour, getToday } from "../../../utils/dateTimeUtils"; +import { dayjsToStr, getHour, getToday } from "../../../utils/dateTimeUtils"; /** * today는 결과 발표난 이후부터 시간, 오늘의 스터디 @@ -16,6 +16,12 @@ export const getStudyDateStatus = (date: string) => { (currentDate.isSame(selectedDate) && currentHours < STUDY_RESULT_HOUR); if (isTodayCondition) return "today"; - if (selectedDate.isBefore(currentDate)) return "passed"; + if ( + (dayjsToStr(selectedDate) === dayjsToStr(currentDate) && currentHours >= STUDY_RESULT_HOUR) || + selectedDate.isBefore(currentDate) + ) { + return "passed"; + } + return "not passed"; }; diff --git a/pageTemplates/home/HomeStudySection.tsx b/pageTemplates/home/HomeStudySection.tsx index 4db74c242..61c548dce 100644 --- a/pageTemplates/home/HomeStudySection.tsx +++ b/pageTemplates/home/HomeStudySection.tsx @@ -53,7 +53,8 @@ export default function HomeStudySection() { useEffect(() => { if (!studyVoteData || !studyVoteData.length || !session?.user) return; - const sortedData = sortStudyVoteData(studyVoteData, studyVoteData[0].status !== "pending"); + const sortedData = sortStudyVoteData(studyVoteData, studyDateStatus !== "not passed"); + const cardList = setStudyDataToCardCol(sortedData, date as string, session?.user.uid); setStudyCardColData(cardList.slice(0, 3)); setSortedStudyCardList(cardList); From f847947a347c820bf19786ed1f822f3fc255c820 Mon Sep 17 00:00:00 2001 From: seungju Date: Wed, 17 Apr 2024 01:15:40 +0900 Subject: [PATCH 03/10] feat: add UI and modal for editing study memo --- .../molecules/cards/ProfileCommentCard.tsx | 27 +++++++++++- components/organisms/ProfileCardColumn.tsx | 1 + hooks/study/mutations.ts | 4 +- modals/Modals.tsx | 2 + modals/study/StudyAttendCheckModal.tsx | 3 +- modals/study/StudyChangeMemoModal.tsx | 42 +++++++++++++++++++ pageTemplates/study/StudyParticipants.tsx | 30 +++++++++++-- 7 files changed, 99 insertions(+), 10 deletions(-) create mode 100644 modals/study/StudyChangeMemoModal.tsx diff --git a/components/molecules/cards/ProfileCommentCard.tsx b/components/molecules/cards/ProfileCommentCard.tsx index 3add80b86..506ee4811 100644 --- a/components/molecules/cards/ProfileCommentCard.tsx +++ b/components/molecules/cards/ProfileCommentCard.tsx @@ -1,3 +1,6 @@ +import { Flex } from "@chakra-ui/react"; +import { faPenToSquare } from "@fortawesome/pro-regular-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import styled from "styled-components"; import { IUserSummary } from "../../../types/models/userTypes/userInfoTypes"; @@ -8,9 +11,15 @@ export interface IProfileCommentCard { user: IUserSummary; comment?: string; rightComponent?: React.ReactNode; + setMemo?: () => void; } -export default function ProfileCommentCard({ user, comment, rightComponent }: IProfileCommentCard) { +export default function ProfileCommentCard({ + user, + comment, + rightComponent, + setMemo, +}: IProfileCommentCard) { return ( @@ -19,13 +28,27 @@ export default function ProfileCommentCard({ user, comment, rightComponent }: IP {user.name} - {comment !== null ? comment : user.comment} + + {comment !== null ? comment : user.comment} + {setMemo && ( + + )} + {rightComponent} ); } +const Button = styled.button` + display: inline-block; + margin-left: 4px; + padding: 0 4px; + color: var(--gray-3); +`; + const CardContainer = styled.div` display: flex; align-items: center; diff --git a/components/organisms/ProfileCardColumn.tsx b/components/organisms/ProfileCardColumn.tsx index 34d6064ce..44509e381 100644 --- a/components/organisms/ProfileCardColumn.tsx +++ b/components/organisms/ProfileCardColumn.tsx @@ -12,6 +12,7 @@ export default function ProfileCardColumn({ userCardArr }: IProfileCardColumn) { key={idx} user={userCard.user} comment={userCard?.comment} + setMemo={userCard?.setMemo} rightComponent={userCard?.rightComponent} /> ))} diff --git a/hooks/study/mutations.ts b/hooks/study/mutations.ts index b8bf02f53..cab519916 100644 --- a/hooks/study/mutations.ts +++ b/hooks/study/mutations.ts @@ -67,12 +67,12 @@ export const useStudyOpenFreeMutation = (date: string, options?: MutationOptions options, ); -export const useStudyAttendCheckMutation = (date: Dayjs, options?: MutationOptions) => +export const useStudyAttendCheckMutation = (date: string, options?: MutationOptions) => useMutation( (memo) => requestServer<{ memo: string }>({ method: "patch", - url: `vote/${dayjsToStr(date)}/arrived`, + url: `vote/${date}/arrived`, body: { memo }, }), options, diff --git a/modals/Modals.tsx b/modals/Modals.tsx index be896ad47..5a0afee06 100644 --- a/modals/Modals.tsx +++ b/modals/Modals.tsx @@ -24,6 +24,7 @@ export interface IFooterOptions { text?: string; func?: () => void; isRedTheme?: boolean; + isLoading?: boolean; }; sub?: { text?: string; @@ -125,6 +126,7 @@ export function ModalLayout({ colorScheme={main?.isRedTheme ? "redTheme" : "mintTheme"} w="100%" onClick={func} + isLoading={main?.isLoading} > {text} diff --git a/modals/study/StudyAttendCheckModal.tsx b/modals/study/StudyAttendCheckModal.tsx index d529e703c..00f9e39bf 100644 --- a/modals/study/StudyAttendCheckModal.tsx +++ b/modals/study/StudyAttendCheckModal.tsx @@ -29,7 +29,6 @@ import { ModalSubtitle } from "../../styles/layout/modal"; import { IModal } from "../../types/components/modalTypes"; import { LocationEn } from "../../types/services/locationTypes"; import { convertLocationLangTo } from "../../utils/convertUtils/convertDatas"; -import { now } from "../../utils/dateTimeUtils"; import { IFooterOptions, ModalLayout } from "../Modals"; const LOCATE_GAP = 0.00008; @@ -69,7 +68,7 @@ function StudyAttendCheckModal({ setIsModal }: IStudyAttendCheckModal) { const { mutate: getAlphabet } = useAlphabetMutation("get"); const { mutate: getDeposit } = usePointSystemMutation("deposit"); - const { mutate: handleArrived } = useStudyAttendCheckMutation(now().startOf("day"), { + const { mutate: handleArrived } = useStudyAttendCheckMutation(date, { onSuccess() { queryClient.invalidateQueries([STUDY_VOTE, date, location]); const alphabet = getRandomAlphabet(20); diff --git a/modals/study/StudyChangeMemoModal.tsx b/modals/study/StudyChangeMemoModal.tsx new file mode 100644 index 000000000..62f7dea69 --- /dev/null +++ b/modals/study/StudyChangeMemoModal.tsx @@ -0,0 +1,42 @@ +import { useParams } from "next/navigation"; +import { useState } from "react"; +import { useQueryClient } from "react-query"; +import Textarea from "../../components/atoms/Textarea"; +import { STUDY_VOTE } from "../../constants/keys/queryKeys"; +import { PLACE_TO_LOCATION } from "../../constants/serviceConstants/studyConstants/studyLocationConstants"; +import { useStudyAttendCheckMutation } from "../../hooks/study/mutations"; +import { IModal } from "../../types/components/modalTypes"; +import { IFooterOptions, ModalLayout } from "../Modals"; + +interface IStudyChangeMemoModal extends IModal { + hasModalMemo; +} +export default function StudyChangeMemoModal({ hasModalMemo, setIsModal }: IStudyChangeMemoModal) { + const { id, date } = useParams<{ id: string; date: string }>() || {}; + const location = PLACE_TO_LOCATION[id]; + + const [value, setValue] = useState(hasModalMemo); + + const queryClient = useQueryClient(); + + const { mutate: changeStudyMemo, isLoading } = useStudyAttendCheckMutation(date, { + onSuccess() { + queryClient.invalidateQueries([STUDY_VOTE, date, location]); + setIsModal(true); + }, + }); + + const footerOptions: IFooterOptions = { + main: { + text: "변경", + func: () => changeStudyMemo(value), + isLoading, + }, + }; + + return ( + +