From 4467a90e8fd937d1d0ac212156260cef7c190b84 Mon Sep 17 00:00:00 2001 From: HiHoi Date: Thu, 15 Feb 2024 14:33:00 +0900 Subject: [PATCH 1/3] fix: design change --- src/app/showcase/page.tsx | 19 ++- src/app/showcase/panel/CardContainer.style.ts | 8 +- src/app/showcase/panel/CardContainer.tsx | 46 +++++- src/app/showcase/panel/CardStack.tsx | 12 +- src/app/showcase/panel/PhoneFrame.tsx | 13 +- src/app/showcase/panel/PostCard.style.ts | 16 +++ src/app/showcase/panel/PostCard.tsx | 23 +-- src/app/showcase/panel/ShowcaseCard.style.ts | 40 ++---- src/app/showcase/panel/ShowcaseCard.tsx | 136 ++++++++++-------- src/states/useShowcaseCardStore.tsx | 60 ++++++++ 10 files changed, 253 insertions(+), 120 deletions(-) create mode 100644 src/states/useShowcaseCardStore.tsx diff --git a/src/app/showcase/page.tsx b/src/app/showcase/page.tsx index c99bd72a1..c1f1712a1 100644 --- a/src/app/showcase/page.tsx +++ b/src/app/showcase/page.tsx @@ -17,7 +17,7 @@ const Showcase = () => { const [page, setPage] = useState(1) const [cardList, setCardList] = useState>([]) const [draggedCardList, setDraggedCardList] = useState([]) - const { isPc } = useMedia() + const { isPc, isTablet } = useMedia() const { isLogin } = useAuthStore() const axiosWithAuth = useAxiosWithAuth() const { data, isLoading, error } = useSWR>( @@ -85,7 +85,7 @@ const Showcase = () => { else if (isLoading && !cardList.length) message = '로딩중' else if (error) message = '에러 발생' - if (isPc) { + if (isPc && !isTablet) { return ( { ) } + + if (isTablet) { + return ( + + + + ) + } + return ( removeCard: (recruit_id: number) => void message: string addCard?: () => void + addDisabled?: boolean }) => { - const { isPc } = useMedia() + const { isPc, isTablet } = useMedia() return ( {!message ? ( @@ -62,6 +67,35 @@ const CardContainer = ({ {message} )} + + {isTablet && isPc && ( + + + + )} + {isTablet && isPc && ( + removeCard(cardList[cardList.length - 1]?.id)} + disabled={cardList.length === 1} + > + + + )} + ) } diff --git a/src/app/showcase/panel/CardStack.tsx b/src/app/showcase/panel/CardStack.tsx index 4e85477e9..3ebc4a2e8 100644 --- a/src/app/showcase/panel/CardStack.tsx +++ b/src/app/showcase/panel/CardStack.tsx @@ -4,7 +4,6 @@ import { Box } from '@mui/material' import React, { useState } from 'react' import { motion, AnimatePresence } from 'framer-motion' import * as style from './ShowcaseCard.style' -import useMedia from '@/hook/useMedia' import { ICardData } from '@/app/showcase/panel/types' import { ShowcaseCard } from './ShowcaseCard' @@ -25,7 +24,6 @@ const CardStack = ({ addCard?: () => void }) => { const [dragged, setDragged] = useState(false) - const { isPc } = useMedia() const checkDragDirection = (x: number, y: number) => { return y < 0 ? ESwipeDirection.up : ESwipeDirection.down @@ -51,10 +49,7 @@ const CardStack = ({ return ( <> - + 1 ? 1 : 0, @@ -65,7 +60,7 @@ const CardStack = ({ > @@ -80,7 +75,7 @@ const CardStack = ({ > @@ -122,7 +117,6 @@ const CardStack = ({ > diff --git a/src/app/showcase/panel/PhoneFrame.tsx b/src/app/showcase/panel/PhoneFrame.tsx index 9164633ad..7d8f7987c 100644 --- a/src/app/showcase/panel/PhoneFrame.tsx +++ b/src/app/showcase/panel/PhoneFrame.tsx @@ -6,11 +6,13 @@ const PhoneFrame = ({ imageUrl }: { imageUrl: string | undefined }) => { { src={imageUrl} sx={{ width: '16rem', - height: '40rem', + height: '20rem', objectFit: 'contain', }} /> @@ -32,8 +34,9 @@ const PhoneFrame = ({ imageUrl }: { imageUrl: string | undefined }) => { {}) }, [setFavorite, axiosWithAuth]) const clickLike = useCallback(() => { @@ -78,6 +79,7 @@ function PostCard({ } } }) + .catch(() => {}) }, [setIsLiked, setLikeNum, axiosWithAuth]) return ( @@ -89,17 +91,15 @@ function PostCard({ backfaceVisibility: 'hidden', }} ref={ref} - onClick={onClick} > - + + + + { + const [lineCount, setLineCount] = useState({ + title: 1, + content: 1, + }) const router = useRouter() - const { isPc } = useMedia() + const card = useRef(null) const [currentPageUrl, setCurrentPageUrl] = useState('') - //window is not defined 에러 방지 + useEffect(() => { + setLineCount({ + title: getLineCount(46, 22.5, 2), + content: getLineCount(191, 18, 8), + }) + }, [card]) + useEffect(() => { setCurrentPageUrl(window.location.href) + + const handleResize = () => { + if (card.current) { + setLineCount({ + title: getLineCount(46, 22.5, 2), + content: getLineCount(191, 18, 8), + }) + } + } + + window.addEventListener('resize', handleResize) + return () => { + window.removeEventListener('resize', handleResize) + } }, []) - const getLineCount = (originHeight: number, lineHeight: number) => { - const lineCount = Math.floor((cardWidth * originHeight) / 328 / lineHeight) - return lineCount ? lineCount : 1 + const getLineCount = ( + originHeight: number, + lineHeight: number, + maxLine: number, + ) => { + const removeCount = card.current?.clientHeight ?? 0 < 441 ? 2 : 1 + const lineCount = Math.floor( + ((card.current?.clientHeight ?? 0) * originHeight) / lineHeight / 441, + ) + if (lineCount > maxLine) return maxLine + else if (lineCount < 1 + removeCount) return 1 + else return lineCount - removeCount } const handleSeeAll = (e: React.MouseEvent) => { @@ -71,6 +103,7 @@ const ShowcaseCardBack = ({ backfaceVisibility: 'hidden', padding: '1rem', }} + ref={card} > {content ? ( @@ -118,10 +151,7 @@ const ShowcaseCardBack = ({ color={'text.normal'} sx={{ ...style.cardTitleStyleBase, - height: isPc ? '46px' : getLineCount(46, 22.5) * 22.5, - WebkitLineClamp: isPc - ? 2 - : getLineCount(46, 22.5) /* 라인수 */, + WebkitLineClamp: lineCount.title, }} > {title} @@ -137,30 +167,38 @@ const ShowcaseCardBack = ({ }} onClick={onClick} > - - {content.split('\n').map((line) => { - return ( - <> - {line} -
- - ) - })} -
+ + h1:first-of-type': { + marginTop: 0, + }, + '.toastui-editor-contents h1': { + paddingBottom: 0, + }, + '.toastui-editor-contents h2': { + paddingBottom: 0, + }, + }} + /> +
@@ -199,7 +237,6 @@ const ShowcaseCard = ({ data, dragged, setDragged, - sx, }: { data: ICardData sx?: SxProps @@ -207,30 +244,11 @@ const ShowcaseCard = ({ setDragged: React.Dispatch> }) => { const [isFlipped, setIsFlipped] = useState(false) - const [cardWidth, setCardWidth] = useState(0) const [currentDomain, setCurrentDomain] = useState('') - const { isPc } = useMedia() useEffect(() => { // 현재 도메인 설정 setCurrentDomain(window.location.origin) - - // 카드 너비 설정 - setCardWidth( - isPc ? window.innerWidth * 0.9 : (window.innerHeight * 0.8 * 328) / 800, - ) - const handleResize = () => { - const newCardWidth = isPc - ? window.innerWidth * 0.9 - : (window.innerHeight * 0.8 * 328) / 800 - setCardWidth(newCardWidth) - } - - window.addEventListener('resize', handleResize) - - return () => { - window.removeEventListener('resize', handleResize) - } }, []) const handleMouseUp = (e: React.MouseEvent) => { @@ -262,23 +280,21 @@ const ShowcaseCard = ({ like={data.like} liked={data.liked} sx={{ - ...sx, + ...style.cardStyleBase, backfaceVisibility: 'hidden', transform: 'translate(-50%, 0)', - width: isPc ? '90%' : '90vw', }} onClick={handleMouseUp} /> diff --git a/src/states/useShowcaseCardStore.tsx b/src/states/useShowcaseCardStore.tsx new file mode 100644 index 000000000..a0b2269ff --- /dev/null +++ b/src/states/useShowcaseCardStore.tsx @@ -0,0 +1,60 @@ +import { ICardData } from '@/app/showcase/panel/types' +import { create } from 'zustand' + +import axios from 'axios' + +interface IShowcaseStore { + showcases: ICardData[] + draggedCardList: ICardData[] + page: number + index: number + setShowcases: (showcases: ICardData[]) => void + setDraggedCardList: (draggedCardList: ICardData[]) => void + getShowcases: (page: number) => void + removeShowcase: () => void + nextShowcase: () => void + prevShowcase: () => void + resetShowcases: () => void +} + +const useShowcaseStore = create((set, get) => { + return { + showcases: [], + draggedCardList: [], + page: 1, + index: 0, + setShowcases: (showcases: ICardData[]) => { + set(() => ({ showcases: showcases })) + }, + setDraggedCardList: (draggedCardList: ICardData[]) => { + set(() => ({ draggedCardList: draggedCardList })) + }, + + getShowcases: (page: number) => { + axios + .get( + `${process.env.NEXT_PUBLIC_CSR_API}/api/v1/showcase?page=${page}&pageSize=10`, + ) + .then((res) => { + const oldShowcases = get().showcases + const newShowcases = [...oldShowcases] + .reverse() + .concat(res.data.content) + set(() => ({ showcases: newShowcases, page: page })) + }) + }, + + removeShowcase: () => { + const oldShowcases = get().showcases + const oldLength = oldShowcases.length + if (oldShowcases.length > 1) { + oldShowcases.push(oldShowcases[oldLength - 1]) + } + }, + nextShowcase: () => {}, + prevShowcase: () => {}, + resetShowcases: () => {}, + } +}) + +export default useShowcaseStore From 2f4c3941e6176223a5f3519effc134e133614550 Mon Sep 17 00:00:00 2001 From: HiHoi Date: Thu, 15 Feb 2024 15:18:29 +0900 Subject: [PATCH 2/3] fix: like and favorite function --- src/app/showcase/page.tsx | 2 + src/app/showcase/panel/CardContainer.tsx | 5 +- src/app/showcase/panel/CardStack.tsx | 5 +- src/app/showcase/panel/PostCard.tsx | 59 +++++++++++++++++++----- src/app/showcase/panel/ShowcaseCard.tsx | 11 ++++- src/types/IPostCard.ts | 4 +- 6 files changed, 71 insertions(+), 15 deletions(-) diff --git a/src/app/showcase/page.tsx b/src/app/showcase/page.tsx index c1f1712a1..640cbd5c0 100644 --- a/src/app/showcase/page.tsx +++ b/src/app/showcase/page.tsx @@ -107,6 +107,7 @@ const Showcase = () => { message={message} addCard={addCard} addDisabled={draggedCardList.length === 0} + mutate={setCardList} /> ) @@ -118,6 +119,7 @@ const Showcase = () => { removeCard={removeCard} message={message} addCard={addCard} + mutate={setCardList} /> ) } diff --git a/src/app/showcase/panel/CardContainer.tsx b/src/app/showcase/panel/CardContainer.tsx index 8a06f381a..aa9022b36 100644 --- a/src/app/showcase/panel/CardContainer.tsx +++ b/src/app/showcase/panel/CardContainer.tsx @@ -1,6 +1,6 @@ 'use client' -import React from 'react' +import React, { Dispatch, SetStateAction } from 'react' import useMedia from '@/hook/useMedia' import { IconButton, Stack, Typography } from '@mui/material' import * as containerStyle from './CardContainer.style' @@ -16,12 +16,14 @@ const CardContainer = ({ message, addCard, addDisabled, + mutate, }: { cardList: Array removeCard: (recruit_id: number) => void message: string addCard?: () => void addDisabled?: boolean + mutate: Dispatch> }) => { const { isPc, isTablet } = useMedia() return ( @@ -62,6 +64,7 @@ const CardContainer = ({ cardList={cardList} removeCard={removeCard} addCard={addCard} + mutate={mutate} /> ) : ( {message} diff --git a/src/app/showcase/panel/CardStack.tsx b/src/app/showcase/panel/CardStack.tsx index 3ebc4a2e8..af6c81b07 100644 --- a/src/app/showcase/panel/CardStack.tsx +++ b/src/app/showcase/panel/CardStack.tsx @@ -1,7 +1,7 @@ 'use client' import { Box } from '@mui/material' -import React, { useState } from 'react' +import React, { Dispatch, SetStateAction, useState } from 'react' import { motion, AnimatePresence } from 'framer-motion' import * as style from './ShowcaseCard.style' import { ICardData } from '@/app/showcase/panel/types' @@ -18,10 +18,12 @@ const CardStack = ({ cardList, removeCard, addCard, + mutate, }: { cardList: Array removeCard: (recruit_id: number) => void addCard?: () => void + mutate: Dispatch> }) => { const [dragged, setDragged] = useState(false) @@ -119,6 +121,7 @@ const CardStack = ({ data={card} dragged={dragged} setDragged={setDragged} + mutate={mutate} />
) diff --git a/src/app/showcase/panel/PostCard.tsx b/src/app/showcase/panel/PostCard.tsx index 1a8372e46..e577199b1 100644 --- a/src/app/showcase/panel/PostCard.tsx +++ b/src/app/showcase/panel/PostCard.tsx @@ -31,14 +31,21 @@ function PostCard({ liked, isFavorite, onClick, + mutate, }: IPostCardShowcase) { const ref = React.useRef(null) const [currentCardWidth, setCurrentCardWidth] = useState(0) - const [favorite, setFavorite] = useState(isFavorite) - const [likeNum, setLikeNum] = useState(like) - const [isLiked, setIsLiked] = useState(liked) + const [favorite, setFavorite] = useState(false) + const [likeNum, setLikeNum] = useState(0) + const [isLiked, setIsLiked] = useState(false) const axiosWithAuth = useAxiosWithAuth() + useEffect(() => { + setFavorite(isFavorite) + setLikeNum(like) + setIsLiked(liked) + }, [like, liked, isFavorite]) + useEffect(() => { if (ref.current) { setCurrentCardWidth(ref.current.clientWidth) @@ -59,28 +66,58 @@ function PostCard({ ) .then((res) => { if (res.status === 200) { - setFavorite(!favorite) + mutate((prev) => { + return prev.map((card) => { + if (card.id === postId) { + return { + ...card, + favorite: !favorite, + } + } + return card + }) + }) } }) .catch(() => {}) - }, [setFavorite, axiosWithAuth]) + }, [favorite, setFavorite, mutate]) const clickLike = useCallback(() => { axiosWithAuth .post(`${process.env.NEXT_PUBLIC_CSR_API}/api/v1/showcase/like/${postId}`) .then((res) => { if (res.status === 200) { - if (liked === false) { - setIsLiked(true) - setLikeNum(likeNum + 1) + if (isLiked === false) { + mutate((prev) => { + return prev.map((card) => { + if (card.id === postId) { + return { + ...card, + like: likeNum + 1, + liked: !isLiked, + } + } + return card + }) + }) } else { - setIsLiked(false) - setLikeNum(likeNum - 1) + mutate((prev) => { + return prev.map((card) => { + if (card.id === postId) { + return { + ...card, + like: likeNum - 1, + liked: !isLiked, + } + } + return card + }) + }) } } }) .catch(() => {}) - }, [setIsLiked, setLikeNum, axiosWithAuth]) + }, [isLiked, likeNum, setLikeNum, setIsLiked]) return ( > + mutate: Dispatch> }) => { const [isFlipped, setIsFlipped] = useState(false) const [currentDomain, setCurrentDomain] = useState('') @@ -285,6 +293,7 @@ const ShowcaseCard = ({ transform: 'translate(-50%, 0)', }} onClick={handleMouseUp} + mutate={mutate} /> void + mutate: Dispatch> } export interface IHitchhikingCardBack { From 5110eb9ffdd9f646eac53e6ff3b3d460bb1cc9d2 Mon Sep 17 00:00:00 2001 From: HiHoi Date: Thu, 15 Feb 2024 15:30:36 +0900 Subject: [PATCH 3/3] fix: design --- src/app/showcase/page.tsx | 16 +--------------- src/app/showcase/panel/CardContainer.tsx | 6 ++---- 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/app/showcase/page.tsx b/src/app/showcase/page.tsx index 640cbd5c0..229fae121 100644 --- a/src/app/showcase/page.tsx +++ b/src/app/showcase/page.tsx @@ -98,27 +98,13 @@ const Showcase = () => { ) } - if (isTablet) { - return ( - - - - ) - } - return ( ) diff --git a/src/app/showcase/panel/CardContainer.tsx b/src/app/showcase/panel/CardContainer.tsx index aa9022b36..db458edf6 100644 --- a/src/app/showcase/panel/CardContainer.tsx +++ b/src/app/showcase/panel/CardContainer.tsx @@ -76,7 +76,7 @@ const CardContainer = ({ display={'flex'} justifyContent={'space-between'} > - {isTablet && isPc && ( + <> - )} - {isTablet && isPc && ( removeCard(cardList[cardList.length - 1]?.id)} @@ -97,7 +95,7 @@ const CardContainer = ({ sx={{ ...style.buttonIconStyle, color: 'text.alternative' }} /> - )} + )