diff --git a/src/@components/@common/BestPiickleCard/LastBestPiickleCard/index.tsx b/src/@components/@common/BestPiickleCard/LastBestPiickleCard/index.tsx
new file mode 100644
index 00000000..ce0f31e1
--- /dev/null
+++ b/src/@components/@common/BestPiickleCard/LastBestPiickleCard/index.tsx
@@ -0,0 +1,20 @@
+import * as St from "./style";
+
+interface LastCardProps {
+ handleClickCard: () => void;
+}
+
+export default function LastBestPiickleCard(props: LastCardProps) {
+ const { handleClickCard } = props;
+
+ return (
+
+
+ 나머지 주제들도
+
+ 보고 싶다면?
+
+ 나머지 보기
+
+ );
+}
diff --git a/src/@components/@common/BestPiickleCard/LastBestPiickleCard/style.ts b/src/@components/@common/BestPiickleCard/LastBestPiickleCard/style.ts
new file mode 100644
index 00000000..ebfefcac
--- /dev/null
+++ b/src/@components/@common/BestPiickleCard/LastBestPiickleCard/style.ts
@@ -0,0 +1,53 @@
+import styled from "styled-components";
+
+export const LastCard = styled.div`
+ position: relative;
+
+ display: flex;
+ flex-direction: column;
+
+ width: 18rem;
+ height: 10.6rem;
+
+ border-radius: 0.4rem;
+
+ padding: 2.1rem 1.2rem 0.8rem;
+ background: ${({ theme }) => theme.newColors.white};
+
+ cursor: default;
+`;
+
+export const LastCardWButtonWrapper = styled.div`
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ margin-top: 1.2rem;
+ align-self: flex-end;
+
+ width: 6.9rem;
+ height: 2.5rem;
+
+ border-radius: 2.9rem;
+ background: ${({ theme }) => theme.newColors.green};
+
+ color: ${({ theme }) => theme.newColors.white};
+ ${({ theme }) => theme.newFonts.btn2}
+
+ cursor: pointer;
+`;
+
+export const LastCardContent = styled.p`
+ margin-top: 0.4rem;
+
+ text-align: left;
+
+ white-space: normal;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+
+ ${({ theme }) => theme.newFonts.btn1}
+ color: ${({ theme }) => theme.newColors.gray900};
+`;
diff --git a/src/@components/@common/BestPiickleCard/index.tsx b/src/@components/@common/BestPiickleCard/index.tsx
index 7a36e9bf..825f6ef0 100644
--- a/src/@components/@common/BestPiickleCard/index.tsx
+++ b/src/@components/@common/BestPiickleCard/index.tsx
@@ -1,6 +1,7 @@
import { LocationType } from "../../../types/cardCollection";
import { GTM_CLASS_NAME } from "../../../util/const/gtm";
-import useNavigateCardCollection, { NavigateCardCollectionBestType } from "../hooks/useNavigateCardCollection";
+import useNavigateCardCollection, { NavigateRecentCollectionType } from "../hooks/useNavigateCardCollection";
+import LastBestPiickleCard from "./LastBestPiickleCard";
import * as St from "./style";
interface BestPiickleCardProps {
@@ -12,24 +13,25 @@ interface BestPiickleCardProps {
idx: number;
canNavigate: boolean;
isLast?: boolean;
+ locationType: LocationType;
}
export default function BestPiickleCard(props: BestPiickleCardProps) {
- const { bestPiickle, idx, canNavigate, isLast } = props;
+ const { bestPiickle, idx, canNavigate, isLast, locationType } = props;
const { content, tags } = bestPiickle;
const GTM_IDX_KEY = `mainBestPiickle${idx + 1}`;
- const navigateCardCollection = useNavigateCardCollection(LocationType.BEST) as NavigateCardCollectionBestType;
+ const navigateCardCollection = useNavigateCardCollection(locationType) as NavigateRecentCollectionType;
- const onClickCard = () => {
+ const handleClickCard = () => {
if (!canNavigate) return;
navigateCardCollection(idx);
};
return (
-
- {isLast ? (
-
+
+ {!isLast ? (
+
{tags.map((tag: string, i: number) => {
return {tag.slice(1)};
@@ -39,14 +41,7 @@ export default function BestPiickleCard(props: BestPiickleCardProps) {
카드 보기
) : (
-
-
- 나머지 주제들도
-
- 보고 싶다면?
-
- 나머지 보기
-
+
)}
);
diff --git a/src/@components/@common/BestPiickleCard/style.ts b/src/@components/@common/BestPiickleCard/style.ts
index 82683011..20ed8e21 100644
--- a/src/@components/@common/BestPiickleCard/style.ts
+++ b/src/@components/@common/BestPiickleCard/style.ts
@@ -47,25 +47,3 @@ export const PickButtonWrapper = styled.div`
text-align: right;
`;
-
-export const LastCard = styled(BestPiickleCard)`
- display: flex;
- flex-direction: column;
-
- padding-top: 2.1rem;
- background: ${({ theme }) => theme.newColors.white};
-`;
-
-export const LastCardButton = styled.button`
- margin-top: 1.2rem;
- align-self: flex-end;
-
- width: 6.9rem;
- height: 2.5rem;
-
- border-radius: 2.9rem;
- background: ${({ theme }) => theme.newColors.green};
-
- color: ${({ theme }) => theme.newColors.white};
- ${({ theme }) => theme.newFonts.btn2}
-`;
diff --git a/src/@components/@common/hooks/useNavigateCardCollection.ts b/src/@components/@common/hooks/useNavigateCardCollection.ts
index a3d753f2..cadf0754 100644
--- a/src/@components/@common/hooks/useNavigateCardCollection.ts
+++ b/src/@components/@common/hooks/useNavigateCardCollection.ts
@@ -12,6 +12,9 @@ export type NavigateCardCollectionBookMarkType = (sliderIdx?: number) => void;
export type NavigateCardCollectionCategoryType = (categoryId: string, sliderIdx?: number) => void;
export type NavigateCardCollectionFilterType = (filterTypes: string[], sliderIdx?: number) => void;
export type NavigateCardCollectionMedleyType = (medleyId: string, sliderIdx?: number) => void;
+export type NavigateRecentCollectionType = (sliderIdx?: number) => void;
+export type NavigateFemaleCollectionType = (sliderIdx?: number) => void;
+export type NavigateMaleCollectionType = (sliderIdx?: number) => void;
export default function useNavigateCardCollection(locationType: LocationType) {
const navigate = useNavigate();
@@ -57,6 +60,22 @@ export default function useNavigateCardCollection(locationType: LocationType) {
navigate(`${routePaths.CardCollection}?type=${LocationType.MEDLEY}&medleyId=${medleyId}`);
setSliderIdx(sliderIdx);
};
+
+ case LocationType.RECENT:
+ return (sliderIdx = 0) => {
+ navigate(`${routePaths.CardCollection}?type=${LocationType.RECENT}`);
+ setSliderIdx(sliderIdx);
+ };
+ case LocationType.FEMALE:
+ return (sliderIdx = 0) => {
+ navigate(`${routePaths.CardCollection}?type=${LocationType.FEMALE}`);
+ setSliderIdx(sliderIdx);
+ };
+ case LocationType.MALE:
+ return (sliderIdx = 0) => {
+ navigate(`${routePaths.CardCollection}?type=${LocationType.MALE}`);
+ setSliderIdx(sliderIdx);
+ };
}
}
diff --git a/src/@components/BestPiicklePage/BestPiickleRank/RankItem/index.tsx b/src/@components/BestPiicklePage/BestPiickleRank/RankItem/index.tsx
index de8ad5da..df42d36b 100644
--- a/src/@components/BestPiicklePage/BestPiickleRank/RankItem/index.tsx
+++ b/src/@components/BestPiicklePage/BestPiickleRank/RankItem/index.tsx
@@ -1,40 +1,35 @@
-import { useState } from "react";
-
import IcBookmarkCheck_16_20 from "../../../../asset/icon/IcBookmarkCheck_16_20";
-import { cardCollectionApi } from "../../../../core/api/cardCollection";
import { LocationType } from "../../../../types/cardCollection";
import useNavigateCardCollection, {
NavigateCardCollectionBookMarkType,
} from "../../../@common/hooks/useNavigateCardCollection";
+import useCardBookmark from "../../../CardCollectionPage/hooks/useCardBookmark";
import * as St from "./style";
interface RankItemProps {
+ openLoginModalHandler: () => void;
cardId: string;
content: string;
rank: number;
+ isBookmark: boolean;
}
export default function RankItem(props: RankItemProps) {
- const { cardId, content, rank } = props;
+ const { cardId, content, rank, isBookmark, openLoginModalHandler } = props;
const navigateRankCollection = useNavigateCardCollection(LocationType.BEST) as NavigateCardCollectionBookMarkType;
- const [isBookmarked, setIsBookmarked] = useState(true);
- const toggleBookmark = () => {
- setIsBookmarked((prev) => !prev);
- //cardCollectionApi.addNDeleteBookmark(cardId);
- };
+ const { isBookmarked, handleClickBookmark } = useCardBookmark(isBookmark, openLoginModalHandler);
return (
- {rank}
- {content}
+ {rank + 1}
+ navigateRankCollection(rank)}>{content}
-
+ handleClickBookmark(cardId)}>
- navigateRankCollection(rank)} />
);
}
diff --git a/src/@components/BestPiicklePage/BestPiickleRank/RankItem/style.ts b/src/@components/BestPiicklePage/BestPiickleRank/RankItem/style.ts
index 9b140acb..05450098 100644
--- a/src/@components/BestPiicklePage/BestPiickleRank/RankItem/style.ts
+++ b/src/@components/BestPiicklePage/BestPiickleRank/RankItem/style.ts
@@ -14,15 +14,6 @@ export const RankItemContainer = styled.article`
height: 4.8rem;
`;
-export const RankItemLink = styled.button`
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
-
- width: 80%;
-`;
-
export const RankItemContent = styled.span`
display: flex;
flex-direction: row;
@@ -43,8 +34,10 @@ export const RankItemText = styled.p`
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
-
+
width: 26.4rem;
+
+ cursor: pointer;
`;
export const BookmarkWrapper = styled.div`
diff --git a/src/@components/BestPiicklePage/BestPiickleRank/index.tsx b/src/@components/BestPiicklePage/BestPiickleRank/index.tsx
index cecaf9a0..36128224 100644
--- a/src/@components/BestPiicklePage/BestPiickleRank/index.tsx
+++ b/src/@components/BestPiicklePage/BestPiickleRank/index.tsx
@@ -1,5 +1,12 @@
+import { LocationType } from "../../../types/cardCollection";
import { HeadingTitle } from "../../../util/main/headingTitles";
import HeadingTitleContainer from "../../@common/HeadingTitleContainer";
+import useModal from "../../@common/hooks/useModal";
+import useNavigateCardCollection, {
+ NavigateCardCollectionBookMarkType,
+} from "../../@common/hooks/useNavigateCardCollection";
+import LoginModal from "../../@common/LoginModal";
+import { useBestPiickle } from "../../MainPage/hooks/useBestPiickle";
import RankItem from "./RankItem";
import * as St from "./style";
@@ -9,21 +16,30 @@ const rankTitles: HeadingTitle = {
};
export default function BestPiickleRank() {
+ const { bestPiickle } = useBestPiickle();
+ const { isModalOpen: isLoginModalOpen, toggleModal: toggleLoginModal } = useModal();
+ const navigateRankCollection = useNavigateCardCollection(LocationType.BEST) as NavigateCardCollectionBookMarkType;
return (
- {/* todo : rankitem id 수정*/}
-
-
-
-
-
-
-
-
+ {bestPiickle &&
+ [...bestPiickle.data]
+ .slice(0, 8)
+ .map(({ _id, content, isBookmark }, idx) => (
+
+ ))}
- 이어서 베스트 피클 카드 보기
+ navigateRankCollection(8)}>이어서 베스트 피클 카드 보기
+
+ {isLoginModalOpen && }
);
}
diff --git a/src/@components/BestPiicklePage/BestPiickleRecommend/RecommendItem/index.tsx b/src/@components/BestPiicklePage/BestPiickleRecommend/RecommendItem/index.tsx
index ec9854bf..98f07dbc 100644
--- a/src/@components/BestPiicklePage/BestPiickleRecommend/RecommendItem/index.tsx
+++ b/src/@components/BestPiicklePage/BestPiickleRecommend/RecommendItem/index.tsx
@@ -1,34 +1,34 @@
import BestPiickleCard from "../../../@common/BestPiickleCard";
import useDraggingContainer from "../../../@common/hooks/useDraggingContainer";
-import { useBestPiickle } from "../../../MainPage/hooks/useBestPiickle";
+import { recommendListType } from "..";
import * as St from "./style";
interface RecommendProps {
- recommendType: string;
+ recommendList: recommendListType;
}
export default function RecommendItem(props: RecommendProps) {
- const { recommendType } = props;
- const { bestPiickle } = useBestPiickle();
+ const { recommendList } = props;
const { scrollableContainerProps, isDragging } = useDraggingContainer();
+
return (
- {recommendType}
+ {recommendList.subtitle}
- {bestPiickle && (
+ {recommendList.cards && (
- {bestPiickle &&
- bestPiickle.data.slice(0, 4).map((bestPiickle, idx) => {
- return (
-
- );
- })}
+ {recommendList.cards.slice(0, 4).map((cards, idx) => {
+ return (
+
+ );
+ })}
)}
diff --git a/src/@components/BestPiicklePage/BestPiickleRecommend/hooks/useCardsByGender.ts b/src/@components/BestPiicklePage/BestPiickleRecommend/hooks/useCardsByGender.ts
new file mode 100644
index 00000000..3d11add8
--- /dev/null
+++ b/src/@components/BestPiicklePage/BestPiickleRecommend/hooks/useCardsByGender.ts
@@ -0,0 +1,20 @@
+import useSWR from "swr";
+
+import { realReq } from "../../../../core/api/common/axios";
+import { PATH } from "../../../../core/api/common/constants";
+import { CardList } from "../../../../types/cardCollection";
+import { PiickleSWRResponse } from "../../../../types/remote/swr";
+
+export function useCardsByGender(gender: "남" | "여") {
+ const { data } = useSWR>(
+ `${PATH.CARDS_}${PATH.CARDS_GENDER}/${gender}`,
+ realReq.GET_SWR,
+ {
+ suspense: true,
+ },
+ );
+
+ return {
+ genderBookmarkedCards: data?.data.data,
+ };
+}
diff --git a/src/@components/BestPiicklePage/BestPiickleRecommend/hooks/useRecentlyBookmarked.ts b/src/@components/BestPiicklePage/BestPiickleRecommend/hooks/useRecentlyBookmarked.ts
new file mode 100644
index 00000000..a62101a4
--- /dev/null
+++ b/src/@components/BestPiicklePage/BestPiickleRecommend/hooks/useRecentlyBookmarked.ts
@@ -0,0 +1,16 @@
+import useSWR from "swr";
+
+import { realReq } from "../../../../core/api/common/axios";
+import { PATH } from "../../../../core/api/common/constants";
+import { RecentCardList } from "../../../../types/cardCollection";
+import { PiickleSWRResponse } from "../../../../types/remote/swr";
+
+export function useRecentlyBookmarked() {
+ const { data } = useSWR>(`${PATH.CARDS_}${PATH.CARDS_RECENT}`, realReq.GET_SWR, {
+ suspense: true,
+ });
+
+ return {
+ recentlyBookmarkedCards: data?.data.data.cardResponseDtos,
+ };
+}
diff --git a/src/@components/BestPiicklePage/BestPiickleRecommend/index.tsx b/src/@components/BestPiicklePage/BestPiickleRecommend/index.tsx
index fc446455..fee8b028 100644
--- a/src/@components/BestPiicklePage/BestPiickleRecommend/index.tsx
+++ b/src/@components/BestPiicklePage/BestPiickleRecommend/index.tsx
@@ -1,5 +1,8 @@
+import { CardList, LocationType } from "../../../types/cardCollection";
import { HeadingTitle } from "../../../util/main/headingTitles";
import HeadingTitleContainer from "../../@common/HeadingTitleContainer";
+import { useCardsByGender } from "./hooks/useCardsByGender";
+import { useRecentlyBookmarked } from "./hooks/useRecentlyBookmarked";
import RecommendItem from "./RecommendItem";
import * as St from "./style";
@@ -8,17 +11,41 @@ const recommendTitles: HeadingTitle = {
content: "",
};
+export type recommendListType = {
+ subtitle: string;
+ cards?: CardList[];
+ locationType: LocationType;
+};
+
export default function BestPiickleRecommend() {
+ const { recentlyBookmarkedCards } = useRecentlyBookmarked();
+ const { genderBookmarkedCards: femaleBookmarkedCards } = useCardsByGender("여");
+ const { genderBookmarkedCards: maleBookmarkedCards } = useCardsByGender("남");
+
+ const recommendLists: recommendListType[] = [
+ {
+ subtitle: "💖 유저들이 가장 최근에 북마크한 대화주제",
+ cards: recentlyBookmarkedCards,
+ locationType: LocationType.RECENT,
+ },
+ {
+ subtitle: "👩 여성이 북마크한 대화주제들",
+ cards: femaleBookmarkedCards,
+ locationType: LocationType.FEMALE,
+ },
+ {
+ subtitle: "👱♂️ 남성이 북마크한 대화주제를 확인해보세요",
+ cards: maleBookmarkedCards,
+ locationType: LocationType.MALE,
+ },
+ ];
+
return (
- {[
- "💖 유저들이 가장 최근에 북마크한 대화주제",
- "👩 여성이 북마크한 대화주제들",
- "👱♂️ 남성이 북마크한 대화주제를 확인해보세요",
- ].map((recommendType, idx) => (
-
+ {recommendLists.map((recommendList, idx) => (
+
))}
);
diff --git a/src/@components/BestPiicklePage/index.tsx b/src/@components/BestPiicklePage/index.tsx
index eef6b368..c763c210 100644
--- a/src/@components/BestPiicklePage/index.tsx
+++ b/src/@components/BestPiicklePage/index.tsx
@@ -4,7 +4,7 @@ import Header from "../@common/Header";
import SuspenseBoundary from "../@common/SuspenseBoundary";
import BestPiickleRank from "./BestPiickleRank";
import BestPiickleRecommend from "./BestPiickleRecommend";
-import St from "./style";
+import * as St from "./style";
export default function BestPiicklePage() {
return (
diff --git a/src/@components/BestPiicklePage/style.ts b/src/@components/BestPiicklePage/style.ts
index f6668530..8a70aaf9 100644
--- a/src/@components/BestPiicklePage/style.ts
+++ b/src/@components/BestPiicklePage/style.ts
@@ -1,11 +1,6 @@
import styled from "styled-components";
-const Root = styled.main`
+export const Root = styled.main`
display: flex;
flex-direction: column;
`;
-
-const St = {
- Root,
-};
-export default St;
diff --git a/src/@components/CardCollectionPage/hooks/useCardLists.ts b/src/@components/CardCollectionPage/hooks/useCardLists.ts
index d795e73a..3fac554e 100644
--- a/src/@components/CardCollectionPage/hooks/useCardLists.ts
+++ b/src/@components/CardCollectionPage/hooks/useCardLists.ts
@@ -11,6 +11,7 @@ import useCardListsFilter from "./useCardListsFilter";
interface ExtendedCardList extends Array {
cardList?: CardList[]; // with category id
cards?: CardList[]; // with medly id
+ cardResponseDtos?: CardList[];
}
export function useCardLists() {
@@ -43,6 +44,8 @@ function getReturnCardLists(
return data?.data.data.cardList;
case LocationType.MEDLEY:
return data?.data.data.cards;
+ case LocationType.RECENT:
+ return data?.data.data.cardResponseDtos;
default:
return data?.data.data;
}
@@ -88,6 +91,13 @@ function getSWRFetchingKeyByLocation(cardsTypeLocation: CardsTypeLocation) {
case LocationType.FILTER: {
return `${PATH.CATEGORIES_}${PATH.CATEGORIES_CARDS}?${cardsTypeLocation.filterTypes}`;
}
+ case LocationType.RECENT:
+ return `${PATH.CARDS_}${PATH.CARDS_RECENT}`;
+ case LocationType.FEMALE:
+ return `${PATH.CARDS_}${PATH.CARDS_GENDER}/여`;
+ case LocationType.MALE:
+ return `${PATH.CARDS_}${PATH.CARDS_GENDER}/남`;
+
case LocationType.ALL:
default: {
const searchParams = qs.stringify(
diff --git a/src/@components/MainPage/BestPiickle/index.tsx b/src/@components/MainPage/BestPiickle/index.tsx
index 17578115..84f61824 100644
--- a/src/@components/MainPage/BestPiickle/index.tsx
+++ b/src/@components/MainPage/BestPiickle/index.tsx
@@ -1,4 +1,5 @@
import { routePaths } from "../../../core/routes/path";
+import { LocationType } from "../../../types/cardCollection";
import { headingTitles } from "../../../util/main/headingTitles";
import BestPiickleCard from "../../@common/BestPiickleCard";
import HeadingTitleContainer from "../../@common/HeadingTitleContainer";
@@ -28,7 +29,7 @@ export default function BestPiickle() {
bestPiickle={bestPiickle}
idx={idx}
canNavigate={!isDragging}
- isLast={idx !== 5}
+ locationType={LocationType.BEST}
/>
);
})}
diff --git a/src/core/api/common/constants.ts b/src/core/api/common/constants.ts
index bda52959..43566117 100644
--- a/src/core/api/common/constants.ts
+++ b/src/core/api/common/constants.ts
@@ -10,6 +10,8 @@ export const PATH = {
BALLOTS: "/ballots",
CARDS_: "/cards",
CARDS_BEST: "/best",
+ CARDS_RECENT: "/recentlyBookmarkedCard",
+ CARDS_GENDER: "/cardByBookmarkedGender",
NOTICES: "/notices",
MEDLEY: "/medley",
};
diff --git a/src/types/cardCollection.ts b/src/types/cardCollection.ts
index a1e1db75..b4127f89 100644
--- a/src/types/cardCollection.ts
+++ b/src/types/cardCollection.ts
@@ -5,6 +5,9 @@ export const enum LocationType {
CATEGORY = "category",
FILTER = "filter",
MEDLEY = "medley",
+ RECENT = "recent",
+ FEMALE = "female",
+ MALE = "male",
}
interface AllTypeLocation {
@@ -33,13 +36,28 @@ interface MedleyTypeLocation {
medleyId: string;
}
+interface RecentTypeLocation {
+ type: LocationType.RECENT;
+}
+
+interface FemaleTypeLocation {
+ type: LocationType.FEMALE;
+}
+
+interface MaleTypeLocation {
+ type: LocationType.MALE;
+}
+
export type CardsTypeLocation =
| AllTypeLocation
| BestTypeLocation
| BookmarkTypeLocation
| CategoryTypeLocation
| FilterTypeLocation
- | MedleyTypeLocation;
+ | MedleyTypeLocation
+ | RecentTypeLocation
+ | FemaleTypeLocation
+ | MaleTypeLocation;
export interface CardList {
_id: string;
@@ -48,3 +66,8 @@ export interface CardList {
isBookmark: boolean;
filter: string[];
}
+
+export interface RecentCardList {
+ recentlyDate: string;
+ cardResponseDtos: CardList[];
+}