Skip to content

Commit

Permalink
feature/study-heart (#222)
Browse files Browse the repository at this point in the history
  • Loading branch information
SeungJL authored Sep 6, 2024
1 parent c9188ca commit 9fcbd4c
Show file tree
Hide file tree
Showing 12 changed files with 123 additions and 31 deletions.
69 changes: 68 additions & 1 deletion components/molecules/cards/PostThumbnailCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,16 @@ import { Box, Flex } from "@chakra-ui/react";
import dayjs from "dayjs";
import Image from "next/image";
import Link from "next/link";
import { useEffect, useState } from "react";
import styled from "styled-components";

import { STUDY_PREFERENCE_LOCAL } from "../../../constants/keys/queryKeys";
import { useToast } from "../../../hooks/custom/CustomToast";
import { useStudyPreferenceMutation } from "../../../hooks/study/mutations";
import { SingleLineText } from "../../../styles/layout/components";
import { IImageProps } from "../../../types/components/assetTypes";
import { ITextAndColorSchemes } from "../../../types/components/propTypes";
import { IStudyVotePlaces } from "../../../types/models/studyTypes/studyInterActions";
import { IUserSummary } from "../../../types/models/userTypes/userInfoTypes";
import { dayjsToFormat } from "../../../utils/dateTimeUtils";
import OutlineBadge from "../../atoms/badges/OutlineBadge";
Expand All @@ -23,8 +28,9 @@ export interface IPostThumbnailCard {
statusText?: string;
maxCnt?: number;
func?: () => void;

registerDate?: string;
isPreferPlace?: boolean;
id?: string;
}

interface IPostThumbnailCardObj {
Expand All @@ -43,8 +49,13 @@ export function PostThumbnailCard({
func = undefined,
type,
registerDate,
isPreferPlace,
id,
},
}: IPostThumbnailCardObj) {
const toast = useToast();


const userAvatarArr = participants
?.filter((par) => par)
.map((par) => ({
Expand All @@ -54,6 +65,45 @@ export function PostThumbnailCard({

const CLOSED_TEXT_ARR = ["모집 마감", "닫힘"];

const [isHeart, setIsHeart] = useState(isPreferPlace);

useEffect(() => {
setIsHeart(isPreferPlace);
}, [isPreferPlace]);

const { mutate: setStudyPreference } = useStudyPreferenceMutation({
onSuccess() {
toast("success", "변경되었습니다.");
},
});

const toggleHeart = (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
const preferenceStorage = localStorage.getItem(STUDY_PREFERENCE_LOCAL);
const savedPrefer = JSON.parse(preferenceStorage) as IStudyVotePlaces;

const newPrefer = { ...savedPrefer };
if (isHeart) {
if (savedPrefer.place === id) {
newPrefer.place = savedPrefer.subPlace?.[0];
newPrefer.subPlace = savedPrefer.subPlace.filter((sub) => sub !== newPrefer.place);
} else {
newPrefer.subPlace = savedPrefer.subPlace.filter((sub) => sub !== id);
}
} else {
if (newPrefer?.place) {
newPrefer.subPlace = [...savedPrefer.subPlace, id];
} else {
newPrefer.place = id;
}
}
setIsHeart((old) => !old);

localStorage.setItem(STUDY_PREFERENCE_LOCAL, JSON.stringify(newPrefer as IStudyVotePlaces));

setStudyPreference(newPrefer);
};

return (
<CardLink href={url} onClick={func}>
<Flex flex={1}>
Expand All @@ -72,6 +122,23 @@ export function PostThumbnailCard({
sizes="100px"
priority={image.priority}
/>
{type === "study" && (
<Box
as="button"
pos="absolute"
p={1}
bottom={-1}
right={1}
color="white"
onClick={toggleHeart}
>
{isHeart ? (
<i className="fa-solid fa-heart fa-sm" />
) : (
<i className="fa-regular fa-heart fa-sm" />
)}
</Box>
)}
</Box>
<Flex direction="column" ml="12px" flex={1}>
<Flex align="center" fontSize="16px">
Expand Down
4 changes: 2 additions & 2 deletions components/organisms/Calendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,15 +119,15 @@ function Calendar({ monthFirstDate, calendarContents }: CalendarProps) {
const isToday = false;
const contentArr = getDaySchedules(item);

console.log(5, Object.values(daySchedules));

const dateInfo = Object.values(daySchedules).map((title) => {
return contentArr?.find((c) => c.content === title);
// return contentArr[index]; // 순서를 고려하여 index에 해당하는 요소를 선택
});

endingSchedules.forEach((item) => deleteSchedule(item));
endingSchedules = [];
console.log(dateInfo);

return (
<Box
w={DAY_BLOCK_WIDTH}
Expand Down
1 change: 1 addition & 0 deletions components/organisms/CardColumnLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ interface ICardColumnLayout {
func?: () => void;
}
export function CardColumnLayout({ cardDataArr, url, func }: ICardColumnLayout) {

return (
<Layout>
{cardDataArr.map((cardData, idx) => (
Expand Down
20 changes: 18 additions & 2 deletions libs/study/sortStudyVoteData.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { IParticipation, StudyStatus } from "../../types/models/studyTypes/studyDetails";
import { IStudyVotePlaces } from "../../types/models/studyTypes/studyInterActions";

export const sortStudyVoteData = (participations: IParticipation[], isConfirmed?: boolean) => {
export const sortStudyVoteData = (
participations: IParticipation[],
preferPlaces?: IStudyVotePlaces,
isConfirmed?: boolean,
) => {
const getCount = (participation: IParticipation) => {
if (!isConfirmed) return participation.attendences.length;
return participation.attendences.filter((who) => who.firstChoice).length;
Expand All @@ -16,6 +21,13 @@ export const sortStudyVoteData = (participations: IParticipation[], isConfirmed?
}
};

const getPlacePriority = (placeId: string) => {
if (!preferPlaces) return;
if (placeId === preferPlaces.place) return 1; // main이면 가장 높은 우선순위
if (preferPlaces.subPlace.includes(placeId)) return 2; // sub 배열에 있으면 그다음 우선순위
return 3; // 그 외는 낮은 우선순위
};

const sortedData = participations
.map((par) => ({
...par,
Expand All @@ -25,8 +37,12 @@ export const sortStudyVoteData = (participations: IParticipation[], isConfirmed?
const aStatusPriority = getStatusPriority(a.status);
const bStatusPriority = getStatusPriority(b.status);
if (aStatusPriority !== bStatusPriority) return aStatusPriority - bStatusPriority;
const countDiff = getCount(b) - getCount(a);
if (countDiff !== 0) return countDiff;
const aPlacePriority = getPlacePriority(a.place._id);
const bPlacePriority = getPlacePriority(b.place._id);

return getCount(b) - getCount(a);
return aPlacePriority - bPlacePriority;
});

return isConfirmed ? sortedData : sortedData.filter((par) => par.place.brand !== "자유 신청");
Expand Down
1 change: 1 addition & 0 deletions pageTemplates/home/study/HomeNewStudySpace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ function HomeNewStudySpace({ places }: HomeNewStudySpaceProps) {
badge: { text: "신규 오픈", colorScheme: "red" },
type: "study",
registerDate: place.registerDate,
id: place._id,
}));

return (
Expand Down
26 changes: 23 additions & 3 deletions pageTemplates/home/study/HomeStudyCol.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
CardColumnLayoutSkeleton,
} from "../../../components/organisms/CardColumnLayout";
import { STUDY_CHECK_POP_UP, STUDY_VOTING_TABLE } from "../../../constants/keys/localStorage";
import { STUDY_PREFERENCE_LOCAL } from "../../../constants/keys/queryKeys";
import { LOCATION_RECRUITING, LOCATION_TO_FULLNAME } from "../../../constants/location";
import {
STUDY_DATE_START_HOUR,
Expand All @@ -29,7 +30,10 @@ import {
studyDateStatusState,
} from "../../../recoils/studyRecoils";
import { IParticipation, StudyStatus } from "../../../types/models/studyTypes/studyDetails";
import { StudyVotingSave } from "../../../types/models/studyTypes/studyInterActions";
import {
IStudyVotePlaces,
StudyVotingSave,
} from "../../../types/models/studyTypes/studyInterActions";
import { InactiveLocation, LocationEn } from "../../../types/services/locationTypes";
import { convertLocationLangTo } from "../../../utils/convertUtils/convertDatas";
import { dayjsToStr } from "../../../utils/dateTimeUtils";
Expand Down Expand Up @@ -57,15 +61,28 @@ function HomeStudyCol({ studyVoteData, isLoading }: HomeStudyColProps) {

const { mutate: decideStudyResult } = useStudyResultDecideMutation(date);

const preferenceStorage = JSON.parse(
localStorage.getItem(STUDY_PREFERENCE_LOCAL),
) as IStudyVotePlaces;

useEffect(() => {
if (!studyVoteData || !studyVoteData.length || !session?.user || !studyDateStatus) {
setMyStudy(undefined);
setStudyCardColData(null);
return;
}
const sortedData = sortStudyVoteData(studyVoteData, studyDateStatus !== "not passed");
const sortedData = sortStudyVoteData(
studyVoteData,
preferenceStorage,
studyDateStatus !== "not passed",
);

const cardList = setStudyDataToCardCol(sortedData, date as string, session?.user.uid);
const cardList = setStudyDataToCardCol(
sortedData,
date as string,
session?.user.uid,
preferenceStorage ? [preferenceStorage?.place, ...(preferenceStorage?.subPlace || [])] : [],
);

setStudyCardColData(cardList.slice(0, 3));
setSortedStudyCardList(cardList);
Expand Down Expand Up @@ -172,6 +189,7 @@ export const setStudyDataToCardCol = (
studyData: IParticipation[],
urlDateParam: string,
uid: string,
preferPlaces: string[],
): IPostThumbnailCard[] => {
const privateStudy = studyData.find((par) => par.place.brand === "자유 신청");
const filteredData = studyData.filter((par) => par.place.brand !== "자유 신청");
Expand All @@ -192,6 +210,8 @@ export const setStudyDataToCardCol = (
type: "study",
statusText:
data.status === "pending" && data.attendences.some((who) => who.user.uid === uid) && "GOOD",
isPreferPlace: preferPlaces?.includes(data.place._id),
id: data.place._id,
}));

return cardColData;
Expand Down
7 changes: 4 additions & 3 deletions pageTemplates/vote/VoteDrawer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useEffect, useState } from "react";
import BottomDrawerLg from "../../components/organisms/drawer/BottomDrawerLg";
import { STUDY_PREFERENCE_LOCAL } from "../../constants/keys/queryKeys";
import { useStudyPreferenceQuery } from "../../hooks/study/queries";
import { PreferStorageProps, StudyVoteMapActionType } from "../../pages/vote";
import { StudyVoteMapActionType } from "../../pages/vote";
import { DispatchType } from "../../types/hooks/reactTypes";
import { IParticipation, IPlace } from "../../types/models/studyTypes/studyDetails";
import {
Expand Down Expand Up @@ -34,13 +34,14 @@ function VoteDrawer({ studyVoteData, myVote, setMyVote, setActionType }: VoteDra

const { data: studyPreference } = useStudyPreferenceQuery({
enabled: !preferenceStorage,
onSuccess() {
onSuccess(data) {
localStorage.setItem(STUDY_PREFERENCE_LOCAL, JSON.stringify(data));
setMyVote(null);
},
});

const savedPrefer = preferenceStorage
? (JSON.parse(preferenceStorage) as PreferStorageProps)?.prefer
? (JSON.parse(preferenceStorage) as IStudyVotePlaces)
: studyPreference;

const savedPreferPlace: { place: IPlace; subPlace: IPlace[] } = savedPrefer && {
Expand Down
14 changes: 2 additions & 12 deletions pageTemplates/vote/voteDrawer/VoteDrawerItem.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,15 @@
import { Box, Flex } from "@chakra-ui/react";
import dayjs from "dayjs";
import styled from "styled-components";

import { STUDY_PREFERENCE_LOCAL } from "../../../constants/keys/queryKeys";
import { useToast } from "../../../hooks/custom/CustomToast";
import { useStudyPreferenceMutation } from "../../../hooks/study/mutations";
import { PreferStorageProps } from "../../../pages/vote";
import { DispatchType } from "../../../types/hooks/reactTypes";
import {
IStudyVotePlaces,
IStudyVoteWithPlace,
} from "../../../types/models/studyTypes/studyInterActions";
import { dayjsToStr } from "../../../utils/dateTimeUtils";
import { VoteDrawerItemProps as ItemProps } from "../VoteDrawer";

interface VoteDrawerItemProps {
item: ItemProps;
savedPrefer: IStudyVotePlaces;
Expand Down Expand Up @@ -97,17 +93,11 @@ function VoteDrawerItem({
}
}

localStorage.setItem(
STUDY_PREFERENCE_LOCAL,
JSON.stringify({
prefer: newPrefer,
date: dayjsToStr(dayjs()),
} as PreferStorageProps),
);
localStorage.setItem(STUDY_PREFERENCE_LOCAL, JSON.stringify(newPrefer as IStudyVotePlaces));

setStudyPreference(newPrefer);
};
console.log(item.place);

return (
<Flex
py="8px"
Expand Down
4 changes: 2 additions & 2 deletions pages/gather/[id]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ function GatherDetail() {
const isGuest = session?.user.name === "guest";

const [gather, setGather] = useState<IGather>();
console.log(gather);

const [transferGather, setTransferGather] = useRecoilState(transferGatherDataState);
const { data: gatherData } = useGatherIDQuery(+id, { enabled: !!id && !transferGather });
console.log(23, gatherData);

useEffect(() => {
if (gatherData) {
setGather(gatherData);
Expand Down
2 changes: 1 addition & 1 deletion pages/gather/[id]/setting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ function Setting() {
</Slide>
{modalType === "inviteMember" && <InviteUserModal setIsModal={() => setModalType(null)} />}
{modalType === "waitingMember" && (
<RightDrawer title="신천중인 인원" onClose={() => setModalType(null)}>
<RightDrawer title="신청중인 인원" onClose={() => setModalType(null)}>
<Flex direction="column">
{waitingMembers?.map((who, idx) => (
<ProfileCommentCard
Expand Down
2 changes: 1 addition & 1 deletion pages/study/waiting/[location]/[date]/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export default function Page() {
}, [studyAll]);

const studyWaitingUsers = studyAll && getWaitingSpaceProps(studyAll);
const sortedStudyPlaces = studyAll && sortStudyVoteData(studyAll, false);
const sortedStudyPlaces = studyAll && sortStudyVoteData(studyAll, null, false);

const [category, setCategory] = useState("참여 멤버");
const [isPointModal, setIsPointModal] = useState(false);
Expand Down
4 changes: 0 additions & 4 deletions pages/vote.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ export default function StudyVoteMap() {
enabled: !!location && !!date,
});



//메인 스터디 장소가 선택되면 3km 거리 이하의 장소들이 2지망으로 자동 선택
useEffect(() => {
if (!studyVoteData || !myVote?.place || myVote?.subPlace) return;
Expand Down Expand Up @@ -105,7 +103,6 @@ export default function StudyVoteMap() {
handleMarker={(place) => setMyVote((old) => setVotePlaceInfo(place, old))}
/>
</MapLayout>

{studyVoteData && (
<VoteDrawer
myVote={myVote}
Expand All @@ -114,7 +111,6 @@ export default function StudyVoteMap() {
setActionType={setActionType}
/>
)}

<VoteTimeDrawer
myVote={
myVote && {
Expand Down

0 comments on commit 9fcbd4c

Please sign in to comment.