From 8c0201537c0d1dafb1e36912949680b82daa1474 Mon Sep 17 00:00:00 2001 From: s0zzang Date: Thu, 19 Dec 2024 13:48:03 +0900 Subject: [PATCH 1/7] =?UTF-8?q?Fix:=20zustand=20=EC=83=81=ED=83=9C=20?= =?UTF-8?q?=EA=B5=AC=EB=8F=85=EC=9C=BC=EB=A1=9C=20=EC=9D=B8=ED=95=9C=20?= =?UTF-8?q?=EC=9E=A6=EC=9D=80=20=EB=A6=AC=EB=A0=8C=EB=8D=94=EB=A7=81=20?= =?UTF-8?q?=EB=B3=B4=EC=99=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Modal/Modal.tsx | 5 ++++- src/hooks/useModal.ts | 5 ++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/components/Modal/Modal.tsx b/src/components/Modal/Modal.tsx index ff94feb..0d211d8 100644 --- a/src/components/Modal/Modal.tsx +++ b/src/components/Modal/Modal.tsx @@ -3,6 +3,7 @@ import Button from '@components/Button/Button'; import styled from '@emotion/styled'; import useModal from '@hooks/useModal'; +import { useModalStore } from '@store/useModalStore'; import { Hidden, TypoBodyMdR, TypoTitleSmS } from '@styles/Common'; import variables from '@styles/Variables'; @@ -40,7 +41,9 @@ interface IContentStyle { * - 모달 내 버튼 : {text: string, event: MouseEventHandler}[] */ const Modal = ({ modalId = 1, type = 'default', title, children, withBtn = true, buttons = [] }: ModalProp) => { - const { isOpen, close } = useModal(modalId); + const modals = useModalStore((state) => state.modals); + const isOpen = modals[modalId]; + const { close } = useModal(modalId); const handleClose = () => close(); return ( diff --git a/src/hooks/useModal.ts b/src/hooks/useModal.ts index 7beee11..33ee304 100644 --- a/src/hooks/useModal.ts +++ b/src/hooks/useModal.ts @@ -1,12 +1,11 @@ import { useModalStore } from '@store/useModalStore'; const useModal = (modalId = 1) => { - const { modals, setOpen } = useModalStore((state) => state); - const isOpen = modals[modalId] || false; + const setOpen = useModalStore((state) => state.setOpen); const open = () => setOpen(modalId, true); const close = () => setOpen(modalId, false); - return { isOpen, open, close }; + return { open, close }; }; export default useModal; From 8358862433048a33e1dc1d208848cff429e53e4d Mon Sep 17 00:00:00 2001 From: s0zzang Date: Fri, 27 Dec 2024 15:51:14 +0900 Subject: [PATCH 2/7] =?UTF-8?q?Structure:=20=EA=B3=B5=ED=86=B5=20=EC=8A=A4?= =?UTF-8?q?=EC=99=80=EC=9D=B4=ED=8D=BC=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8(=EC=9D=B4=EB=AF=B8=EC=A7=80,=20=EB=94=A4)=20=EA=B7=B8?= =?UTF-8?q?=EB=A3=B9=ED=95=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Studio/StudioItem.tsx | 2 +- src/components/{ImageSwiper => Swiper}/ImageSwiper.tsx | 0 src/pages/Studio/StudioReview/components/StudioReviewItem.tsx | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename src/components/{ImageSwiper => Swiper}/ImageSwiper.tsx (100%) diff --git a/src/components/Studio/StudioItem.tsx b/src/components/Studio/StudioItem.tsx index 3cc8287..f325999 100644 --- a/src/components/Studio/StudioItem.tsx +++ b/src/components/Studio/StudioItem.tsx @@ -1,6 +1,6 @@ /** @jsxImportSource @emotion/react */ import Bookmark from '@components/Bookmark/Bookmark'; -import ImageSwiper from '@components/ImageSwiper/ImageSwiper'; +import ImageSwiper from '@components/Swiper/ImageSwiper'; import styled from '@emotion/styled'; import { TypoTitleSmS } from '@styles/Common'; import variables from '@styles/Variables'; diff --git a/src/components/ImageSwiper/ImageSwiper.tsx b/src/components/Swiper/ImageSwiper.tsx similarity index 100% rename from src/components/ImageSwiper/ImageSwiper.tsx rename to src/components/Swiper/ImageSwiper.tsx diff --git a/src/pages/Studio/StudioReview/components/StudioReviewItem.tsx b/src/pages/Studio/StudioReview/components/StudioReviewItem.tsx index 6b259ac..4daf77f 100644 --- a/src/pages/Studio/StudioReview/components/StudioReviewItem.tsx +++ b/src/pages/Studio/StudioReview/components/StudioReviewItem.tsx @@ -5,7 +5,7 @@ import variables from '@styles/Variables'; import StarRating from './StarRating'; import ReviewContent from './ReviewContent'; import { useState } from 'react'; -import ImageSwiper from '@components/ImageSwiper/ImageSwiper'; +import ImageSwiper from '@components/Swiper/ImageSwiper'; import { formatTimeAgo } from '@utils/formatTimeAgo'; import { IReviewImages } from 'types/types'; From 01b8a69c45b55c70fd78de3c93c7e78ef874bfaf Mon Sep 17 00:00:00 2001 From: s0zzang Date: Fri, 27 Dec 2024 15:51:42 +0900 Subject: [PATCH 3/7] =?UTF-8?q?Cont:=20=EB=94=A4=20=EB=AA=A8=EB=8B=AC=20?= =?UTF-8?q?=EC=8A=A4=EC=99=80=EC=9D=B4=ED=8D=BC=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EC=9E=91=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Swiper/DimSwiper.tsx | 53 +++++++++++++++++++ .../StudioPortfolio/PortfolioSwiper.tsx | 25 +++++++++ .../StudioPortfolio/StudioPortfolio.tsx | 39 +++++++++++--- src/pages/Studio/components/DimmedModal.tsx | 15 ++---- src/store/useDimSwiper.ts | 11 ++++ 5 files changed, 126 insertions(+), 17 deletions(-) create mode 100644 src/components/Swiper/DimSwiper.tsx create mode 100644 src/pages/Studio/StudioPortfolio/PortfolioSwiper.tsx create mode 100644 src/store/useDimSwiper.ts diff --git a/src/components/Swiper/DimSwiper.tsx b/src/components/Swiper/DimSwiper.tsx new file mode 100644 index 0000000..39e2d4e --- /dev/null +++ b/src/components/Swiper/DimSwiper.tsx @@ -0,0 +1,53 @@ +import { useDimSwiperStore } from '@store/useDimSwiper'; +import { Dispatch, ReactNode, SetStateAction, useEffect, useState } from 'react'; +import { Navigation, Pagination, Virtual } from 'swiper/modules'; +import { Swiper, SwiperClass } from 'swiper/react'; +import { IPortfolio } from 'types/types'; + +import 'swiper/css'; +import 'swiper/css/pagination'; + +interface IDimSwiper { + children: ReactNode; + data: IPortfolio[]; + setSlideSet: Dispatch>; +} + +const DimSwiper = ({ children, data, setSlideSet }: IDimSwiper) => { + const [swiperRef, setSwiperRef] = useState(); + const { selectedId, setSelectedId } = useDimSwiperStore(); + const isFirstSlide = data[0].id === selectedId; + + const getNewSlideSet = (clickedId: number) => { + return data.filter(({ id }: { id: number }) => id === clickedId || id === clickedId - 1 || id === clickedId + 1); + }; + + const handleChange = () => { + if (!swiperRef) return null; + + const direction = swiperRef.swipeDirection === 'next' ? 1 : -1; + setSelectedId(selectedId, direction); + swiperRef.slideTo(isFirstSlide ? 0 : 1, 0, false); + }; + + const swiperOption = { + modules: [Virtual, Pagination, Navigation], + onSwiper: (e: SwiperClass) => setSwiperRef(e), + onTransitionEnd: handleChange, + slidesPerView: 1, + initialSlide: isFirstSlide ? 0 : 1, + pagination: { + type: 'fraction' as 'fraction', + }, + centeredSlides: true, + }; + + useEffect(() => { + // console.log(isFirstSlide); + setSlideSet(getNewSlideSet(selectedId)); + }, [selectedId]); + + return {children}; +}; + +export default DimSwiper; diff --git a/src/pages/Studio/StudioPortfolio/PortfolioSwiper.tsx b/src/pages/Studio/StudioPortfolio/PortfolioSwiper.tsx new file mode 100644 index 0000000..5b931ae --- /dev/null +++ b/src/pages/Studio/StudioPortfolio/PortfolioSwiper.tsx @@ -0,0 +1,25 @@ +/** @jsxImportSource @emotion/react */ + +import DimSwiper from '@components/Swiper/DimSwiper'; +import { TypoBodyMdR } from '@styles/Common'; +import { useState } from 'react'; +import { SwiperSlide } from 'swiper/react'; +import { IPortfolio } from 'types/types'; + +const PortfolioSwiper = ({ data, studioName }: { data: IPortfolio[]; studioName: string }) => { + const [slideSet, setSlideSet] = useState([]); + + return ( + + {slideSet && + slideSet.map(({ id, url, description }) => ( + + {`${studioName}-${id}`} +

{description}

+
+ ))} +
+ ); +}; + +export default PortfolioSwiper; diff --git a/src/pages/Studio/StudioPortfolio/StudioPortfolio.tsx b/src/pages/Studio/StudioPortfolio/StudioPortfolio.tsx index aa384f8..296e68f 100644 --- a/src/pages/Studio/StudioPortfolio/StudioPortfolio.tsx +++ b/src/pages/Studio/StudioPortfolio/StudioPortfolio.tsx @@ -1,19 +1,32 @@ +/** @jsxImportSource @emotion/react */ + import Button from '@components/Button/Button'; import Header from '@components/Header/Header'; import MasonryList from '@components/Masonry/Masonry'; import EmptyMessage from '@components/Message/EmptyMessage'; import StudioNavigator from '@components/Navigator/StudioNavigator'; import styled from '@emotion/styled'; +import useModal from '@hooks/useModal'; +import { useDimSwiperStore } from '@store/useDimSwiper'; import { useEffect, useState } from 'react'; import { useParams } from 'react-router-dom'; import { IPortfolio } from 'types/types'; +import DimmedModal from '../components/DimmedModal'; +import PortfolioSwiper from './PortfolioSwiper'; const StudioPortfolio = () => { + const { _id } = useParams() as { _id: string }; + const { open } = useModal(1); + const [data, setData] = useState([]); const [studioName, setStudioName] = useState(''); - const { _id } = useParams() as { _id: string }; - const handleClick = () => { - console.log('click'); + const [menuNames, setMenuNames] = useState(); + + const setSelectedId = useDimSwiperStore((state) => state.setSelectedId); + + const handleClick = (clickedId: number) => { + setSelectedId(clickedId); + open(); }; const fetchPortfolio = async () => { @@ -25,7 +38,8 @@ const StudioPortfolio = () => { }, }); const data = await response.json(); - setData(data.content); + setData(data.portfolioDtos.content); + setMenuNames(data.menuNameList); } catch (err) { console.error('Failed to fetch data'); } @@ -38,20 +52,26 @@ const StudioPortfolio = () => { return ( <> -
+
  • + {menuNames && + menuNames.map((menu) => ( +
  • +
  • + ))}
    - {data && data.length ? ( + {data.length ? ( {data.map(({ url, studio, id }) => ( -
    +
    handleClick(id)}> {`${studio}-${id}`}
    ))} @@ -60,6 +80,10 @@ const StudioPortfolio = () => { )} + + + + ); }; @@ -68,6 +92,7 @@ export default StudioPortfolio; const FilterBoxStyle = styled.ul` display: flex; + gap: 0.6rem; margin: 1.2rem 0; `; diff --git a/src/pages/Studio/components/DimmedModal.tsx b/src/pages/Studio/components/DimmedModal.tsx index b10bc41..0a7f0d7 100644 --- a/src/pages/Studio/components/DimmedModal.tsx +++ b/src/pages/Studio/components/DimmedModal.tsx @@ -1,18 +1,13 @@ /** @jsxImportSource @emotion/react */ import Modal from '@components/Modal/Modal'; -import { css } from '@emotion/react'; +// import { css } from '@emotion/react'; import styled from '@emotion/styled'; -import { Swiper } from 'swiper/react'; const DimmedModal = ({ children }: { children: React.ReactNode }) => { return ( <> - - - {children} - - + {children} ); @@ -23,8 +18,8 @@ const DimmedModalStyle = styled.div` display: flex; `; -const swiperStyle = css` - color: white; -`; +// const swiperStyle = css` +// color: white; +// `; export default DimmedModal; diff --git a/src/store/useDimSwiper.ts b/src/store/useDimSwiper.ts new file mode 100644 index 0000000..37c0b37 --- /dev/null +++ b/src/store/useDimSwiper.ts @@ -0,0 +1,11 @@ +import { create } from 'zustand'; + +interface DimSwiperState { + selectedId: number; + setSelectedId: (id: number, direction?: number) => void; +} + +export const useDimSwiperStore = create((set) => ({ + selectedId: 0, + setSelectedId: (id, direction) => set((state) => ({ selectedId: (id || state.selectedId) + (direction || 1) })), +})); From 7a0bf6b1d12fc0200d4448db44d44156f877666d Mon Sep 17 00:00:00 2001 From: s0zzang Date: Fri, 27 Dec 2024 15:51:58 +0900 Subject: [PATCH 4/7] =?UTF-8?q?Type:=20=ED=8F=AC=ED=8A=B8=ED=8F=B4?= =?UTF-8?q?=EB=A6=AC=EC=98=A4=20=EC=9D=91=EB=8B=B5=20=ED=83=80=EC=9E=85=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20-=20menuId?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/types/types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/types/types.ts b/src/types/types.ts index c007177..836540c 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -4,6 +4,7 @@ export interface IPortfolio { vibe: string; name: string; url: string; + menuId: number; description: string; created_at: string; updated_at: null | string; From 1186aa34aaa809215118a02f6db9486d9ac5431b Mon Sep 17 00:00:00 2001 From: s0zzang Date: Fri, 27 Dec 2024 15:59:49 +0900 Subject: [PATCH 5/7] =?UTF-8?q?Fix:=20#f6ff5f3=20=EC=BB=A4=EB=B0=8B=20?= =?UTF-8?q?=EA=B8=B0=EC=A4=80=20=EC=B5=9C=EC=8B=A0=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Swiper/ImageSwiper.tsx | 52 ++++++++++++++++----------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/src/components/Swiper/ImageSwiper.tsx b/src/components/Swiper/ImageSwiper.tsx index ce6362c..487fb45 100644 --- a/src/components/Swiper/ImageSwiper.tsx +++ b/src/components/Swiper/ImageSwiper.tsx @@ -2,22 +2,22 @@ import { css } from '@emotion/react'; import { Swiper, SwiperSlide, SwiperProps } from 'swiper/react'; import 'swiper/css'; -import { Autoplay, Mousewheel, Pagination } from 'swiper/modules'; +import { Mousewheel, Pagination } from 'swiper/modules'; import variables from '@styles/Variables'; import { IPortfolio, IReviewImages } from 'types/types'; interface ImageSwiperProps extends SwiperProps { images: IPortfolio[] | IReviewImages[]; imageStyle?: ReturnType; - imgProps?: { + imgprops?: { + customStyle?: ReturnType; loading?: string; onLoad?: (e: React.SyntheticEvent) => void; }; } - const ImageSwiper = ({ images, - modules = [Mousewheel, Pagination, Autoplay], + modules = [Mousewheel, Pagination], mousewheel = { forceToAxis: true, sensitivity: 1 }, spaceBetween = 3, slidesPerView = 3.6, @@ -41,28 +41,40 @@ const ImageSwiper = ({ return images; }; + const conditionalContainerStyle = slidesPerView === 1 ? containerFullStyle : containerDefaultStyle; + return ( - - {getImages(images).map((image, index) => ( - - {`이미지 - - ))} - +
    + + {getImages(images).map((image, index) => ( + + {`이미지 + + ))} + +
    ); }; export default ImageSwiper; +const containerFullStyle = css` + margin-left: calc(-1 * ${variables.layoutPadding}); +`; + +const containerDefaultStyle = css` + width: 100%; + margin-bottom: 1.4rem; +`; + const swiperStyle = css` width: calc(100% + ${variables.layoutPadding}); margin-right: ${variables.layoutPadding}; From 32c10918cf958773ab2eb102868bbba1cf7959d2 Mon Sep 17 00:00:00 2001 From: s0zzang Date: Fri, 27 Dec 2024 16:04:50 +0900 Subject: [PATCH 6/7] =?UTF-8?q?Fix:=20=EB=B3=91=ED=95=A9=20=EC=9C=84?= =?UTF-8?q?=ED=95=B4=20=EC=9D=B4=EC=A0=84=20=EA=B2=BD=EB=A1=9C=EB=A1=9C=20?= =?UTF-8?q?=EC=9E=AC=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/{Swiper => ImageSwiper}/ImageSwiper.tsx | 0 src/components/Studio/StudioItem.tsx | 2 +- src/pages/Studio/StudioReview/components/StudioReviewItem.tsx | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename src/components/{Swiper => ImageSwiper}/ImageSwiper.tsx (100%) diff --git a/src/components/Swiper/ImageSwiper.tsx b/src/components/ImageSwiper/ImageSwiper.tsx similarity index 100% rename from src/components/Swiper/ImageSwiper.tsx rename to src/components/ImageSwiper/ImageSwiper.tsx diff --git a/src/components/Studio/StudioItem.tsx b/src/components/Studio/StudioItem.tsx index 29f0d1e..cc29e59 100644 --- a/src/components/Studio/StudioItem.tsx +++ b/src/components/Studio/StudioItem.tsx @@ -1,6 +1,6 @@ /** @jsxImportSource @emotion/react */ import Bookmark from '@components/Bookmark/Bookmark'; -import ImageSwiper from '@components/Swiper/ImageSwiper'; +import ImageSwiper from '@components/ImageSwiper/ImageSwiper'; import styled from '@emotion/styled'; import { TypoTitleSmS } from '@styles/Common'; import variables from '@styles/Variables'; diff --git a/src/pages/Studio/StudioReview/components/StudioReviewItem.tsx b/src/pages/Studio/StudioReview/components/StudioReviewItem.tsx index 1b00de9..8ec1159 100644 --- a/src/pages/Studio/StudioReview/components/StudioReviewItem.tsx +++ b/src/pages/Studio/StudioReview/components/StudioReviewItem.tsx @@ -6,7 +6,7 @@ import variables from '@styles/Variables'; import StarRating from './StarRating'; import ReviewContent from './ReviewContent'; import { useState } from 'react'; -import ImageSwiper from '@components/Swiper/ImageSwiper'; +import ImageSwiper from '@components/ImageSwiper/ImageSwiper'; import { formatTimeAgo } from '@utils/formatTimeAgo'; import { IReviewImages } from 'types/types'; import { css } from '@emotion/react'; From d3d855a67e6a7d1df98f80059168f59a2c00a4c8 Mon Sep 17 00:00:00 2001 From: s0zzang Date: Fri, 27 Dec 2024 16:07:21 +0900 Subject: [PATCH 7/7] =?UTF-8?q?Fix:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EC=8A=A4=EC=99=80=EC=9D=B4=ED=8D=BC=20=EA=B2=BD=EB=A1=9C=20?= =?UTF-8?q?=EC=9E=AC=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Studio/StudioItem.tsx | 2 +- src/components/{ImageSwiper => Swiper}/ImageSwiper.tsx | 0 src/pages/Studio/StudioMenu/StudioMenuDetail.tsx | 2 +- src/pages/Studio/StudioReview/components/StudioReviewItem.tsx | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename src/components/{ImageSwiper => Swiper}/ImageSwiper.tsx (100%) diff --git a/src/components/Studio/StudioItem.tsx b/src/components/Studio/StudioItem.tsx index cc29e59..29f0d1e 100644 --- a/src/components/Studio/StudioItem.tsx +++ b/src/components/Studio/StudioItem.tsx @@ -1,6 +1,6 @@ /** @jsxImportSource @emotion/react */ import Bookmark from '@components/Bookmark/Bookmark'; -import ImageSwiper from '@components/ImageSwiper/ImageSwiper'; +import ImageSwiper from '@components/Swiper/ImageSwiper'; import styled from '@emotion/styled'; import { TypoTitleSmS } from '@styles/Common'; import variables from '@styles/Variables'; diff --git a/src/components/ImageSwiper/ImageSwiper.tsx b/src/components/Swiper/ImageSwiper.tsx similarity index 100% rename from src/components/ImageSwiper/ImageSwiper.tsx rename to src/components/Swiper/ImageSwiper.tsx diff --git a/src/pages/Studio/StudioMenu/StudioMenuDetail.tsx b/src/pages/Studio/StudioMenu/StudioMenuDetail.tsx index 3ac60b1..1815795 100644 --- a/src/pages/Studio/StudioMenu/StudioMenuDetail.tsx +++ b/src/pages/Studio/StudioMenu/StudioMenuDetail.tsx @@ -8,7 +8,7 @@ import StudioMenuDetailInfo from './StudioMenuDetailInfo'; import { useEffect, useState } from 'react'; import StudioMenuDetailReview from './StudioMenuDetailReview'; import { IMenuListRes } from 'types/types'; -import ImageSwiper from '@components/ImageSwiper/ImageSwiper'; +import ImageSwiper from '@components/Swiper/ImageSwiper'; import Button from '@components/Button/Button'; const StudioMenuDetail = () => { diff --git a/src/pages/Studio/StudioReview/components/StudioReviewItem.tsx b/src/pages/Studio/StudioReview/components/StudioReviewItem.tsx index 8ec1159..1b00de9 100644 --- a/src/pages/Studio/StudioReview/components/StudioReviewItem.tsx +++ b/src/pages/Studio/StudioReview/components/StudioReviewItem.tsx @@ -6,7 +6,7 @@ import variables from '@styles/Variables'; import StarRating from './StarRating'; import ReviewContent from './ReviewContent'; import { useState } from 'react'; -import ImageSwiper from '@components/ImageSwiper/ImageSwiper'; +import ImageSwiper from '@components/Swiper/ImageSwiper'; import { formatTimeAgo } from '@utils/formatTimeAgo'; import { IReviewImages } from 'types/types'; import { css } from '@emotion/react';