From 5f95112e168a337ac7f1dcf0975c7482d25de153 Mon Sep 17 00:00:00 2001 From: Dahye Yun <102305630+Dahyeeee@users.noreply.github.com> Date: Mon, 11 Sep 2023 15:35:50 +0900 Subject: [PATCH] =?UTF-8?q?=EB=AA=A8=EB=B0=94=EC=9D=BC=20=EB=B2=84?= =?UTF-8?q?=EC=A0=84=EC=97=90=EC=84=9C=20=EC=A7=80=EB=8F=84=20=EB=B3=BC=20?= =?UTF-8?q?=EC=88=98=20=EC=9E=88=EB=8A=94=20=EA=B8=B0=EB=8A=A5=20(#544)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 모바일에서 지도보기 버튼 추가, 지도 보는 기능 * refactor: 트립페이지 모바일 버전 컴포넌트 분리 * feat: 모바일에서 지도볼때도 daylog tab보이도록 수정 * refactor: 버튼 스타일 수정, 패딩 수정 * chore: 리베이스로 인한 버그 수정 --- .../common/DayLogList/DayLogList.style.ts | 2 +- .../src/pages/TripPage/TripMobilePage.tsx | 102 ++++++++++++++++++ frontend/src/pages/TripPage/TripPage.style.ts | 43 +++++++- frontend/src/pages/TripPage/TripPage.tsx | 26 ++--- frontend/src/router/AppRouter.tsx | 4 +- frontend/src/router/lazy.ts | 4 + frontend/webpack.config.js | 7 +- 7 files changed, 161 insertions(+), 27 deletions(-) create mode 100644 frontend/src/pages/TripPage/TripMobilePage.tsx diff --git a/frontend/src/components/common/DayLogList/DayLogList.style.ts b/frontend/src/components/common/DayLogList/DayLogList.style.ts index 0e842c4d7..2f9d6fe8d 100644 --- a/frontend/src/components/common/DayLogList/DayLogList.style.ts +++ b/frontend/src/components/common/DayLogList/DayLogList.style.ts @@ -11,7 +11,7 @@ export const containerStyling = css({ padding: `${Theme.spacer.spacing4} 50px`, '@media screen and (max-width: 600px)': { - padding: Theme.spacer.spacing4, + padding: `${Theme.spacer.spacing2} ${Theme.spacer.spacing4}`, }, '& > ul': { diff --git a/frontend/src/pages/TripPage/TripMobilePage.tsx b/frontend/src/pages/TripPage/TripMobilePage.tsx new file mode 100644 index 000000000..73b4fa53d --- /dev/null +++ b/frontend/src/pages/TripPage/TripMobilePage.tsx @@ -0,0 +1,102 @@ +import { useMemo, useState } from 'react'; +import { useParams } from 'react-router-dom'; + +import { Button, Flex, Tab, Tabs, useSelect } from 'hang-log-design-system'; + +import { + buttonContainerStyling, + buttonStyling, + containerStyling, + contentStyling, + mapMobileContainerStyling, +} from '@pages/TripPage/TripPage.style'; + +import DayLogItem from '@components/common/DayLogItem/DayLogItem'; +import GoogleMapWrapper from '@components/common/GoogleMapWrapper/GoogleMapWrapper'; +import TripInformation from '@components/common/TripInformation/TripInformation'; +import TripMap from '@components/common/TripMap/TripMap'; + +import { useTripQuery } from '@hooks/api/useTripQuery'; +import { useTrip } from '@hooks/trip/useTrip'; + +import { formatMonthDate } from '@utils/formatter'; + +const TripMobilePage = () => { + const [isDaylogShown, setIsDaylogShown] = useState(true); + const { tripId } = useParams(); + + const { tripData } = useTripQuery(Number(tripId)); + + const { selected: selectedDayLogId, handleSelectClick: handleDayLogIdSelectClick } = useSelect( + tripData.dayLogs[0].id + ); + const selectedDayLog = tripData.dayLogs.find((log) => log.id === selectedDayLogId)!; + const { dates } = useTrip(Number(tripId)); + + const places = useMemo( + () => + selectedDayLog.items + .filter((item) => item.itemType) + .map((item) => ({ + id: item.id, + name: item.title, + coordinate: { lat: item.place!.latitude, lng: item.place!.longitude }, + })), + [selectedDayLog.items] + ); + + return ( + +
+ +
+ + {dates.map((date, index) => { + const isLast = index === dates.length - 1; + const tabText = + date.id === selectedDayLog.id + ? `Day ${index + 1} - ${formatMonthDate(date.date)} ` + : `Day ${index + 1}`; + + return ( + + ); + })} + + {isDaylogShown && ( + + )} +
+
+ {!isDaylogShown && ( +
+ + + +
+ )} +
+ +
+
+ ); +}; + +export default TripMobilePage; diff --git a/frontend/src/pages/TripPage/TripPage.style.ts b/frontend/src/pages/TripPage/TripPage.style.ts index 6a271788f..e55161f08 100644 --- a/frontend/src/pages/TripPage/TripPage.style.ts +++ b/frontend/src/pages/TripPage/TripPage.style.ts @@ -1,5 +1,7 @@ import { css } from '@emotion/react'; +import { Theme } from 'hang-log-design-system'; + export const containerStyling = css({ position: 'relative', @@ -13,6 +15,7 @@ export const containerStyling = css({ '@media screen and (max-width: 600px)': { width: '100vw', + paddingBottom: '0', }, }); @@ -23,10 +26,13 @@ export const mapContainerStyling = css({ width: '50vw', height: 'calc(100vh - 81px)', +}); - '@media screen and (max-width: 600px)': { - height: 'calc(100vh - 65px)', - }, +export const mapMobileContainerStyling = css({ + position: 'sticky', + + width: '100vw', + height: 'calc(100vh - 65px)', }); export const skeletonContainerStyling = css({ @@ -34,3 +40,34 @@ export const skeletonContainerStyling = css({ borderRadius: 0, }, }); + +export const buttonContainerStyling = css({ + position: 'fixed', + bottom: '30px', + display: 'flex', + width: '100%', + alignItems: 'center', + justifyContent: 'center', +}); + +export const contentStyling = css({ + display: 'flex', + flexDirection: 'column', + gap: Theme.spacer.spacing4, + + width: '100%', + padding: `${Theme.spacer.spacing4} 50px`, + + '@media screen and (max-width: 600px)': { + padding: `${Theme.spacer.spacing3} ${Theme.spacer.spacing4} 0 ${Theme.spacer.spacing4}`, + }, + + '& > ul': { + width: '100%', + }, +}); + +export const buttonStyling = css({ + borderRadius: '40px', + boxShadow: Theme.boxShadow.shadow8, +}); diff --git a/frontend/src/pages/TripPage/TripPage.tsx b/frontend/src/pages/TripPage/TripPage.tsx index e68f3546b..3db990c4b 100644 --- a/frontend/src/pages/TripPage/TripPage.tsx +++ b/frontend/src/pages/TripPage/TripPage.tsx @@ -1,8 +1,6 @@ import { useMemo } from 'react'; import { useParams } from 'react-router-dom'; -import { useRecoilValue } from 'recoil'; - import { Flex, useSelect } from 'hang-log-design-system'; import { containerStyling, mapContainerStyling } from '@pages/TripPage/TripPage.style'; @@ -14,15 +12,11 @@ import TripMap from '@components/common/TripMap/TripMap'; import { useTripQuery } from '@hooks/api/useTripQuery'; -import { mediaQueryMobileState } from '@store/mediaQuery'; - const TripPage = () => { const { tripId } = useParams(); if (!tripId) throw new Error('존재하지 않는 tripId 입니다.'); - const isMobile = useRecoilValue(mediaQueryMobileState); - const { tripData } = useTripQuery(Number(tripId)); const { selected: selectedDayLogId, handleSelectClick: handleDayLogIdSelectClick } = useSelect( @@ -53,17 +47,15 @@ const TripPage = () => { onTabChange={handleDayLogIdSelectClick} /> - {!isMobile && ( -
- - - -
- )} +
+ + + +
); }; diff --git a/frontend/src/router/AppRouter.tsx b/frontend/src/router/AppRouter.tsx index 826dd5e55..541b0bf1d 100644 --- a/frontend/src/router/AppRouter.tsx +++ b/frontend/src/router/AppRouter.tsx @@ -12,6 +12,7 @@ import TripPageSkeleton from '@pages/TripPage/TripPageSkeleton'; import TripsPageSkeleton from '@pages/TripsPage/TripsPageSkeleton'; import { isLoggedInState } from '@store/auth'; +import { mediaQueryMobileState } from '@store/mediaQuery'; import * as Lazy from '@router/lazy'; @@ -19,6 +20,7 @@ import { PATH } from '@constants/path'; const AppRouter = () => { const isLoggedIn = useRecoilValue(isLoggedInState); + const isMobile = useRecoilValue(mediaQueryMobileState); const router = createBrowserRouter([ { @@ -40,7 +42,7 @@ const AppRouter = () => { path: PATH.TRIP(':tripId'), element: ( }> - + {isMobile ? : } ), }, diff --git a/frontend/src/router/lazy.ts b/frontend/src/router/lazy.ts index 14f81ed95..98b89207f 100644 --- a/frontend/src/router/lazy.ts +++ b/frontend/src/router/lazy.ts @@ -30,6 +30,10 @@ export const TripPage = lazy( () => import(/* webpackChunkName: "TripPage" */ '@pages/TripPage/TripPage') ); +export const TripMobilePage = lazy( + () => import(/* webpackChunkName: "TripPage" */ '@pages/TripPage/TripMobilePage') +); + export const TripsPage = lazy( () => import(/* webpackChunkName: "TripsPage" */ '@pages/TripsPage/TripsPage') ); diff --git a/frontend/webpack.config.js b/frontend/webpack.config.js index da59009e8..31b59fa90 100644 --- a/frontend/webpack.config.js +++ b/frontend/webpack.config.js @@ -5,6 +5,7 @@ const path = require('path'); const webpack = require('webpack'); const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); const CompressionPlugin = require('compression-webpack-plugin'); +const CopyPlugin = require('copy-webpack-plugin'); const prod = process.env.NODE_ENV === 'production'; @@ -29,8 +30,6 @@ const plugins = [ ]; if (!prod) { - const CopyPlugin = require('copy-webpack-plugin'); - plugins.push( new CopyPlugin({ patterns: [{ from: 'public/mockServiceWorker.js', to: '' }], @@ -42,9 +41,7 @@ module.exports = { mode: prod ? 'production' : 'development', devtool: prod ? 'hidden-source-map' : 'eval', entry: './src/index.tsx', - resolve: { - extensions: ['.js', '.jsx', '.ts', '.tsx'], - }, + module: { rules: [ {