Skip to content

Commit

Permalink
TripPage, TripEditPage 리팩토링 (#537)
Browse files Browse the repository at this point in the history
* fix: TripEditPage 데이터 패칭 waterfall 문제 해결

* refactor: useQuery 옵션 defaultOptions로 옮기기

* fix: Header cursor pointer 문제 해결

* refactor: Footer 수정

* refactor: 회원가입, 로그인 버튼 하나로 합치기

* refactor: props로 넘겨주는 대신 TripInformation에서 직접 데이터 가져오기

* refactor: TripInformation 수정 버튼 네이밍 수정에서 완료로 변경

* refactor: TripItem 제목 스타일링 수정

* refactor: 모바일일때 image carousel navigation 보이게 변경

* refactor: 수정, 삭제 버튼 더보기 메뉴에서 보여주는 대신 아이콘으로 변경

* refactor: 기타 탭에서 아이템 생성 시 디폴트 카테고리 기타로 설정

* refactor: 이미지 용량 10mb 이상으로 인한 에러 발생 시 상황에 맞는 에러 메세지 보여주기

* refactor: 아이템 추가할 때 제목에 공백 입력 후 아이템 추가 시 에러 메세지 보여주기

* refactor: TripItemList 컴포넌트 수정

* fix: 테스트 코드 수정
  • Loading branch information
ashleysyheo authored Sep 4, 2023
1 parent 4bc9635 commit ed693fa
Show file tree
Hide file tree
Showing 45 changed files with 220 additions and 269 deletions.
13 changes: 10 additions & 3 deletions frontend/.storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ import { initialize, mswDecorator } from 'msw-storybook-addon';

import { HangLogProvider, Spinner } from 'hang-log-design-system';

import { axiosInstance } from '../src/api/axiosInstance';
import { ACCESS_TOKEN_KEY } from '../src/constants/api';
import { ACCESS_TOKEN_KEY, NETWORK } from '../src/constants/api';
import { handlers } from '../src/mocks/handlers';

initialize();
Expand Down Expand Up @@ -48,7 +47,15 @@ const preview: Preview = {

export default preview;

const queryClient = new QueryClient();
const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: NETWORK.RETRY_COUNT,
suspense: true,
useErrorBoundary: true,
},
},
});

const localStorageResetDecorator = (Story) => {
window.localStorage.clear();
Expand Down
6 changes: 0 additions & 6 deletions frontend/cypress/e2e/login.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ describe('로그인', () => {

it('웹 사이트 처음 방문 시 서비스 소개 페이지를 볼 수 있다.', () => {
cy.findByText('로그인');
cy.findByText('회원가입');
cy.findByText('시작하기');
});

Expand All @@ -25,11 +24,6 @@ describe('로그인', () => {
cy.location('pathname').should('eq', PATH.LOGIN);
});

it('회원가입 버튼을 클릭하면 회원가입 페이지로 이동한다.', () => {
cy.findByText('회원가입').click();
cy.location('pathname').should('eq', PATH.SIGN_UP);
});

it('로그인하면 메인 페이지 화면이 여행 목록 페이지로 변경된다.', () => {
cy.findByText('로그인').click();

Expand Down
25 changes: 11 additions & 14 deletions frontend/cypress/e2e/trip.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ describe('여행 수정 페이지', () => {
});
});

it('여행 수정 페이지에서 "여행 정보 수정" 버튼과 "저장" 버튼을 볼 수 있다.', () => {
it('여행 수정 페이지에서 "여행 정보 수정" 버튼과 "완료" 버튼을 볼 수 있다.', () => {
cy.findByText('여행 정보 수정');

cy.findByText('저장');
cy.findByText('완료');
});

it('여행 수정 페이지에서 선택 된 날짜 길이 만큼 데이로그 탭이 만들어져 있다.', () => {
Expand All @@ -62,7 +62,7 @@ describe('여행 수정 페이지', () => {
cy.findByPlaceholderText('소제목').should('have.value', title);

items.forEach((item: TripItemData) => {
cy.get('h6').contains(item.title);
cy.get('p').contains(item.title);
});
});
});
Expand All @@ -74,7 +74,7 @@ describe('여행 수정 페이지', () => {
const { items } = expectedData.dayLogs[1];

items.forEach((item: TripItemData) => {
cy.get('h6').contains(item.title);
cy.get('p').contains(item.title);
});
});
});
Expand Down Expand Up @@ -289,7 +289,7 @@ describe('여행 아이템 추가', () => {

cy.findByRole('dialog').should('not.exist');

cy.get('h6').contains('샹젤리제 거리 -> 에펠탑 지하철').should('exist');
cy.get('p').contains('샹젤리제 거리 -> 에펠탑 지하철').should('exist');
});

it('여행 아이템 추가 모달에서 필수 정보 외에도 입력하고 아이템을 추가한 후에 여행 아이템 목록에서 볼 수 있다.', () => {
Expand All @@ -310,7 +310,7 @@ describe('여행 아이템 추가', () => {

cy.findByRole('dialog').should('not.exist');

cy.get('h6').contains('샹젤리제 거리 -> 에펠탑 지하철').should('exist');
cy.get('p').contains('샹젤리제 거리 -> 에펠탑 지하철').should('exist');

cy.findByText('샹젤리제 거리 -> 에펠탑 지하철').parent().find('svg').should('have.length', 6);
cy.findByText('샹젤리제 거리 -> 에펠탑 지하철')
Expand Down Expand Up @@ -339,16 +339,14 @@ describe('여행 아이템 수정', () => {
cy.wait(4000);
});

it('여행 아이템의 더 보기 버튼을 클릭해서 여행 아이템을 수정할 수 있다.', () => {
cy.get('button[aria-label="더 보기 메뉴"]').first().click({ force: true });
cy.findByText('수정').click();
it('여행 아이템의 수정 버튼을 클릭해서 여행 아이템을 수정할 수 있다.', () => {
cy.get('svg[aria-label="수정"]').first().click({ force: true });

cy.findByRole('dialog').should('be.visible');
});

it.skip('여행 아이템 수정 모달을 열면 여행 아이템 정보가 입력되어 있다.', () => {
cy.get('button[aria-label="더 보기 메뉴"]').first().click({ force: true });
cy.findByText('수정').click();
cy.get('svg[aria-label="수정"]').first().click({ force: true });

cy.fixture('trip.json').then((expectedData) => {
const { items } = expectedData.dayLogs[0];
Expand All @@ -365,8 +363,7 @@ describe('여행 아이템 수정', () => {
});

it.skip('여행 아이템 수정 모달에서 여행 아이템 정보를 수정하면 여행 아이템 목록에서 변경된 정보를 볼 수 있다.', () => {
cy.get('button[aria-label="더 보기 메뉴"]').first().click({ force: true });
cy.findByText('수정').click();
cy.get('svg[aria-label="수정"]').first().click({ force: true });

cy.findByRole('radio', { name: /기타/ }).click();
cy.get('#title').type(' 택시');
Expand All @@ -383,7 +380,7 @@ describe('여행 아이템 수정', () => {
const { items } = expectedData.dayLogs[0];
const firstItem: TripItemData = items[0];

cy.get('h6').contains(`${firstItem.title} 택시`).should('exist');
cy.get('p').contains(`${firstItem.title} 택시`).should('exist');

cy.findByText(`${firstItem.title} 택시`)
.parent()
Expand Down
3 changes: 3 additions & 0 deletions frontend/src/assets/svg/bin-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions frontend/src/assets/svg/edit-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions frontend/src/components/common/DayLogList/DayLogList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Tab, Tabs } from 'hang-log-design-system';
import DayLogItem from '@components/common/DayLogItem/DayLogItem';
import { containerStyling } from '@components/common/DayLogList/DayLogList.style';

import { useTripDates } from '@hooks/trip/useTripDates';
import { useTrip } from '@hooks/trip/useTrip';

import { formatMonthDate } from '@utils/formatter';

Expand All @@ -26,7 +26,7 @@ const DayLogList = ({
onTabChange,
openAddModal,
}: DayLogListProps) => {
const { dates } = useTripDates(tripId);
const { dates } = useTrip(tripId);

return (
<section css={containerStyling}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ export const moreButtonStyling = css({
'& svg': {
width: '20px',
height: '20px',

'& path': {
stroke: Theme.color.white,
strokeWidth: 1.5,
},
},
});

Expand All @@ -38,3 +33,23 @@ export const moreMenuListStyling = css({
color: Theme.color.gray800,
},
});

export const svgButtonStyling = css({
width: '20px',
height: '20px',
marginLeft: '12px',

cursor: 'pointer',
});

export const binIconStyling = css({
'& path': {
stroke: Theme.color.white,
},
});

export const editIconStyling = css({
'& path': {
fill: Theme.color.white,
},
});
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { useNavigate } from 'react-router-dom';

import { Button, Menu, MenuItem, MenuList, useOverlay } from 'hang-log-design-system';
import { Button } from 'hang-log-design-system';

import {
moreButtonStyling,
moreMenuListStyling,
moreMenuStyling,
binIconStyling,
editIconStyling,
svgButtonStyling,
} from '@components/common/TripInformation/TripButtons/TripButtons.style';
import TripShareButton from '@components/common/TripInformation/TripShareButton/TripShareButton';

Expand All @@ -15,7 +15,8 @@ import type { TripData } from '@type/trip';

import { PATH } from '@constants/path';

import MoreIcon from '@assets/svg/more-icon.svg';
import BinIcon from '@assets/svg/bin-icon.svg';
import EditIcon from '@assets/svg/edit-icon.svg';

interface TripButtonsProps {
tripId: number;
Expand All @@ -25,7 +26,6 @@ interface TripButtonsProps {
export const TripButtons = ({ tripId, sharedCode }: TripButtonsProps) => {
const navigate = useNavigate();
const deleteTripMutation = useDeleteTripMutation();
const { isOpen: isMenuOpen, open: openMenu, close: closeMenu } = useOverlay();

const goToEditPage = () => {
navigate(PATH.EDIT_TRIP(tripId));
Expand All @@ -50,17 +50,8 @@ export const TripButtons = ({ tripId, sharedCode }: TripButtonsProps) => {
가계부
</Button>
<TripShareButton tripId={tripId} sharedCode={sharedCode} />
<Menu css={moreMenuStyling} closeMenu={closeMenu}>
<button css={moreButtonStyling} type="button" aria-label="더 보기 메뉴" onClick={openMenu}>
<MoreIcon />
</button>
{isMenuOpen && (
<MenuList css={moreMenuListStyling}>
<MenuItem onClick={goToEditPage}>수정</MenuItem>
<MenuItem onClick={handleDeleteButtonClick}>삭제</MenuItem>
</MenuList>
)}
</Menu>
<EditIcon css={[svgButtonStyling, editIconStyling]} onClick={goToEditPage} />
<BinIcon css={[svgButtonStyling, binIconStyling]} onClick={handleDeleteButtonClick} />
</>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const TripEditButtons = ({ tripId, openEditModal }: TripEditButtonsProps) => {
여행 정보 수정
</Button>
<Button variant="primary" size="small" onClick={() => navigate(`/trip/${tripId}`)}>
저장
완료
</Button>
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,14 @@ export const descriptionStyling = css({
export const buttonContainerStyling = css({
position: 'absolute',
top: Theme.spacer.spacing4,
right: Theme.spacer.spacing4,
right: '50px',
display: 'flex',
alignItems: 'center',
gap: Theme.spacer.spacing1,

'@media screen and (max-width: 600px)': {
right: Theme.spacer.spacing4,
},
});

export const badgeStyling = css({
Expand All @@ -85,6 +89,6 @@ export const badgeWrapperStyling = css({
},

'@media screen and (max-width: 600px)': {
width: 'calc(100vw - 220px)',
width: 'calc(100vw - 232px)',
},
});
31 changes: 15 additions & 16 deletions frontend/src/components/common/TripInformation/TripInformation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,63 +17,62 @@ import {
} from '@components/common/TripInformation/TripInformation.style';
import TripInfoEditModal from '@components/trip/TripInfoEditModal/TripInfoEditModal';

import { useTrip } from '@hooks/trip/useTrip';

import { mediaQueryMobileState } from '@store/mediaQuery';

import { formatDate } from '@utils/formatter';

import type { TripData } from '@type/trip';

import DefaultThumbnail from '@assets/png/trip-information_default-thumbnail.png';

interface TripInformationProps extends Omit<TripData, 'dayLogs'> {
interface TripInformationProps {
tripId: number;
isEditable?: boolean;
isShared?: boolean;
}

const TripInformation = ({
isEditable = true,
isShared = false,
...information
}: TripInformationProps) => {
const TripInformation = ({ isEditable = true, isShared = false, tripId }: TripInformationProps) => {
const isMobile = useRecoilValue(mediaQueryMobileState);

const { isOpen: isEditModalOpen, close: closeEditModal, open: openEditModal } = useOverlay();

const { tripData } = useTrip(tripId);

return (
<>
<header css={sectionStyling}>
<Box css={imageWrapperStyling}>
<div />
<img src={information.imageUrl ?? DefaultThumbnail} alt="여행 대표 이미지" />
<img src={tripData.imageUrl ?? DefaultThumbnail} alt="여행 대표 이미지" />
</Box>
<Box tag="section">
<Box css={badgeWrapperStyling}>
{information.cities.map(({ id, name }) => (
{tripData.cities.map(({ id, name }) => (
<Badge key={id} css={badgeStyling}>
{name}
</Badge>
))}
</Box>
<Heading css={titleStyling} size={isMobile ? 'medium' : 'large'}>
{information.title}
{tripData.title}
</Heading>
<Text>
{formatDate(information.startDate)} - {formatDate(information.endDate)}
{formatDate(tripData.startDate)} - {formatDate(tripData.endDate)}
</Text>
<Text css={descriptionStyling} size="small">
{information.description}
{tripData.description}
</Text>
</Box>
<Box css={buttonContainerStyling}>
{isEditable ? (
<TripEditButtons tripId={information.id} openEditModal={openEditModal} />
<TripEditButtons tripId={tripData.id} openEditModal={openEditModal} />
) : (
!isShared && <TripButtons tripId={information.id} sharedCode={information.sharedCode} />
!isShared && <TripButtons tripId={tripData.id} sharedCode={tripData.sharedCode} />
)}
</Box>
</header>
{isEditModalOpen && (
<TripInfoEditModal isOpen={isEditModalOpen} onClose={closeEditModal} {...information} />
<TripInfoEditModal isOpen={isEditModalOpen} onClose={closeEditModal} {...tripData} />
)}
</>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { css } from '@emotion/react';
import { Theme } from 'hang-log-design-system';

export const shareButtonStyling = css({
marginLeft: Theme.spacer.spacing3,
height: '20px',
marginLeft: '12px',
border: 'none',

backgroundColor: 'transparent',
Expand Down
Loading

0 comments on commit ed693fa

Please sign in to comment.