diff --git a/core/designsystem/src/main/java/com/hankki/core/designsystem/theme/Type.kt b/core/designsystem/src/main/java/com/hankki/core/designsystem/theme/Type.kt index 748ee4a9c..5311a7047 100644 --- a/core/designsystem/src/main/java/com/hankki/core/designsystem/theme/Type.kt +++ b/core/designsystem/src/main/java/com/hankki/core/designsystem/theme/Type.kt @@ -26,6 +26,7 @@ class HankkiTypography internal constructor( h1: TextStyle, h2: TextStyle, suitH1: TextStyle, + suitH2: TextStyle, sub1: TextStyle, sub2: TextStyle, sub3: TextStyle, @@ -47,6 +48,8 @@ class HankkiTypography internal constructor( private set var suitH1: TextStyle by mutableStateOf(suitH1) private set + var suitH2: TextStyle by mutableStateOf(suitH2) + private set var sub1: TextStyle by mutableStateOf(sub1) private set var sub2: TextStyle by mutableStateOf(sub2) @@ -80,6 +83,7 @@ class HankkiTypography internal constructor( h1: TextStyle = this.h1, h2: TextStyle = this.h2, suitH1: TextStyle = this.suitH1, + suitH2: TextStyle = this.suitH2, sub1: TextStyle = this.sub1, sub2: TextStyle = this.sub2, sub3: TextStyle = this.sub3, @@ -98,6 +102,7 @@ class HankkiTypography internal constructor( h1, h2, suitH1, + suitH2, sub1, sub2, sub3, @@ -118,6 +123,7 @@ class HankkiTypography internal constructor( h1 = other.h1 h2 = other.h2 suitH1 = other.suitH1 + suitH2 = other.suitH2 sub1 = other.sub1 sub2 = other.sub2 sub3 = other.sub3 @@ -156,6 +162,12 @@ fun hankkiTypography(): HankkiTypography { fontSize = 24.sp, lineHeight = 36.sp ), + suitH2 = TextStyle( + fontFamily = SuiteBold, + fontWeight = FontWeight.Bold, + fontSize = 20.sp, + lineHeight = 30.sp + ), sub1 = TextStyle( fontFamily = PretendardSemiBold, fontWeight = FontWeight.SemiBold, diff --git a/domain/my/.gitignore b/domain/my/.gitignore new file mode 100644 index 000000000..42afabfd2 --- /dev/null +++ b/domain/my/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/domain/my/build.gradle.kts b/domain/my/build.gradle.kts new file mode 100644 index 000000000..540cfbfaf --- /dev/null +++ b/domain/my/build.gradle.kts @@ -0,0 +1,4 @@ +// domain +plugins { + alias(libs.plugins.hankki.kotlin) +} \ No newline at end of file diff --git a/domain/my/src/main/java/com/hankki/domain/my/entity/UserInfoEntity.kt b/domain/my/src/main/java/com/hankki/domain/my/entity/UserInfoEntity.kt new file mode 100644 index 000000000..eabe8826b --- /dev/null +++ b/domain/my/src/main/java/com/hankki/domain/my/entity/UserInfoEntity.kt @@ -0,0 +1,6 @@ +package com.hankki.domain.my.entity + +data class UserInfoEntity ( + val name : String, + val image : String +) \ No newline at end of file diff --git a/feature/my/build.gradle.kts b/feature/my/build.gradle.kts index fcfabd2d5..5d36b85ed 100644 --- a/feature/my/build.gradle.kts +++ b/feature/my/build.gradle.kts @@ -8,4 +8,12 @@ android { setNamespace("feature.my") } -dependencies {} +dependencies { + //domain + implementation(projects.domain.my) + + //other + implementation(libs.coil.compose) +} + + diff --git a/feature/my/src/main/java/com/hankki/feature/my/MyRoute.kt b/feature/my/src/main/java/com/hankki/feature/my/MyRoute.kt index 5b09bfd0b..06c7cc160 100644 --- a/feature/my/src/main/java/com/hankki/feature/my/MyRoute.kt +++ b/feature/my/src/main/java/com/hankki/feature/my/MyRoute.kt @@ -1,28 +1,181 @@ package com.hankki.feature.my +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding -import androidx.compose.material3.Button +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +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.res.stringResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import coil.compose.AsyncImage +import com.hankki.core.common.extension.noRippleClickable +import com.hankki.core.designsystem.theme.Gray400 +import com.hankki.core.designsystem.theme.Gray900 +import com.hankki.core.designsystem.theme.HankkiTheme +import com.hankki.core.designsystem.theme.HankkijogboTheme +import com.hankki.core.designsystem.theme.Red +import com.hankki.core.designsystem.theme.White +import com.hankki.feature.my.component.ButtonWithArrowIcon +import com.hankki.feature.my.component.ButtonWithImageAndBorder +import com.hankki.feature.my.component.MyTitle @Composable -fun MyRoute(paddingValues: PaddingValues, navigateToDummy: () -> Unit) { - MyScreen(paddingValues, navigateToDummy = navigateToDummy) +fun MyRoute( + paddingValues: PaddingValues, + navigateToDummy: () -> Unit, + myViewModel: MyViewModel = hiltViewModel() +) { + val myState by myViewModel.myState.collectAsStateWithLifecycle() + + LaunchedEffect(true) { + myViewModel.loadMockInformation() + } + + MyScreen( + paddingValues = paddingValues, + navigateToDummy = navigateToDummy, + userName = myState.userState.name, + userImage = myState.userState.image + ) } @Composable fun MyScreen( paddingValues: PaddingValues, navigateToDummy: () -> Unit, + userName: String, + userImage: String ) { - Column(modifier = Modifier.padding(paddingValues)) { - Text(text = "My") + val scrollState = rememberScrollState() + + Column( + modifier = Modifier + .padding(paddingValues) + .padding(horizontal = 22.dp) + .fillMaxSize() + .verticalScroll(scrollState), + horizontalAlignment = Alignment.CenterHorizontally + ) { + MyTitle(title = stringResource(R.string.my)) + + Spacer(modifier = Modifier.height(15.dp)) + + AsyncImage( + modifier = Modifier + .size(98.dp) + .clip(CircleShape), + model = userImage, + contentDescription = stringResource(R.string.profile_image), + contentScale = ContentScale.None + ) + + Spacer(modifier = Modifier.height(10.dp)) + + Text( + text = stringResource(R.string.message_user_name, userName), + color = Gray900, + style = HankkiTheme.typography.suitH2, + textAlign = TextAlign.Center + ) + + Spacer(modifier = Modifier.height(19.dp)) - Button(onClick = navigateToDummy) { - Text(text = "Go to Dummy") + Row( + modifier = Modifier + .fillMaxWidth() + .background( + Red, + shape = RoundedCornerShape(12.dp) + ) + .clip(RoundedCornerShape(12.dp)) + .padding(start = 28.dp, end = 29.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween, + ) { + Text( + text = stringResource(R.string.my_jogbo), + style = HankkiTheme.typography.sub1, + color = White, + ) + Image( + painter = painterResource(id = R.drawable.ic_mygraphic), + contentDescription = null, + ) + } + + Spacer(modifier = Modifier.height(19.dp)) + + Row { + ButtonWithImageAndBorder( + R.drawable.ic_report, + stringResource(R.string.description_store_report), + Modifier.weight(1f) + ) + Spacer(modifier = Modifier.width(18.dp)) + ButtonWithImageAndBorder( + R.drawable.ic_good, + stringResource(R.string.description_store_like), + Modifier.weight(1f) + ) + } + + ButtonWithArrowIcon(stringResource(R.string.faq), navigateToDummy) + + ButtonWithArrowIcon(stringResource(R.string.inquiry), navigateToDummy) + + ButtonWithArrowIcon(stringResource(R.string.logout), navigateToDummy) + + Box( + modifier = Modifier + .fillMaxWidth(), + contentAlignment = Alignment.CenterEnd + ) { + Text( + text = stringResource(R.string.quit), + modifier = Modifier + .noRippleClickable(onClick = navigateToDummy) + .padding(top = 14.dp, start = 15.dp, bottom = 13.dp), + textAlign = TextAlign.End, + style = HankkiTheme.typography.body4, + color = Gray400, + ) } } } + + +@Preview(showBackground = true) +@Composable +fun MyScreenPreview() { + HankkijogboTheme { + MyScreen( + paddingValues = PaddingValues(), navigateToDummy = {}, userName = "", userImage = "" + ) + } +} \ No newline at end of file diff --git a/feature/my/src/main/java/com/hankki/feature/my/MyState.kt b/feature/my/src/main/java/com/hankki/feature/my/MyState.kt new file mode 100644 index 000000000..d2c6bd5dd --- /dev/null +++ b/feature/my/src/main/java/com/hankki/feature/my/MyState.kt @@ -0,0 +1,7 @@ +package com.hankki.feature.my + +import com.hankki.domain.my.entity.UserInfoEntity + +data class MyState( + val userState : UserInfoEntity = UserInfoEntity("","") +) \ No newline at end of file diff --git a/feature/my/src/main/java/com/hankki/feature/my/MyViewModel.kt b/feature/my/src/main/java/com/hankki/feature/my/MyViewModel.kt new file mode 100644 index 000000000..023e610cc --- /dev/null +++ b/feature/my/src/main/java/com/hankki/feature/my/MyViewModel.kt @@ -0,0 +1,29 @@ +package com.hankki.feature.my + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.hankki.domain.my.entity.UserInfoEntity +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch +import javax.inject.Inject + +@HiltViewModel +class MyViewModel @Inject constructor() : ViewModel() { + private val _myState = MutableStateFlow(MyState()) + val myState: StateFlow + get() = _myState.asStateFlow() + + fun loadMockInformation() { + viewModelScope.launch { + val mockUserName = "송한끼" + val mockUserImage = "" + val mockUserInformation = UserInfoEntity(mockUserName, mockUserImage) + _myState.value = _myState.value.copy( + userState = mockUserInformation + ) + } + } +} \ No newline at end of file diff --git a/feature/my/src/main/java/com/hankki/feature/my/component/ButtonWithArrowIcon.kt b/feature/my/src/main/java/com/hankki/feature/my/component/ButtonWithArrowIcon.kt new file mode 100644 index 000000000..08e9ab49c --- /dev/null +++ b/feature/my/src/main/java/com/hankki/feature/my/component/ButtonWithArrowIcon.kt @@ -0,0 +1,53 @@ +package com.hankki.feature.my.component + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.hankki.core.common.extension.noRippleClickable +import com.hankki.core.designsystem.theme.Gray200 +import com.hankki.core.designsystem.theme.Gray900 +import com.hankki.core.designsystem.theme.HankkiTheme +import com.hankki.core.designsystem.theme.HankkijogboTheme +import com.hankki.feature.my.R + +@Composable +fun ButtonWithArrowIcon( + itemTitle: String, + onClick: () -> Unit, + modifier: Modifier = Modifier +) { + Row( + modifier + .fillMaxWidth() + .padding(vertical = 18.dp) + .noRippleClickable(onClick = onClick), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + Text( + text = itemTitle, + style = HankkiTheme.typography.body3, + color = Gray900 + ) + Image(painterResource(id = R.drawable.ic_arrow_right), "ic_arrow_right") + } + HorizontalDivider(thickness = 1.dp, color = Gray200) +} + +@Composable +@Preview +fun ItemWithArrowPreview() { + HankkijogboTheme { + ButtonWithArrowIcon(itemTitle = "title", onClick = {}, modifier = Modifier) + } +} diff --git a/feature/my/src/main/java/com/hankki/feature/my/component/ButtonWithImageAndBorder.kt b/feature/my/src/main/java/com/hankki/feature/my/component/ButtonWithImageAndBorder.kt new file mode 100644 index 000000000..408a1fa42 --- /dev/null +++ b/feature/my/src/main/java/com/hankki/feature/my/component/ButtonWithImageAndBorder.kt @@ -0,0 +1,72 @@ +package com.hankki.feature.my.component + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.hankki.core.designsystem.theme.Gray200 +import com.hankki.core.designsystem.theme.Gray50 +import com.hankki.core.designsystem.theme.Gray900 +import com.hankki.core.designsystem.theme.HankkiTheme +import com.hankki.core.designsystem.theme.HankkijogboTheme +import com.hankki.feature.my.R + +@Composable +fun ButtonWithImageAndBorder( + buttonImage: Int, + buttonDescription: String, + modifier: Modifier = Modifier +) { + Column( + modifier + .fillMaxWidth() + .background( + Gray50, + shape = RoundedCornerShape(size = 12.dp) + ) + .border( + 1.dp, + color = Gray200, + shape = RoundedCornerShape(size = 12.dp) + ) + .padding(top = 18.dp, bottom = 17.dp), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Image( + painter = painterResource(id = buttonImage), + contentDescription = buttonDescription + ) + Spacer(modifier = Modifier.height(12.dp)) + Text( + text = buttonDescription, + style = HankkiTheme.typography.body3, + color = Gray900, + textAlign = TextAlign.Center + ) + } +} + +@Composable +@Preview +fun ButtonPrev() { + HankkijogboTheme { + ButtonWithImageAndBorder( + buttonImage = R.drawable.ic_good, + buttonDescription = "test", + modifier = Modifier + ) + } +} \ No newline at end of file diff --git a/feature/my/src/main/java/com/hankki/feature/my/component/Title.kt b/feature/my/src/main/java/com/hankki/feature/my/component/Title.kt new file mode 100644 index 000000000..476290374 --- /dev/null +++ b/feature/my/src/main/java/com/hankki/feature/my/component/Title.kt @@ -0,0 +1,27 @@ +package com.hankki.feature.my.component + +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import com.hankki.core.designsystem.theme.Gray900 +import com.hankki.core.designsystem.theme.HankkiTheme + +@Composable +fun MyTitle(title: String) { + Row { + Text( + text = title, + color = Gray900, + style = HankkiTheme.typography.sub3, + textAlign = TextAlign.Center, + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 18.dp) + ) + } +} diff --git a/feature/my/src/main/res/drawable/ic_arrow_right.xml b/feature/my/src/main/res/drawable/ic_arrow_right.xml new file mode 100644 index 000000000..8b7f0299d --- /dev/null +++ b/feature/my/src/main/res/drawable/ic_arrow_right.xml @@ -0,0 +1,13 @@ + + + diff --git a/feature/my/src/main/res/drawable/ic_good.xml b/feature/my/src/main/res/drawable/ic_good.xml new file mode 100644 index 000000000..94ed0ce5b --- /dev/null +++ b/feature/my/src/main/res/drawable/ic_good.xml @@ -0,0 +1,13 @@ + + + diff --git a/feature/my/src/main/res/drawable/ic_mygraphic.xml b/feature/my/src/main/res/drawable/ic_mygraphic.xml new file mode 100644 index 000000000..7e27c70b5 --- /dev/null +++ b/feature/my/src/main/res/drawable/ic_mygraphic.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + diff --git a/feature/my/src/main/res/drawable/ic_report.xml b/feature/my/src/main/res/drawable/ic_report.xml new file mode 100644 index 000000000..c13a69ced --- /dev/null +++ b/feature/my/src/main/res/drawable/ic_report.xml @@ -0,0 +1,9 @@ + + + diff --git a/feature/my/src/main/res/values/strings.xml b/feature/my/src/main/res/values/strings.xml new file mode 100644 index 000000000..5f3159d7b --- /dev/null +++ b/feature/my/src/main/res/values/strings.xml @@ -0,0 +1,13 @@ + + + MY + profile image + %1$s 님\n한끼 잘 챙겨 드세요 + 나의 족보 + 내가 제보한 식당 + 좋아요 누른 식당 + FAQ + 1:1 문의 + 로그아웃 + 탈퇴하기 + \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 581a00ec8..8801096dd 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -43,7 +43,8 @@ include( // domain include( - ":domain:dummy" + ":domain:dummy", + ":domain:my" ) // feature