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/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/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..a79658e93
--- /dev/null
+++ b/modals/study/StudyChangeMemoModal.tsx
@@ -0,0 +1,43 @@
+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 (
+
+
+ );
+}
diff --git a/modals/study/StudyInviteModal.tsx b/modals/study/StudyInviteModal.tsx
index b3026eed7..780ae026d 100644
--- a/modals/study/StudyInviteModal.tsx
+++ b/modals/study/StudyInviteModal.tsx
@@ -1,10 +1,9 @@
-import { Button, ModalFooter } from "@chakra-ui/react";
-import { useRouter } from "next/router";
+import { Button } from "@chakra-ui/react";
import { useSession } from "next-auth/react";
+import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import styled from "styled-components";
-import { SQUARE_RANDOM_IMAGE } from "../../assets/images/imageUrl";
import { WEB_URL } from "../../constants/system";
import { ModalSubtitle } from "../../styles/layout/modal";
import { IModal } from "../../types/components/modalTypes";
@@ -43,14 +42,14 @@ function StudyInviteModal({ setIsModal, place }: IStudyInviteModal) {
content: {
title: "같이 스터디 할래?",
description: place?.fullname,
- imageUrl: SQUARE_RANDOM_IMAGE[randomNum],
+ imageUrl: place.image,
link: {
mobileWebUrl: url,
webUrl: url,
},
},
address: location,
- // addressTitle: "카카오 본사",
+
buttons: [
{
title: "웹으로 이동",
@@ -68,30 +67,28 @@ function StudyInviteModal({ setIsModal, place }: IStudyInviteModal) {
const footerOptions: IFooterOptions = {
children: (
-
-
-
-
-
-
+
+
+
+
),
};
diff --git a/pageTemplates/study/StudyDateBar.tsx b/pageTemplates/study/StudyDateBar.tsx
index d78b42108..d55ba914b 100644
--- a/pageTemplates/study/StudyDateBar.tsx
+++ b/pageTemplates/study/StudyDateBar.tsx
@@ -3,15 +3,20 @@ import { faPlus } from "@fortawesome/pro-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import dayjs from "dayjs";
import { useParams } from "next/navigation";
+import { useState } from "react";
import styled from "styled-components";
+import StudyInviteModal from "../../modals/study/StudyInviteModal";
+import { IPlace } from "../../types/models/studyTypes/studyDetails";
import { dayjsToFormat } from "../../utils/dateTimeUtils";
interface IStudyDateBar {
isPrivateStudy: boolean;
+ place: IPlace;
}
-function StudyDateBar({ isPrivateStudy }: IStudyDateBar) {
+function StudyDateBar({ isPrivateStudy, place }: IStudyDateBar) {
const { date } = useParams<{ date: string }>();
+ const [isInviteModal, setIsInviteModal] = useState(false);
return (
<>
@@ -27,11 +32,13 @@ function StudyDateBar({ isPrivateStudy }: IStudyDateBar) {
rightIcon={}
padding="0 var(--gap-2)"
borderColor="var(--gray-5)"
+ onClick={() => setIsInviteModal(true)}
>
친구초대
)}
+ {isInviteModal && }
>
);
}
diff --git a/pageTemplates/study/StudyParticipants.tsx b/pageTemplates/study/StudyParticipants.tsx
index 5a53c00e7..4b01420ce 100644
--- a/pageTemplates/study/StudyParticipants.tsx
+++ b/pageTemplates/study/StudyParticipants.tsx
@@ -1,6 +1,7 @@
import { Box, Flex } from "@chakra-ui/react";
import dayjs from "dayjs";
import Image from "next/image";
+import { useSession } from "next-auth/react";
import { useState } from "react";
import Slide from "../../components/layouts/PageSlide";
@@ -8,6 +9,7 @@ import AttendanceBadge from "../../components/molecules/badge/AttendanceBadge";
import { IProfileCommentCard } from "../../components/molecules/cards/ProfileCommentCard";
import ProfileCardColumn from "../../components/organisms/ProfileCardColumn";
import ImageZoomModal from "../../modals/ImageZoomModal";
+import StudyChangeMemoModal from "../../modals/study/StudyChangeMemoModal";
import { IAttendance } from "../../types/models/studyTypes/studyDetails";
import { IAbsence } from "../../types/models/studyTypes/studyInterActions";
import { dayjsToFormat } from "../../utils/dateTimeUtils";
@@ -17,13 +19,20 @@ interface IStudyParticipants {
absences: IAbsence[];
}
export default function StudyParticipants({ participants, absences }: IStudyParticipants) {
+ const { data: session } = useSession();
+
+ const [hasModalMemo, setHasModalMemo] = useState();
const [hasImageProps, setHasImageProps] = useState<{
image: string;
toUid: string;
}>();
const userCardArr: IProfileCommentCard[] = participants.map((par) => {
- const obj = composeUserCardArr(par, absences);
+ const togglehasModalMemo =
+ par.user.uid === session?.user.uid && par.memo
+ ? (memo: string) => setHasModalMemo(memo)
+ : null;
+ const obj = composeUserCardArr(par, absences, togglehasModalMemo);
const rightComponentProps = obj.rightComponentProps;
@@ -90,6 +99,12 @@ export default function StudyParticipants({ participants, absences }: IStudyPart
setIsModal={() => setHasImageProps(null)}
/>
)}
+ {hasModalMemo && (
+ setHasModalMemo(null)}
+ />
+ )}
>
);
}
@@ -101,15 +116,22 @@ interface IReturnProps extends Omit {
};
}
-const composeUserCardArr = (participant: IAttendance, absences: IAbsence[]): IReturnProps => {
+const composeUserCardArr = (
+ participant: IAttendance,
+ absences: IAbsence[],
+ setHasModalMemo: (memo: string) => void,
+): IReturnProps => {
const arrived = participant?.arrived
? dayjsToFormat(dayjs(participant.arrived).subtract(9, "hour"), "HH:mm")
: null;
const absent = absences.find((absence) => absence.user.uid === participant.user.uid);
+ const memo = participant.memo;
+ const user = participant.user;
return {
- user: participant.user,
- comment: participant.memo || absent?.message || "",
+ user: user,
+ comment: memo || absent?.message || "",
+ setMemo: setHasModalMemo ? () => setHasModalMemo(memo) : null,
rightComponentProps:
arrived || absent
? {
diff --git a/pages/study/[id]/[date]/index.tsx b/pages/study/[id]/[date]/index.tsx
index 1e112a2bb..56f9cfbfa 100644
--- a/pages/study/[id]/[date]/index.tsx
+++ b/pages/study/[id]/[date]/index.tsx
@@ -1,5 +1,5 @@
-import { useParams } from "next/navigation";
import { useSession } from "next-auth/react";
+import { useParams } from "next/navigation";
import { useEffect } from "react";
import { useRecoilState, useSetRecoilState } from "recoil";
import styled from "styled-components";
@@ -78,7 +78,7 @@ export default function Page() {
>
)}
-
+
{!isPrivateStudy && (
)}