Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] - touroot v1.3.2 #595

Merged
merged 143 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
143 commits
Select commit Hold shift + click to select a range
9567c54
[Feature] - 프로젝트 환경 세팅 (#4)
jinyoung234 Jul 11, 2024
f61f3a0
docs: pull request 템플릿 추가
jinyoung234 Jul 12, 2024
74b2c26
Merge branch 'main' of https://github.com/woowacourse-teams/2024-tour…
jinyoung234 Jul 12, 2024
88b5338
chore: package.json 내 broswerslist 변경
jinyoung234 Jul 12, 2024
eae8ec9
[Feature] - stylelint 설정 (#51)
jinyoung234 Jul 18, 2024
3f2bcac
[Feature] - 여행기 상세 기능 구현 (#42)
jinyoung234 Jul 18, 2024
0dbb436
[Feature] - codeowner 및 자동 할당 설정 (#59)
jinyoung234 Jul 18, 2024
fed47b2
[Feature] - 테스트 환경 설정 추가 (#58)
jinyoung234 Jul 18, 2024
5a5ec69
[Feature] Storybook 배포 설정 (#61)
jinyoung234 Jul 19, 2024
5a43f26
[Feature] - react-router-dom 설정 (#71)
simorimi Jul 20, 2024
e3cfe6f
[Feature] - 서비스 Foundation 설정 (#76)
jinyoung234 Jul 21, 2024
8a362a8
[Feature] - msw 설정 (#73)
jinyoung234 Jul 21, 2024
acffcbd
[Feature] - 여행기 등록 페이지에 필요한 공통 컴포넌트 구현(지니) (#91)
jinyoung234 Jul 23, 2024
64a8dd3
[Feature] - 여행기 등록 페이지에 필요한 공통 컴포넌트 구현(시모) (#90)
simorimi Jul 23, 2024
51f1960
[Feature] - 여행기 등록 페이지에 필요한 공통 컴포넌트 구현(리버) (#89)
0jenn0 Jul 23, 2024
75347fd
[Feature] - 여행기 등록 기능 구현 (#115)
jinyoung234 Jul 24, 2024
e0111a4
[Feature] - 로그인 페이지 구현 (#80)
simorimi Jul 25, 2024
74b3847
[Feature] - 여행 계획 등록 페이지 구현 (#125)
jinyoung234 Jul 25, 2024
db8593b
[Feature] - 메인 페이지 구현 (#78)
0jenn0 Jul 25, 2024
85269c7
[Feature] - 여행 계획 상세조회 페이지 구현 (#127)
simorimi Jul 25, 2024
c6fab4d
refactor: 네이밍 변경에 따른 수정 및 불 필요한 코드 삭제
jinyoung234 Jul 25, 2024
95beeb7
refactor: 스타일링 조정 및 stylelint에 맞게 순서 수정
jinyoung234 Jul 25, 2024
9d6d932
refactor(storybook): decorator 수정
jinyoung234 Jul 25, 2024
19b2343
chore(createPathElement): 설정
jinyoung234 Jul 25, 2024
97c834b
Merge branch 'develop/fe' of https://github.com/woowacourse-teams/202…
jinyoung234 Jul 25, 2024
a6298db
[Feature] - 2차 스프린트 QA 진행 (#141)
jinyoung234 Jul 29, 2024
246056e
Merge branch 'develop/fe' of https://github.com/woowacourse-teams/202…
jinyoung234 Jul 29, 2024
5b6067b
chore: chromatic 배포 yml 파일 추가 (#117)
jinyoung234 Jul 29, 2024
8940c34
[Feature] - CI 설정 (#66)
jinyoung234 Jul 29, 2024
41385c7
[Feature] - 3주차 스프린트 리팩토링 (#145)
0jenn0 Jul 30, 2024
9266413
fix: ci 에러 해결 (#150)
jinyoung234 Jul 30, 2024
ff4d4fa
[Feature] - sentry 세팅하기 (#168)
0jenn0 Jul 31, 2024
9c9bc7d
[Feature] - 2차 스프린트 리팩토링 (#164)
simorimi Jul 31, 2024
b687dc1
[Feature] - 전환 기능 구현 (#146)
jinyoung234 Aug 1, 2024
94ab563
[Feature] - 인가 처리 추가 (#176)
jinyoung234 Aug 1, 2024
e3c65c7
[Feature] - 상수화 작업 진행 (#188)
jinyoung234 Aug 2, 2024
95db77a
[Feature] - 타입 구조 변경 (#191)
jinyoung234 Aug 3, 2024
0c072c4
[Feature] - 여행기 무한 스크롤 관련 테스트 추가 (#166)
jinyoung234 Aug 3, 2024
342a052
[Feature] - 모달 컴포넌트 구현 (#200)
jinyoung234 Aug 3, 2024
23e8051
fix: 여행 전환 후 다른 페이지에서 다시 등록 페이지로 접근 시 데이터가 남아있는 문제 해결 (#207)
jinyoung234 Aug 5, 2024
db5c393
[Fix] - 등록 페이지에서 제목과 여행 장소 설명란 한글 입력시 제한 길이보다 1자 더 입력되는 문제 해결 (#210)
simorimi Aug 5, 2024
1cb90cf
[Feature] - Login 명세 변경 (#181)
jinyoung234 Aug 6, 2024
0e67f83
[Feature] - 메인페이지 skeleton 작업 (#221)
0jenn0 Aug 7, 2024
ac2e4f9
[Feature] - Drawer가 열려져있는 경우 화면 스크롤 안되도록 수정 (#222)
0jenn0 Aug 7, 2024
5c7eba9
[Feature] - user 컨텍스트에 access token만 담도록 수정 & 로그인/로그아웃 버튼 수정 (#224)
0jenn0 Aug 7, 2024
68144ab
[Feature] - 여행 계획 등록 기능 변경 & 테스트 추가 (#225)
jinyoung234 Aug 7, 2024
7c5363f
[Feature] - 여행 공유하기 기능 구현 (#226)
jinyoung234 Aug 7, 2024
0cc61e9
[Feature] - 여행 계획 & 여행기 삭제 기능 구현 (#229)
simorimi Aug 7, 2024
2eb318a
[Feature] - 마이 페이지 구현 (#236)
0jenn0 Aug 7, 2024
3405bb4
[Fix] - 3차 스프린트 QA 반영(리버) (#255)
0jenn0 Aug 8, 2024
0a3c6f8
[Fix] - 3차 스프린트 QA 반영(지니) (#256)
jinyoung234 Aug 8, 2024
ddc1cb0
[Feature] - sentry 초기 설정 변경 & 소스맵 설정 추가 (#261)
jinyoung234 Aug 8, 2024
2a66bba
[Fix] - 3차 스프린트 QA 반영(시모) (#262)
simorimi Aug 8, 2024
1d182e0
[Feature] - 배포한 서비스를 모니터링 하는 도구 GA 세팅 (#263)
simorimi Aug 8, 2024
053a1c4
[Fix] - 한 Day 내 중복된 장소 이름이 존재할 경우 게시물이 지속적으로 생기는 문제 해결 (#266)
jinyoung234 Aug 8, 2024
b87a781
[Fix] - 3차 스프린트 QA 반영 2차 (리버) (#276)
0jenn0 Aug 9, 2024
f3ee6ae
[Fix] - 3차 스프린트 QA 반영 2차 (시모) (#275)
simorimi Aug 9, 2024
f8d9065
[Fix] - 3차 스프린트 QA 반영 2차 (지니) (#280)
jinyoung234 Aug 9, 2024
fbb0581
refactor: 마커 색상 변경 & 여행기 상세 페이지 title & subtitle 순서 변경 (#283)
jinyoung234 Aug 9, 2024
1d96bd4
[Fix] - 만료된 access token 핸들링 (#292)
jinyoung234 Aug 13, 2024
8871599
[Fix] - 삭제 및 등록 시 여러번 요청하지 못하게 수정 (#295)
simorimi Aug 13, 2024
2dffa25
[Feature] - refresh token 클라이언트 내 적용 (#307)
jinyoung234 Aug 14, 2024
56f7c70
[Feature] - TravelogueCard 컴포넌트 리팩터링 (#314)
jinyoung234 Aug 14, 2024
871c5ce
[Feature] - Input 컴포넌트 리팩토링 (#310)
0jenn0 Aug 14, 2024
6639505
Fix - image error 처리 누락, 여행기 삭제시 마이페이지로 넘어갈 때 tab 초기값 수정 , 여행기 썸네일 (#…
0jenn0 Aug 14, 2024
9005dc5
[Fix] - Icon, Icon Button storybook에서 iconType option 적용되도록 수정 (#327)
0jenn0 Aug 17, 2024
b7ed482
[Feature] - 여행 계획 TO DO 기능 구현 (#333)
jinyoung234 Aug 18, 2024
33680b8
[Feature] - tag 기능 구현 (#335)
simorimi Aug 18, 2024
339281f
[Feature] - 여행기 장소 이미지 업로드 중일 경우, spinner를 보여주도록 리팩터링 (#332)
jinyoung234 Aug 19, 2024
264c01b
[Feature] - 사용자 닉네임 수정 (#317)
0jenn0 Aug 19, 2024
32d759d
[Feature] - 검색 구현 (#328)
0jenn0 Aug 19, 2024
9b6c78e
[Feature] - 여행기 상세보기 페이지에서 지도 상세보기 구현 (#334)
0jenn0 Aug 19, 2024
d71225d
[Feature] - 여행기 좋아요 기능 구현 (#342)
jinyoung234 Aug 20, 2024
f9834b1
[Feature] - 썸네일 에러 발생 시 예외 처리 추가 (#356)
jinyoung234 Aug 20, 2024
d02f4fa
[Feature] - 여행기 및 여행 계획 수정 페이지 구현 (#348)
simorimi Aug 20, 2024
ef2ab4f
[Feature] - 플로팅 버튼에 여행 계획 작성 추가 (#368)
simorimi Aug 21, 2024
68e7d15
[Feature] - required 구현 (#361)
0jenn0 Aug 21, 2024
d36d916
[Fix] - 4차 스프린트 QA 반영 1차 (시모) (#374)
simorimi Aug 22, 2024
7552cbb
[Fix] - 4차 스프린트 QA 반영 1차 (지니) (#375)
jinyoung234 Aug 22, 2024
5fbbf11
[Feature] - 프론트엔드 dev, prod 분리 작업 (#378)
jinyoung234 Aug 22, 2024
7190acd
[Fix] - 4차 스프린트 QA 반영 1차 (리버) (#376)
0jenn0 Aug 22, 2024
92920ef
[Feature] - 404 NotFound 페이지 구현 (#380)
0jenn0 Aug 22, 2024
8790e29
[Fix] - 로딩, 에러 처리 및 메인페이지, 로그인 콜백 페이지 오류 수정 (#391)
simorimi Aug 22, 2024
cd346aa
[Fix] - 여행 계획 수정, 마이페이지, 검색 페이지 에러 핸들링 (#393)
0jenn0 Aug 22, 2024
02915f5
[Fix] - 여행기 등록 & 수정, 여행 계획 등록, 여행 계획 상세 페이지 예외 및 로딩 처리 (#394)
jinyoung234 Aug 22, 2024
5729b7b
[Fix] - 4차 스프린트 QA 반영 2차 (시모) (#400)
simorimi Aug 22, 2024
c4129da
[Fix] - 4차 스프린트 QA 반영 2차 (리버) (#401)
0jenn0 Aug 22, 2024
399e11b
[Fix] - 4차 스프린트 QA 반영 2차 (지니) (#402)
jinyoung234 Aug 22, 2024
5f5a098
fix: 여행 계획 상세 페이지 내 작성자 아닌 게시물 접근 시 alert가 2번 뜨는 현상 개선 (#404)
jinyoung234 Aug 22, 2024
d594224
[Fix] - line height,shareModal 수정 (#407)
0jenn0 Aug 23, 2024
bd1fe8c
v1.0.1
simorimi Aug 23, 2024
75b3da2
Merge branch 'production/fe' into develop/fe
jinyoung234 Aug 23, 2024
834063a
[Feature] - e2e 테스트 초기 설정 및 여행 계획 등록, 로그인, 메인 페이지 e2e 테스트 구현 (#412)
jinyoung234 Sep 15, 2024
4d66c7b
[Feature] - 여행 계획 등록 페이지 리팩터링 (#414)
jinyoung234 Sep 15, 2024
6e537c0
fix: 폰트 import path 수정 (#429)
jinyoung234 Sep 23, 2024
d39bcd1
[Feature] - kakao bundle lazy loading 적용 (#430)
jinyoung234 Sep 23, 2024
f226563
[Feature] - 데모데이 피드백 반영(지니) (#418)
jinyoung234 Sep 25, 2024
dedf12d
[Feature] - webpack 캐시 버스팅 설정 (#447)
jinyoung234 Sep 26, 2024
8b5c1c3
[Feature] - 코드 스플리팅 설정 (#450)
jinyoung234 Sep 26, 2024
946d03e
[Feature] - 여행 계획 상세 페이지 성능 최적화 (#453)
jinyoung234 Sep 26, 2024
923fdc8
[Feature] - Layout Shift 개선 (#454)
simorimi Sep 26, 2024
e4eb2fb
[Feature] - 이미지 최적화 (#455)
0jenn0 Sep 26, 2024
3c83966
v1.1.0
jinyoung234 Sep 26, 2024
b26edb2
Merge branch 'production/fe' into develop/fe
jinyoung234 Sep 26, 2024
cf7943c
[Feature] - 데모데이 피드백 반영(시모) (#434)
simorimi Sep 26, 2024
a78cad1
[Feature] - 데모데이 피드백 반영(리버) (#444)
0jenn0 Sep 26, 2024
5547064
fix(MainPage): 테그 필터링 스크롤 되지 않는 문제 해결 (#460)
simorimi Sep 26, 2024
77101e6
[Fix] - 검색 페이지 탭바 width 수정, 여행기 수정페이지에서 이미지 최적화 안됨 (#462)
0jenn0 Sep 26, 2024
3392b4a
fix: 검색 페이지는 코드 스플리팅을 하지 않는 것으로 변경 (#465)
jinyoung234 Sep 26, 2024
61d02fe
fix(NotFound): NotFound 버튼 텍스트 수정 (#473)
jinyoung234 Sep 26, 2024
0088feb
[Fix] - tag filter 및 sort localStorage key 값이 공유되는 현상 해결 및 태그 변경시 최상단…
simorimi Sep 26, 2024
54f4694
[Fix] - 상세보기에서 좋아요 누를 때마다 지도 움직이는 문제 & 사용자가 지도를 확대하지 못하는 문제 해결 (#478)
jinyoung234 Sep 27, 2024
9383d7a
[Fix] - 5차 스프린트 QA 반영 1차 (리버) (#479)
0jenn0 Sep 27, 2024
eed5d15
[Fix] - 5차 스프린트 QA 반영 1차 (시모) (#485)
simorimi Sep 27, 2024
60957ce
v1.2.0
jinyoung234 Sep 27, 2024
08c0a1d
Merge branch 'production/fe' into develop/fe
jinyoung234 Sep 27, 2024
9ca4b40
[Refactor] - API 요청 및 응답 명세 통일 (#508)
simorimi Oct 7, 2024
33aeb8a
[Feature] - Immer을 사용한 코드 구조 개선 (#495)
jinyoung234 Oct 7, 2024
0c37e9f
fix(GoogleMapLoadScript): 구글맵을 한국어로 받아오도록 수정 (#488)
0jenn0 Oct 14, 2024
a2351d2
[Feature] - 여행 계획 & 여행기 상세 페이지로 이동 시 scroll 최상단으로 이동 되도록 변경 (#511)
jinyoung234 Oct 14, 2024
267a0ff
[Feature] - 여행기 & 여행 계획 등록/수정 페이지 리팩터링 (#520)
jinyoung234 Oct 14, 2024
b1371a0
[Feature] - 프로필 이미지 수정 기능 및 여행기 등록 시 여행 장소마다 국가 코드 주도록 구현 (#535)
simorimi Oct 21, 2024
9a2ea31
[Fix] - 6차 피드백 반영(시모) (#545)
simorimi Oct 21, 2024
23e234e
[Feature] - 메인 페이지, 로그인 페이지 웹 접근성 개선 (#529)
0jenn0 Oct 22, 2024
4a34949
[Feature] - 마이페이지 좋아요 탭 및 검색 창 국가 탭 기능 구현 (#556)
simorimi Oct 22, 2024
74c9dfb
[Fix] - 여행기 & 여행 계획 등록 과정에서 클라이언트 내에서 유효성 검사를 하도록 변경 (#537)
jinyoung234 Oct 23, 2024
8cab7f8
[Feature] - 랜딩 페이지 구현 (#539)
0jenn0 Oct 23, 2024
f6c4453
[Feature] - 여행기 및 여행 계획 상세페이지 접근성 개선 (#566)
simorimi Oct 23, 2024
6ad4826
[Feature] - 여행 계획 등록 페이지 접근성 개선 (#554)
jinyoung234 Oct 23, 2024
d729bd4
fix(router): lazy loading 제거 (#558)
jinyoung234 Oct 23, 2024
ed2c51b
fix: 토큰 만료시 토큰 재발급을 하지 않는 이슈 해결 (#560)
jinyoung234 Oct 23, 2024
0b3b3ee
[Feature] - 검색 결과 페이지 내 필터링 옵션 적용 (#565)
jinyoung234 Oct 23, 2024
e970e20
[Fix] - 메인페이지 modal css 깨짐 및 modal, drawer 애니메이션 적용 안되던 이슈 수정 (#567)
0jenn0 Oct 23, 2024
8017c22
Merge branch 'production/fe' into develop/fe
jinyoung234 Oct 23, 2024
b106c74
[Fix] - 6차 데모데이 1차 QA(지니) (#580)
jinyoung234 Oct 24, 2024
c8102c1
[Fix] - 6차 데모데이 1차 QA(시모) (#578)
simorimi Oct 24, 2024
b220ad8
[Fix] - 6차 데모데이 1차 QA(리버) (#581)
0jenn0 Oct 24, 2024
9f5d3af
[Fix] - 랜딩 페이지 페이지 잘리는 문제 및 todo 세로 배열이 맞지 않는 문제 (#583)
simorimi Oct 24, 2024
a6f7777
[Fix] - 랜딩페이지 화살표 위치 문제 해결 및 두번째 페이지 에니메이션 문제 해결 (#585)
simorimi Oct 24, 2024
5c0fc9c
Merge branch 'production/fe' into develop/fe
jinyoung234 Oct 24, 2024
0f9561f
[Fix] - 6차 데모데이 2차 QA(지니) (#593)
jinyoung234 Oct 24, 2024
0262eb7
fix(MainPage): 더보기 버튼 보이는 문제 해결 (#592)
simorimi Oct 24, 2024
3ba0579
[Fix] - 6차 데모데이 2차 QA(리버) (#594)
0jenn0 Oct 24, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@tanstack/react-query-devtools": "^5.51.1",
"axios": "^1.7.2",
"dotenv-webpack": "^8.1.0",
"heic2any": "^0.0.4",
"immer": "^10.1.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { css } from "@emotion/react";
import { css, keyframes } from "@emotion/react";
import styled from "@emotion/styled";

import theme from "@styles/theme";
Expand Down Expand Up @@ -61,3 +61,21 @@ export const Gradient = styled.div`
height: 20rem;
background: linear-gradient(to bottom, rgb(255 255 255 / 0%) 0%, rgb(255 255 255 / 50%) 100%);
`;

const float = keyframes`
0% { transform: translateY(0px); }
50% { transform: translateY(-1rem); }
100% { transform: translateY(0px); }
`;

export const iconStyle = css`
position: absolute;
bottom: 0;
z-index: ${theme.zIndex.toast};
padding: ${theme.spacing.m};
opacity: 0.5;

background-color: transparent;

animation: ${float} 1s ease-in-out infinite;
`;
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { useNavigate } from "react-router-dom";

import { Button, Text } from "@components/common";
import { Button, Icon, Text } from "@components/common";

import { ROUTE_PATHS_MAP } from "@constants/route";

import { PRIMITIVE_COLORS } from "@styles/tokens";

import { BigTturi } from "@assets/webp";

import { createAnimation } from "../Animation.styled";
Expand Down Expand Up @@ -47,6 +49,7 @@ const FirstPage = () => {
</S.Container>
<S.Gradient />
<S.Image src={BigTturi} alt="" />
<Icon iconType="down-arrow" size="60" color={PRIMITIVE_COLORS.white} css={S.iconStyle} />
</S.Layout>
);
};
Expand Down
8 changes: 0 additions & 8 deletions frontend/src/components/pages/landing/LandingPage.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,3 @@ export const firstPageStyle = css`
top: 0;
z-index: 1;
`;

export const secondPageStyle = css`
position: absolute;
top: 100vh;
z-index: 2;
width: 100%;
transition: transform 0.1s ease-out;
`;
7 changes: 1 addition & 6 deletions frontend/src/components/pages/landing/LandingPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,15 @@ import FourthPage from "./FourthPage/FourthPage";
import * as S from "./LandingPage.styled";
import SecondPage from "./SecondPage/SecondPage";
import ThirdPage from "./ThirdPage/ThirdPage";
import useScrollAnimation from "./hook/useScrollAnimation";

const LandingPage = () => {
const [secondPageRef] = useScrollAnimation();

return (
<S.Layout>
<S.PageWrapper>
<div css={S.firstPageStyle}>
<FirstPage />
</div>
<div css={S.secondPageStyle} ref={secondPageRef}>
<SecondPage />
</div>
<SecondPage />
</S.PageWrapper>
<ThirdPage />
<FourthPage />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { css, keyframes } from "@emotion/react";
import { css } from "@emotion/react";

import theme from "@styles/theme";
import { PRIMITIVE_COLORS } from "@styles/tokens";
Expand Down Expand Up @@ -99,24 +99,6 @@ export const emojiStyle = css`
z-index: 10;
`;

const float = keyframes`
0% { transform: translateY(0px); }
50% { transform: translateY(-1rem); }
100% { transform: translateY(0px); }
`;

export const buttonStyle = css`
position: absolute;
top: -5.8rem;
z-index: ${theme.zIndex.toast};
padding: ${theme.spacing.m};
opacity: 0.5;

background-color: transparent;

animation: ${float} 1s ease-in-out infinite;
`;

export const primaryText = css`
color: ${theme.colors.primary};
`;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { Icon, Text } from "@components/common";

import { PRIMITIVE_COLORS } from "@styles/tokens";
import { Text } from "@components/common";

import { MainPageImage } from "@assets/webp";

Expand All @@ -14,7 +12,6 @@ const SecondPage = () => {

return (
<div css={S.layout}>
<Icon iconType="down-arrow" size="60" color={PRIMITIVE_COLORS.white} css={S.buttonStyle} />
<div css={S.contentContainer}>
<Box
ref={registerElement("Box1")}
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/components/pages/main/MainPage.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,18 +125,18 @@ export const MainPageList = styled.li`
export const FetchButton = styled.button`
position: fixed;
bottom: 0;
left: 0;
left: -10rem;
z-index: ${({ theme }) => theme.zIndex.floating};
padding: ${({ theme }) => theme.spacing.xs};

background-color: ${PRIMITIVE_COLORS.black};

color: ${PRIMITIVE_COLORS.white};

transform: translateY(100%);
transition: transform 0.3s;
transform: translateX(0);

&:focus {
transform: translateY(0);
transform: translateX(10rem);
transition: transform 0.3s;
}
`;
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useNavigate } from "react-router-dom";
import { useBeforeUnload, useNavigate } from "react-router-dom";

import {
Accordion,
Expand All @@ -18,6 +18,7 @@ import { useTravelPlanInitialization } from "@components/pages/travelPlanEdit/ho
import TravelPlanDayAccordion from "@components/pages/travelPlanRegister/TravelPlanDayAccordion/TravelPlanDayAccordion";

import useTravelPlanFormState from "@hooks/pages/useTravelPlanFormState/useTravelPlanFormState";
import usePrompt from "@hooks/usePrompt";
import useToggle from "@hooks/useToggle";

import { ERROR_MESSAGE_MAP } from "@constants/errorMessage";
Expand Down Expand Up @@ -69,6 +70,15 @@ const TravelPlanEditPage = () => {

const navigate = useNavigate();

usePrompt({
message: "사이트에서 나가시겠습니까?",
when: ({ currentLocation, nextLocation }) => currentLocation.pathname !== nextLocation.pathname,
});

useBeforeUnload((event) => {
event.preventDefault();
});

if (status === "error") {
const errorMessage =
error?.message === ERROR_MESSAGE_MAP.api.travelPlanOnlyWriter
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { useBeforeUnload } from "react-router-dom";

import { useTravelTransformDetailContext } from "@contexts/TravelTransformDetailProvider";

import {
Expand All @@ -18,6 +20,7 @@ import useTravelPlanRegister from "@components/pages/travelPlanRegister/hooks/us

import useTravelPlanFormState from "@hooks/pages/useTravelPlanFormState/useTravelPlanFormState";
import useAuthRedirect from "@hooks/useAuthRedirect";
import usePrompt from "@hooks/usePrompt";
import useToggle from "@hooks/useToggle";

import { CYPRESS_DATA_MAP } from "@constants/cypress";
Expand Down Expand Up @@ -69,8 +72,22 @@ const TravelPlanRegisterPage = () => {
handleBottomSheetClose,
);

usePrompt({
message: "사이트에서 나가시겠습니까?",
when: ({ currentLocation, nextLocation }) => currentLocation.pathname !== nextLocation.pathname,
});

useAuthRedirect();

usePrompt({
message: "사이트에서 나가시겠습니까?",
when: ({ currentLocation, nextLocation }) => currentLocation.pathname !== nextLocation.pathname,
});

useBeforeUnload((event) => {
event.preventDefault();
});

return (
<>
<S.Layout>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { useBeforeUnload } from "react-router-dom";

import {
Accordion,
Button,
Expand All @@ -18,6 +20,7 @@ import TravelogueDayAccordion from "@components/pages/travelogueRegister/Travelo

import useTravelogueFormState from "@hooks/pages/useTravelogueFormState/useTravelogueFormState";
import { useDragScroll } from "@hooks/useDragScroll";
import usePrompt from "@hooks/usePrompt";
import useToggle from "@hooks/useToggle";
import useUnmountAnimation from "@hooks/useUnmountAnimation";

Expand Down Expand Up @@ -78,6 +81,15 @@ const TravelogueEditPage = () => {
handleInitializeThumbnail,
});

usePrompt({
message: "사이트에서 나가시겠습니까?",
when: ({ currentLocation, nextLocation }) => currentLocation.pathname !== nextLocation.pathname,
});

useBeforeUnload((event) => {
event.preventDefault();
});

return (
<>
<S.Layout>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ interface ImageState {
isLoading: boolean;
}

const MAX_FILE_SIZE = 25 * 1024 * 1024; // 25MB in bytes

export const useTravelogueMultiImageUpload = ({
dayIndex,
placeIndex,
Expand Down Expand Up @@ -71,18 +73,20 @@ export const useTravelogueMultiImageUpload = ({
};

const handleChangeImage = async (e: React.ChangeEvent<HTMLInputElement>) => {
if (isPaused) {
alert(ERROR_MESSAGE_MAP.network);
return;
}

const files = Array.from(e.target.files as FileList);

if (imageStates.length + files.length > MAX_IMAGE_UPLOAD_COUNT) {
alert(ERROR_MESSAGE_MAP.imageUpload);
return;
}

const oversizedFile = files.find((file) => file.size > MAX_FILE_SIZE);

if (oversizedFile) {
alert(`파일 '${oversizedFile.name}'이 25MB 제한을 초과했습니다.`);
return;
}

try {
addLoadingImageStates(files);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { useBeforeUnload } from "react-router-dom";

import { useTravelTransformDetailContext } from "@contexts/TravelTransformDetailProvider";

import {
Expand All @@ -20,6 +22,7 @@ import useTravelogueRegister from "@components/pages/travelogueRegister/hooks/us
import useTravelogueFormState from "@hooks/pages/useTravelogueFormState/useTravelogueFormState";
import useAuthRedirect from "@hooks/useAuthRedirect";
import { useDragScroll } from "@hooks/useDragScroll";
import usePrompt from "@hooks/usePrompt";
import useToggle from "@hooks/useToggle";

import { FORM_VALIDATIONS_MAP } from "@constants/formValidation";
Expand Down Expand Up @@ -57,6 +60,15 @@ const TravelogueRegisterPage = () => {
isEnabledForm,
} = useTravelogueFormState(transformDetail?.days ?? []);

usePrompt({
message: "사이트에서 나가시겠습니까?",
when: ({ currentLocation, nextLocation }) => currentLocation.pathname !== nextLocation.pathname,
});

useBeforeUnload((event) => {
event.preventDefault();
});

const payload = {
title,
thumbnail: thumbnail || (process.env.DEFAULT_THUMBNAIL_IMAGE ?? ""),
Expand Down
28 changes: 22 additions & 6 deletions frontend/src/hooks/useModalControl.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useEffect } from 'react';
import usePressESC from '@hooks/usePressESC';
import { useEffect } from "react";

import usePressESC from "@hooks/usePressESC";

/**
* modal control에 관한 훅입니다.
Expand All @@ -10,11 +11,26 @@ const useModalControl = <T extends (...args: unknown[]) => void>(isOpen: boolean
usePressESC(isOpen, onToggle);

useEffect(() => {
if (isOpen) document.body.style.overflow = 'hidden';
if (isOpen) {
const scrollY = window.scrollY;

document.body.style.position = "fixed";
document.body.style.width = "100%";
document.body.style.top = `-${scrollY}px`;
document.body.style.overflow = "hidden";

document.body.style.touchAction = "none";

return () => {
document.body.style.position = "";
document.body.style.width = "";
document.body.style.top = "";
document.body.style.overflow = "auto";
document.body.style.touchAction = "";

return () => {
document.body.style.overflow = 'auto';
};
window.scrollTo(0, scrollY);
};
}
}, [isOpen]);
};

Expand Down
25 changes: 25 additions & 0 deletions frontend/src/hooks/usePrompt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { useEffect } from "react";
import { BlockerFunction, useBlocker } from "react-router-dom";

const usePrompt = ({ when, message }: { when: boolean | BlockerFunction; message: string }) => {
const blocker = useBlocker(when);

useEffect(() => {
if (blocker.state === "blocked") {
const proceed = window.confirm(message);
if (proceed) {
setTimeout(blocker.proceed, 0);
} else {
blocker.reset();
}
}
}, [blocker, message]);

useEffect(() => {
if (blocker.state === "blocked" && !when) {
blocker.reset();
}
}, [blocker, when]);
};

export default usePrompt;
Loading
Loading