Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature/#11] 프로필 페이지 & 좋아요 목록 페이지 구현 #15

Merged
merged 9 commits into from
Nov 7, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.hackathon.alddeul_babsang.core_ui.component

class BottomSheetButton {
}
seoyeonsw marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.hackathon.alddeul_babsang.domain.entity

data class ProfileLikeListEntity(
val id: Long,
val avatar: String? = null,
val name: String,
val codeName: String,
val address: String,
val phone: String,
val favorite: Boolean=false,
)
seoyeonsw marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,17 @@ package com.hackathon.alddeul_babsang.presentation.profile.navigation

import androidx.navigation.NavGraphBuilder
import androidx.navigation.compose.composable
import com.hackathon.alddeul_babsang.presentation.profile.screen.ProfileLikeListRoute
import com.hackathon.alddeul_babsang.presentation.profile.screen.ProfileRoute


fun NavGraphBuilder.profileNavGraph(
navigator: ProfileNavigator
) {
composable(route = "profile") {
ProfileRoute(navigator = navigator)
}
}
composable(route = "profileLikeList") {
ProfileLikeListRoute(navigator = navigator)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,8 @@ import androidx.navigation.NavController
class ProfileNavigator(
val navController: NavController
) {

fun navigateBack() {
navController.popBackStack()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
package com.hackathon.alddeul_babsang.presentation.profile.screen

import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage
import com.hackathon.alddeul_babsang.R
import com.hackathon.alddeul_babsang.core_ui.theme.AlddeulBabsangTheme
import com.hackathon.alddeul_babsang.core_ui.theme.Gray300
import com.hackathon.alddeul_babsang.core_ui.theme.Orange700
import com.hackathon.alddeul_babsang.core_ui.theme.Orange800
import com.hackathon.alddeul_babsang.core_ui.theme.Orange900
import com.hackathon.alddeul_babsang.core_ui.theme.body2Regular
import com.hackathon.alddeul_babsang.core_ui.theme.body4Regular
import com.hackathon.alddeul_babsang.core_ui.theme.head4Bold
import com.hackathon.alddeul_babsang.domain.entity.ProfileLikeListEntity

@Composable
fun LikeItem(
data: ProfileLikeListEntity
) {
var isFavorite by remember { mutableStateOf(data.favorite ?: false) }

// 클릭할 때마다 favorite 값 토글
val heartIconId = if (isFavorite) {
R.drawable.ic_heart_red
} else {
R.drawable.ic_heart_white
}


Column(
modifier = Modifier
.width(350.dp)
seoyeonsw marked this conversation as resolved.
Show resolved Hide resolved
.border(
width = 1.dp,
color = Orange700,
shape = RoundedCornerShape(14.dp)
)
.height(240.dp)
) {
Box(
modifier = Modifier
.fillMaxWidth()
.height(140.dp)
.clip(RoundedCornerShape(topStart = 14.dp, topEnd = 14.dp))
) {
// AsyncImage 로드
LoadImageWithPlaceholder(data.codeName, data.avatar)

Image(
painter = painterResource(heartIconId),
contentDescription = null,
modifier = Modifier
.padding(end = 10.dp, top = 10.dp)
.align(Alignment.TopEnd) // Box 내에서 오른쪽 끝으로 배치
.clickable {
// 클릭 시 좋아요 상태를 토글
isFavorite = !isFavorite
}
)
}

Spacer(modifier = Modifier.height(15.dp))

Row {
Text(
text = data.name,
style = head4Bold,
color = Orange900,
modifier = Modifier.padding(start = 20.dp)
)

Spacer(modifier = Modifier.width(15.dp))

Text(
text = data.codeName,
style = body2Regular,
color = Orange800,
modifier = Modifier
.align(Alignment.Bottom)
.padding(bottom = 3.dp)
)
}

Spacer(modifier = Modifier.height(12.dp))

Text(
text = data.address,
style = body4Regular,
color = Gray300,
modifier = Modifier.padding(start = 20.dp)
)

Spacer(modifier = Modifier.height(7.dp))

Text(
text = data.phone,
style = body4Regular,
color = Gray300,
modifier = Modifier.padding(start = 20.dp)
)
}
}

@Composable
fun LoadImageWithPlaceholder(codeName: String, imageUrl: String?) {
var imageId = R.drawable.ic_korean_food
if (codeName == "경양식/일식") {
imageId = R.drawable.ic_japanese_food
} else if (codeName == "한식") {
imageId = R.drawable.ic_korean_food
} else if (codeName == "중식") {
imageId = R.drawable.ic_chinese_food
} else {
imageId = R.drawable.ic_etc_food
}
seoyeonsw marked this conversation as resolved.
Show resolved Hide resolved


Box(
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
.background(color = Orange700) // 배경색 설정
) {
if (imageUrl.isNullOrEmpty()) {
// imageUrl이 null이나 empty일 경우 대체 이미지 표시
Image(
painter = painterResource(id = imageId), // 대체 이미지
contentDescription = null,
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
.padding(vertical = 15.dp)
)
} else {
// imageUrl이 null이 아니면 AsyncImage로 비동기 이미지 로드
AsyncImage(
model = imageUrl,
contentDescription = null,
placeholder = painterResource(id = imageId), // codeName에 따라 다른 placeholder 제공
contentScale = ContentScale.Crop,
modifier = Modifier
.fillMaxWidth()
.fillMaxHeight()
.padding(vertical = 15.dp)
seoyeonsw marked this conversation as resolved.
Show resolved Hide resolved
)
}
}
}

@Preview(showBackground = true)
@Composable
fun ReviewItemPreview() {
AlddeulBabsangTheme {
LikeItem(
data = ProfileLikeListEntity(
id = 1,
avatar = null,
name = "송이네 밥상",
codeName = "경양식/일식",
address = "서울특별시 용산구 청파동 11",
phone = "02-210-0220",
favorite = true
)
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.hackathon.alddeul_babsang.presentation.profile.screen


import androidx.lifecycle.ViewModel
import com.hackathon.alddeul_babsang.domain.entity.ProfileLikeListEntity
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject

@HiltViewModel
class LikeListViewModel @Inject constructor() : ViewModel() {


val mockLikeList = listOf(
ProfileLikeListEntity(
id=1,
avatar = null,
name = "송이네 밥상",
codeName = "기타외식업",
address = "서울특별시 용산구 청파동 81",
phone = "02-210-0120",
favorite = true
),
ProfileLikeListEntity(
id=2,
avatar = null,
name = "송이네 일식",
codeName = "경양식/일식",
address = "서울특별시 용산구 청파동 11",
phone = "02-210-0220",
favorite = true
),
ProfileLikeListEntity(
id=3,
avatar = null,
name = "송이네 한식",
codeName = "한식",
address = "서울특별시 용산구 청파동 31",
phone = "02-223-0220",
favorite = true
),
ProfileLikeListEntity(
id=4,
avatar = null,
name = "송이네 중식",
codeName = "중식",
address = "서울특별시 용산구 청파동 31",
phone = "02-223-0220",
favorite = true
),
ProfileLikeListEntity(
id=4,
avatar = "https://avatars.githubusercontent.com/u/166610834?s=400&u=568eacc2e4696d563a4fd732c148edba2196e4f6&v=4",
name = "송이네 밥상",
codeName = "중식",
address = "서울특별시 용산구 청파동 31",
phone = "02-223-0220",
favorite = true
)

)
}
Loading
Loading