-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FE] 작성한 리뷰를 확인할 수 있는 반응형 레이아웃 (#1038)
* feat: 현재 미디어 쿼리 상태와 디바이스 종류(boolean)를 리턴하는 훅 * feat: 작성한 리뷰 페이지의 분할 레이아웃을 담당하는 WrittenReviewItem 레이아웃 컴포넌트 * feat: 임시 WrittenReviewList 컴포넌트 * feat: 임시 DetailedWrittenReview 컴포넌트 * feat: 임시 작성한 리뷰 확인 페이지 * feat: 작성한 리뷰 페이지에 대한 임시 라우팅 * feat: 임시 레이아웃, 반응형 적용 * feat: 선택한 리뷰가 없을 때의 컴포넌트 추가 * refactor: 페이지 레이아웃 이름을 더 직관적이고 단순하게 수정 * chore: WrittenReviewPage의 layout 폴더 위치를 component 하위로 변경 * refactor: 작성한 리뷰 확인 페이지의 이름을 WrittenReviewPage로 간략하게 변경 * refactor: 반응형 레이아웃을 위해 queryString 도입 (+변경된 페이지명에 따른 추가 변경사항) * chore: amplitude 페이지 정보에 작성한 리뷰 확인 페이지 추가 * refactor: 작성한 리뷰 확인 페이지에 early return 스타일 적용 * refactor: useSearchParamAndQuery의 매개변수 paramKey를 optional로 변경 * refactor: 미디어 쿼리 관련 훅 리팩토링 - mediaType 대신 breakpoint로 명시 1. 훅 이름 변경 2. 변수명 변경 * chore: 간단한 변수명 수정 * chore: Breakpoints 타입 분리 * chore: 경로 수정 * refactor: resize 함수에 debounce 추가 * refactor: xSmall 사이즈를 430으로 변경(일단 아이폰 프로 맥스를 위해 430으로 맞춤) * chore: 에러 바운더리에 적용된 속성 이름 변경 * fix: useDeviceBreakpoints훅에서 large 크기일 때 undefined가 나오던 문제 * refactor: ReviewList와 ReviewListItem 스타일 조정 - large 사이즈에서만 2분할되도록 변경 * refactor: 작성한 리뷰 확인 페이지 반응형 조절 - 2분할은 large 사이즈에서만 이루어지도록 변경 * fix: WrittenReviewList에 고정 width값(Detailed의 Outline과 동일) 부여
- Loading branch information
Showing
26 changed files
with
417 additions
and
6 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// 임시 컴포넌트! 작성한 리뷰 확인 && 받은 리뷰 확인 아이템 | ||
|
||
import * as S from './styles'; | ||
|
||
interface ReviewListItemProps { | ||
handleClick: () => void; | ||
} | ||
|
||
const ReviewListItem = ({ handleClick }: ReviewListItemProps) => { | ||
return <S.ReviewListItem onClick={handleClick}>리뷰 목록 아이템입니다</S.ReviewListItem>; | ||
}; | ||
|
||
export default ReviewListItem; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import styled from '@emotion/styled'; | ||
|
||
import media from '@/utils/media'; | ||
|
||
export const ReviewListItem = styled.li` | ||
display: flex; | ||
flex-direction: column; | ||
min-width: ${({ theme }) => theme.writtenReviewLayoutSize.largeMinWidth}; | ||
max-width: ${({ theme }) => theme.writtenReviewLayoutSize.largeMaxWidth}; | ||
min-height: 20rem; | ||
max-height: 24rem; | ||
border: 0.2rem solid ${({ theme }) => theme.colors.placeholder}; | ||
border-radius: ${({ theme }) => theme.borderRadius.basic}; | ||
${media.medium} { | ||
min-width: 62vw; | ||
min-height: 18vh; | ||
} | ||
${media.small} { | ||
min-width: 65vw; | ||
min-height: 14vh; | ||
} | ||
${media.xSmall} { | ||
min-width: 70vw; | ||
min-height: 14vh; | ||
} | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
frontend/src/pages/WrittenReviewPage/components/DetailedWrittenReview/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { NoSelectedReviewGuide } from '../index'; | ||
import { PageContentLayout } from '../layouts'; | ||
|
||
import * as S from './styles'; | ||
|
||
export interface DetailedWrittenReviewProps { | ||
$isDisplayable: boolean; | ||
selectedReviewId: number | null; | ||
} | ||
|
||
const DetailedWrittenReview = ({ $isDisplayable, selectedReviewId }: DetailedWrittenReviewProps) => { | ||
// 추후 이곳에서 직접 상세 리뷰 데이터 호출 | ||
|
||
return ( | ||
<PageContentLayout title="작성한 리뷰 상세보기"> | ||
<S.DetailedWrittenReview $isDisplayable={$isDisplayable}> | ||
<S.Outline>{selectedReviewId ? <div>{selectedReviewId} 선택함 </div> : <NoSelectedReviewGuide />}</S.Outline> | ||
</S.DetailedWrittenReview> | ||
</PageContentLayout> | ||
); | ||
}; | ||
|
||
export default DetailedWrittenReview; |
47 changes: 47 additions & 0 deletions
47
frontend/src/pages/WrittenReviewPage/components/DetailedWrittenReview/styles.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import styled from '@emotion/styled'; | ||
|
||
import media from '@/utils/media'; | ||
|
||
import { DetailedWrittenReviewProps } from '.'; | ||
|
||
export interface StyleProps extends Pick<DetailedWrittenReviewProps, '$isDisplayable'> {} | ||
|
||
export const DetailedWrittenReview = styled.div<StyleProps>` | ||
display: block; | ||
max-width: ${({ theme }) => theme.writtenReviewLayoutSize.largeMaxWidth}; | ||
${media.medium} { | ||
${({ $isDisplayable }) => | ||
$isDisplayable | ||
? ` | ||
display: block; | ||
` | ||
: ` | ||
display: none; | ||
`} | ||
} | ||
`; | ||
|
||
export const Outline = styled.div` | ||
display: flex; | ||
align-items: center; | ||
width: 100%; | ||
min-width: ${({ theme }) => theme.writtenReviewLayoutSize.largeMinWidth}; | ||
max-width: ${({ theme }) => theme.writtenReviewLayoutSize.largeMaxWidth}; | ||
height: 100%; | ||
min-height: ${({ theme }) => theme.writtenReviewLayoutSize.largeMaxHeight}; | ||
border: 0.2rem solid ${({ theme }) => theme.colors.lightGray}; | ||
border-radius: ${({ theme }) => theme.borderRadius.basic}; | ||
${media.medium} { | ||
min-width: 65vw; | ||
max-width: 65vw; | ||
} | ||
${media.small} { | ||
min-width: 75vw; | ||
max-width: 75vw; | ||
} | ||
`; |
14 changes: 14 additions & 0 deletions
14
frontend/src/pages/WrittenReviewPage/components/NoSelectedReviewGuide/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import SlideArrowsIcon from '@/assets/slideArrows.svg'; | ||
|
||
import * as S from './styles'; | ||
|
||
const NoSelectedReviewGuide = () => { | ||
return ( | ||
<S.NoSelectedReview> | ||
<img src={SlideArrowsIcon} alt="" /> | ||
<p>확인할 리뷰를 선택해주세요!</p> | ||
</S.NoSelectedReview> | ||
); | ||
}; | ||
|
||
export default NoSelectedReviewGuide; |
31 changes: 31 additions & 0 deletions
31
frontend/src/pages/WrittenReviewPage/components/NoSelectedReviewGuide/styles.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import styled from '@emotion/styled'; | ||
|
||
import media from '@/utils/media'; | ||
|
||
export const NoSelectedReview = styled.section` | ||
display: flex; | ||
gap: 2rem; | ||
align-items: center; | ||
justify-content: center; | ||
margin: 0 auto; | ||
img { | ||
height: 3rem; | ||
${media.medium} { | ||
height: 2.8rem; | ||
margin-left: 2.5rem; | ||
} | ||
} | ||
p { | ||
font-size: ${({ theme }) => theme.fontSize.mediumSmall}; | ||
font-weight: bold; | ||
color: ${({ theme }) => theme.colors.disabled}; | ||
${media.medium} { | ||
font-size: ${({ theme }) => theme.fontSize.basic}; | ||
} | ||
} | ||
`; |
29 changes: 29 additions & 0 deletions
29
frontend/src/pages/WrittenReviewPage/components/WrittenReviewList/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import ReviewListItem from '@/components/ReviewListItem'; | ||
|
||
import { PageContentLayout } from '../layouts'; | ||
|
||
import * as S from './styles'; | ||
|
||
interface WrittenReviewListProps { | ||
handleClick: (reviewId: number) => void; | ||
} | ||
|
||
const WrittenReviewList = ({ handleClick }: WrittenReviewListProps) => { | ||
// 리뷰 리스트 받아오기 | ||
const reviewIdList = [5, 1, 2, 3, 4]; | ||
|
||
return ( | ||
<PageContentLayout title="작성한 리뷰 목록"> | ||
<S.WrittenReviewList> | ||
{/** 추후 이벤트 위임 형식으로 변경 가능 */} | ||
|
||
{/** TODO: 작성한 리뷰 없을 때의 컴포넌트 추가*/} | ||
{reviewIdList.map((reviewId) => ( | ||
<ReviewListItem key={reviewId} handleClick={() => handleClick(reviewId)} /> | ||
))} | ||
</S.WrittenReviewList> | ||
</PageContentLayout> | ||
); | ||
}; | ||
|
||
export default WrittenReviewList; |
32 changes: 32 additions & 0 deletions
32
frontend/src/pages/WrittenReviewPage/components/WrittenReviewList/styles.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import styled from '@emotion/styled'; | ||
|
||
import media from '@/utils/media'; | ||
|
||
export const WrittenReviewList = styled.ul` | ||
overflow-x: hidden; | ||
overflow-y: auto; | ||
display: flex; | ||
flex-direction: column; | ||
gap: 1.7rem; | ||
width: 100%; | ||
min-width: ${({ theme }) => theme.writtenReviewLayoutSize.largeMinWidth}; | ||
max-width: ${({ theme }) => theme.writtenReviewLayoutSize.largeMaxWidth}; | ||
height: 100%; | ||
min-height: ${({ theme }) => theme.writtenReviewLayoutSize.largeMaxHeight}; | ||
max-height: ${({ theme }) => theme.writtenReviewLayoutSize.largeMaxHeight}; | ||
${media.medium} { | ||
min-width: 65vw; | ||
max-width: 65vw; | ||
} | ||
${media.small} { | ||
min-width: 75vw; | ||
max-width: 75vw; | ||
} | ||
& > li { | ||
margin-right: 0.5rem; | ||
} | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export { default as NoSelectedReviewGuide } from './NoSelectedReviewGuide'; | ||
export { default as DetailedWrittenReview } from './DetailedWrittenReview'; | ||
export { default as WrittenReviewList } from './WrittenReviewList'; |
18 changes: 18 additions & 0 deletions
18
frontend/src/pages/WrittenReviewPage/components/layouts/PageContentLayout/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { EssentialPropsWithChildren } from '@/types'; | ||
|
||
import * as S from './styles'; | ||
|
||
interface WrittenReviewItemProps { | ||
title: string; | ||
} | ||
|
||
const PageContentLayout = ({ title, children }: EssentialPropsWithChildren<WrittenReviewItemProps>) => { | ||
return ( | ||
<S.PageContentLayout> | ||
<S.Title>{title}</S.Title> | ||
<S.Content>{children}</S.Content> | ||
</S.PageContentLayout> | ||
); | ||
}; | ||
|
||
export default PageContentLayout; |
23 changes: 23 additions & 0 deletions
23
frontend/src/pages/WrittenReviewPage/components/layouts/PageContentLayout/styles.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import styled from '@emotion/styled'; | ||
|
||
export const PageContentLayout = styled.article` | ||
display: flex; | ||
flex-direction: column; | ||
justify-content: center; | ||
height: 100%; | ||
margin: 0 auto; | ||
`; | ||
|
||
export const Title = styled.h2` | ||
align-self: flex-start; | ||
margin-top: 4.7rem; | ||
margin-bottom: 2.4rem; | ||
font-size: 1.8rem; | ||
font-weight: bold; | ||
text-align: left; | ||
`; | ||
|
||
export const Content = styled.section``; |
1 change: 1 addition & 0 deletions
1
frontend/src/pages/WrittenReviewPage/components/layouts/index.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default as PageContentLayout } from './PageContentLayout'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default as useDeviceBreakpoints } from './useDeviceBreakpoints'; |
53 changes: 53 additions & 0 deletions
53
frontend/src/pages/WrittenReviewPage/hooks/useDeviceBreakpoints/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import { useState, useLayoutEffect } from 'react'; | ||
|
||
import { breakpoint } from '@/styles/theme'; | ||
import { Breakpoints } from '@/types/media'; | ||
import { debounce } from '@/utils'; | ||
|
||
interface CurrentDevice { | ||
isMobile: boolean; | ||
isTablet: boolean; | ||
isDesktop: boolean; | ||
} | ||
|
||
const DEBOUNCE_TIME = 100; | ||
|
||
/** | ||
현재 미디어 쿼리 상태와 디바이스 종류(boolean)를 리턴하는 훅 | ||
*/ | ||
const useDeviceBreakpoints = () => { | ||
const [breakpointType, setBreakPointType] = useState<Breakpoints | null>(null); | ||
const breakpointsArray = Object.entries(breakpoint); | ||
|
||
const getDeviceType = (breakpointType: Breakpoints | null): CurrentDevice => ({ | ||
isMobile: breakpointType === 'xSmall' || breakpointType === 'xxSmall', | ||
isTablet: breakpointType === 'small' || breakpointType === 'medium', | ||
isDesktop: breakpointType === 'large', | ||
}); | ||
|
||
const handleResize = debounce(() => { | ||
const currentWidth = window.innerWidth; | ||
|
||
// 마지막 breakpoint만 특정 범위 사이의 width 값이 아닌, 해당 기준 이상인 값이므로 따로 처리 | ||
const inRangeBreakpoint = breakpointsArray.find(([, width]) => currentWidth <= width); | ||
const upperBoundBreakpoint = breakpointsArray[breakpointsArray.length - 1]; | ||
|
||
const finalBreakpoint = inRangeBreakpoint || upperBoundBreakpoint; | ||
|
||
setBreakPointType((finalBreakpoint[0] as Breakpoints) ?? null); | ||
}, DEBOUNCE_TIME); | ||
|
||
useLayoutEffect(() => { | ||
handleResize(); | ||
window.addEventListener('resize', handleResize); | ||
|
||
return () => window.removeEventListener('resize', handleResize); | ||
}, []); | ||
|
||
return { | ||
breakpointType, | ||
deviceType: getDeviceType(breakpointType), | ||
}; | ||
}; | ||
|
||
export default useDeviceBreakpoints; |
Oops, something went wrong.