Skip to content

Commit

Permalink
[FE] feat: 좌측 상단에 경로를 표시하는 Breadcrumb 컴포넌트 구현 (#372)
Browse files Browse the repository at this point in the history
* fix: Pretendard 폰트가 정상적으로 적용되도록 나눔고딕 제거

* chore: 오른쪽 화살표 이미지 추가

* feat: 경로 표시를 위한 Breadcrumb 컴포넌트 구현

* refactor: rightArrow 이미지를 '/'로 변경

* feat: 리뷰 목록 페이지에 Breadcrumb 컴포넌트 추가

* style: css 속성 순서 변경

* refactor: 경로 반환 로직을 useBreadcrumbPaths 훅으로 분리

* refactor: Breadcrumb 컴포넌트 렌더링을 App.tsx로 이동

* feat: 작성 완료 페이지 경로 추가

* refactor: path가 number, string일 경우를 명확히 구분하여 처리

* chore: 코드 컨벤션에 맞춰 배열 이름을 List로 변경

* refactor: 각 페이지별 경로 상수 처리

* refactor: 객체 키를 모두 소문자로 변경

* refactor: 경로 상수를 src/index.tsx에도 적용

* refactor: 카멜 케이스로 변경 후 적용
  • Loading branch information
soosoo22 authored Aug 16, 2024
1 parent 825b30c commit 7cda545
Show file tree
Hide file tree
Showing 14 changed files with 153 additions and 49 deletions.
5 changes: 5 additions & 0 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { Outlet } from 'react-router';

import { Main, PageLayout, Sidebar, Topbar, SideModal } from './components';
import Breadcrumb from './components/common/Breadcrumb';
import { useSidebar } from './hooks';
import useBreadcrumbPaths from './hooks/useBreadcrumbPaths';

const App = () => {
const { isSidebarHidden, isSidebarModalOpen, closeSidebar, openSidebar } = useSidebar();

const breadcrumbPathList = useBreadcrumbPaths();

return (
<PageLayout>
{/* {isSidebarModalOpen && (
Expand All @@ -14,6 +18,7 @@ const App = () => {
</SideModal>
)} */}
<Topbar openSidebar={openSidebar} />
{breadcrumbPathList.length > 1 && <Breadcrumb pathList={breadcrumbPathList} />}
<Main>
<Outlet />
</Main>
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/assets/rightArrow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 3 additions & 4 deletions frontend/src/components/AnswerListRecheckModal/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ import styled from '@emotion/styled';
export const AnswerListContainer = styled.div``;

export const CardLayout = styled.div`
display: flex;
flex-direction: column;
gap: 1.2rem;
position: relative;
overflow: hidden;
display: flex;
flex-direction: column;
gap: 1.2rem;
width: ${({ theme }) => theme.formWidth};
`;
Expand Down
39 changes: 39 additions & 0 deletions frontend/src/components/common/Breadcrumb/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react';
import { useNavigate } from 'react-router';

import * as S from './styles';

type PathType = string | number;

export interface Path {
pageName: string;
path: PathType;
}

interface BreadcrumbProps {
pathList: Path[];
}

const Breadcrumb = ({ pathList }: BreadcrumbProps) => {
const navigate = useNavigate();

const handleNavigation = (path: PathType) => {
if (typeof path === 'number') {
navigate(path);
} else {
navigate(path);
}
};

return (
<S.BreadcrumbList>
{pathList.map(({ pageName, path }, index) => (
<S.BreadcrumbItem key={index} onClick={() => handleNavigation(path)}>
{pageName}
</S.BreadcrumbItem>
))}
</S.BreadcrumbList>
);
};

export default Breadcrumb;
21 changes: 21 additions & 0 deletions frontend/src/components/common/Breadcrumb/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import styled from '@emotion/styled';

export const BreadcrumbList = styled.ul`
display: flex;
padding: 2rem 0 0 2.5rem;
list-style: none;
`;

export const BreadcrumbItem = styled.li`
cursor: pointer;
&:not(:last-child)::after {
content: '/';
margin: 0 2rem;
}
&:last-child {
color: ${({ theme }) => theme.colors.primary};
text-decoration: underline;
}
`;
6 changes: 2 additions & 4 deletions frontend/src/components/common/modals/ContentModal/styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export const ContentModalContainer = styled.div`
left: 50%;
transform: translate(-50%, -50%);
overflow: hidden;
display: flex;
flex-direction: column;
gap: 2rem;
Expand All @@ -18,8 +19,6 @@ export const ContentModalContainer = styled.div`
background-color: ${({ theme }) => theme.colors.white};
border-radius: ${({ theme }) => theme.borderRadius.basic};
overflow: hidden;
`;

export const ContentModalHeader = styled.div`
Expand All @@ -30,9 +29,8 @@ export const ContentModalHeader = styled.div`
`;

export const Contents = styled.div`
padding-right: 1.2rem;
overflow-y: auto;
padding-right: 1.2rem;
`;

export const CloseButton = styled.button`
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/constants/routes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const ROUTES = {
home: '/',
reviewList: 'user/review-list',
reviewWriting: 'user/review-writing',
reviewWritingComplete: 'user/review-writing-complete',
detailedReview: 'user/detailed-review',
};
35 changes: 35 additions & 0 deletions frontend/src/hooks/useBreadcrumbPaths.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { useLocation } from 'react-router-dom';

import { Path } from '@/components/common/Breadcrumb';
import { ROUTES } from '@/constants/routes';

const useBreadcrumbPaths = () => {
const { pathname } = useLocation();

const breadcrumbPathList: Path[] = [
{ pageName: '연결 페이지', path: ROUTES.home }, // TODO: 연결 페이지 경로 결정되면 수정 필요
];

if (pathname === `/${ROUTES.reviewList}`) {
breadcrumbPathList.push({ pageName: '목록 페이지', path: pathname });
}

if (pathname.includes(`/${ROUTES.reviewWriting}/`)) {
breadcrumbPathList.push({ pageName: '작성 페이지', path: pathname });
}

if (pathname === `/${ROUTES.reviewWritingComplete}`) {
breadcrumbPathList.push({ pageName: '작성 페이지', path: -1 }, { pageName: '작성 완료 페이지', path: pathname });
}

if (pathname.includes(ROUTES.detailedReview)) {
breadcrumbPathList.push(
{ pageName: '목록 페이지', path: ROUTES.reviewList },
{ pageName: '상세 페이지', path: pathname },
);
}

return breadcrumbPathList;
};

export default useBreadcrumbPaths;
11 changes: 6 additions & 5 deletions frontend/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
} from '@/pages';

import { DEV_ENVIRONMENT } from './constants';
import { ROUTES } from './constants/routes';
import globalStyles from './styles/globalStyles';
import theme from './styles/theme';

Expand Down Expand Up @@ -46,7 +47,7 @@ const queryClient = new QueryClient({

const router = createBrowserRouter([
{
path: '/',
path: ROUTES.home,
element: <App />,
errorElement: <ErrorPage />,
children: [
Expand All @@ -58,14 +59,14 @@ const router = createBrowserRouter([
path: 'user',
element: <div>user</div>,
},
{ path: 'user/review-writing/:reviewRequestCode', element: <ReviewWritingCardFormPage /> },
{ path: 'user/review-writing-complete', element: <ReviewWritingCompletePage /> },
{ path: `${ROUTES.reviewWriting}/:reviewRequestCode`, element: <ReviewWritingCardFormPage /> },
{ path: ROUTES.reviewWritingComplete, element: <ReviewWritingCompletePage /> },
{
path: 'user/review-list',
path: ROUTES.reviewList,
element: <ReviewListPage />,
},
{
path: 'user/detailed-review/:reviewId',
path: `${ROUTES.detailedReview}/:reviewId`,
element: <DetailedReviewPage />,
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ export const Description = styled.section`
width: 100%;
height: 9rem;
margin: 0;
padding: 1rem 3rem;
background-color: ${({ theme }) => theme.colors.lightPurple};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export const CopyTextButton = styled.button`
width: 2.4rem;
min-width: 2.4rem;
height: 2.4rem;
border: none;
background: none;
border: none;
`;
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,14 @@ import styled from '@emotion/styled';
export const ReviewGroupDataModal = styled.div`
display: flex;
flex-direction: column;
width: 52rem;
height: 23rem;
`;

export const ReviewGroupDataTitle = styled.h3`
font-weight: ${({ theme }) => theme.fontWeight.bold};
font-size: 2rem;
margin-bottom: 4rem;
font-size: 2rem;
font-weight: ${({ theme }) => theme.fontWeight.bold};
`;

export const ReviewGroupDataContainer = styled.div`
Expand All @@ -22,9 +21,10 @@ export const ReviewGroupDataContainer = styled.div`

export const ReviewGroupDataItem = styled.div`
display: flex;
justify-content: space-between;
gap: 1.8rem;
align-items: center;
justify-content: space-between;
font-size: 1.5rem;
`;

Expand All @@ -42,31 +42,28 @@ export const WarningContainer = styled.div`
display: flex;
flex-direction: column;
gap: 0.4rem;
margin-top: 3.7rem;
`;

export const CheckContainer = styled.div`
font-size: 1.5rem;
display: flex;
align-items: center;
gap: 0.6rem;
align-items: center;
font-size: 1.5rem;
`;

export const Checkbox = styled.input`
height: 1rem;
cursor: pointer;
width: 1rem;
height: 1rem;
margin-right: 0.3rem;
cursor: pointer;
`;

export const CheckMessage = styled.p`
font-size: 1.3rem;
`;

export const Warning = styled.p`
color: ${({ theme }) => theme.colors.red};
font-size: smaller;
color: ${({ theme }) => theme.colors.red};
`;
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ export const InputContainer = styled.div`
`;

export const ErrorMessage = styled.p`
font-size: 1.3rem;
color: ${({ theme }) => theme.colors.red};
height: 1.3rem;
padding-left: 0.7rem;
font-size: 1.3rem;
color: ${({ theme }) => theme.colors.red};
`;
39 changes: 19 additions & 20 deletions frontend/src/pages/ReviewListPage/components/PageContents/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,32 @@ interface PageContentsProps {

const PageContents = ({ groupAccessCode }: PageContentsProps) => {
const navigate = useNavigate();

const { data: reviewListData } = useGetReviewList(groupAccessCode);

const handleReviewClick = (id: number) => {
navigate(`/user/detailed-review/${id}`);
};

return (
<>
<S.Layout>
<ReviewInfoSection projectName={reviewListData.projectName} revieweeName={reviewListData.revieweeName} />
{/* <SearchSection handleChange={() => {}} options={OPTIONS} placeholder={USER_SEARCH_PLACE_HOLDER} /> */}
<S.ReviewSection>
{reviewListData.reviews.map((review) => (
// const isLastElement = pageIndex === data.pages.length - 1 && reviewIndex === page.reviews.length - 1;
<div key={review.reviewId} onClick={() => handleReviewClick(review.reviewId)}>
<ReviewCard
projectName={reviewListData.projectName}
createdAt={review.createdAt}
contentPreview={review.contentPreview}
categories={review.categories}
/>
{/* <div ref={isLastElement ? lastReviewElementRef : null}></div> */}
</div>
))}
</S.ReviewSection>
</S.Layout>
</>
<S.Layout>
<ReviewInfoSection projectName={reviewListData.projectName} revieweeName={reviewListData.revieweeName} />
{/* <SearchSection handleChange={() => {}} options={OPTIONS} placeholder={USER_SEARCH_PLACE_HOLDER} /> */}
<S.ReviewSection>
{reviewListData.reviews.map((review) => (
// const isLastElement = pageIndex === data.pages.length - 1 && reviewIndex === page.reviews.length - 1;
<div key={review.reviewId} onClick={() => handleReviewClick(review.reviewId)}>
<ReviewCard
projectName={reviewListData.projectName}
createdAt={review.createdAt}
contentPreview={review.contentPreview}
categories={review.categories}
/>
{/* <div ref={isLastElement ? lastReviewElementRef : null}></div> */}
</div>
))}
</S.ReviewSection>
</S.Layout>
);
};

Expand Down

0 comments on commit 7cda545

Please sign in to comment.