From 072c383b78439a45b1b5086d687624123ee9b469 Mon Sep 17 00:00:00 2001 From: Ashley Heo Date: Tue, 8 Aug 2023 00:00:16 +0900 Subject: [PATCH 1/9] =?UTF-8?q?feat:=20useMediaQuery=20=ED=9B=85=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/App.tsx | 2 ++ frontend/src/constants/ui.ts | 2 ++ frontend/src/hooks/common/useMediaQuery.ts | 31 ++++++++++++++++++++++ frontend/src/store/mediaQuery.ts | 11 ++++++++ 4 files changed, 46 insertions(+) create mode 100644 frontend/src/hooks/common/useMediaQuery.ts create mode 100644 frontend/src/store/mediaQuery.ts diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 2e4791727..95cba85e6 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,5 +1,6 @@ import { Outlet } from 'react-router-dom'; +import { useMediaQuery } from '@hooks/common/useMediaQuery'; import { useResetError } from '@hooks/common/useResetError'; import Error from '@components/common/Error/Error'; @@ -10,6 +11,7 @@ import Header from '@components/layout/Header/Header'; const App = () => { const { handleErrorReset } = useResetError(); + useMediaQuery(); return ( diff --git a/frontend/src/constants/ui.ts b/frontend/src/constants/ui.ts index f065a9ad0..53bddb040 100644 --- a/frontend/src/constants/ui.ts +++ b/frontend/src/constants/ui.ts @@ -9,3 +9,5 @@ export const TRIP_ITEM_ADD_MAX_IMAGE_UPLOAD_COUNT = 5; export const EXPENSE_CATEGORY_INFORMATION_SKELETON_LENGTH = 6; export const EXPENSE_LIST_SKELETON_LENGTH = 5; + +export const MOBILE_MEDIA_QUERY_SIZE = '(max-width: 600px)'; diff --git a/frontend/src/hooks/common/useMediaQuery.ts b/frontend/src/hooks/common/useMediaQuery.ts new file mode 100644 index 000000000..0218c6645 --- /dev/null +++ b/frontend/src/hooks/common/useMediaQuery.ts @@ -0,0 +1,31 @@ +import { MOBILE_MEDIA_QUERY_SIZE } from '@constants/ui'; +import { mediaQueryMobileState, viewportWidthState } from '@store/mediaQuery'; +import { useCallback, useEffect, useRef } from 'react'; +import { useSetRecoilState } from 'recoil'; + +export const useMediaQuery = () => { + const setViewportWidth = useSetRecoilState(viewportWidthState); + const setIsMobile = useSetRecoilState(mediaQueryMobileState); + const mediaQueryRef = useRef(null); + + const handleWindowResize = useCallback(() => { + setIsMobile(window.matchMedia(MOBILE_MEDIA_QUERY_SIZE).matches); + setViewportWidth(window.innerWidth); + }, [setIsMobile, setViewportWidth]); + + useEffect(() => { + setIsMobile(window.matchMedia(MOBILE_MEDIA_QUERY_SIZE).matches); + setViewportWidth(window.innerWidth); + }, [setIsMobile, setViewportWidth]); + + useEffect(() => { + const mediaQueryList = window.matchMedia(MOBILE_MEDIA_QUERY_SIZE); + mediaQueryRef.current = mediaQueryList; + + mediaQueryRef.current.addEventListener('change', handleWindowResize); + + return () => { + mediaQueryRef.current?.removeEventListener('change', handleWindowResize); + }; + }, [handleWindowResize]); +}; diff --git a/frontend/src/store/mediaQuery.ts b/frontend/src/store/mediaQuery.ts new file mode 100644 index 000000000..5a4b46cba --- /dev/null +++ b/frontend/src/store/mediaQuery.ts @@ -0,0 +1,11 @@ +import { atom } from 'recoil'; + +export const mediaQueryMobileState = atom({ + key: 'mediaQueryMobile', + default: false, +}); + +export const viewportWidthState = atom({ + key: 'viewportWidth', + default: 0, +}); From 237b2ffb8c18e067c7e46b1297b6eae7b62c2b79 Mon Sep 17 00:00:00 2001 From: Ashley Heo Date: Tue, 8 Aug 2023 00:03:28 +0900 Subject: [PATCH 2/9] =?UTF-8?q?feat:=20TripEditPage=20=EB=B0=98=EC=9D=91?= =?UTF-8?q?=ED=98=95=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DayLogItem/TitleInput/TitleInput.style.ts | 5 +++ .../common/DayLogList/DayLogList.style.ts | 4 +++ .../TripInformation/TripInformation.style.ts | 26 +++++++++++++++- .../TripInformation/TripInformation.tsx | 12 ++++--- .../TripItem/EditMenu/EditMenu.style.ts | 16 +++++++--- .../common/TripItem/EditMenu/EditMenu.tsx | 8 +++-- .../common/TripItem/TripItem.style.ts | 10 ++++++ .../components/common/TripItem/TripItem.tsx | 31 ++++++++++++++----- .../common/TripItemList/TripItemList.tsx | 3 +- .../TripItemAddModal/DateInput/DateInput.tsx | 3 +- .../trips/TripsItem/TripsItem.style.ts | 2 +- .../src/pages/ExpensePage/ExpensePage.tsx | 1 + .../pages/TripCreatePage/TripCreatePage.tsx | 3 +- .../pages/TripEditPage/TripEditPage.style.ts | 10 ++++++ .../src/pages/TripEditPage/TripEditPage.tsx | 24 ++++++++------ .../src/stories/common/DayLogList.stories.tsx | 3 +- .../src/stories/trip/PlaceInput.stories.tsx | 2 +- .../stories/trips/TripsItemList.stories.tsx | 3 +- 18 files changed, 130 insertions(+), 36 deletions(-) diff --git a/frontend/src/components/common/DayLogItem/TitleInput/TitleInput.style.ts b/frontend/src/components/common/DayLogItem/TitleInput/TitleInput.style.ts index f539bf6cc..3d0a37e1b 100644 --- a/frontend/src/components/common/DayLogItem/TitleInput/TitleInput.style.ts +++ b/frontend/src/components/common/DayLogItem/TitleInput/TitleInput.style.ts @@ -18,6 +18,11 @@ export const inputStyling = css({ transition: 'all .2s ease-in', + '@media screen and (max-width: 600px)': { + maxWidth: '60%', + minWidth: '40%', + }, + '&:focus': { boxShadow: `inset`, borderColor: Theme.color.gray200, diff --git a/frontend/src/components/common/DayLogList/DayLogList.style.ts b/frontend/src/components/common/DayLogList/DayLogList.style.ts index 95ebd0579..0dba5720e 100644 --- a/frontend/src/components/common/DayLogList/DayLogList.style.ts +++ b/frontend/src/components/common/DayLogList/DayLogList.style.ts @@ -9,6 +9,10 @@ export const containerStyling = css({ width: '100%', padding: `${Theme.spacer.spacing4} 50px`, + '@media screen and (max-width: 600px)': { + padding: Theme.spacer.spacing4, + }, + '& > ul': { width: '100%', }, diff --git a/frontend/src/components/common/TripInformation/TripInformation.style.ts b/frontend/src/components/common/TripInformation/TripInformation.style.ts index 75b322e12..b962a87ea 100644 --- a/frontend/src/components/common/TripInformation/TripInformation.style.ts +++ b/frontend/src/components/common/TripInformation/TripInformation.style.ts @@ -7,6 +7,11 @@ export const sectionStyling = css({ minHeight: '240px', padding: `${Theme.spacer.spacing4} 50px`, + '@media screen and (max-width: 600px)': { + minHeight: '220px', + padding: Theme.spacer.spacing4, + }, + '& *': { color: Theme.color.white, }, @@ -50,7 +55,7 @@ export const descriptionStyling = css({ export const buttonContainerStyling = css({ position: 'absolute', top: Theme.spacer.spacing4, - right: '50px', + right: Theme.spacer.spacing4, display: 'flex', gap: Theme.spacer.spacing1, }); @@ -61,4 +66,23 @@ export const badgeStyling = css({ export const badgeWrapperStyling = css({ width: '60%', + minHeight: '24px', + marginBottom: Theme.spacer.spacing2, + + overflowX: 'scroll', + whiteSpace: 'nowrap', + '-ms-overflow-style': 'none', + scrollbarWidth: 'none', + + '& > span': { + marginRight: Theme.spacer.spacing1, + }, + + '::-webkit-scrollbar': { + display: 'none', + }, + + '@media screen and (max-width: 600px)': { + width: 'calc(100vw - 220px)', + }, }); diff --git a/frontend/src/components/common/TripInformation/TripInformation.tsx b/frontend/src/components/common/TripInformation/TripInformation.tsx index 025a58370..ac13c522a 100644 --- a/frontend/src/components/common/TripInformation/TripInformation.tsx +++ b/frontend/src/components/common/TripInformation/TripInformation.tsx @@ -1,7 +1,9 @@ +import { mediaQueryMobileState } from '@/store/mediaQuery'; import DefaultThumbnail from '@assets/png/trip-information_default-thumbnail.png'; import type { TripData } from '@type/trip'; -import { Badge, Box, Flex, Heading, Text, Theme, useOverlay } from 'hang-log-design-system'; +import { Badge, Box, Heading, Text, useOverlay } from 'hang-log-design-system'; import { memo } from 'react'; +import { useRecoilValue } from 'recoil'; import { formatDate } from '@utils/formatter'; @@ -24,6 +26,8 @@ interface TripInformationProps extends Omit { } const TripInformation = ({ isEditable = true, ...information }: TripInformationProps) => { + const isMobile = useRecoilValue(mediaQueryMobileState); + const { isOpen: isEditModalOpen, close: closeEditModal, open: openEditModal } = useOverlay(); return ( @@ -34,14 +38,14 @@ const TripInformation = ({ isEditable = true, ...information }: TripInformationP 여행 대표 이미지 - + {information.cities.map(({ id, name }) => ( {name} ))} - - + + {information.title} diff --git a/frontend/src/components/common/TripItem/EditMenu/EditMenu.style.ts b/frontend/src/components/common/TripItem/EditMenu/EditMenu.style.ts index 92ae6e030..b73423a4a 100644 --- a/frontend/src/components/common/TripItem/EditMenu/EditMenu.style.ts +++ b/frontend/src/components/common/TripItem/EditMenu/EditMenu.style.ts @@ -19,11 +19,17 @@ export const moreButtonStyling = css({ }, }); -export const moreMenuStyling = css({ - position: 'absolute', - top: 0, - right: 0, -}); +export const getMoreMenuStyling = (hasImage: boolean, imageHeight: number) => { + return css({ + position: 'absolute', + top: 0, + right: 0, + + '@media screen and (max-width: 600px)': { + top: hasImage ? `calc(${imageHeight}px + ${Theme.spacer.spacing3})` : 0, + }, + }); +}; export const moreMenuListStyling = css({ minWidth: 'unset', diff --git a/frontend/src/components/common/TripItem/EditMenu/EditMenu.tsx b/frontend/src/components/common/TripItem/EditMenu/EditMenu.tsx index a66bdadb9..356e4bfd8 100644 --- a/frontend/src/components/common/TripItem/EditMenu/EditMenu.tsx +++ b/frontend/src/components/common/TripItem/EditMenu/EditMenu.tsx @@ -5,18 +5,20 @@ import { Menu, MenuItem, MenuList, useOverlay } from 'hang-log-design-system'; import { useDeleteTripItemMutation } from '@hooks/api/useDeleteTripItemMutation'; import { + getMoreMenuStyling, moreButtonStyling, moreMenuListStyling, - moreMenuStyling, } from '@components/common/TripItem/EditMenu/EditMenu.style'; import TripItemAddModal from '@components/trip/TripItemAddModal/TripItemAddModal'; interface EditMenuProps extends TripItemData { tripId: number; dayLogId: number; + hasImage: boolean; + imageHeight: number; } -const EditMenu = ({ tripId, dayLogId, ...information }: EditMenuProps) => { +const EditMenu = ({ tripId, dayLogId, hasImage, imageHeight, ...information }: EditMenuProps) => { const deleteTripItemMutation = useDeleteTripItemMutation(); const { isOpen: isMenuOpen, open: openMenu, close: closeMenu } = useOverlay(); @@ -28,7 +30,7 @@ const EditMenu = ({ tripId, dayLogId, ...information }: EditMenuProps) => { return ( <> - + diff --git a/frontend/src/components/common/TripItem/TripItem.style.ts b/frontend/src/components/common/TripItem/TripItem.style.ts index 225f84371..02a6d62ed 100644 --- a/frontend/src/components/common/TripItem/TripItem.style.ts +++ b/frontend/src/components/common/TripItem/TripItem.style.ts @@ -22,6 +22,16 @@ export const getContainerStyling = ({ }); }; +export const contentContainerStyling = css({ + display: 'flex', + gap: Theme.spacer.spacing4, + + '@media screen and (max-width: 600px)': { + flexDirection: 'column', + gap: Theme.spacer.spacing3, + }, +}); + export const informationContainerStyling = css({ width: '100%', }); diff --git a/frontend/src/components/common/TripItem/TripItem.tsx b/frontend/src/components/common/TripItem/TripItem.tsx index aa5420ad4..bcd60f39f 100644 --- a/frontend/src/components/common/TripItem/TripItem.tsx +++ b/frontend/src/components/common/TripItem/TripItem.tsx @@ -1,7 +1,9 @@ import { CURRENCY_ICON } from '@constants/trip'; +import { mediaQueryMobileState, viewportWidthState } from '@store/mediaQuery'; import type { TripItemData } from '@type/tripItem'; -import { Box, Flex, Heading, ImageCarousel, Text, Theme } from 'hang-log-design-system'; -import { useEffect, useRef } from 'react'; +import { Box, Heading, ImageCarousel, Text } from 'hang-log-design-system'; +import { useEffect, useMemo, useRef } from 'react'; +import { useRecoilValue } from 'recoil'; import { formatNumberToMoney } from '@utils/formatter'; @@ -10,6 +12,7 @@ import { useDraggedItem } from '@hooks/common/useDraggedItem'; import StarRating from '@components/common/StarRating/StarRating'; import EditMenu from '@components/common/TripItem/EditMenu/EditMenu'; import { + contentContainerStyling, expenseStyling, getContainerStyling, informationContainerStyling, @@ -38,6 +41,12 @@ const TripItem = ({ onDragEnd, ...information }: TripListItemProps) => { + const isMobile = useRecoilValue(mediaQueryMobileState); + const viewportWidth = useRecoilValue(viewportWidthState); + + const imageWidth = useMemo(() => viewportWidth - 48, [viewportWidth]); + const imageHeight = useMemo(() => (imageWidth / 4.5) * 3, [imageWidth]); + const { isDragging, handleDrag, handleDragEnd } = useDraggedItem(onDragEnd); const itemRef = useRef(null); @@ -58,11 +67,11 @@ const TripItem = ({ onDragEnter={onDragEnter} onDragEnd={isEditable ? handleDragEnd : undefined} > - +
{information.imageUrls.length > 0 && ( )} - - {isEditable ? : null} +
+ {isEditable ? ( + 0} + imageHeight={imageHeight} + {...information} + /> + ) : null} ); }; diff --git a/frontend/src/components/common/TripItemList/TripItemList.tsx b/frontend/src/components/common/TripItemList/TripItemList.tsx index dc6978d73..65869ea8d 100644 --- a/frontend/src/components/common/TripItemList/TripItemList.tsx +++ b/frontend/src/components/common/TripItemList/TripItemList.tsx @@ -1,10 +1,11 @@ -import { sortByOrdinal } from '@/utils/sort'; import { PATH } from '@constants/path'; import type { TripItemData } from '@type/tripItem'; import { Button, Divider, Heading, Text } from 'hang-log-design-system'; import { Fragment, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; +import { sortByOrdinal } from '@utils/sort'; + import { useDayLogOrderMutation } from '@hooks/api/useDayLogOrderMutation'; import { useDragAndDrop } from '@hooks/common/useDragAndDrop'; import { useScrollFocus } from '@hooks/common/useScrollFocus'; diff --git a/frontend/src/components/trip/TripItemAddModal/DateInput/DateInput.tsx b/frontend/src/components/trip/TripItemAddModal/DateInput/DateInput.tsx index 39f075d51..067025bdf 100644 --- a/frontend/src/components/trip/TripItemAddModal/DateInput/DateInput.tsx +++ b/frontend/src/components/trip/TripItemAddModal/DateInput/DateInput.tsx @@ -1,5 +1,4 @@ /* eslint-disable react/jsx-no-useless-fragment */ -import { useTripDates } from '@/hooks/trip/useTripDates'; import type { TripItemFormData } from '@type/tripItem'; import { Select } from 'hang-log-design-system'; import type { ChangeEvent } from 'react'; @@ -7,6 +6,8 @@ import { memo } from 'react'; import { formatMonthDate } from '@utils/formatter'; +import { useTripDates } from '@hooks/trip/useTripDates'; + interface DateInputProps { currentCategory: TripItemFormData['itemType']; tripId: number; diff --git a/frontend/src/components/trips/TripsItem/TripsItem.style.ts b/frontend/src/components/trips/TripsItem/TripsItem.style.ts index 8e253c6d0..f51d4c672 100644 --- a/frontend/src/components/trips/TripsItem/TripsItem.style.ts +++ b/frontend/src/components/trips/TripsItem/TripsItem.style.ts @@ -46,7 +46,7 @@ export const badgeBoxStyling = css({ scrollbarWidth: 'none', '& > span': { - marginRight: Theme.spacer.spacing2, + marginRight: Theme.spacer.spacing1, }, '::-webkit-scrollbar': { diff --git a/frontend/src/pages/ExpensePage/ExpensePage.tsx b/frontend/src/pages/ExpensePage/ExpensePage.tsx index 1f8f00a9a..166208881 100644 --- a/frontend/src/pages/ExpensePage/ExpensePage.tsx +++ b/frontend/src/pages/ExpensePage/ExpensePage.tsx @@ -12,6 +12,7 @@ const ExpensePage = () => { const { tripId } = useParams(); if (!tripId) throw new Error('존재하지 않는 tripId 입니다.'); + const { expenseData } = useExpenseQuery(Number(tripId)); return ( diff --git a/frontend/src/pages/TripCreatePage/TripCreatePage.tsx b/frontend/src/pages/TripCreatePage/TripCreatePage.tsx index 823f1984b..a70638a71 100644 --- a/frontend/src/pages/TripCreatePage/TripCreatePage.tsx +++ b/frontend/src/pages/TripCreatePage/TripCreatePage.tsx @@ -1,4 +1,3 @@ -import TripCreateForm from '@/components/trip/TripCreateForm/TripCreateForm'; import CreatePageImage from '@assets/svg/create-page-image.svg'; import { Box, Flex, Heading } from 'hang-log-design-system'; @@ -8,6 +7,8 @@ import { containerStyling, } from '@pages/TripCreatePage/TripCreatePage.style'; +import TripCreateForm from '@components/trip/TripCreateForm/TripCreateForm'; + const TripCreatePage = () => { return ( diff --git a/frontend/src/pages/TripEditPage/TripEditPage.style.ts b/frontend/src/pages/TripEditPage/TripEditPage.style.ts index 4eae6036e..358889737 100644 --- a/frontend/src/pages/TripEditPage/TripEditPage.style.ts +++ b/frontend/src/pages/TripEditPage/TripEditPage.style.ts @@ -1,4 +1,5 @@ import { css } from '@emotion/react'; +import { Theme } from 'hang-log-design-system'; export const containerStyling = css({ position: 'relative', @@ -7,6 +8,10 @@ export const containerStyling = css({ '@media screen and (max-width: 1200px)': { width: '60vw', }, + + '@media screen and (max-width: 600px)': { + width: '100vw', + }, }); export const mapContainerStyling = css({ @@ -28,6 +33,11 @@ export const addButtonStyling = css({ '@media screen and (max-width: 1200px)': { left: 'calc(60vw - 114px)', }, + + '@media screen and (max-width: 600px)': { + bottom: Theme.spacer.spacing4, + left: 'calc(100vw - 88px)', + }, }); export const skeletonContainerStyling = css({ diff --git a/frontend/src/pages/TripEditPage/TripEditPage.tsx b/frontend/src/pages/TripEditPage/TripEditPage.tsx index 175e210d9..5da5cdaaf 100644 --- a/frontend/src/pages/TripEditPage/TripEditPage.tsx +++ b/frontend/src/pages/TripEditPage/TripEditPage.tsx @@ -1,6 +1,8 @@ +import { mediaQueryMobileState } from '@store/mediaQuery'; import { Flex, FloatingButton, useOverlay, useSelect } from 'hang-log-design-system'; import { useMemo } from 'react'; import { useParams } from 'react-router-dom'; +import { useRecoilValue } from 'recoil'; import { useExpenseCategoryQuery } from '@hooks/api/useExpenseCategoryQuery'; import { useTripQuery } from '@hooks/api/useTripQuery'; @@ -22,6 +24,8 @@ const TripEditPage = () => { if (!tripId) throw new Error('존재하지 않는 tripId 입니다.'); + const isMobile = useRecoilValue(mediaQueryMobileState); + const { tripData } = useTripQuery(Number(tripId)); useExpenseCategoryQuery(); @@ -66,15 +70,17 @@ const TripEditPage = () => { /> )} -
- - - -
+ {!isMobile && ( +
+ + + +
+ )}
); }; diff --git a/frontend/src/stories/common/DayLogList.stories.tsx b/frontend/src/stories/common/DayLogList.stories.tsx index 9ac204c58..cb197c150 100644 --- a/frontend/src/stories/common/DayLogList.stories.tsx +++ b/frontend/src/stories/common/DayLogList.stories.tsx @@ -1,8 +1,9 @@ -import { useTripQuery } from '@/hooks/api/useTripQuery'; import { trip } from '@mocks/data/trip'; import type { Meta, StoryObj } from '@storybook/react'; import { useSelect } from 'hang-log-design-system'; +import { useTripQuery } from '@hooks/api/useTripQuery'; + import DayLogList from '@components/common/DayLogList/DayLogList'; const meta = { diff --git a/frontend/src/stories/trip/PlaceInput.stories.tsx b/frontend/src/stories/trip/PlaceInput.stories.tsx index 4c6f997b6..a5b4cb410 100644 --- a/frontend/src/stories/trip/PlaceInput.stories.tsx +++ b/frontend/src/stories/trip/PlaceInput.stories.tsx @@ -1,8 +1,8 @@ -import GoogleMapWrapper from '@/components/common/GoogleMapWrapper/GoogleMapWrapper'; import type { Meta, StoryObj } from '@storybook/react'; import type { TripItemFormData } from '@type/tripItem'; import { useState } from 'react'; +import GoogleMapWrapper from '@components/common/GoogleMapWrapper/GoogleMapWrapper'; import PlaceInput from '@components/trip/TripItemAddModal/PlaceInput/PlaceInput'; const meta = { diff --git a/frontend/src/stories/trips/TripsItemList.stories.tsx b/frontend/src/stories/trips/TripsItemList.stories.tsx index 7fa4ddac6..3f7bd47b4 100644 --- a/frontend/src/stories/trips/TripsItemList.stories.tsx +++ b/frontend/src/stories/trips/TripsItemList.stories.tsx @@ -1,7 +1,8 @@ -import { sortByStartDate } from '@/utils/sort'; import { trips } from '@mocks/data/trips'; import type { Meta, StoryObj } from '@storybook/react'; +import { sortByStartDate } from '@utils/sort'; + import TripsItemList from '@components/trips/TripsItemList/TripsItemList'; const meta = { From 3d80c4bc093f761d6720629b7190ec5ed15f46ab Mon Sep 17 00:00:00 2001 From: Ashley Heo Date: Tue, 8 Aug 2023 00:06:02 +0900 Subject: [PATCH 3/9] =?UTF-8?q?feat:=20TripPage=20=EB=B0=98=EC=9D=91?= =?UTF-8?q?=ED=98=95=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/TripPage/TripPage.style.ts | 4 ++++ frontend/src/pages/TripPage/TripPage.tsx | 24 ++++++++++++------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/frontend/src/pages/TripPage/TripPage.style.ts b/frontend/src/pages/TripPage/TripPage.style.ts index 255aea68f..23b5b18b9 100644 --- a/frontend/src/pages/TripPage/TripPage.style.ts +++ b/frontend/src/pages/TripPage/TripPage.style.ts @@ -10,6 +10,10 @@ export const containerStyling = css({ '@media screen and (max-width: 1200px)': { width: '60vw', }, + + '@media screen and (max-width: 600px)': { + width: '100vw', + }, }); export const mapContainerStyling = css({ diff --git a/frontend/src/pages/TripPage/TripPage.tsx b/frontend/src/pages/TripPage/TripPage.tsx index 1a2b53c20..a382162c9 100644 --- a/frontend/src/pages/TripPage/TripPage.tsx +++ b/frontend/src/pages/TripPage/TripPage.tsx @@ -1,6 +1,8 @@ +import { mediaQueryMobileState } from '@store/mediaQuery'; import { Flex, useSelect } from 'hang-log-design-system'; import { useMemo } from 'react'; import { useParams } from 'react-router-dom'; +import { useRecoilValue } from 'recoil'; import { useTripQuery } from '@hooks/api/useTripQuery'; @@ -16,6 +18,8 @@ const TripPage = () => { if (!tripId) throw new Error('존재하지 않는 tripId 입니다.'); + const isMobile = useRecoilValue(mediaQueryMobileState); + const { tripData } = useTripQuery(Number(tripId)); const { selected: selectedDayLogId, handleSelectClick: handleDayLogIdSelectClick } = useSelect( @@ -46,15 +50,17 @@ const TripPage = () => { onTabChange={handleDayLogIdSelectClick} /> -
- - - -
+ {!isMobile && ( +
+ + + +
+ )}
); }; From d7c9357ad05a4abbebf4f8b689df4a4597906801 Mon Sep 17 00:00:00 2001 From: Ashley Heo Date: Tue, 8 Aug 2023 00:13:29 +0900 Subject: [PATCH 4/9] =?UTF-8?q?feat:=20Skeleton=20=EB=B0=98=EC=9D=91?= =?UTF-8?q?=ED=98=95=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/DayLogItem/DayLogItemSkeleton.tsx | 6 ++++- .../TripInformation/TripInformation.tsx | 2 +- .../common/TripItem/TripItemSkeleton.tsx | 22 +++++++++++++++---- frontend/src/hooks/common/useMediaQuery.ts | 8 ++++++- frontend/src/hooks/common/useScrollFocus.ts | 2 +- frontend/src/mocks/handlers/trips.ts | 2 +- 6 files changed, 33 insertions(+), 9 deletions(-) diff --git a/frontend/src/components/common/DayLogItem/DayLogItemSkeleton.tsx b/frontend/src/components/common/DayLogItem/DayLogItemSkeleton.tsx index 5b35e8f12..c1c5566ef 100644 --- a/frontend/src/components/common/DayLogItem/DayLogItemSkeleton.tsx +++ b/frontend/src/components/common/DayLogItem/DayLogItemSkeleton.tsx @@ -1,13 +1,17 @@ +import { mediaQueryMobileState } from '@store/mediaQuery'; import { Box, Flex, Skeleton } from 'hang-log-design-system'; +import { useRecoilValue } from 'recoil'; import { containerStyling, headerStyling } from '@components/common/DayLogItem/DayLogItem.style'; import TripItemListSkeleton from '@components/common/TripItemList/TripItemListSkeleton'; const DayLogItemSkeleton = () => { + const isMobile = useRecoilValue(mediaQueryMobileState); + return ( - + diff --git a/frontend/src/components/common/TripInformation/TripInformation.tsx b/frontend/src/components/common/TripInformation/TripInformation.tsx index ac13c522a..38a797c2b 100644 --- a/frontend/src/components/common/TripInformation/TripInformation.tsx +++ b/frontend/src/components/common/TripInformation/TripInformation.tsx @@ -1,5 +1,5 @@ -import { mediaQueryMobileState } from '@/store/mediaQuery'; import DefaultThumbnail from '@assets/png/trip-information_default-thumbnail.png'; +import { mediaQueryMobileState } from '@store/mediaQuery'; import type { TripData } from '@type/trip'; import { Badge, Box, Heading, Text, useOverlay } from 'hang-log-design-system'; import { memo } from 'react'; diff --git a/frontend/src/components/common/TripItem/TripItemSkeleton.tsx b/frontend/src/components/common/TripItem/TripItemSkeleton.tsx index 8a0d75b4f..9be5bcdb9 100644 --- a/frontend/src/components/common/TripItem/TripItemSkeleton.tsx +++ b/frontend/src/components/common/TripItem/TripItemSkeleton.tsx @@ -1,15 +1,29 @@ -import { Box, Flex, Skeleton, Theme } from 'hang-log-design-system'; +import { mediaQueryMobileState, viewportWidthState } from '@store/mediaQuery'; +import { Box, Skeleton } from 'hang-log-design-system'; +import { useMemo } from 'react'; +import { useRecoilValue } from 'recoil'; import { + contentContainerStyling, getContainerStyling, informationContainerStyling, } from '@components/common/TripItem/TripItem.style'; const TripItemSkeleton = () => { + const isMobile = useRecoilValue(mediaQueryMobileState); + const viewportWidth = useRecoilValue(viewportWidthState); + + const imageWidth = useMemo(() => viewportWidth - 48, [viewportWidth]); + const imageHeight = useMemo(() => (imageWidth / 4.5) * 3, [imageWidth]); + return (
  • - - +
    + @@ -17,7 +31,7 @@ const TripItemSkeleton = () => { - +
  • ); }; diff --git a/frontend/src/hooks/common/useMediaQuery.ts b/frontend/src/hooks/common/useMediaQuery.ts index 0218c6645..e3c6f53d4 100644 --- a/frontend/src/hooks/common/useMediaQuery.ts +++ b/frontend/src/hooks/common/useMediaQuery.ts @@ -13,6 +13,10 @@ export const useMediaQuery = () => { setViewportWidth(window.innerWidth); }, [setIsMobile, setViewportWidth]); + const handleViewportWidthChange = useCallback(() => { + setViewportWidth(window.innerWidth); + }, [setViewportWidth]); + useEffect(() => { setIsMobile(window.matchMedia(MOBILE_MEDIA_QUERY_SIZE).matches); setViewportWidth(window.innerWidth); @@ -23,9 +27,11 @@ export const useMediaQuery = () => { mediaQueryRef.current = mediaQueryList; mediaQueryRef.current.addEventListener('change', handleWindowResize); + window.addEventListener('resize', handleViewportWidthChange); return () => { mediaQueryRef.current?.removeEventListener('change', handleWindowResize); + window.removeEventListener('resize', handleViewportWidthChange); }; - }, [handleWindowResize]); + }, [handleWindowResize, handleViewportWidthChange]); }; diff --git a/frontend/src/hooks/common/useScrollFocus.ts b/frontend/src/hooks/common/useScrollFocus.ts index 737193d33..61f0f5ac5 100644 --- a/frontend/src/hooks/common/useScrollFocus.ts +++ b/frontend/src/hooks/common/useScrollFocus.ts @@ -1,4 +1,4 @@ -import { focusedIdState } from '@/store/scrollFocus'; +import { focusedIdState } from '@store/scrollFocus'; import { useCallback, useEffect, useState } from 'react'; import { useSetRecoilState } from 'recoil'; diff --git a/frontend/src/mocks/handlers/trips.ts b/frontend/src/mocks/handlers/trips.ts index cdd9c0b3e..b9024d319 100644 --- a/frontend/src/mocks/handlers/trips.ts +++ b/frontend/src/mocks/handlers/trips.ts @@ -17,7 +17,7 @@ export const tripsHandlers = [ }), rest.get(`${END_POINTS.TRIPS}/:tripId`, (_, res, ctx) => { - return res(ctx.status(200), ctx.json(trip)); + return res(ctx.delay(3000), ctx.status(200), ctx.json(trip)); }), rest.put(`${END_POINTS.TRIPS}/:tripId`, (req, res, ctx) => { From f72ddc403d6939b43c17d3ed308b724076f42ee7 Mon Sep 17 00:00:00 2001 From: Ashley Heo Date: Tue, 8 Aug 2023 00:16:24 +0900 Subject: [PATCH 5/9] =?UTF-8?q?feat:=20Header,=20Footer=20=EB=B0=98?= =?UTF-8?q?=EC=9D=91=ED=98=95=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/layout/Footer/Footer.style.ts | 4 ++++ frontend/src/components/layout/Header/Header.style.ts | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/frontend/src/components/layout/Footer/Footer.style.ts b/frontend/src/components/layout/Footer/Footer.style.ts index d1d919728..5ad321131 100644 --- a/frontend/src/components/layout/Footer/Footer.style.ts +++ b/frontend/src/components/layout/Footer/Footer.style.ts @@ -15,6 +15,10 @@ export const containerStyling = css({ backgroundColor: Theme.color.white, + '@media screen and (max-width: 600px)': { + height: '124px', + }, + '& *': { color: Theme.color.gray600, }, diff --git a/frontend/src/components/layout/Header/Header.style.ts b/frontend/src/components/layout/Header/Header.style.ts index e58470c33..f054da155 100644 --- a/frontend/src/components/layout/Header/Header.style.ts +++ b/frontend/src/components/layout/Header/Header.style.ts @@ -11,6 +11,10 @@ export const headerStyling = css({ backgroundColor: Theme.color.white, padding: `${Theme.spacer.spacing4} 50px`, + '@media screen and (max-width: 600px)': { + padding: `${Theme.spacer.spacing3} ${Theme.spacer.spacing4}`, + }, + '& > *': { cursor: 'pointer', }, From add67a51a9255677b855d1b40e5a16c141e34379 Mon Sep 17 00:00:00 2001 From: Ashley Heo Date: Tue, 8 Aug 2023 00:37:29 +0900 Subject: [PATCH 6/9] =?UTF-8?q?feat:=20TripItemAddModal=20=EB=B0=98?= =?UTF-8?q?=EC=9D=91=ED=98=95=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TripItemAddModal.style.ts | 14 +++++++++++ .../TripItemAddModal/TripItemAddModal.tsx | 24 ++++++++++++++++--- frontend/src/mocks/handlers/trips.ts | 2 +- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/trip/TripItemAddModal/TripItemAddModal.style.ts b/frontend/src/components/trip/TripItemAddModal/TripItemAddModal.style.ts index 67d10636d..3bdc95329 100644 --- a/frontend/src/components/trip/TripItemAddModal/TripItemAddModal.style.ts +++ b/frontend/src/components/trip/TripItemAddModal/TripItemAddModal.style.ts @@ -4,6 +4,11 @@ import { Theme } from 'hang-log-design-system'; export const wrapperStyling = css({ width: '696px', minHeight: '528px', + + '@media screen and (max-width: 600px)': { + width: `calc(100vw - ${Theme.spacer.spacing4})`, + height: `calc(100vh - ${Theme.spacer.spacing7})`, + }, }); export const formStyling = css({ @@ -14,4 +19,13 @@ export const formStyling = css({ '& > button': { width: '100%', }, + + '@media screen and (max-width: 600px)': { + width: `calc(100vw - ${Theme.spacer.spacing7})`, + height: `calc(100vh - ${Theme.spacer.spacing8})`, + + overflowY: 'auto', + '-ms-overflow-style': 'none', + scrollbarWidth: 'none', + }, }); diff --git a/frontend/src/components/trip/TripItemAddModal/TripItemAddModal.tsx b/frontend/src/components/trip/TripItemAddModal/TripItemAddModal.tsx index 0b813b34f..4b46518ba 100644 --- a/frontend/src/components/trip/TripItemAddModal/TripItemAddModal.tsx +++ b/frontend/src/components/trip/TripItemAddModal/TripItemAddModal.tsx @@ -1,5 +1,7 @@ +import { mediaQueryMobileState } from '@store/mediaQuery'; import type { TripItemFormData } from '@type/tripItem'; import { Button, Flex, Modal, Theme } from 'hang-log-design-system'; +import { useRecoilValue } from 'recoil'; import { useAddTripItemForm } from '@hooks/trip/useAddTripItemForm'; @@ -34,6 +36,8 @@ const TripItemAddModal = ({ isOpen = true, onClose, }: TripItemAddModalProps) => { + const isMobile = useRecoilValue(mediaQueryMobileState); + const { tripItemInformation, isTitleError, updateInputValue, disableTitleError, handleSubmit } = useAddTripItemForm({ tripId, @@ -47,8 +51,15 @@ const TripItemAddModal = ({
    - - + + - + { - return res(ctx.delay(3000), ctx.status(200), ctx.json(trip)); + return res(ctx.status(200), ctx.json(trip)); }), rest.put(`${END_POINTS.TRIPS}/:tripId`, (req, res, ctx) => { From 22701e1381f4104dbf184e4a138237457aaf4863 Mon Sep 17 00:00:00 2001 From: Ashley Heo Date: Tue, 8 Aug 2023 00:42:18 +0900 Subject: [PATCH 7/9] =?UTF-8?q?refactor:=20TripItemAddModal=20=EC=8A=A4?= =?UTF-8?q?=ED=83=80=EC=9D=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/TripInformation/TripInformation.tsx | 5 ++--- .../TripItemAddModal/DateInput/DateInput.style.ts | 5 +++++ .../trip/TripItemAddModal/DateInput/DateInput.tsx | 11 ++++++++++- .../trip/TripItemAddModal/TripItemAddModal.style.ts | 9 +++++++-- 4 files changed, 24 insertions(+), 6 deletions(-) create mode 100644 frontend/src/components/trip/TripItemAddModal/DateInput/DateInput.style.ts diff --git a/frontend/src/components/common/TripInformation/TripInformation.tsx b/frontend/src/components/common/TripInformation/TripInformation.tsx index 38a797c2b..92134c67f 100644 --- a/frontend/src/components/common/TripInformation/TripInformation.tsx +++ b/frontend/src/components/common/TripInformation/TripInformation.tsx @@ -7,6 +7,8 @@ import { useRecoilValue } from 'recoil'; import { formatDate } from '@utils/formatter'; +import TripButtons from '@components/common/TripInformation/TripButtons/TripButtons'; +import TripEditButtons from '@components/common/TripInformation/TripEditButtons/TripEditButtons'; import { badgeStyling, badgeWrapperStyling, @@ -18,9 +20,6 @@ import { } from '@components/common/TripInformation/TripInformation.style'; import TripInfoEditModal from '@components/trip/TripInfoEditModal/TripInfoEditModal'; -import TripButtons from './TripButtons/TripButtons'; -import TripEditButtons from './TripEditButtons/TripEditButtons'; - interface TripInformationProps extends Omit { isEditable?: boolean; } diff --git a/frontend/src/components/trip/TripItemAddModal/DateInput/DateInput.style.ts b/frontend/src/components/trip/TripItemAddModal/DateInput/DateInput.style.ts new file mode 100644 index 000000000..0b94f2593 --- /dev/null +++ b/frontend/src/components/trip/TripItemAddModal/DateInput/DateInput.style.ts @@ -0,0 +1,5 @@ +import { css } from '@emotion/react'; + +export const selectStyling = css({ + height: '48px', +}); diff --git a/frontend/src/components/trip/TripItemAddModal/DateInput/DateInput.tsx b/frontend/src/components/trip/TripItemAddModal/DateInput/DateInput.tsx index 067025bdf..c912b4ca6 100644 --- a/frontend/src/components/trip/TripItemAddModal/DateInput/DateInput.tsx +++ b/frontend/src/components/trip/TripItemAddModal/DateInput/DateInput.tsx @@ -8,6 +8,8 @@ import { formatMonthDate } from '@utils/formatter'; import { useTripDates } from '@hooks/trip/useTripDates'; +import { selectStyling } from '@components/trip/TripItemAddModal/DateInput/DateInput.style'; + interface DateInputProps { currentCategory: TripItemFormData['itemType']; tripId: number; @@ -23,7 +25,14 @@ const DateInput = ({ currentCategory, tripId, dayLogId, updateInputValue }: Date }; return ( - <> {Array.from({ length: dates.length - 1 }, (_, index) => (