Skip to content

Commit 0133ddb

Browse files
authored
merge #73 -> develop
[Feat/#63] 저장한·기록한 산책 루트 화면 ViewModel + 상태 관리 구조 적용
2 parents 4bc13a5 + 81c532c commit 0133ddb

21 files changed

+441
-40
lines changed

app/src/main/java/com/paw/key/presentation/ui/mypage/ArchivedCourseDetailScreen.kt

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@ package com.paw.key.presentation.ui.mypage
22

33
import androidx.compose.foundation.background
44
import androidx.compose.foundation.layout.Box
5-
import androidx.compose.foundation.layout.Column
65
import androidx.compose.foundation.layout.fillMaxSize
76
import androidx.compose.foundation.layout.fillMaxWidth
87
import androidx.compose.foundation.layout.padding
98
import androidx.compose.foundation.lazy.LazyColumn
10-
import androidx.compose.material3.SnackbarHostState
119
import androidx.compose.runtime.Composable
1210
import androidx.compose.runtime.getValue
1311
import androidx.compose.runtime.mutableStateOf
@@ -16,27 +14,39 @@ import androidx.compose.runtime.setValue
1614
import androidx.compose.ui.Modifier
1715
import androidx.compose.ui.tooling.preview.Preview
1816
import androidx.compose.ui.unit.dp
17+
import androidx.hilt.navigation.compose.hiltViewModel
18+
import androidx.lifecycle.compose.collectAsStateWithLifecycle
1919
import com.paw.key.core.designsystem.component.CourseDetail
2020
import com.paw.key.core.designsystem.component.ImageModal
2121
import com.paw.key.core.designsystem.component.PawkeyButton
2222
import com.paw.key.core.designsystem.component.TopBar
2323
import com.paw.key.core.designsystem.theme.PawKeyTheme
2424
import com.paw.key.core.designsystem.theme.White1
25+
import com.paw.key.presentation.ui.mypage.state.ArchivedDetailContract
26+
import com.paw.key.presentation.ui.mypage.viewmodel.ArchivedDetailViewModel
2527

2628
@Composable
2729
fun ArchivedDetailRoute(
2830
navigateUp: () -> Unit,
31+
navigateToWalk: () -> Unit,
2932
modifier: Modifier = Modifier,
33+
viewModel: ArchivedDetailViewModel = hiltViewModel()
3034
) {
35+
val state = viewModel.state.collectAsStateWithLifecycle()
36+
3137
ArchivedCourseDetailScreen(
38+
state = state.value,
3239
navigateUp = navigateUp,
40+
navigateToWalk = navigateToWalk,
3341
modifier = modifier
3442
)
3543
}
3644

3745
@Composable
3846
fun ArchivedCourseDetailScreen(
47+
state: ArchivedDetailContract.ArchivedDetailState,
3948
navigateUp: () -> Unit,
49+
navigateToWalk: () -> Unit,
4050
modifier: Modifier = Modifier
4151
){
4252
var isImageExpanded by remember { mutableStateOf(false) }
@@ -76,7 +86,7 @@ fun ArchivedCourseDetailScreen(
7686

7787
if (isImageExpanded) {
7888
ImageModal(
79-
imageUrl = "https://pawkey-server.com/image.jpg",
89+
imageUrl = state.imageUrl,
8090
onDismiss = { isImageExpanded = false }
8191
)
8292
}
@@ -87,6 +97,18 @@ fun ArchivedCourseDetailScreen(
8797
@Composable
8898
fun ArchivedCourseDetailPreview(){
8999
PawKeyTheme {
90-
ArchivedCourseDetailScreen(navigateUp = {})
100+
ArchivedCourseDetailScreen(state = ArchivedDetailContract.ArchivedDetailState(
101+
title = "한강 산책로",
102+
petName = "후추",
103+
date = "2025/06/02",
104+
location = "뚝섬유원지",
105+
distance = "4.5km",
106+
time = "1시간 30분 소요",
107+
option = listOf("풍경이 좋아요", "조용해요", "길이 깨끗해요"),
108+
imageUrl = "https://pawkey-server.com/image.jpg"
109+
),
110+
navigateUp = {},
111+
navigateToWalk = {}
112+
)
91113
}
92114
}

app/src/main/java/com/paw/key/presentation/ui/mypage/ArchivedCourseListScreen.kt

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,36 @@ import androidx.compose.runtime.Composable
77
import androidx.compose.ui.Modifier
88
import androidx.compose.ui.tooling.preview.Preview
99
import androidx.compose.ui.unit.dp
10+
import androidx.hilt.navigation.compose.hiltViewModel
11+
import androidx.lifecycle.compose.collectAsStateWithLifecycle
1012
import com.paw.key.core.designsystem.component.CourseCard
1113
import com.paw.key.core.designsystem.component.TopBar
1214
import com.paw.key.core.designsystem.theme.PawKeyTheme
1315
import com.paw.key.core.designsystem.theme.White1
16+
import com.paw.key.presentation.ui.mypage.state.ArchivedListContract
17+
import com.paw.key.presentation.ui.mypage.state.SavedListContract.CourseCardData
18+
import com.paw.key.presentation.ui.mypage.viewmodel.ArchivedListViewModel
1419

1520
@Composable
1621
fun ArchivedCourseRoute(
1722
navigateUp: () -> Unit,
1823
navigateNext: () -> Unit,
1924
modifier: Modifier = Modifier,
25+
viewModel: ArchivedListViewModel = hiltViewModel()
2026
) {
27+
val state = viewModel.state.collectAsStateWithLifecycle()
28+
2129
ArchivedCourseListScreen(
30+
state = state.value,
2231
navigateUp = navigateUp,
2332
navigateNext = navigateNext,
24-
modifier = modifier
33+
modifier = modifier
2534
)
2635
}
2736

2837
@Composable
2938
fun ArchivedCourseListScreen(
39+
state: ArchivedListContract.ArchivedListState,
3040
navigateUp: () -> Unit,
3141
navigateNext: () -> Unit,
3242
modifier: Modifier = Modifier
@@ -81,6 +91,21 @@ fun ArchivedCourseListScreen(
8191
@Composable
8292
fun ArchivedCourseListScreenPreview() {
8393
PawKeyTheme {
84-
ArchivedCourseListScreen(navigateUp = {}, navigateNext = {})
94+
ArchivedCourseListScreen(
95+
state = ArchivedListContract.ArchivedListState(
96+
courseList = listOf(
97+
ArchivedListContract.CourseCardData(
98+
title = "예시 산책로",
99+
petName = "하루",
100+
date = "2025/01/01",
101+
location = "강남",
102+
distance = "2.3km",
103+
time = "45분"
104+
)
105+
)
106+
),
107+
navigateUp = {},
108+
navigateNext = {}
109+
)
85110
}
86111
}

app/src/main/java/com/paw/key/presentation/ui/mypage/MyPageScreen.kt

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,13 @@ import androidx.compose.ui.graphics.vector.ImageVector
1919
import androidx.compose.ui.res.vectorResource
2020
import androidx.compose.ui.unit.dp
2121
import androidx.compose.ui.tooling.preview.Preview
22+
import androidx.hilt.navigation.compose.hiltViewModel
23+
import androidx.lifecycle.compose.collectAsStateWithLifecycle
2224
import com.paw.key.R
2325
import com.paw.key.core.designsystem.component.SubChip
2426
import com.paw.key.core.designsystem.theme.PawKeyTheme
27+
import com.paw.key.presentation.ui.mypage.state.MyPageContract
28+
import com.paw.key.presentation.ui.mypage.viewmodel.MyPageViewModel
2529

2630
@Composable
2731
fun MyPageRoute(
@@ -32,9 +36,13 @@ fun MyPageRoute(
3236
navigateArchivedCourse: () -> Unit,
3337
navigateSavedCourse: () -> Unit,
3438
snackBarHostState: SnackbarHostState,
35-
modifier: Modifier = Modifier
39+
modifier: Modifier = Modifier,
40+
viewModel: MyPageViewModel = hiltViewModel()
3641
) {
42+
val state = viewModel.state.collectAsStateWithLifecycle()
43+
3744
MyPageScreen(
45+
state = state.value,
3846
paddingValues = paddingValues,
3947
navigateUp = navigateUp,
4048
navigateUserProfile = navigateUserProfile,
@@ -43,12 +51,12 @@ fun MyPageRoute(
4351
navigateSavedCourse = navigateSavedCourse,
4452
snackBarHostState = snackBarHostState,
4553
modifier = modifier
46-
4754
)
4855
}
4956

5057
@Composable
5158
fun MyPageScreen(
59+
state: MyPageContract.MyPageState,
5260
paddingValues: PaddingValues,
5361
navigateUp: () -> Unit,
5462
navigateUserProfile: () -> Unit,
@@ -70,19 +78,23 @@ fun MyPageScreen(
7078
style = PawKeyTheme.typography.head22B,
7179
modifier = Modifier.padding(start = 16.dp, top = 16.dp, bottom = 12.dp)
7280
)
73-
OwnerCard(ownerName = "김도기님", role = "견주", navigateUserProfile = navigateUserProfile)
74-
81+
OwnerCard(
82+
ownerName = state.ownerName,
83+
role = state.role,
84+
navigateUserProfile = navigateUserProfile
85+
)
7586
Spacer(modifier = Modifier.height(19.dp))
7687

7788
PetCard(
78-
name = "포비",
79-
age = "12세",
80-
gender = "여아",
81-
tags = listOf("조금 느긋해요", "#오토바이소리", "#대형견"),
82-
walkCount = "7회",
83-
totalDistance = "14km",
89+
name = state.petName,
90+
age = state.petAge,
91+
gender = state.petGender,
92+
tags = state.petTags,
93+
walkCount = state.walkCount,
94+
totalDistance = state.totalDistance,
8495
navigatePetProfile = navigatePetProfile
8596
)
97+
8698
Spacer(modifier = Modifier.height(12.dp))
8799

88100
WalkRouteList(
@@ -159,7 +171,7 @@ fun PetCard(
159171
)
160172
Text(
161173
text = "반려견 프로필",
162-
style = PawKeyTheme.typography.caption12Sb1,
174+
style = PawKeyTheme.typography.body16Sb,
163175
color = Color.White
164176
)
165177
Spacer(modifier = Modifier.weight(1f))
@@ -290,7 +302,16 @@ fun WalkRouteList(
290302
@Composable
291303
private fun MyPageScreenPreview() {
292304
PawKeyTheme {
293-
MyPageScreen(
305+
MyPageScreen(state = MyPageContract.MyPageState(
306+
ownerName = "김도기님",
307+
role = "견주",
308+
petName = "포비",
309+
petAge = "12세",
310+
petGender = "여아",
311+
petTags = listOf("조금 느긋해요", "#오토바이소리", "#대형견"),
312+
walkCount = "7회",
313+
totalDistance = "14km"
314+
),
294315
paddingValues = PaddingValues(),
295316
navigateUp = {},
296317
navigateUserProfile = {},

app/src/main/java/com/paw/key/presentation/ui/mypage/PetProfileScreen.kt

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,41 @@ import androidx.compose.ui.layout.ContentScale
1616
import androidx.compose.ui.res.painterResource
1717
import androidx.compose.ui.res.vectorResource
1818
import androidx.compose.ui.tooling.preview.Preview
19+
import androidx.hilt.navigation.compose.hiltViewModel
20+
import androidx.lifecycle.compose.collectAsStateWithLifecycle
1921
import com.paw.key.R
2022
import com.paw.key.core.designsystem.component.TopBar
2123
import com.paw.key.core.designsystem.theme.PawKeyTheme
24+
import com.paw.key.presentation.ui.mypage.state.PetProfileContract
25+
import com.paw.key.presentation.ui.mypage.viewmodel.PetProfileViewModel
2226

2327
@Composable
2428
fun PetProfileRoute(
2529
navigateUp : () -> Unit,
2630
modifier: Modifier = Modifier,
31+
viewModel: PetProfileViewModel = hiltViewModel()
2732
) {
33+
val state = viewModel.state.collectAsStateWithLifecycle()
34+
2835
PetProfileScreen(
36+
state = state.value,
2937
navigateUp = navigateUp,
3038
modifier = modifier
3139
)
3240
}
3341

3442
@Composable
3543
fun PetProfileScreen(
44+
state: PetProfileContract.PetProfileState,
3645
navigateUp: () -> Unit,
46+
modifier: Modifier = Modifier,
47+
imageUrl: String? = null,
3748
name: String = "까루",
3849
gender: String = "남아",
3950
breed: String = "코리안 숏헤어",
4051
age: String = "4세",
41-
personality: String = "활동적",
42-
modifier: Modifier = Modifier
52+
energyLevel: String = "활동적이에요",
53+
socialLevel: String = "불편해해요"
4354
) {
4455
Column(
4556
modifier = modifier
@@ -58,6 +69,7 @@ fun PetProfileScreen(
5869
.clip(CircleShape)
5970
.border(2.dp, PawKeyTheme.colors.green500, CircleShape)
6071
) {
72+
// TODO: imageUrl AsyncImage로 URL 로딩
6173
Image(
6274
painter = painterResource(id = R.drawable.profile),
6375
contentDescription = null,
@@ -106,7 +118,7 @@ fun PetProfileScreen(
106118
color = PawKeyTheme.colors.gray600
107119
)
108120
Text(
109-
text = "활동적이에요",
121+
text = energyLevel,
110122
style = PawKeyTheme.typography.head18Sb,
111123
color = PawKeyTheme.colors.green500
112124
)
@@ -124,7 +136,7 @@ fun PetProfileScreen(
124136
color = PawKeyTheme.colors.gray600
125137
)
126138
Text(
127-
text = "불편해해요",
139+
text = socialLevel,
128140
style = PawKeyTheme.typography.head18Sb,
129141
color = PawKeyTheme.colors.green500
130142
)
@@ -164,7 +176,15 @@ fun PetProfileItem(
164176
fun PetProfileScreenPreview() {
165177
PawKeyTheme {
166178
PetProfileScreen(
167-
navigateUp = {},
179+
state = PetProfileContract.PetProfileState(
180+
name = "까루",
181+
gender = "남아",
182+
breed = "코리안 숏헤어",
183+
age = "4세",
184+
energyLevel = "활동적이에요",
185+
socialLevel = "불편해해요"
186+
),
187+
navigateUp = {}
168188
)
169189
}
170190
}

0 commit comments

Comments
 (0)