From 8c9515b8154cf4680f0821c5b9ad87060462a06e Mon Sep 17 00:00:00 2001 From: ruehan Date: Wed, 27 Nov 2024 12:14:50 +0900 Subject: [PATCH 1/8] =?UTF-8?q?=F0=9F=90=9BFix:=20=EA=B0=95=EB=B2=88?= =?UTF-8?q?=EB=94=B0=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=9D=B4?= =?UTF-8?q?=EB=A6=84=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/WalkPage/index.tsx | 11 +++++++---- src/pages/WalkPage/styles.ts | 4 ++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/pages/WalkPage/index.tsx b/src/pages/WalkPage/index.tsx index 47a9de4..11e67be 100644 --- a/src/pages/WalkPage/index.tsx +++ b/src/pages/WalkPage/index.tsx @@ -3,9 +3,12 @@ import MapComponent from './components/MapComponent' import * as S from './styles' import { Helmet } from 'react-helmet-async' import { useNavigate } from 'react-router-dom' +import { useState } from 'react' export default function WalkPage() { const navigate = useNavigate() + const [_modalType, _setModalType] = useState<'request' | 'accept' | 'complete' | 'progress' | 'friend' | null>(null) + const [isModalOpen, _setIsModalOpen] = useState(false) return ( @@ -19,12 +22,12 @@ export default function WalkPage() { 강남구 논현동 - - - + + + - + ) } diff --git a/src/pages/WalkPage/styles.ts b/src/pages/WalkPage/styles.ts index 12d188d..e76634f 100644 --- a/src/pages/WalkPage/styles.ts +++ b/src/pages/WalkPage/styles.ts @@ -53,7 +53,7 @@ export const LocationText = styled.div` font-style: bold; ` -export const ProfileImgWrapper = styled.div` +export const WalkerListButtonWrapper = styled.div` width: 45px; height: 45px; border-radius: 50%; @@ -61,7 +61,7 @@ export const ProfileImgWrapper = styled.div` background-color: #f0f0f0; ` -export const ProfileImg = styled(DogProfile)` +export const WalkerListIcon = styled(DogProfile)` width: 100%; height: 100%; ` From 26b5e420fdea2e2f0e00e47de9b0ab27c84c20d2 Mon Sep 17 00:00:00 2001 From: ruehan Date: Wed, 27 Nov 2024 16:26:36 +0900 Subject: [PATCH 2/8] =?UTF-8?q?=F0=9F=8E=A8Design:=20lighten=5F3=20?= =?UTF-8?q?=EB=B0=B0=EA=B2=BD=EC=83=89=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Button/ActionButton.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/Button/ActionButton.ts b/src/components/Button/ActionButton.ts index 178def3..167cf0c 100644 --- a/src/components/Button/ActionButton.ts +++ b/src/components/Button/ActionButton.ts @@ -1,7 +1,7 @@ import styled, { BrandColors, FontWeight, GrayscaleColors, Typography } from 'styled-components' type BgColorType = - | Extract + | Extract | Extract type ActionButtonProps = { @@ -19,6 +19,7 @@ type ActionButtonStyles = { const ACTION_BUTTON_FONT_COLORS: Record = { default: 'gc_4', lighten_2: 'font_1', + lighten_3: 'font_1', font_1: 'gc_4', gc_4: 'font_1', gc_1: 'font_4', From 3c971a372e2434561e72141b65295c32f45d1657 Mon Sep 17 00:00:00 2001 From: ruehan Date: Wed, 27 Nov 2024 16:31:13 +0900 Subject: [PATCH 3/8] =?UTF-8?q?=F0=9F=8E=A8Design:=20=EA=B0=95=EB=B2=88?= =?UTF-8?q?=EB=94=B0=20=EB=AA=A8=EB=8B=AC=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/WalkerListModal/index.tsx | 54 ++++++ .../components/WalkerListModal/styles.ts | 160 ++++++++++++++++++ src/pages/WalkPage/index.tsx | 15 +- 3 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 src/pages/WalkPage/components/WalkerListModal/index.tsx create mode 100644 src/pages/WalkPage/components/WalkerListModal/styles.ts diff --git a/src/pages/WalkPage/components/WalkerListModal/index.tsx b/src/pages/WalkPage/components/WalkerListModal/index.tsx new file mode 100644 index 0000000..b792afa --- /dev/null +++ b/src/pages/WalkPage/components/WalkerListModal/index.tsx @@ -0,0 +1,54 @@ +import * as S from './styles' + +interface WalkerListModalProps { + isOpen: boolean + onClose: () => void + isClosing: boolean +} + +export default function WalkerListModal({ isOpen, onClose, isClosing }: WalkerListModalProps) { + if (!isOpen) return null + + const handleBackgroundClick = (e: React.MouseEvent) => { + if (e.target === e.currentTarget) { + onClose() + } + } + + return ( + + + 강번따 리스트 + + + {Array(10) + .fill(0) + .map((_, i) => ( + + + + + 밤돌이 + + 포메라니안 + + 4살 + + + + + 산책 횟수

 4회

+
+
+
+ + 강번따 + +
+ ))} +
+
+
+
+ ) +} diff --git a/src/pages/WalkPage/components/WalkerListModal/styles.ts b/src/pages/WalkPage/components/WalkerListModal/styles.ts new file mode 100644 index 0000000..d60438f --- /dev/null +++ b/src/pages/WalkPage/components/WalkerListModal/styles.ts @@ -0,0 +1,160 @@ +import { styled } from 'styled-components' +import { ActionButton } from '~components/Button/ActionButton' +import { Separator } from '~components/Separator' + +export const Overlay = styled.div` + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + align-items: flex-end; + z-index: 1000; + + animation: fadeIn 0.3s ease-out; + + &.closing { + animation: fadeOut 0.3s ease-out; + } + + @keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } + } + + @keyframes fadeOut { + from { + opacity: 1; + } + to { + opacity: 0; + } + } +` + +export const WalkerListContainer = styled.div` + position: fixed; + bottom: 0; + left: 0; + right: 0; + background-color: white; + border-radius: 40px 40px 0 0; + padding: 20px; + z-index: 101; + height: 80dvh; + display: flex; + flex-direction: column; + animation: slideUp 0.6s ease-out; + + &.closing { + animation: slideDown 0.3s ease-out; + } + + @keyframes slideUp { + from { + transform: translateY(100%); + } + to { + transform: translateY(0); + } + } + + @keyframes slideDown { + from { + transform: translateY(0); + } + to { + transform: translateY(100%); + } + } +` + +export const ModalTitle = styled.h2` + font-size: 18px; + font-weight: bold; + margin-bottom: 16px; + text-align: center; +` + +export const WalkerListSection = styled.div` + flex: 1; + overflow-y: auto; +` + +export const WalkerList = styled.div` + display: flex; + flex-direction: column; +` + +export const WalkerItem = styled.div` + display: flex; + align-items: center; + justify-content: space-between; + padding: 16px 0; + border-bottom: 1px solid #f0f0f0; +` + +export const ProfileArea = styled.div` + display: flex; + align-items: center; +` + +export const ProfileCircle = styled.div` + width: 64px; + height: 64px; + border-radius: 50%; + background-color: #ffe4d6; + margin-right: 12px; +` + +export const InfoArea = styled.div` + flex: 1; + color: ${({ theme }) => theme.colors.grayscale.font_2}; + font-size: 14px; +` + +export const Name = styled.div` + font-size: 17px; + font-weight: bold; + margin-bottom: 4px; + color: #111111; +` + +export const Details = styled.div` + font-size: 14px; + color: #666; + margin-bottom: 2px; + display: flex; + align-items: center; +` + +export const Detail = styled.p` + font-size: 14px; + color: #666; + margin-bottom: 2px; +` + +export const WalkCount = styled.div` + font-size: 14px; + color: ${({ theme }) => theme.colors.grayscale.font_1}; + font-weight: 700; + display: flex; + + p { + color: ${({ theme }) => theme.colors.brand.default}; + } +` + +export const WalkBtn = styled(ActionButton)` + width: fit-content; +` + +export const WalkListSeparator = styled(Separator)` + margin: 0 4px; +` diff --git a/src/pages/WalkPage/index.tsx b/src/pages/WalkPage/index.tsx index 11e67be..3cacff8 100644 --- a/src/pages/WalkPage/index.tsx +++ b/src/pages/WalkPage/index.tsx @@ -4,11 +4,22 @@ import * as S from './styles' import { Helmet } from 'react-helmet-async' import { useNavigate } from 'react-router-dom' import { useState } from 'react' +import WalkerListModal from '~pages/WalkPage/components/WalkerListModal' export default function WalkPage() { const navigate = useNavigate() const [_modalType, _setModalType] = useState<'request' | 'accept' | 'complete' | 'progress' | 'friend' | null>(null) const [isModalOpen, _setIsModalOpen] = useState(false) + const [isWalkerListOpen, setIsWalkerListOpen] = useState(false) + const [isClosing, setIsClosing] = useState(false) + + const handleWalkerListClose = () => { + setIsClosing(true) + setTimeout(() => { + setIsClosing(false) + setIsWalkerListOpen(false) + }, 300) + } return ( @@ -23,11 +34,13 @@ export default function WalkPage() { 강남구 논현동 - + setIsWalkerListOpen(true)} /> + + ) } From ad4fb2b9c2ac0a1e7209576dbb681a87fcbe4c77 Mon Sep 17 00:00:00 2001 From: ruehan Date: Thu, 28 Nov 2024 11:33:23 +0900 Subject: [PATCH 4/8] =?UTF-8?q?=F0=9F=8E=A8Design:=20=EC=82=B0=EC=B1=85=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/WalkCompletePage/index.tsx | 45 ++++++++++++++++ src/pages/WalkCompletePage/styles.ts | 76 ++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+) create mode 100644 src/pages/WalkCompletePage/index.tsx create mode 100644 src/pages/WalkCompletePage/styles.ts diff --git a/src/pages/WalkCompletePage/index.tsx b/src/pages/WalkCompletePage/index.tsx new file mode 100644 index 0000000..4427939 --- /dev/null +++ b/src/pages/WalkCompletePage/index.tsx @@ -0,0 +1,45 @@ +import * as S from './styles' + +const walkData = { + date: '2024.12.14', + time: '1:10:00', + distance: '2.4km', + calories: '200kcal', + mapImage: 'https://imagedelivery.net/CJyrB-EkqcsF2D6ApJzEBg/6d853db2-fb51-465c-eaa8-e9e38be01f00/public', +} + +export default function WalkCompletePage() { + return ( + + {walkData.date} + + + 견주닉넴과 밤톨이가 +
+ 30분동안 산책했어요. +
+ + + + + + + {walkData.time} + 산책 시간 + + + {walkData.distance} + 산책 거리 + + + {walkData.calories} + 소모한 칼로리 + + + + + 산책 경로 + +
+ ) +} diff --git a/src/pages/WalkCompletePage/styles.ts b/src/pages/WalkCompletePage/styles.ts new file mode 100644 index 0000000..a3d3274 --- /dev/null +++ b/src/pages/WalkCompletePage/styles.ts @@ -0,0 +1,76 @@ +import { styled } from 'styled-components' +import WalkCompleteDog from '~assets/result_dog.svg?react' +import { Box } from '~components/Box' +import { Typo13, Typo17, Typo20 } from '~components/Typo' +import { FOOTER_HEIGHT } from '~constants/layout' + +export const WalkCompletePage = styled.div` + background-color: ${({ theme }) => theme.colors.brand.lighten_3}; + width: 100%; + height: calc(100dvh - ${FOOTER_HEIGHT}px); + padding: 24px; + display: flex; + flex-direction: column; + gap: 20px; +` + +export const Date = styled(Typo17)` + font-weight: 700; + color: #333; +` + +export const Title = styled(Typo20)` + font-weight: 800; + + span { + color: #8b4513; + } +` + +export const WalkStats = styled(Box)` + display: flex; + justify-content: space-between; + padding: 22px 33px; + /* border-radius: 12px; */ +` + +export const StatItem = styled.div` + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; +` + +export const StatValue = styled(Typo20)` + font-weight: 800; + color: ${({ theme }) => theme.colors.grayscale.font_1}; +` + +export const StatLabel = styled(Typo13)` + font-weight: 500; + color: ${({ theme }) => theme.colors.grayscale.font_1}; +` + +export const MapSection = styled.div` + width: 100%; + height: 240px; + border-radius: 12px; + overflow: hidden; + + img { + width: 100%; + height: 100%; + object-fit: cover; + } +` + +export const DogImageArea = styled.div` + display: flex; + justify-content: right; +` + +export const DogImage = styled(WalkCompleteDog)` + width: 142px; + height: 151px; + display: flex; +` From 5c199b78daafa6927fca82e8c9afc4713a383c8e Mon Sep 17 00:00:00 2001 From: ruehan Date: Thu, 28 Nov 2024 11:34:33 +0900 Subject: [PATCH 5/8] =?UTF-8?q?=E2=9C=A8=20Feat:=20=EC=82=B0=EC=B1=85=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C=20rotue=20=EC=84=A4=EC=A0=95=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 --- src/components/LazyComponents.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/LazyComponents.tsx b/src/components/LazyComponents.tsx index d049ff8..46e14b2 100644 --- a/src/components/LazyComponents.tsx +++ b/src/components/LazyComponents.tsx @@ -7,3 +7,4 @@ export const MyPage = lazy(() => import('~pages/MyPage')) export const WalkPage = lazy(() => import('~pages/WalkPage')) export const RegisterPage = lazy(() => import('~pages/RegisterPage/Owner')) export const RegisterDogPage = lazy(() => import('~pages/RegisterPage/Dog')) +export const WalkCompletePage = lazy(() => import('~pages/WalkCompletePage')) From bcc887acd5dee6e203df07adbc825480ef72c8e9 Mon Sep 17 00:00:00 2001 From: ruehan Date: Thu, 28 Nov 2024 14:56:11 +0900 Subject: [PATCH 6/8] =?UTF-8?q?=E2=9C=A8=20Feat:=20=EA=B0=95=EC=95=84?= =?UTF-8?q?=EC=A7=80=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/result_dog.svg | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/assets/result_dog.svg diff --git a/src/assets/result_dog.svg b/src/assets/result_dog.svg new file mode 100644 index 0000000..bd460df --- /dev/null +++ b/src/assets/result_dog.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + From d557129da93ccc9fcb7168a8d77aa171c064d434 Mon Sep 17 00:00:00 2001 From: ruehan Date: Thu, 28 Nov 2024 14:56:49 +0900 Subject: [PATCH 7/8] =?UTF-8?q?=E2=9C=A8=20Feat:=20=EC=82=B0=EC=B1=85=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C=20route=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/router.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/router.tsx b/src/router.tsx index 9763fa7..4f6fa40 100644 --- a/src/router.tsx +++ b/src/router.tsx @@ -24,6 +24,10 @@ export const router = createBrowserRouter([ path: '/walk', element: , }, + { + path: '/walk-complete', + element: , + }, { path: '/mypage', element: , From 8e1037c7418291b430f120328510b71bee42289a Mon Sep 17 00:00:00 2001 From: ruehan Date: Thu, 28 Nov 2024 16:52:42 +0900 Subject: [PATCH 8/8] =?UTF-8?q?=F0=9F=90=9B=20Fix:=20=EB=AA=A8=EB=8B=AC=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WalkPage/components/MapComponent/index.tsx | 14 +++++++++++++- src/pages/WalkPage/index.tsx | 1 - 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/pages/WalkPage/components/MapComponent/index.tsx b/src/pages/WalkPage/components/MapComponent/index.tsx index 32aa557..3ca2ed8 100644 --- a/src/pages/WalkPage/components/MapComponent/index.tsx +++ b/src/pages/WalkPage/components/MapComponent/index.tsx @@ -16,6 +16,7 @@ import XYZ from 'ol/source/XYZ' import ReactDOMServer from 'react-dom/server' import * as S from '~pages/WalkPage/styles' import { MIN_ACCURACY, MIN_DISTANCE, MIN_TIME_INTERVAL } from '~types/map' +import { useNavigate } from 'react-router-dom' const ORS_API_URL = '/ors/v2/directions/foot-walking/geojson' @@ -30,7 +31,12 @@ export const getMarkerIconString = () => { return svgString } -export default function MapComponent() { +// 모달 상태를 props로 받도록 수정 +interface MapComponentProps { + isModalOpen?: boolean +} + +export default function MapComponent({ isModalOpen = false }: MapComponentProps) { // 지도 관련 ref const mapRef = useRef(null) const currentLocationMarkerRef = useRef | null>(null) @@ -63,6 +69,8 @@ export default function MapComponent() { const [autoRotate, setAutoRotate] = useState(false) const lastHeadingRef = useRef(0) + const navigate = useNavigate() + useEffect(() => { return () => { if (currentLocationMarkerRef.current) { @@ -591,6 +599,8 @@ export default function MapComponent() { duration: 500, }) } + + navigate('/walk-complete') } } @@ -700,6 +710,7 @@ export default function MapComponent() { $bgColor={isWalking ? 'font_1' : 'default'} $fontWeight='700' $isWalking={isWalking} + disabled={isModalOpen} // 모달이 열려있을 때 버튼 비활성화 > {isWalking ? '산책 끝' : '산책 시작'} @@ -716,6 +727,7 @@ export default function MapComponent() { $bgColor={isWalking ? 'font_1' : 'default'} $fontWeight='700' $isWalking={isWalking} + disabled={isModalOpen} // 모달이 열려있을 때 버튼 비활성화 > {isWalking ? '산책 끝' : '산책 시작'} diff --git a/src/pages/WalkPage/index.tsx b/src/pages/WalkPage/index.tsx index 3cacff8..105d017 100644 --- a/src/pages/WalkPage/index.tsx +++ b/src/pages/WalkPage/index.tsx @@ -39,7 +39,6 @@ export default function WalkPage() { - )