Skip to content

Commit 359fc30

Browse files
authored
Merge pull request #104 from prgrms-web-devcourse-final-project/68-design/walk-result-ui
[Design] #68 산책 마무리 및 강번따 UI 구현
2 parents fa4dec0 + 7778835 commit 359fc30

File tree

11 files changed

+396
-8
lines changed

11 files changed

+396
-8
lines changed

src/assets/result_dog.svg

Lines changed: 20 additions & 0 deletions
Loading

src/components/Button/ActionButton.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import styled, { BrandColors, FontWeight, GrayscaleColors, Typography } from 'styled-components'
22

33
type BgColorType =
4-
| Extract<keyof BrandColors, 'default' | 'lighten_2'>
4+
| Extract<keyof BrandColors, 'default' | 'lighten_2' | 'lighten_3'>
55
| Extract<keyof GrayscaleColors, 'gc_4' | 'gc_1' | 'font_1'>
66

77
type ActionButtonProps = {
@@ -19,6 +19,7 @@ type ActionButtonStyles = {
1919
const ACTION_BUTTON_FONT_COLORS: Record<BgColorType, keyof GrayscaleColors> = {
2020
default: 'gc_4',
2121
lighten_2: 'font_1',
22+
lighten_3: 'font_1',
2223
font_1: 'gc_4',
2324
gc_4: 'font_1',
2425
gc_1: 'font_4',

src/components/LazyComponents.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ export const WalkPage = lazy(() => import('~pages/WalkPage'))
88
export const SocialPage = lazy(() => import('~pages/SocialPage'))
99
export const RegisterPage = lazy(() => import('~pages/RegisterPage/Register'))
1010
export const RegisterDogPage = lazy(() => import('~pages/RegisterPage/Dog'))
11+
export const WalkCompletePage = lazy(() => import('~pages/WalkCompletePage'))
1112
export const ProfilePage = lazy(() => import('~pages/ProfilePage'))

src/pages/WalkCompletePage/index.tsx

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import * as S from './styles'
2+
3+
const walkData = {
4+
date: '2024.12.14',
5+
time: '1:10:00',
6+
distance: '2.4km',
7+
calories: '200kcal',
8+
mapImage: 'https://imagedelivery.net/CJyrB-EkqcsF2D6ApJzEBg/6d853db2-fb51-465c-eaa8-e9e38be01f00/public',
9+
}
10+
11+
export default function WalkCompletePage() {
12+
return (
13+
<S.WalkCompletePage>
14+
<S.Date>{walkData.date}</S.Date>
15+
16+
<S.Title>
17+
견주닉넴과 밤톨이가
18+
<br />
19+
<span>30분</span>동안 산책했어요.
20+
</S.Title>
21+
<S.DogImageArea>
22+
<S.DogImage />
23+
</S.DogImageArea>
24+
25+
<S.WalkStats>
26+
<S.StatItem>
27+
<S.StatValue className='value'>{walkData.time}</S.StatValue>
28+
<S.StatLabel className='label'>산책 시간</S.StatLabel>
29+
</S.StatItem>
30+
<S.StatItem>
31+
<S.StatValue className='value'>{walkData.distance}</S.StatValue>
32+
<S.StatLabel className='label'>산책 거리</S.StatLabel>
33+
</S.StatItem>
34+
<S.StatItem>
35+
<S.StatValue className='value'>{walkData.calories}</S.StatValue>
36+
<S.StatLabel className='label'>소모한 칼로리</S.StatLabel>
37+
</S.StatItem>
38+
</S.WalkStats>
39+
40+
<S.MapSection>
41+
<img src={walkData.mapImage} alt='산책 경로' />
42+
</S.MapSection>
43+
</S.WalkCompletePage>
44+
)
45+
}

src/pages/WalkCompletePage/styles.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { styled } from 'styled-components'
2+
import WalkCompleteDog from '~assets/result_dog.svg?react'
3+
import { Box } from '~components/Box'
4+
import { Typo13, Typo17, Typo20 } from '~components/Typo'
5+
import { FOOTER_HEIGHT } from '~constants/layout'
6+
7+
export const WalkCompletePage = styled.div`
8+
background-color: ${({ theme }) => theme.colors.brand.lighten_3};
9+
width: 100%;
10+
height: calc(100dvh - ${FOOTER_HEIGHT}px);
11+
padding: 24px;
12+
display: flex;
13+
flex-direction: column;
14+
gap: 20px;
15+
`
16+
17+
export const Date = styled(Typo17)`
18+
font-weight: 700;
19+
color: #333;
20+
`
21+
22+
export const Title = styled(Typo20)`
23+
font-weight: 800;
24+
25+
span {
26+
color: #8b4513;
27+
}
28+
`
29+
30+
export const WalkStats = styled(Box)`
31+
display: flex;
32+
justify-content: space-between;
33+
padding: 22px 33px;
34+
/* border-radius: 12px; */
35+
`
36+
37+
export const StatItem = styled.div`
38+
display: flex;
39+
flex-direction: column;
40+
align-items: center;
41+
gap: 8px;
42+
`
43+
44+
export const StatValue = styled(Typo20)`
45+
font-weight: 800;
46+
color: ${({ theme }) => theme.colors.grayscale.font_1};
47+
`
48+
49+
export const StatLabel = styled(Typo13)`
50+
font-weight: 500;
51+
color: ${({ theme }) => theme.colors.grayscale.font_1};
52+
`
53+
54+
export const MapSection = styled.div`
55+
width: 100%;
56+
height: 240px;
57+
border-radius: 12px;
58+
overflow: hidden;
59+
60+
img {
61+
width: 100%;
62+
height: 100%;
63+
object-fit: cover;
64+
}
65+
`
66+
67+
export const DogImageArea = styled.div`
68+
display: flex;
69+
justify-content: right;
70+
`
71+
72+
export const DogImage = styled(WalkCompleteDog)`
73+
width: 142px;
74+
height: 151px;
75+
display: flex;
76+
`

src/pages/WalkPage/components/MapComponent/index.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import XYZ from 'ol/source/XYZ'
1616
import ReactDOMServer from 'react-dom/server'
1717
import * as S from '~pages/WalkPage/styles'
1818
import { MIN_ACCURACY, MIN_DISTANCE, MIN_TIME_INTERVAL } from '~types/map'
19+
import { useNavigate } from 'react-router-dom'
1920

2021
const ORS_API_URL = '/ors/v2/directions/foot-walking/geojson'
2122

@@ -30,7 +31,12 @@ export const getMarkerIconString = () => {
3031
return svgString
3132
}
3233

33-
export default function MapComponent() {
34+
// 모달 상태를 props로 받도록 수정
35+
interface MapComponentProps {
36+
isModalOpen?: boolean
37+
}
38+
39+
export default function MapComponent({ isModalOpen = false }: MapComponentProps) {
3440
// 지도 관련 ref
3541
const mapRef = useRef<Map | null>(null)
3642
const currentLocationMarkerRef = useRef<Feature<Geometry> | null>(null)
@@ -63,6 +69,8 @@ export default function MapComponent() {
6369
const [autoRotate, setAutoRotate] = useState<boolean>(false)
6470
const lastHeadingRef = useRef<number>(0)
6571

72+
const navigate = useNavigate()
73+
6674
useEffect(() => {
6775
return () => {
6876
if (currentLocationMarkerRef.current) {
@@ -591,6 +599,8 @@ export default function MapComponent() {
591599
duration: 500,
592600
})
593601
}
602+
603+
navigate('/walk-complete')
594604
}
595605
}
596606

@@ -700,6 +710,7 @@ export default function MapComponent() {
700710
$bgColor={isWalking ? 'font_1' : 'default'}
701711
$fontWeight='700'
702712
$isWalking={isWalking}
713+
disabled={isModalOpen} // 모달이 열려있을 때 버튼 비활성화
703714
>
704715
{isWalking ? '산책 끝' : '산책 시작'}
705716
</S.StyledActionButton>
@@ -716,6 +727,7 @@ export default function MapComponent() {
716727
$bgColor={isWalking ? 'font_1' : 'default'}
717728
$fontWeight='700'
718729
$isWalking={isWalking}
730+
disabled={isModalOpen} // 모달이 열려있을 때 버튼 비활성화
719731
>
720732
{isWalking ? '산책 끝' : '산책 시작'}
721733
</S.StyledActionButton>
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import * as S from './styles'
2+
3+
interface WalkerListModalProps {
4+
isOpen: boolean
5+
onClose: () => void
6+
isClosing: boolean
7+
}
8+
9+
export default function WalkerListModal({ isOpen, onClose, isClosing }: WalkerListModalProps) {
10+
if (!isOpen) return null
11+
12+
const handleBackgroundClick = (e: React.MouseEvent) => {
13+
if (e.target === e.currentTarget) {
14+
onClose()
15+
}
16+
}
17+
18+
return (
19+
<S.Overlay className={isClosing ? 'closing' : ''} onClick={handleBackgroundClick}>
20+
<S.WalkerListContainer className={isClosing ? 'closing' : ''}>
21+
<S.ModalTitle>강번따 리스트</S.ModalTitle>
22+
<S.WalkerListSection>
23+
<S.WalkerList>
24+
{Array(10)
25+
.fill(0)
26+
.map((_, i) => (
27+
<S.WalkerItem key={i}>
28+
<S.ProfileArea>
29+
<S.ProfileCircle />
30+
<S.InfoArea>
31+
<S.Name>밤돌이</S.Name>
32+
<S.Details>
33+
<S.Detail>포메라니안</S.Detail>
34+
<S.WalkListSeparator $height={8} />
35+
<S.Detail>4살</S.Detail>
36+
<S.WalkListSeparator $height={8} />
37+
<S.Detail></S.Detail>
38+
</S.Details>
39+
<S.WalkCount>
40+
산책 횟수 <p>&nbsp;4회</p>
41+
</S.WalkCount>
42+
</S.InfoArea>
43+
</S.ProfileArea>
44+
<S.WalkBtn $type='roundedRect' $bgColor='lighten_3' $fontWeight='700'>
45+
강번따
46+
</S.WalkBtn>
47+
</S.WalkerItem>
48+
))}
49+
</S.WalkerList>
50+
</S.WalkerListSection>
51+
</S.WalkerListContainer>
52+
</S.Overlay>
53+
)
54+
}

0 commit comments

Comments
 (0)