diff --git a/frontend/src/components/layouts/Footer/style.ts b/frontend/src/components/layouts/Footer/style.ts index 51c79fd4c..394029288 100644 --- a/frontend/src/components/layouts/Footer/style.ts +++ b/frontend/src/components/layouts/Footer/style.ts @@ -21,6 +21,8 @@ export const Footer = styled.footer` background-color: ${({ theme }) => theme.colors.white}; + border-top: 0.1rem solid ${({ theme }) => theme.colors.lightGray}; + ${media.xSmall} { flex-direction: column; gap: 0.2rem; diff --git a/frontend/src/components/layouts/Topbar/components/Logo/styles.ts b/frontend/src/components/layouts/Topbar/components/Logo/styles.ts index 682e0908d..860d6abea 100644 --- a/frontend/src/components/layouts/Topbar/components/Logo/styles.ts +++ b/frontend/src/components/layouts/Topbar/components/Logo/styles.ts @@ -3,17 +3,11 @@ import styled from '@emotion/styled'; import media from '@/utils/media'; export const Logo = styled.div` - line-height: 8rem; text-align: center; span { - font-size: 3rem; + font-size: 2.8rem; font-weight: ${({ theme }) => theme.fontWeight.bolder}; - letter-spacing: 0.7rem; - - ${media.small} { - font-size: 2.8rem; - } ${media.xSmall} { font-size: 2.6rem; diff --git a/frontend/src/constants/amplitudeEventName.ts b/frontend/src/constants/amplitudeEventName.ts index c610d53b7..a90ae22e5 100644 --- a/frontend/src/constants/amplitudeEventName.ts +++ b/frontend/src/constants/amplitudeEventName.ts @@ -24,6 +24,7 @@ export const PAGE_VISITED_EVENT_NAME: { [key in Exclude]: s detailedReview: '[page] 리뷰 상세 보기 페이지', reviewWriting: '[page] 리뷰 작성 페이지', reviewWritingComplete: '[page] 리뷰 작성 완료 페이지', + reviewLinks: '[page] 리뷰 링크 관리 페이지', }; export const REVIEW_WRITING_EVENT_NAME = { diff --git a/frontend/src/constants/route.ts b/frontend/src/constants/route.ts index 0826e9ff8..df2fc17fe 100644 --- a/frontend/src/constants/route.ts +++ b/frontend/src/constants/route.ts @@ -7,4 +7,5 @@ export const ROUTE = { detailedReview: 'user/detailed-review', reviewZone: 'user/review-zone', reviewCollection: 'user/review-collection', + reviewLinks: 'user/review-links', }; diff --git a/frontend/src/pages/HomePage/components/URLGeneratorForm/styles.ts b/frontend/src/pages/HomePage/components/URLGeneratorForm/styles.ts index 80fcda2fa..a15d87396 100644 --- a/frontend/src/pages/HomePage/components/URLGeneratorForm/styles.ts +++ b/frontend/src/pages/HomePage/components/URLGeneratorForm/styles.ts @@ -8,10 +8,10 @@ export const URLGeneratorForm = styled.section` justify-content: center; width: 40%; - padding: 0 9rem; ${media.medium} { width: 45%; + padding: 0 9rem; h2 { font-size: 2rem; diff --git a/frontend/src/pages/ReviewLinkPage/components/ReviewLinkDashboard/index.tsx b/frontend/src/pages/ReviewLinkPage/components/ReviewLinkDashboard/index.tsx new file mode 100644 index 000000000..aaf99ed0c --- /dev/null +++ b/frontend/src/pages/ReviewLinkPage/components/ReviewLinkDashboard/index.tsx @@ -0,0 +1,27 @@ +import { URLGeneratorForm } from '@/pages/HomePage/components'; + +import ReviewLinkLayout from '../layouts/ReviewLinkLayout'; + +import * as S from './styles'; + +const ReviewLinkDashboard = () => { + return ( + + + + + + + + {/* TODO: ReviewCard 컴포넌트 추가 및 생성한 리뷰 링크가 없을 경우, 돋보기 컴포넌트 추가 */} + <> + + + + ); +}; + +export default ReviewLinkDashboard; diff --git a/frontend/src/pages/ReviewLinkPage/components/ReviewLinkDashboard/styles.ts b/frontend/src/pages/ReviewLinkPage/components/ReviewLinkDashboard/styles.ts new file mode 100644 index 000000000..8d4ab58ae --- /dev/null +++ b/frontend/src/pages/ReviewLinkPage/components/ReviewLinkDashboard/styles.ts @@ -0,0 +1,78 @@ +import styled from '@emotion/styled'; + +import media from '@/utils/media'; + +export const ReviewLinkDashboardContainer = styled.div` + display: flex; + justify-content: center; + gap: 7rem; + + width: 100%; + + ${media.medium} { + gap: 4rem; + } + + @media screen and (max-width: 900px) { + gap: 2rem; + } + + ${media.small} { + flex-direction: column; + align-items: center; + } +`; + +export const FormSection = styled.section` + section { + width: auto; + } + + padding: 5rem 0; + + ${media.medium} { + section { + padding: 0; + } + } + + ${media.small} { + width: 100%; + padding: 0; + } +`; + +export const Separator = styled.div` + width: 0.1rem; + // 전체 영역에서 헤더(7rem)와 푸터(6rem) 영역 제외하고, 추후 네비게이션 탭이 추가되면 해당 영역도 제외 + min-height: calc(100vh - 13rem); + + background-color: ${({ theme }) => theme.colors.lightGray}; + + ${media.small} { + display: none; + } +`; + +export const LinkSection = styled.section` + display: flex; + flex-direction: column; + justify-content: flex-start; + gap: 3rem; + + width: 100%; + + padding: 5rem 0; + + ${media.medium} { + width: 50%; + } + + ${media.small} { + width: 85%; + } + + ${media.xSmall} { + width: 90%; + } +`; diff --git a/frontend/src/pages/ReviewLinkPage/components/layouts/ReviewLinkLayout/index.tsx b/frontend/src/pages/ReviewLinkPage/components/layouts/ReviewLinkLayout/index.tsx new file mode 100644 index 000000000..b6ca6fee1 --- /dev/null +++ b/frontend/src/pages/ReviewLinkPage/components/layouts/ReviewLinkLayout/index.tsx @@ -0,0 +1,22 @@ +import { EssentialPropsWithChildren } from '@/types'; + +import * as S from './styles'; + +interface ReviewLinkListLayoutProps { + title: string; + subTitle: string; +} + +const ReviewLinkLayout = ({ title, subTitle, children }: EssentialPropsWithChildren) => { + return ( + + + {title} + {subTitle} + + {children} + + ); +}; + +export default ReviewLinkLayout; diff --git a/frontend/src/pages/ReviewLinkPage/components/layouts/ReviewLinkLayout/styles.ts b/frontend/src/pages/ReviewLinkPage/components/layouts/ReviewLinkLayout/styles.ts new file mode 100644 index 000000000..ed8ec571f --- /dev/null +++ b/frontend/src/pages/ReviewLinkPage/components/layouts/ReviewLinkLayout/styles.ts @@ -0,0 +1,58 @@ +import styled from '@emotion/styled'; + +import media from '@/utils/media'; + +export const ReviewLinkLayout = styled.div` + display: flex; + flex-direction: column; + + gap: 4rem; +`; + +export const TitleWrapper = styled.div` + display: flex; + flex-direction: column; + gap: 0.8rem; +`; + +export const Title = styled.h2` + ${media.medium} { + font-size: 2rem; + } + + ${media.xSmall} { + font-size: 1.8rem; + } + + ${media.xxSmall} { + font-size: 1.6rem; + } +`; + +export const SubTitle = styled.span` + color: ${({ theme }) => theme.colors.gray}; + + ${media.xSmall} { + font-size: 1.5rem; + } + + ${media.xxSmall} { + font-size: 1.3rem; + } +`; + +export const CardList = styled.ul` + display: flex; + flex-direction: column; + gap: 4rem; + + max-height: calc(100vh - 34rem); + overflow-y: auto; + + padding-right: 2rem; + + ${media.small} { + max-height: none; + padding-right: 0; + } +`; diff --git a/frontend/src/pages/ReviewLinkPage/index.tsx b/frontend/src/pages/ReviewLinkPage/index.tsx new file mode 100644 index 000000000..f9ecf4719 --- /dev/null +++ b/frontend/src/pages/ReviewLinkPage/index.tsx @@ -0,0 +1,14 @@ +import { ErrorSuspenseContainer } from '@/components'; + +import ReviewLinkDashboard from './components/ReviewLinkDashboard'; + +const ReviewLinkPage = () => { + return ( + + {/* TODO: 네비게이션 탭 추가 */} + + + ); +}; + +export default ReviewLinkPage; diff --git a/frontend/src/pages/index.tsx b/frontend/src/pages/index.tsx index 4dc586d19..28b98890c 100644 --- a/frontend/src/pages/index.tsx +++ b/frontend/src/pages/index.tsx @@ -7,3 +7,4 @@ export { default as ReviewWritingPage } from './ReviewWritingPage'; export { default as ReviewWritingCompletePage } from './ReviewWritingCompletePage'; export { default as ReviewZonePage } from './ReviewZonePage'; export { default as ReviewCollectionPage } from './ReviewCollectionPage'; +export { default as ReviewLinkPage } from './ReviewLinkPage'; diff --git a/frontend/src/router.tsx b/frontend/src/router.tsx index 0fd64b227..a8abb7137 100644 --- a/frontend/src/router.tsx +++ b/frontend/src/router.tsx @@ -10,6 +10,7 @@ const ReviewWritingPage = lazy(() => import('@/pages/ReviewWritingPage')); const ReviewZonePage = lazy(() => import('@/pages/ReviewZonePage')); const ReviewCollectionPage = lazy(() => import('@/pages/ReviewCollectionPage')); const LoadingPage = lazy(() => import('@/pages/LoadingPage')); +const ReviewLinkPage = lazy(() => import('@/pages/ReviewLinkPage')); import App from './App'; import { ErrorSuspenseContainer } from './components'; @@ -52,6 +53,7 @@ const router = createBrowserRouter([ ), }, { path: `${ROUTE.reviewCollection}/:${ROUTE_PARAM.reviewRequestCode}`, element: }, + { path: `${ROUTE.reviewLinks}`, element: }, ], }, ]);