diff --git a/src/App.tsx b/src/App.tsx index cece7b2b..fbf6c264 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -19,7 +19,7 @@ function App() { {routes.map(({ Element, path, withNav, withAuth }) => { - const elemet = withAuth ? ( + const element = withAuth ? ( @@ -29,22 +29,20 @@ function App() { if (withNav) { return ( }> - + ); } - return ; + return ; })} - {state?.backgroundLocation && ( - - } /> - - )} + + } /> + ); } -export default App; +export default App; \ No newline at end of file diff --git a/src/apis/instance.ts b/src/apis/instance.ts index 759453ba..ffe0ec01 100644 --- a/src/apis/instance.ts +++ b/src/apis/instance.ts @@ -42,4 +42,4 @@ instance.interceptors.response.use( }, ); -export default instance; +export default instance; \ No newline at end of file diff --git a/src/components/alert/styles.ts b/src/components/alert/styles.ts index 3ee21a75..ae4023aa 100644 --- a/src/components/alert/styles.ts +++ b/src/components/alert/styles.ts @@ -22,10 +22,6 @@ export const Container = styled.div` margin: 20px 0 30px 0; } - @media (max-width : 500px) { - width : 90vw; - } - ${mediaQueries.mobile(` position: absolute; diff --git a/src/pages/gallery/components/galleryHeader/index.tsx b/src/pages/gallery/components/galleryHeader/index.tsx index 0777e6ef..6d347044 100644 --- a/src/pages/gallery/components/galleryHeader/index.tsx +++ b/src/pages/gallery/components/galleryHeader/index.tsx @@ -30,7 +30,8 @@ const GalleryHeader = ({ galleryId, galleryNick, chatRoomId, title, thumbnail, c auth: { nickname }, accessToken, } = memberStore(); - const location = `https://dartgallery.site/info/${galleryId}`; + + const location = `https://www.dartgallery.site/info/${galleryId}`; const mutation = useMutation({ mutationKey: ['review'], diff --git a/src/pages/gallery/components/galleryTemplate/mobile/styles.ts b/src/pages/gallery/components/galleryTemplate/mobile/styles.ts index 681fdff1..a3aca3c7 100644 --- a/src/pages/gallery/components/galleryTemplate/mobile/styles.ts +++ b/src/pages/gallery/components/galleryTemplate/mobile/styles.ts @@ -65,7 +65,7 @@ export const BtnBlock = styled.div` display: flex; justify-content : space-between; gap: 20px; - padding : 0 40px; + padding : 0 20px; z-index : 9; `; diff --git a/src/pages/gallery/components/reviewModal/styles.ts b/src/pages/gallery/components/reviewModal/styles.ts index 0edce862..8588587b 100644 --- a/src/pages/gallery/components/reviewModal/styles.ts +++ b/src/pages/gallery/components/reviewModal/styles.ts @@ -16,6 +16,10 @@ export const Container = styled.div` flex-direction : column; gap : 15px; } + + @media (max-width: 500px) { + width : 90vw; + } `; export const ScoreBox = styled.div` @@ -60,6 +64,11 @@ export const TextReview = styled.textarea<{ width: number; height: number; }>` &:focus { border-color: ${colors.black}; } + + @media (max-width: 500px) { + width : 86vw; + height : 300px; + } `; export const ToReview = styled.p` diff --git a/src/pages/gallery/components/shareModal/styles.ts b/src/pages/gallery/components/shareModal/styles.ts index 9f442cfe..6a7a34cc 100644 --- a/src/pages/gallery/components/shareModal/styles.ts +++ b/src/pages/gallery/components/shareModal/styles.ts @@ -9,6 +9,11 @@ export const Container = styled.div` flex-direction: column; gap : 30px; padding : 20px; + + @media (max-width : 500px) { + width : 90vw; + height : 300px; + } `; export const UrlBox = styled.div` @@ -20,6 +25,10 @@ export const UrlBox = styled.div` gap : 20px; padding : 10px; border-radius : 10px; + + @media (max-width : 500px) { + width : 90vw; + } `; export const UrlText = styled.input` @@ -48,6 +57,12 @@ export const CopyBtn = styled.button` &:hover { ${buttonTypeMap.rectangleGray}; } + + @media (max-width : 500px) { + width : 50px; + height : 30px; + ${typographyMap.t9}; + } `; export const SocialBox = styled.div` diff --git a/src/pages/index.ts b/src/pages/index.ts index 30ac2830..5aee16f2 100644 --- a/src/pages/index.ts +++ b/src/pages/index.ts @@ -12,3 +12,4 @@ export { default as MemberInfoPage } from './memberInfo'; export { default as PaymentPage } from './payment'; export { default as SuccessPage } from './payment/success'; export { default as FailPage } from './payment/fail'; +export { default as InfoPage } from './info'; diff --git a/src/pages/info/index.tsx b/src/pages/info/index.tsx new file mode 100644 index 00000000..e625f67e --- /dev/null +++ b/src/pages/info/index.tsx @@ -0,0 +1,186 @@ +import { getGalleryInfo } from "@/apis/gallery"; +import { CircleLoader, Icon, Text } from "@/components"; +import { useQuery } from "@tanstack/react-query"; +import { useParams } from "react-router-dom" +import * as S from './styles'; +import useCustomNavigate from "@/hooks/useCustomNavigate"; +import Logo from '@/assets/images/mainLogo.png'; +import parseDate from "@/utils/parseDate"; +import { alertStore } from "@/stores/modal"; +import { useState } from "react"; +import KakaoMap from "@/pages/main/components/kakaoMap"; +import { starRate } from "@/pages/main/hooks/starRate"; +import Bg from '@/assets/images/display.png'; + +const InfoPage = () => { + const { galleryId } = useParams<{ galleryId: string }>(); + const customNavigate = useCustomNavigate(); + const openModal = alertStore((state) => state.open); + const [openMap, setOpenMap] = useState(false); + const hasEnded = false; + + const { data, isLoading } = useQuery({ + queryKey: ['detail'], + queryFn: () => { + if (galleryId) { + return getGalleryInfo(parseInt(galleryId, 10)); + } + throw new Error('galleryId is undefined'); + }, + enabled:!!galleryId, + }); + + const onHandlePay = (ticket: boolean, fee: number, isOpen: boolean) => { + const showModal = (title: string, description: string, onClickButton: () => void) => { + openModal({ + title, + description, + buttonLabel: '확인', + onClickButton, + }); + }; + + if (!isOpen) { + showModal( + '입장 불가', + '전시가 예정 및 종료 상태로 입장이 불가능합니다.', + async () => close(), + ); + return; + } + + if (ticket || fee === 0) { + customNavigate(`/gallery/${galleryId}`); + } else { + customNavigate(`/payment/${galleryId}/ticket`, { hasAuth: true }); + } + }; + + const onHandleRequest = () => { + // 재전시 요청 api 완성시 구문 작성 + openModal({ + title: '재전시 요청', + description: '서비스 준비 중입니다.', + buttonLabel: '확인', + onClickButton: () => close(), + }); + }; + + const onHandleMap = () => { + setOpenMap(!openMap); + }; + + if (isLoading) return ; + + return ( + + + + + customNavigate('/')} color="white" /> + + + + + {data.title} + + { + customNavigate(`/member/${data.nickname}`); + }} + > + + + {data.nickname} + + + +

{data.content}

+ + + {parseDate(data.startDate)} ~{' '} + {parseDate(data.endDate) === '1970.01.01' ? null : parseDate(data.endDate)} + + + {data.hashtags.map((tag: string, index: number) => ( + + {`#${tag}`} + + ))} + +
+ + {hasEnded ? ( +
onHandleRequest()}> + 재전시 요청 +
+ ) : ( + <> +
₩ {data.fee}
+
onHandlePay(data.hasTicket, data.fee, data.isOpen)} + > + 입장하기 +
+ + )} +
+ {data.address && ( + + + {data.address} + + )} + {data.address && openMap && ( + + )} +
+ + + 관람객 평점 + + + + + + {data.reviewAverage}  + + + / 5 + + + + {starRate(data.reviewAverage)} + + { + customNavigate(`/review/${galleryId}`); + }} + > + 상세 리뷰 보기 > + + + { + customNavigate(`/review/${galleryId}`); + }} + > + 상세 리뷰 보기 > + + + +
+
+ ) +} + +export default InfoPage \ No newline at end of file diff --git a/src/pages/info/styles.ts b/src/pages/info/styles.ts new file mode 100644 index 00000000..16ddd1cb --- /dev/null +++ b/src/pages/info/styles.ts @@ -0,0 +1,263 @@ +import { LayoutMap } from '@/styles/layout'; +import { bolderMap, typographyMap } from '@/styles/typography'; +import styled from '@emotion/styled'; +import modalBottom from '@/assets/images/modalbottom.png'; +import { fadeUp } from '@/pages/gallery/components/galleryDetail/styles'; +import { Icon } from '@/components'; + +export const Wrapper = styled.div<{ infoBg: string }>` + position: fixed; + top: 0; + bottom: 0; + left: 0; + right: 0; + background-image: url(${props => props.infoBg }); + background-size: cover; + background-repeat: no-repeat; + background-position: center; + z-index: var(--dimmed-zindex); +`; + +export const Container = styled.div` + ${LayoutMap.absoluteCenter} + display: flex; + flex-direction: column; + width: 800px; + z-index: var(--modal-zindex); + animation: ${fadeUp} 0.3s ease-in-out; + + @media (max-width: 1024px) { + width : 90vw; + } +`; + +export const CancelIcon = styled(Icon)` + position: absolute; + right: 20px; + top: 20px; +`; +export const MainLogo = styled.img` + width: 70px; + height: 30px; +`; + +export const InfoBox = styled.div<{ thumbnail: string }>` + position: relative; + width: 100%; + height: 80vh; + display: flex; + flex-direction: column; + justify-content: space-between; + gap: 20px; + padding: 100px; + box-sizing: border-box; + background-image: url(${(props) => props.thumbnail}); + background-position: center; + background-size: cover; + background-repeat: no-repeat; + z-index: 12; + + @media (max-width: 1024px) { + padding : 100px 20px; + } +`; + +export const Overlay = styled.div` + position: absolute; + top: 0; + left: 0; + bottom: 0; + right: 0; + background-color: rgba(0, 0, 0, 0.5); + z-index: -1; +`; + +export const DescriptionBlock = styled.div` + width: 350px; + display: flex; + flex-direction: column; + justify-content: center; + gap: 30px; + + #descript { + color: white; + ${typographyMap.t6}; + ${bolderMap.thin}; + word-break: break-word; + } +`; + +export const Top = styled.div` + ${LayoutMap.displayFlex}; + justify-content: flex-start; + gap: 20px; +`; + +export const User = styled.div` + ${LayoutMap.displayFlex}; + justify-content: flex-start; + gap: 5px; + cursor: pointer; + + p { + position: relative; + + &:hover { + text-decoration: underline; + } + } +`; + +export const Circle = styled.div` + width: 10px; + height: 10px; + border-radius: 50%; + background-color: red; +`; + +export const ButtonBlock = styled.div` + width : 100%; + ${LayoutMap.displayFlex}; + justify-content: flex-start; + gap: 10px; + + .price { + ${LayoutMap.displayFlex}; + justify-content: center; + width: 120px; + height: 40px; + background-color: black; + border-radius: 30px; + color: white; + } + + .topay { + ${LayoutMap.displayFlex}; + justify-content: center; + width: 120px; + height: 40px; + background-color: white; + border-radius: 30px; + color: black; + + &:hover { + cursor: pointer; + background-color: black; + border: none; + color: white; + } + } +`; + +export const HashTags = styled.div` + ${LayoutMap.displayFlex}; + justify-content: flex-start; + gap: 10px; +`; + +export const MapBlock = styled.div` + ${LayoutMap.displayFlex}; + gap : 10px; + justify-content: flex-start; + + &:hover p { + text-decoration: underline; + cursor: pointer; + } +`; + +export const ReviewBox = styled.div` + position: relative; + width: 100%; + height: 15vh; + display: flex; + flex-direction: column; + justify-content: center; + gap: 10px; + padding: 10px 150px 10px 110px; + box-sizing: border-box; + background-color: black; + background-image: url(${modalBottom}); + background-size: 100%; + background-repeat: no-repeat; + background-position: center; + + @media (max-width: 1024px) { + padding : 10px 20px; + } + + .reviewText { + @media (max-width: 1024px) { + display: none; + } + } +`; + +export const ScoreBlock = styled.div` + position : relative; + ${LayoutMap.displayFlex}; + justify-content: space-between; + + a { + &:hover { + p { + text-decoration: underline; + } + } + } + + .originalText { + @media (max-width: 1024px) { + display : none; + } + } + + @media (max-width : 1024px) { + justify-content: center; + } +`; + +export const ScoreWrap = styled.div` + ${LayoutMap.displayFlex}; + justify-content: flex-start; + gap: 10px; + + .reactText { + display : none; + + &:hover { + cursor: pointer; + text-decoration: underline; + } + + @media (max-width : 1024px) { + display : block; + position : absolute; + top : -20px; + left : 50%; + transform : translateX(-50%); + } + + @media (max-width : 500px) { + position : none; + } + } +`; + +export const Score = styled.div` + ${LayoutMap.displayFlex}; + margin-right: 30px; + + @media (max-width: 1024px) { + margin-right : 10px; + } +`; + +export const StarBox = styled.div` + ${LayoutMap.displayFlex}; + gap : 5px; + + @media (max-width : 500px) { + display : none; + } +`; \ No newline at end of file diff --git a/src/pages/main/components/galleryInfo/index.tsx b/src/pages/main/components/galleryInfo/index.tsx index 9bbeadbd..30ba6afd 100644 --- a/src/pages/main/components/galleryInfo/index.tsx +++ b/src/pages/main/components/galleryInfo/index.tsx @@ -144,25 +144,39 @@ const GalleryInfo = ({ galleryId, open: isOpen, hasEnded, close }: GalleryInfoPr )} - + 관람객 평점 - + {data.reviewAverage}  - + / 5 - {starRate(data.reviewAverage)} + + {starRate(data.reviewAverage)} + + { + customNavigate(`/review/${galleryId}`); + }} + > + 상세 리뷰 보기 > + { customNavigate(`/review/${galleryId}`); }} diff --git a/src/pages/main/components/galleryInfo/styles.ts b/src/pages/main/components/galleryInfo/styles.ts index 5fbb53d7..ab3faca1 100644 --- a/src/pages/main/components/galleryInfo/styles.ts +++ b/src/pages/main/components/galleryInfo/styles.ts @@ -89,14 +89,8 @@ export const User = styled.div` p { position: relative; - &:hover::after { - content: ''; - position: absolute; - left: 0; - bottom: -3px; - width: 100%; - height: 1px; - background-color: currentColor; + &:hover { + text-decoration: underline; } } `; @@ -174,9 +168,20 @@ export const ReviewBox = styled.div` background-size: 100%; background-repeat: no-repeat; background-position: center; + + @media (max-width: 1024px) { + padding : 10px 20px; + } + + .reviewText { + @media (max-width: 1024px) { + display: none; + } + } `; export const ScoreBlock = styled.div` + position : relative; ${LayoutMap.displayFlex}; justify-content: space-between; @@ -187,15 +192,59 @@ export const ScoreBlock = styled.div` } } } + + .originalText { + @media (max-width: 1024px) { + display : none; + } + } + + @media (max-width : 1024px) { + justify-content: center; + } `; export const ScoreWrap = styled.div` ${LayoutMap.displayFlex}; justify-content: flex-start; gap: 10px; + + .reactText { + display : none; + + &:hover { + cursor: pointer; + text-decoration: underline; + } + + @media (max-width : 1024px) { + display : block; + position : absolute; + top : -20px; + left : 50%; + transform : translateX(-50%); + } + + @media (max-width : 500px) { + position : none; + } + } `; export const Score = styled.div` ${LayoutMap.displayFlex}; margin-right: 30px; + + @media (max-width: 1024px) { + margin-right : 10px; + } +`; + +export const StarBox = styled.div` + ${LayoutMap.displayFlex}; + gap : 5px; + + @media (max-width : 500px) { + display : none; + } `; diff --git a/src/routes/index.ts b/src/routes/index.ts index 878b3fda..2708a731 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -13,6 +13,7 @@ import { SuccessPage, FailPage, EventPage, + InfoPage, } from '@/pages'; interface RouteInfo { @@ -40,6 +41,7 @@ export const routes: RouteInfo[] = [ withNav: true, withAuth: true, }, + { path: '/info/:galleryId', Element: InfoPage }, { path: '/payment/success/:galleryId/:order', Element: SuccessPage, withAuth: true }, { path: '/payment/fail', Element: FailPage, withAuth: true }, { path: '*', Element: ErrorPage }, diff --git a/src/styles/typography.ts b/src/styles/typography.ts index f3a3c3cf..78cd0525 100644 --- a/src/styles/typography.ts +++ b/src/styles/typography.ts @@ -28,6 +28,9 @@ export const typographyMap = { t8: css` font-size: 12px; `, + t9: css` + font-size: 10px; + `, }; export const bolderMap = {