diff --git a/.github/workflows/dokka.yml b/.github/workflows/dokka.yml
index 252f3cd3d..33920026f 100644
--- a/.github/workflows/dokka.yml
+++ b/.github/workflows/dokka.yml
@@ -27,10 +27,12 @@ jobs:
- name: Set Local Properties
env:
BASE_URL: ${{ secrets.BASE_URL }}
+ TEST_BASE_URL: ${{ secrets.TEST_BASE_URL }}
NATIVE_APP_KEY: ${{ secrets.NATIVE_APP_KEY }}
NATIVEAPPKEY: ${{ secrets.NATIVEAPPKEY }}
run: |
echo base.url=\"$BASE_URL\" >> local.properties
+ echo test.base.url=\"$TEST_BASE_URL\" >> local.properties
echo native.app.key=\"$NATIVE_APP_KEY\" >> local.properties
echo nativeAppKey=\"$NATIVEAPPKEY\" >> local.properties
diff --git a/.github/workflows/pr_checker.yml b/.github/workflows/pr_checker.yml
index e8548ccda..d08ddca5a 100644
--- a/.github/workflows/pr_checker.yml
+++ b/.github/workflows/pr_checker.yml
@@ -41,5 +41,11 @@ jobs:
- name: Access Local Properties
env:
base_url: ${{ secrets.BASE_URL }}
+ TEST_BASE_URL: ${{ secrets.TEST_BASE_URL }}
+ NATIVE_APP_KEY: ${{ secrets.NATIVE_APP_KEY }}
+ NATIVEAPPKEY: ${{ secrets.NATIVEAPPKEY }}
run: |
- echo base.url=\"$base_url\" >> local.properties
\ No newline at end of file
+ echo base.url=\"$base_url\" >> local.properties
+ echo test.base.url=\"$TEST_BASE_URL\" >> local.properties
+ echo native.app.key=\"$NATIVE_APP_KEY\" >> local.properties
+ echo nativeAppKey=\"$NATIVEAPPKEY\" >> local.properties
\ No newline at end of file
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index e01b17572..e53028e48 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -38,7 +38,7 @@ android {
buildConfigField(
"String",
"BASE_URL",
- gradleLocalProperties(rootDir, providers).getProperty("base.url")
+ gradleLocalProperties(rootDir, providers).getProperty("test.base.url")
)
}
release {
diff --git a/app/src/main/java/com/terning/point/di/AuthInterceptor.kt b/app/src/main/java/com/terning/point/di/AuthInterceptor.kt
index cc8680022..43de4f28b 100644
--- a/app/src/main/java/com/terning/point/di/AuthInterceptor.kt
+++ b/app/src/main/java/com/terning/point/di/AuthInterceptor.kt
@@ -26,9 +26,9 @@ class AuthInterceptor @Inject constructor(
override fun intercept(chain: Interceptor.Chain): Response {
val originalRequest = chain.request()
- Timber.d("GET REFRESH TOKEN : ${terningDataStore.refreshToken}")
+ Timber.d("GET ACCESS TOKEN : ${terningDataStore.accessToken}")
- val authRequest = if (terningDataStore.refreshToken.isNotBlank()) {
+ val authRequest = if (terningDataStore.accessToken.isNotBlank()) {
originalRequest.newBuilder().newAuthBuilder().build()
} else {
originalRequest
@@ -45,7 +45,7 @@ class AuthInterceptor @Inject constructor(
)
}.onSuccess { data ->
terningDataStore.apply {
- refreshToken = data.refreshToken
+ accessToken = data.accessToken
}
response.close()
@@ -77,7 +77,7 @@ class AuthInterceptor @Inject constructor(
}
private fun Request.Builder.newAuthBuilder() =
- this.addHeader(AUTHORIZATION, "$BEARER ${terningDataStore.refreshToken}")
+ this.addHeader(AUTHORIZATION, "$BEARER ${terningDataStore.accessToken}")
companion object {
private const val CODE_TOKEN_EXPIRED = 401
diff --git a/core/src/main/java/com/terning/core/designsystem/component/bottomsheet/MyPageLogoutBottomSheet.kt b/core/src/main/java/com/terning/core/designsystem/component/bottomsheet/MyPageLogoutBottomSheet.kt
index ff3268983..9d7e9d318 100644
--- a/core/src/main/java/com/terning/core/designsystem/component/bottomsheet/MyPageLogoutBottomSheet.kt
+++ b/core/src/main/java/com/terning/core/designsystem/component/bottomsheet/MyPageLogoutBottomSheet.kt
@@ -1,6 +1,8 @@
package com.terning.core.designsystem.component.bottomsheet
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Text
@@ -41,18 +43,20 @@ fun MyPageLogoutBottomSheet(
content = {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = modifier
) {
+ Spacer(modifier = modifier.height(10.dp))
Text(
text = stringResource(id = R.string.my_page_bottom_sheet_title),
style = TerningTheme.typography.heading1,
- modifier = modifier.padding(top = 35.dp)
)
+ Spacer(modifier = modifier.height(60.dp))
Text(
text = stringResource(id = R.string.my_page_logout_sub),
style = TerningTheme.typography.body4,
color = Grey400,
- modifier = modifier.padding(top = 54.dp)
)
+ Spacer(modifier = modifier.height(64.dp))
RoundButton(
style = TerningTheme.typography.button2,
paddingVertical = 15.dp,
@@ -63,10 +67,10 @@ fun MyPageLogoutBottomSheet(
},
modifier = modifier.padding(
start = 24.dp,
- top = 72.dp,
end = 24.dp
),
)
+ Spacer(modifier = modifier.height(8.dp))
DeleteRoundButton(
style = TerningTheme.typography.button2,
paddingVertical = 15.dp,
@@ -82,11 +86,10 @@ fun MyPageLogoutBottomSheet(
},
modifier = modifier.padding(
start = 24.dp,
- top = 8.dp,
end = 24.dp,
- bottom = 100.dp
)
)
+ Spacer(modifier = modifier.height(32.dp))
}
},
onDismissRequest = { onDismiss() },
diff --git a/core/src/main/java/com/terning/core/designsystem/component/bottomsheet/MyPageQuitBottomSheet.kt b/core/src/main/java/com/terning/core/designsystem/component/bottomsheet/MyPageQuitBottomSheet.kt
index 42c1d597b..dd8717115 100644
--- a/core/src/main/java/com/terning/core/designsystem/component/bottomsheet/MyPageQuitBottomSheet.kt
+++ b/core/src/main/java/com/terning/core/designsystem/component/bottomsheet/MyPageQuitBottomSheet.kt
@@ -1,6 +1,8 @@
package com.terning.core.designsystem.component.bottomsheet
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Text
@@ -42,19 +44,21 @@ fun MyPageQuitBottomSheet(
content = {
Column(
horizontalAlignment = Alignment.CenterHorizontally,
+ modifier = modifier
) {
+ Spacer(modifier = modifier.height(10.dp))
Text(
text = stringResource(id = R.string.my_page_bottom_sheet_title),
style = TerningTheme.typography.heading1,
- modifier = modifier.padding(top = 14.dp)
)
+ Spacer(modifier = modifier.height(28.dp))
Text(
text = stringResource(id = R.string.my_page_quit_sub),
style = TerningTheme.typography.body3,
- modifier = modifier.padding(top = 54.dp),
textAlign = TextAlign.Center,
color = Grey400
)
+ Spacer(modifier = modifier.height(36.dp))
RoundButton(
style = TerningTheme.typography.button2,
paddingVertical = 15.dp,
@@ -63,12 +67,12 @@ fun MyPageQuitBottomSheet(
onButtonClick = {
onQuitClick()
},
- modifier = modifier.padding(
+ modifier = Modifier.padding(
start = 24.dp,
- top = 41.dp,
end = 24.dp
)
)
+ Spacer(modifier = modifier.height(8.dp))
DeleteRoundButton(
style = TerningTheme.typography.button2,
paddingVertical = 15.dp,
@@ -82,13 +86,12 @@ fun MyPageQuitBottomSheet(
}
}
},
- modifier = modifier.padding(
+ modifier = Modifier.padding(
start = 24.dp,
- top = 8.dp,
end = 24.dp,
- bottom = 100.dp
)
)
+ Spacer(modifier = modifier.height(32.dp))
}
},
onDismissRequest = { onDismiss() },
diff --git a/core/src/main/java/com/terning/core/designsystem/component/bottomsheet/SignUpBottomSheet.kt b/core/src/main/java/com/terning/core/designsystem/component/bottomsheet/ProfileBottomSheet.kt
similarity index 76%
rename from core/src/main/java/com/terning/core/designsystem/component/bottomsheet/SignUpBottomSheet.kt
rename to core/src/main/java/com/terning/core/designsystem/component/bottomsheet/ProfileBottomSheet.kt
index db86a1aba..9382ceb7a 100644
--- a/core/src/main/java/com/terning/core/designsystem/component/bottomsheet/SignUpBottomSheet.kt
+++ b/core/src/main/java/com/terning/core/designsystem/component/bottomsheet/ProfileBottomSheet.kt
@@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.itemsIndexed
@@ -17,7 +18,6 @@ import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableIntStateOf
-import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
@@ -27,14 +27,13 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.terning.core.R
-import com.terning.core.designsystem.component.button.RoundButton
import com.terning.core.designsystem.theme.TerningMain
import com.terning.core.designsystem.theme.TerningTheme
import com.terning.core.extension.noRippleClickable
import kotlinx.coroutines.launch
/**
- * 회원가입을 할 때 프로필 이미지를 선택할 수 있는 바텀시트입니다.
+ * 프로필 이미지를 선택할 수 있는 바텀시트입니다.
*
* @param modifier 바텀시트에 적용할 Modifier입니다.
* @param onDismiss 바텀시트가 닫힐 때 호출되는 콜백 함수입니다.
@@ -43,7 +42,7 @@ import kotlinx.coroutines.launch
*/
@OptIn(ExperimentalMaterial3Api::class)
@Composable
-fun SignUpBottomSheet(
+fun ProfileBottomSheet(
modifier: Modifier = Modifier,
onDismiss: () -> Unit,
onSaveClick: (Int) -> Unit,
@@ -52,43 +51,30 @@ fun SignUpBottomSheet(
val scope = rememberCoroutineScope()
val sheetState = rememberModalBottomSheetState()
- var selectedImageIndex by remember { mutableIntStateOf(initialSelectedOption) }
-
TerningBasicBottomSheet(
content = {
- Column {
+ Column(modifier = modifier) {
Text(
text = stringResource(id = R.string.sign_up_bottom_sheet_title),
style = TerningTheme.typography.title2,
- modifier = modifier
+ modifier = Modifier
.padding(
start = 28.dp,
- bottom = 25.dp
+ bottom = 20.dp
),
)
RadioButtonGroup(
onOptionSelected = { index ->
- selectedImageIndex = index
- },
- initialSelectedOption = initialSelectedOption
- )
- Spacer(modifier = modifier.padding(bottom = 24.dp))
- RoundButton(
- style = TerningTheme.typography.button0,
- paddingVertical = 19.dp,
- cornerRadius = 10.dp,
- text = R.string.sign_up_dialog_start,
- onButtonClick = {
scope.launch { sheetState.hide() }
.invokeOnCompletion {
if (!sheetState.isVisible) {
- onSaveClick(selectedImageIndex)
+ onSaveClick(index)
}
}
},
- modifier = modifier.padding(horizontal = 24.dp)
+ initialSelectedOption = initialSelectedOption
)
- Spacer(modifier = modifier.padding(bottom = 15.dp))
+ Spacer(modifier = modifier.padding(bottom = 26.dp))
}
},
onDismissRequest = { onDismiss() },
@@ -99,15 +85,15 @@ fun SignUpBottomSheet(
/**
* 6개의 프로필 이미지 중, 하나의 이미지만 선택할 수 있는 라디오 버튼입니다.
*
- * @param modifier 라디오 버튼에 적용할 Modifier입니다.
* @param onOptionSelected 선택된 이미지의 인덱스 값을 나타내는 콜백 함수입니다.
* @param initialSelectedOption 초기에 선택된 이미지를 나타내는 인덱스 값입니다.
+ * @param modifier 라디오 버튼에 적용할 Modifier입니다.
*/
@Composable
fun RadioButtonGroup(
- modifier: Modifier = Modifier,
onOptionSelected: (Int) -> Unit,
- initialSelectedOption: Int
+ initialSelectedOption: Int,
+ modifier: Modifier = Modifier,
) {
val options = listOf(
R.drawable.ic_terning_profile_00,
@@ -122,35 +108,36 @@ fun RadioButtonGroup(
LazyVerticalGrid(
columns = GridCells.Fixed(3),
- verticalArrangement = Arrangement.spacedBy(20.dp),
- horizontalArrangement = Arrangement.spacedBy(24.dp),
- modifier = modifier
- .padding(horizontal = 42.dp)
+ verticalArrangement = Arrangement.spacedBy(8.dp),
+ horizontalArrangement = Arrangement.spacedBy(20.dp),
+ modifier = modifier.padding(horizontal = 34.dp)
) {
itemsIndexed(options) { index, option ->
val imageModifier = if (selectedOption == options[index]) {
- modifier
+ Modifier
.border(
color = TerningMain,
width = 2.dp,
shape = CircleShape
)
+ .aspectRatio(1f)
} else {
- modifier
+ Modifier.aspectRatio(1f)
}
Image(
painter = painterResource(
id = option
),
- contentDescription = stringResource(id = R.string.sign_up_bottom_sheet_description),
+ contentDescription = "profile image",
modifier = imageModifier
- .aspectRatio(1f)
.noRippleClickable {
onOptionSelected(index)
selectedOption = option
}
.clip(shape = CircleShape)
+ .size(76.dp)
+ .aspectRatio(1f)
)
}
}
diff --git a/feature/src/main/java/com/terning/feature/onboarding/signup/component/SignUpProfile.kt b/core/src/main/java/com/terning/core/designsystem/component/item/ProfileWithPlusButton.kt
similarity index 57%
rename from feature/src/main/java/com/terning/feature/onboarding/signup/component/SignUpProfile.kt
rename to core/src/main/java/com/terning/core/designsystem/component/item/ProfileWithPlusButton.kt
index 86786ed45..659f27b03 100644
--- a/feature/src/main/java/com/terning/feature/onboarding/signup/component/SignUpProfile.kt
+++ b/core/src/main/java/com/terning/core/designsystem/component/item/ProfileWithPlusButton.kt
@@ -1,29 +1,26 @@
-package com.terning.feature.onboarding.signup.component
+package com.terning.core.designsystem.component.item
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentWidth
-import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable
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.tooling.preview.Preview
import androidx.compose.ui.unit.dp
-import com.terning.core.designsystem.component.image.TerningImage
-import com.terning.feature.R
+import com.terning.core.R
@Composable
-fun SignUpProfile(
+fun ProfileWithPlusButton(
index: Int,
modifier: Modifier = Modifier,
) {
- val profile = when (index) {
+ val grade = when (index) {
0 -> R.drawable.ic_terning_profile_00
1 -> R.drawable.ic_terning_profile_01
2 -> R.drawable.ic_terning_profile_02
@@ -36,24 +33,23 @@ fun SignUpProfile(
modifier = modifier.wrapContentWidth()
) {
Image(
- painterResource(id = profile),
- contentDescription = stringResource(id = R.string.sign_up_profile_image),
+ painterResource(id = grade),
+ contentDescription = "profile image",
modifier = modifier
- .clip(shape = RoundedCornerShape(76.dp))
- .size(80.dp)
- .aspectRatio(1f),
+ .clip(shape = CircleShape)
+ .size(80.dp),
contentScale = ContentScale.Crop
)
- Box(
- modifier = modifier.align(Alignment.BottomEnd)
- ) {
- TerningImage(painter = R.drawable.ic_sign_up_button)
- }
+ Image(
+ painter = painterResource(id = R.drawable.ic_sign_up_button),
+ contentDescription = "plus button",
+ modifier = Modifier.align(Alignment.BottomEnd)
+ )
}
}
@Preview(showBackground = true)
@Composable
-fun SignUpProfilePreview() {
- SignUpProfile(index = 1)
+fun ProfileWithPlusButtonPreview() {
+ ProfileWithPlusButton(index = 1)
}
\ No newline at end of file
diff --git a/core/src/main/java/com/terning/core/designsystem/component/textfield/NameTextField.kt b/core/src/main/java/com/terning/core/designsystem/component/textfield/NameTextField.kt
index 7f92022bf..9620bde6c 100644
--- a/core/src/main/java/com/terning/core/designsystem/component/textfield/NameTextField.kt
+++ b/core/src/main/java/com/terning/core/designsystem/component/textfield/NameTextField.kt
@@ -1,8 +1,6 @@
package com.terning.core.designsystem.component.textfield
-import androidx.annotation.StringRes
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
@@ -10,39 +8,122 @@ import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
+import com.terning.core.R
import com.terning.core.designsystem.theme.Black
import com.terning.core.designsystem.theme.Grey300
import com.terning.core.designsystem.theme.Grey400
+import com.terning.core.designsystem.theme.Grey500
+import com.terning.core.designsystem.theme.TerningMain
import com.terning.core.designsystem.theme.TerningTheme
+import com.terning.core.designsystem.theme.WarningRed
+import com.terning.core.designsystem.theme.White
+import com.terning.core.util.NAME_ERROR_REGEX
+
+data class NameFieldState(
+ val name: String,
+ val lineColor: Color,
+ val helperMessage: Int,
+ val helperIcon: Int?,
+ val helperColor: Color,
+ val isValid: Boolean
+)
@Composable
fun NameTextField(
value: String,
onValueChange: (String) -> Unit,
hint: String,
- drawLineColor: Color,
- @StringRes helperMessage: Int,
- helperColor: Color,
- helperIcon: Int? = null,
+ modifier: Modifier = Modifier,
+ onValidationChanged: (Boolean) -> Unit,
+ initialView: Boolean = false
) {
val focusManager = LocalFocusManager.current
val keyboardController = LocalSoftwareKeyboardController.current
+ val nameErrorRegex = NAME_ERROR_REGEX
+ val trimmedName: String
+ var isNameOutOfBounds = false
+ if (value.length > MAX_LENGTH) {
+ trimmedName = value.substring(0, MAX_LENGTH)
+ isNameOutOfBounds = true
+ } else {
+ trimmedName = value
+ }
+
+ val state = when {
+ initialView -> {
+ NameFieldState(
+ name = trimmedName,
+ lineColor = Grey500,
+ helperMessage = R.string.sign_up_helper,
+ helperIcon = R.drawable.ic_name_text_field_check,
+ helperColor = White,
+ isValid = false
+ )
+ }
+
+ nameErrorRegex.matcher(trimmedName).find() -> {
+ NameFieldState(
+ name = trimmedName,
+ lineColor = WarningRed,
+ helperMessage = R.string.sign_up_helper_error,
+ helperIcon = R.drawable.ic_name_text_field_error,
+ helperColor = WarningRed,
+ isValid = false
+ )
+ }
+
+ trimmedName.isEmpty() || trimmedName.isBlank() -> {
+ NameFieldState(
+ name = trimmedName,
+ lineColor = Grey500,
+ helperMessage = R.string.sign_up_helper,
+ helperIcon = null,
+ helperColor = Grey400,
+ isValid = false
+ )
+ }
+
+ isNameOutOfBounds -> {
+ NameFieldState(
+ name = trimmedName,
+ lineColor = WarningRed,
+ helperMessage = R.string.sign_up_helper_out,
+ helperIcon = R.drawable.ic_name_text_field_error,
+ helperColor = WarningRed,
+ isValid = false
+ )
+ }
+
+ else -> {
+ NameFieldState(
+ name = trimmedName,
+ lineColor = TerningMain,
+ helperMessage = R.string.sign_up_helper_available,
+ helperIcon = R.drawable.ic_name_text_field_check,
+ helperColor = TerningMain,
+ isValid = true
+ )
+ }
+ }
+
+ onValidationChanged(state.isValid)
+
TerningBasicTextField(
- value = value,
+ value = state.name,
onValueChange = onValueChange,
- modifier = Modifier,
+ modifier = modifier,
textStyle = TerningTheme.typography.detail1,
textColor = Black,
- drawLineColor = drawLineColor,
+ drawLineColor = state.lineColor,
cursorBrush = SolidColor(Grey400),
hint = hint,
hintColor = Grey300,
showTextLength = true,
- maxTextLength = 12,
- helperMessage = stringResource(id = helperMessage),
- helperIcon = helperIcon,
- helperColor = helperColor,
+ maxTextLength = MAX_LENGTH,
+ helperMessage = stringResource(id = state.helperMessage),
+ helperIcon = state.helperIcon,
+ helperColor = state.helperColor,
imeAction = ImeAction.Done,
onDoneAction = {
focusManager.clearFocus()
@@ -50,3 +131,5 @@ fun NameTextField(
}
)
}
+
+private const val MAX_LENGTH = 12
diff --git a/core/src/main/java/com/terning/core/designsystem/component/textfield/TerningBasicTextField.kt b/core/src/main/java/com/terning/core/designsystem/component/textfield/TerningBasicTextField.kt
index 67c799550..0e8bd9667 100644
--- a/core/src/main/java/com/terning/core/designsystem/component/textfield/TerningBasicTextField.kt
+++ b/core/src/main/java/com/terning/core/designsystem/component/textfield/TerningBasicTextField.kt
@@ -41,6 +41,7 @@ fun TerningBasicTextField(
hintColor: Color,
drawLineColor: Color,
cursorBrush: Brush,
+ helperColor: Color,
strokeWidth: Float = 1f,
leftIcon: Int? = null,
leftIconColor: Color = TerningMain,
@@ -51,7 +52,6 @@ fun TerningBasicTextField(
helperMessage: String = "",
helperIcon: Int? = null,
enabled: Boolean = true,
- helperColor: Color,
readOnly: Boolean = false,
onDoneAction: () -> Unit? = {},
onSearchAction: () -> Unit? = {},
@@ -139,7 +139,7 @@ fun TerningBasicTextField(
) {
helperIcon?.let {
Icon(
- painter = painterResource(id = it),
+ painter = painterResource(id = helperIcon),
contentDescription = null,
tint = helperColor,
)
diff --git a/core/src/main/java/com/terning/core/designsystem/theme/Color.kt b/core/src/main/java/com/terning/core/designsystem/theme/Color.kt
index 1ea24c8b6..38e375622 100644
--- a/core/src/main/java/com/terning/core/designsystem/theme/Color.kt
+++ b/core/src/main/java/com/terning/core/designsystem/theme/Color.kt
@@ -9,6 +9,7 @@ val Grey150 = Color(0xFFE9E9E9)
val Grey200 = Color(0xFFDDDDDD)
val Grey300 = Color(0xFFBCBCBC)
val Grey350 = Color(0xFFADADAD)
+val Grey375 = Color(0xFF898989)
val Grey400 = Color(0xFF666666)
val Grey500 = Color(0xFF373737)
val Black = Color(0xFF171717)
diff --git a/core/src/main/java/com/terning/core/util/Regex.kt b/core/src/main/java/com/terning/core/util/Regex.kt
new file mode 100644
index 000000000..4fd047690
--- /dev/null
+++ b/core/src/main/java/com/terning/core/util/Regex.kt
@@ -0,0 +1,8 @@
+package com.terning.core.util
+
+import java.util.regex.Pattern
+
+private const val NAME_ERROR_PATTERN =
+ "[!@#\$%^&*(),.?\":{}|<>\\[\\]\\\\/\\-=+~`\\p{S}\\p{P}]"
+val NAME_ERROR_REGEX: Pattern =
+ Pattern.compile(NAME_ERROR_PATTERN)
diff --git a/feature/src/main/res/drawable/ic_check.xml b/core/src/main/res/drawable/ic_name_text_field_check.xml
similarity index 100%
rename from feature/src/main/res/drawable/ic_check.xml
rename to core/src/main/res/drawable/ic_name_text_field_check.xml
diff --git a/feature/src/main/res/drawable/ic_sign_up_error.xml b/core/src/main/res/drawable/ic_name_text_field_error.xml
similarity index 100%
rename from feature/src/main/res/drawable/ic_sign_up_error.xml
rename to core/src/main/res/drawable/ic_name_text_field_error.xml
diff --git a/feature/src/main/res/drawable/ic_sign_up_button.xml b/core/src/main/res/drawable/ic_sign_up_button.xml
similarity index 100%
rename from feature/src/main/res/drawable/ic_sign_up_button.xml
rename to core/src/main/res/drawable/ic_sign_up_button.xml
diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml
index ad3c916f7..2a3dd454b 100644
--- a/core/src/main/res/values/strings.xml
+++ b/core/src/main/res/values/strings.xml
@@ -33,7 +33,6 @@
프로필 이미지 선택
- 회원가입 바텀시트
저장하기
잠깐만요!
정말 로그아웃 하시겠어요?
@@ -62,4 +61,10 @@
TerningBasicImage
+
+ 12자리 이내, 문자/숫자 가능, 특수문자/기호 입력불가
+ 이름에 특수문자는 입력할 수 없어요
+ 사용 가능한 이름이에요
+ 이름은 12자리 이내로 설정해 주세요
+
\ No newline at end of file
diff --git a/data/src/main/java/com/terning/data/dto/response/TokenReissueResponseDto.kt b/data/src/main/java/com/terning/data/dto/response/TokenReissueResponseDto.kt
index 56647b905..91cca0810 100644
--- a/data/src/main/java/com/terning/data/dto/response/TokenReissueResponseDto.kt
+++ b/data/src/main/java/com/terning/data/dto/response/TokenReissueResponseDto.kt
@@ -5,6 +5,6 @@ import kotlinx.serialization.Serializable
@Serializable
data class TokenReissueResponseDto(
- @SerialName("refreshToken")
- val refreshToken: String
+ @SerialName("accessToken")
+ val accessToken: String
)
\ No newline at end of file
diff --git a/data/src/main/java/com/terning/data/mapper/auth/TokenReissueMapper.kt b/data/src/main/java/com/terning/data/mapper/auth/TokenReissueMapper.kt
index 90e2e964f..176698aa6 100644
--- a/data/src/main/java/com/terning/data/mapper/auth/TokenReissueMapper.kt
+++ b/data/src/main/java/com/terning/data/mapper/auth/TokenReissueMapper.kt
@@ -4,4 +4,4 @@ import com.terning.data.dto.response.TokenReissueResponseDto
import com.terning.domain.entity.auth.TokenReissue
fun TokenReissueResponseDto.toTokenReissue(): TokenReissue =
- TokenReissue(refreshToken = refreshToken)
+ TokenReissue(accessToken = accessToken)
diff --git a/domain/src/main/java/com/terning/domain/entity/auth/TokenReissue.kt b/domain/src/main/java/com/terning/domain/entity/auth/TokenReissue.kt
index 9841acf59..933015dfc 100644
--- a/domain/src/main/java/com/terning/domain/entity/auth/TokenReissue.kt
+++ b/domain/src/main/java/com/terning/domain/entity/auth/TokenReissue.kt
@@ -1,5 +1,5 @@
package com.terning.domain.entity.auth
data class TokenReissue (
- val refreshToken : String
+ val accessToken : String
)
\ No newline at end of file
diff --git a/feature/build.gradle.kts b/feature/build.gradle.kts
index 6b56a6904..781cf168f 100644
--- a/feature/build.gradle.kts
+++ b/feature/build.gradle.kts
@@ -100,5 +100,4 @@ dependencies {
// KakaoDependencies
implementation(libs.kakao.user)
-
}
\ No newline at end of file
diff --git a/feature/src/main/java/com/terning/feature/filtering/filtering/FilteringOneScreen.kt b/feature/src/main/java/com/terning/feature/filtering/filtering/FilteringOneScreen.kt
index 3f4a28c8c..17ba94a8c 100644
--- a/feature/src/main/java/com/terning/feature/filtering/filtering/FilteringOneScreen.kt
+++ b/feature/src/main/java/com/terning/feature/filtering/filtering/FilteringOneScreen.kt
@@ -1,6 +1,8 @@
package com.terning.feature.filtering.filtering
+import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
@@ -21,6 +23,7 @@ import com.terning.core.designsystem.component.topappbar.BackButtonTopAppBar
import com.terning.core.designsystem.theme.Grey300
import com.terning.core.designsystem.theme.TerningPointTheme
import com.terning.core.designsystem.theme.TerningTheme
+import com.terning.core.designsystem.theme.White
import com.terning.feature.R
import com.terning.feature.filtering.filtering.component.StatusOneRadioGroup
@@ -30,6 +33,7 @@ fun FilteringOneScreen(
onNextClick: (Int) -> Unit,
navigateUp: () -> Unit,
modifier: Modifier = Modifier,
+ paddingValues: PaddingValues = PaddingValues(),
onButtonClick: (Int) -> Unit = {},
) {
val isButtonValid = remember { mutableStateOf(false) }
@@ -38,6 +42,8 @@ fun FilteringOneScreen(
Column(
modifier = modifier
+ .padding(paddingValues)
+ .background(White)
) {
BackButtonTopAppBar(
onBackButtonClick = { navigateUp() }
diff --git a/feature/src/main/java/com/terning/feature/filtering/filtering/FilteringThreeRoute.kt b/feature/src/main/java/com/terning/feature/filtering/filtering/FilteringThreeRoute.kt
index b51640a80..3eb6a89db 100644
--- a/feature/src/main/java/com/terning/feature/filtering/filtering/FilteringThreeRoute.kt
+++ b/feature/src/main/java/com/terning/feature/filtering/filtering/FilteringThreeRoute.kt
@@ -1,6 +1,8 @@
package com.terning.feature.filtering.filtering
+import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
@@ -26,6 +28,7 @@ import com.terning.core.designsystem.component.topappbar.BackButtonTopAppBar
import com.terning.core.designsystem.theme.Grey300
import com.terning.core.designsystem.theme.TerningPointTheme
import com.terning.core.designsystem.theme.TerningTheme
+import com.terning.core.designsystem.theme.White
import com.terning.core.extension.toast
import com.terning.feature.R
import java.util.Calendar
@@ -37,6 +40,7 @@ fun FilteringThreeRoute(
navigateUp: () -> Unit,
navigateToStartHome: () -> Unit,
viewModel: FilteringViewModel = hiltViewModel(),
+ paddingValues: PaddingValues
) {
val context = LocalContext.current
val lifecycleOwner = LocalLifecycleOwner.current
@@ -68,6 +72,7 @@ fun FilteringThreeRoute(
}
FilteringThreeScreen(
+ paddingValues = paddingValues,
navigateUp = { navigateUp() },
chosenYear = chosenYear,
chosenMonth = chosenMonth,
@@ -80,6 +85,7 @@ fun FilteringThreeRoute(
@Composable
fun FilteringThreeScreen(
modifier: Modifier = Modifier,
+ paddingValues: PaddingValues = PaddingValues(),
navigateUp: () -> Unit,
chosenYear: Int,
chosenMonth: Int,
@@ -88,7 +94,9 @@ fun FilteringThreeScreen(
onNextClick: () -> Unit,
) {
Column(
- modifier = modifier,
+ modifier = modifier
+ .padding(paddingValues)
+ .background(White),
) {
BackButtonTopAppBar(
onBackButtonClick = { navigateUp() }
diff --git a/feature/src/main/java/com/terning/feature/filtering/filtering/FilteringTwoScreen.kt b/feature/src/main/java/com/terning/feature/filtering/filtering/FilteringTwoScreen.kt
index e66df12e8..c35eec330 100644
--- a/feature/src/main/java/com/terning/feature/filtering/filtering/FilteringTwoScreen.kt
+++ b/feature/src/main/java/com/terning/feature/filtering/filtering/FilteringTwoScreen.kt
@@ -1,6 +1,8 @@
package com.terning.feature.filtering.filtering
+import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
@@ -21,6 +23,7 @@ import com.terning.core.designsystem.component.topappbar.BackButtonTopAppBar
import com.terning.core.designsystem.theme.Grey300
import com.terning.core.designsystem.theme.TerningPointTheme
import com.terning.core.designsystem.theme.TerningTheme
+import com.terning.core.designsystem.theme.White
import com.terning.feature.R
import com.terning.feature.filtering.filtering.component.StatusTwoRadioGroup
@@ -30,6 +33,7 @@ fun FilteringTwoScreen(
onNextClick: (Int, Int) -> Unit,
navigateUp: () -> Unit,
modifier: Modifier = Modifier,
+ paddingValues: PaddingValues = PaddingValues(),
onButtonClick: (Int) -> Unit = {},
) {
val isButtonValid = remember { mutableStateOf(false) }
@@ -38,6 +42,8 @@ fun FilteringTwoScreen(
Column(
modifier = modifier
+ .padding(paddingValues)
+ .background(White)
) {
BackButtonTopAppBar(
onBackButtonClick = { navigateUp() }
diff --git a/feature/src/main/java/com/terning/feature/filtering/filtering/navigation/FilteringOneNavigation.kt b/feature/src/main/java/com/terning/feature/filtering/filtering/navigation/FilteringOneNavigation.kt
index 266137688..3ac282c44 100644
--- a/feature/src/main/java/com/terning/feature/filtering/filtering/navigation/FilteringOneNavigation.kt
+++ b/feature/src/main/java/com/terning/feature/filtering/filtering/navigation/FilteringOneNavigation.kt
@@ -1,5 +1,6 @@
package com.terning.feature.filtering.filtering.navigation
+import androidx.compose.foundation.layout.PaddingValues
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
@@ -21,11 +22,13 @@ fun NavController.navigateFilteringOne(
}
fun NavGraphBuilder.filteringOneNavGraph(
+ paddingValues: PaddingValues,
navHostController: NavHostController
) {
composable {
val args = it.toRoute()
FilteringOneScreen(
+ paddingValues = paddingValues,
name = args.name,
onNextClick = { grade -> navHostController.navigateFilteringTwo(grade) },
navigateUp = { navHostController.navigateUp() }
diff --git a/feature/src/main/java/com/terning/feature/filtering/filtering/navigation/FilteringThreeNavigation.kt b/feature/src/main/java/com/terning/feature/filtering/filtering/navigation/FilteringThreeNavigation.kt
index 759c65c4d..97f95beae 100644
--- a/feature/src/main/java/com/terning/feature/filtering/filtering/navigation/FilteringThreeNavigation.kt
+++ b/feature/src/main/java/com/terning/feature/filtering/filtering/navigation/FilteringThreeNavigation.kt
@@ -1,5 +1,6 @@
package com.terning.feature.filtering.filtering.navigation
+import androidx.compose.foundation.layout.PaddingValues
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
@@ -23,11 +24,13 @@ fun NavController.navigateFilteringThree(
}
fun NavGraphBuilder.filteringThreeNavGraph(
+ paddingValues: PaddingValues,
navHostController: NavHostController
) {
composable {
val args = it.toRoute()
FilteringThreeRoute(
+ paddingValues = paddingValues,
grade = args.grade,
workingPeriod = args.workingPeriod,
navigateUp = { navHostController.navigateUp() },
diff --git a/feature/src/main/java/com/terning/feature/filtering/filtering/navigation/FilteringTwoNavigation.kt b/feature/src/main/java/com/terning/feature/filtering/filtering/navigation/FilteringTwoNavigation.kt
index 0bde2ac5e..ff9f1286d 100644
--- a/feature/src/main/java/com/terning/feature/filtering/filtering/navigation/FilteringTwoNavigation.kt
+++ b/feature/src/main/java/com/terning/feature/filtering/filtering/navigation/FilteringTwoNavigation.kt
@@ -1,5 +1,6 @@
package com.terning.feature.filtering.filtering.navigation
+import androidx.compose.foundation.layout.PaddingValues
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
@@ -21,11 +22,13 @@ fun NavController.navigateFilteringTwo(
}
fun NavGraphBuilder.filteringTwoNavGraph(
+ paddingValues: PaddingValues,
navHostController: NavHostController
) {
composable {
val args = it.toRoute()
FilteringTwoScreen(
+ paddingValues = paddingValues,
grade = args.grade,
onNextClick = { _, workingPeriod ->
navHostController.navigateFilteringThree(
diff --git a/feature/src/main/java/com/terning/feature/filtering/startfiltering/StartFilteringScreen.kt b/feature/src/main/java/com/terning/feature/filtering/startfiltering/StartFilteringScreen.kt
index e8e1128b2..2429947ce 100644
--- a/feature/src/main/java/com/terning/feature/filtering/startfiltering/StartFilteringScreen.kt
+++ b/feature/src/main/java/com/terning/feature/filtering/startfiltering/StartFilteringScreen.kt
@@ -2,8 +2,10 @@ package com.terning.feature.filtering.startfiltering
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
+import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
@@ -27,12 +29,14 @@ import com.terning.core.designsystem.component.button.RectangleButton
import com.terning.core.designsystem.component.image.TerningImage
import com.terning.core.designsystem.theme.TerningPointTheme
import com.terning.core.designsystem.theme.TerningTheme
+import com.terning.core.designsystem.theme.White
import com.terning.feature.R
import kotlinx.coroutines.delay
@Composable
fun StartFilteringScreen(
modifier: Modifier = Modifier,
+ paddingValues: PaddingValues = PaddingValues(),
onNextClick: () -> Unit
) {
var isVisible by remember { mutableStateOf(false) }
@@ -46,7 +50,10 @@ fun StartFilteringScreen(
}
Box(
- modifier = modifier.fillMaxSize()
+ modifier = modifier
+ .fillMaxSize()
+ .padding(paddingValues)
+ .background(White)
) {
Column(
modifier = Modifier.fillMaxSize(),
diff --git a/feature/src/main/java/com/terning/feature/filtering/startfiltering/navigation/StartFilteringNavigation.kt b/feature/src/main/java/com/terning/feature/filtering/startfiltering/navigation/StartFilteringNavigation.kt
index e70d98afa..17280736b 100644
--- a/feature/src/main/java/com/terning/feature/filtering/startfiltering/navigation/StartFilteringNavigation.kt
+++ b/feature/src/main/java/com/terning/feature/filtering/startfiltering/navigation/StartFilteringNavigation.kt
@@ -1,5 +1,6 @@
package com.terning.feature.filtering.startfiltering.navigation
+import androidx.compose.foundation.layout.PaddingValues
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
@@ -22,11 +23,13 @@ fun NavController.navigateStartFiltering(
}
fun NavGraphBuilder.startFilteringNavGraph(
+ paddingValues: PaddingValues,
navHostController: NavHostController
) {
composable {
val args = it.toRoute()
StartFilteringScreen(
+ paddingValues = paddingValues,
onNextClick = {
navHostController.navigateFilteringOne(args.name)
}
diff --git a/feature/src/main/java/com/terning/feature/filtering/starthome/StartHomeScreen.kt b/feature/src/main/java/com/terning/feature/filtering/starthome/StartHomeScreen.kt
index 63b92593f..29cdba837 100644
--- a/feature/src/main/java/com/terning/feature/filtering/starthome/StartHomeScreen.kt
+++ b/feature/src/main/java/com/terning/feature/filtering/starthome/StartHomeScreen.kt
@@ -2,8 +2,10 @@ package com.terning.feature.filtering.starthome
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.fadeIn
+import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxSize
@@ -24,9 +26,6 @@ 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.navigation.NavController
-import androidx.navigation.NavOptions
-import androidx.navigation.compose.rememberNavController
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieCompositionSpec
import com.airbnb.lottie.compose.LottieConstants
@@ -34,16 +33,14 @@ import com.airbnb.lottie.compose.rememberLottieComposition
import com.terning.core.designsystem.component.button.RectangleButton
import com.terning.core.designsystem.theme.TerningPointTheme
import com.terning.core.designsystem.theme.TerningTheme
+import com.terning.core.designsystem.theme.White
import com.terning.feature.R
-import com.terning.feature.home.home.navigation.navigateHome
-import com.terning.feature.main.MainNavigator
-import com.terning.feature.main.rememberMainNavigator
-import com.terning.feature.onboarding.signin.navigation.SignIn
import kotlinx.coroutines.delay
@Composable
fun StartHomeScreen(
modifier: Modifier = Modifier,
+ paddingValues: PaddingValues = PaddingValues(),
navigateToHome: () -> Unit
) {
var isVisible by remember { mutableStateOf(false) }
@@ -57,7 +54,10 @@ fun StartHomeScreen(
}
Box(
- modifier = modifier.fillMaxSize()
+ modifier = modifier
+ .fillMaxSize()
+ .padding(paddingValues)
+ .background(White)
) {
Column(
modifier = Modifier.fillMaxSize(),
@@ -95,7 +95,7 @@ fun StartHomeScreen(
}
}
-private const val DELAY : Long = 1000
+private const val DELAY: Long = 1000
@Composable
fun StartHomeLottieAnimation(
diff --git a/feature/src/main/java/com/terning/feature/filtering/starthome/navigation/StartHomeNavigation.kt b/feature/src/main/java/com/terning/feature/filtering/starthome/navigation/StartHomeNavigation.kt
index ed29bcf97..9f493d51a 100644
--- a/feature/src/main/java/com/terning/feature/filtering/starthome/navigation/StartHomeNavigation.kt
+++ b/feature/src/main/java/com/terning/feature/filtering/starthome/navigation/StartHomeNavigation.kt
@@ -1,7 +1,6 @@
package com.terning.feature.filtering.starthome.navigation
-import androidx.compose.animation.EnterTransition
-import androidx.compose.animation.ExitTransition
+import androidx.compose.foundation.layout.PaddingValues
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
@@ -21,30 +20,20 @@ fun NavController.navigateStartHome(navOptions: NavOptions? = null) {
}
fun NavGraphBuilder.startHomeNavGraph(
+ paddingValues: PaddingValues,
navHostController: NavHostController
) {
- composable(
- exitTransition = {
- ExitTransition.None
- },
- popEnterTransition = {
- EnterTransition.None
- },
- enterTransition = {
- EnterTransition.None
- },
- popExitTransition = {
- ExitTransition.None
- }
- ) {
- StartHomeScreen(navigateToHome = {
- navHostController.navigateHome(
- navOptions = NavOptions.Builder().setPopUpTo(
- route = SignIn,
- inclusive = true
- ).build()
- )
- }
+ composable {
+ StartHomeScreen(
+ paddingValues = paddingValues,
+ navigateToHome = {
+ navHostController.navigateHome(
+ navOptions = NavOptions.Builder().setPopUpTo(
+ route = SignIn,
+ inclusive = true
+ ).build()
+ )
+ }
)
}
}
diff --git a/feature/src/main/java/com/terning/feature/home/changefilter/ChangeFilterRoute.kt b/feature/src/main/java/com/terning/feature/home/changefilter/ChangeFilterRoute.kt
index ec13a8e4e..dfc3a938a 100644
--- a/feature/src/main/java/com/terning/feature/home/changefilter/ChangeFilterRoute.kt
+++ b/feature/src/main/java/com/terning/feature/home/changefilter/ChangeFilterRoute.kt
@@ -2,7 +2,9 @@ package com.terning.feature.home.changefilter
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
@@ -100,7 +102,10 @@ fun ChangeFilterScreen(
modifier = Modifier
.shadow(elevation = 2.dp)
)
- }
+ },
+ modifier = Modifier
+ .statusBarsPadding()
+ .navigationBarsPadding()
) { paddingValues ->
Column(
modifier = Modifier
diff --git a/feature/src/main/java/com/terning/feature/home/home/HomeRoute.kt b/feature/src/main/java/com/terning/feature/home/home/HomeRoute.kt
index cc92f3bdf..2e9793e17 100644
--- a/feature/src/main/java/com/terning/feature/home/home/HomeRoute.kt
+++ b/feature/src/main/java/com/terning/feature/home/home/HomeRoute.kt
@@ -75,6 +75,7 @@ const val NAME_END_LENGTH = 12
@Composable
fun HomeRoute(
+ paddingValues: PaddingValues,
navController: NavHostController,
viewModel: HomeViewModel = hiltViewModel(),
) {
@@ -109,6 +110,7 @@ fun HomeRoute(
}
HomeScreen(
+ paddingValues = paddingValues,
homeDialogState = homeDialogState,
onChangeFilterClick = { navController.navigateChangeFilter() },
navigateToIntern = { navController.navigateIntern(announcementId = it) },
@@ -119,6 +121,7 @@ fun HomeRoute(
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun HomeScreen(
+ paddingValues: PaddingValues,
homeDialogState: HomeDialogState,
onChangeFilterClick: () -> Unit,
navigateToIntern: (Long) -> Unit,
@@ -162,6 +165,9 @@ fun HomeScreen(
Column(
horizontalAlignment = Alignment.Start,
+ modifier = Modifier
+ .background(White)
+ .padding(paddingValues)
) {
TerningImage(
painter = R.drawable.ic_terning_logo_typo,
diff --git a/feature/src/main/java/com/terning/feature/home/home/navigation/HometNavigation.kt b/feature/src/main/java/com/terning/feature/home/home/navigation/HometNavigation.kt
index 6343c1df4..307d4ed93 100644
--- a/feature/src/main/java/com/terning/feature/home/home/navigation/HometNavigation.kt
+++ b/feature/src/main/java/com/terning/feature/home/home/navigation/HometNavigation.kt
@@ -5,6 +5,7 @@ import androidx.compose.animation.ExitTransition
import androidx.compose.animation.core.LinearOutSlowInEasing
import androidx.compose.animation.core.tween
import androidx.compose.animation.slideIn
+import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.ui.unit.IntOffset
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
@@ -22,7 +23,9 @@ fun NavController.navigateHome(navOptions: NavOptions? = null) {
)
}
-fun NavGraphBuilder.homeNavGraph(navHostController: NavHostController) {
+fun NavGraphBuilder.homeNavGraph(
+ paddingValues : PaddingValues,
+ navHostController: NavHostController) {
composable(
exitTransition = {
ExitTransition.None
@@ -37,7 +40,9 @@ fun NavGraphBuilder.homeNavGraph(navHostController: NavHostController) {
ExitTransition.None
}
) {
- HomeRoute(navController = navHostController)
+ HomeRoute(
+ paddingValues= paddingValues,
+ navController = navHostController)
}
}
diff --git a/feature/src/main/java/com/terning/feature/intern/InternRoute.kt b/feature/src/main/java/com/terning/feature/intern/InternRoute.kt
index 2249e3e68..bcab1d50e 100644
--- a/feature/src/main/java/com/terning/feature/intern/InternRoute.kt
+++ b/feature/src/main/java/com/terning/feature/intern/InternRoute.kt
@@ -2,24 +2,18 @@ package com.terning.feature.intern
import android.view.ViewGroup
import android.webkit.WebView
-import androidx.compose.foundation.border
-import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.shape.RoundedCornerShape
-import androidx.compose.material3.Icon
+import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material3.Scaffold
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.platform.LocalContext
-import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
@@ -30,10 +24,8 @@ import androidx.lifecycle.flowWithLifecycle
import androidx.navigation.NavHostController
import com.terning.core.designsystem.component.dialog.TerningBasicDialog
import com.terning.core.designsystem.component.topappbar.BackButtonTopAppBar
-import com.terning.core.designsystem.theme.Black
import com.terning.core.designsystem.theme.Grey200
import com.terning.core.designsystem.theme.Grey400
-import com.terning.core.designsystem.theme.TerningMain
import com.terning.core.designsystem.theme.TerningTheme
import com.terning.core.extension.customShadow
import com.terning.core.extension.toast
@@ -41,24 +33,24 @@ import com.terning.core.state.UiState
import com.terning.domain.entity.response.InternInfoModel
import com.terning.feature.R
import com.terning.feature.intern.component.InternBottomBar
-import com.terning.feature.intern.component.InternCancelDialog
import com.terning.feature.intern.component.InternCompanyInfo
import com.terning.feature.intern.component.InternInfoRow
import com.terning.feature.intern.component.InternPageTitle
-import com.terning.feature.intern.component.ScrapDialogContent
+import com.terning.feature.intern.component.InternTitle
+import com.terning.feature.intern.model.InternUiState
import java.text.DecimalFormat
@Composable
fun InternRoute(
- navController: NavHostController,
announcementId: Long = 0,
viewModel: InternViewModel = hiltViewModel(),
+ navController: NavHostController,
) {
+ val internState by viewModel.internUiState.collectAsStateWithLifecycle()
+
val context = LocalContext.current
val lifecycleOwner = LocalLifecycleOwner.current
- val state by viewModel.internState.collectAsStateWithLifecycle(lifecycleOwner = lifecycleOwner)
-
LaunchedEffect(key1 = true) {
viewModel.getInternInfo(announcementId)
}
@@ -72,15 +64,15 @@ fun InternRoute(
}
}
- when (state.internInfo) {
- is UiState.Loading -> {}
- is UiState.Empty -> {}
+ when (internState.loadState) {
+ UiState.Loading -> {}
+ UiState.Empty -> {}
is UiState.Failure -> {}
is UiState.Success -> {
InternScreen(
- navController = navController,
- internInfoModel = (state.internInfo as UiState.Success).data,
- announcementId = announcementId
+ internUiState = internState,
+ internInfoModel = (internState.loadState as UiState.Success).data,
+ navController = navController
)
}
}
@@ -91,10 +83,9 @@ fun InternScreen(
modifier: Modifier = Modifier,
navController: NavHostController,
viewModel: InternViewModel = hiltViewModel(),
+ internUiState: InternUiState,
internInfoModel: InternInfoModel,
- announcementId: Long,
) {
- val internState by viewModel.internState.collectAsStateWithLifecycle()
val decimal = DecimalFormat("#,###")
val internInfoList = listOf(
@@ -103,10 +94,12 @@ fun InternScreen(
stringResource(id = R.string.intern_info_start_date) to internInfoModel.startDate,
)
- val qualificationList = internInfoModel.qualification.split(",").map { it.trim() }
- val jobTypeList = internInfoModel.jobType.split(",").map { it.trim() }
+ val qualificationList = listOf(
+ stringResource(id = R.string.intern_recruitment_target) to internInfoModel.qualification,
+ stringResource(id = R.string.intern_info_work) to internInfoModel.jobType,
+ )
- if (internState.showWeb) {
+ if (internUiState.showWeb) {
AndroidView(
factory = {
WebView(it).apply {
@@ -130,7 +123,7 @@ fun InternScreen(
offsetY = 2.dp
),
onBackButtonClick = {
- navController.navigateUp()
+ navController.popBackStack()
},
)
},
@@ -157,244 +150,94 @@ fun InternScreen(
end = 24.dp
)
) {
- Row(
- modifier = modifier
- .border(
- width = 1.dp,
- color = TerningMain,
- shape = RoundedCornerShape(size = 12.dp)
- ),
- horizontalArrangement = Arrangement.spacedBy(
- 0.dp,
- Alignment.CenterHorizontally
- ),
- verticalAlignment = Alignment.CenterVertically
- ) {
- Text(
- text = internInfoModel.dDay,
- style = TerningTheme.typography.title5,
- color = TerningMain,
- modifier = Modifier.padding(
- horizontal = 12.dp,
- vertical = 2.dp
- )
- )
- }
+ Spacer(modifier = modifier.padding(top = 16.dp))
- Text(
- text = internInfoModel.title,
- style = TerningTheme.typography.title2,
- color = Black,
- modifier = modifier.padding(
- top = 4.dp,
- bottom = 16.dp
- )
- )
-
- Column(
- modifier = modifier
- .border(
- width = 1.dp,
- color = TerningMain,
- shape = RoundedCornerShape(size = 5.dp)
- )
- .fillMaxWidth()
- .padding(start = 16.dp, top = 16.dp, bottom = 16.dp),
- verticalArrangement = Arrangement.spacedBy(
- 6.dp,
- Alignment.CenterVertically
- ),
- horizontalAlignment = Alignment.Start,
- ) {
- internInfoList.forEach { (title, value) ->
- InternInfoRow(title, value)
- }
- }
- Row(
- horizontalArrangement = Arrangement.spacedBy(3.dp, Alignment.End),
- verticalAlignment = Alignment.CenterVertically,
- modifier = modifier
- .fillMaxWidth()
- .padding(
- top = 9.dp,
- )
- ) {
- Text(
- text = stringResource(id = R.string.intern_view_count),
- style = TerningTheme.typography.detail3,
- color = Grey400
- )
- Text(
- text = "${decimal.format(internInfoModel.viewCount)}회",
- style = TerningTheme.typography.button4,
- color = Grey400,
- )
- }
- }
-
- Column(
- verticalArrangement = Arrangement.Top,
- ) {
- InternPageTitle(
- modifier = modifier,
- text = stringResource(id = R.string.intern_sub_title_intern_info)
- )
InternCompanyInfo(
modifier = modifier,
companyImage = internInfoModel.companyImage,
company = internInfoModel.company,
companyCategory = internInfoModel.companyCategory
)
+
+ Spacer(modifier = modifier.padding(top = 20.dp))
+
+ InternTitle(
+ modifier = modifier,
+ dDay = internInfoModel.dDay,
+ title = internInfoModel.title,
+ viewCount = decimal.format(internInfoModel.viewCount)
+ )
+
+ Spacer(modifier = modifier.padding(top = 16.dp))
+
InternPageTitle(
modifier = modifier,
text = stringResource(id = R.string.intern_sub_title_intern_summary)
)
+
Column(
- modifier = modifier
- .padding(
- start = 24.dp,
- bottom = 16.dp,
- end = 24.dp
- )
- .fillMaxWidth(),
- verticalArrangement = Arrangement.Top,
- horizontalAlignment = Alignment.Start,
+ modifier = modifier.padding(
+ top = 4.dp,
+ bottom = 4.dp,
+ start = 10.dp
+ )
) {
- Row(
- modifier = modifier.fillMaxWidth(),
- horizontalArrangement = Arrangement.spacedBy(
- 3.dp,
- Alignment.Start
- ),
- verticalAlignment = Alignment.Top
- ) {
- Row(
- modifier = modifier
- .weight(2f),
- verticalAlignment = Alignment.Top,
- ) {
- Icon(
- painter = painterResource(id = R.drawable.ic_first_info_20),
- contentDescription = null
- )
- Text(
- text = stringResource(id = R.string.intern_info_request),
- style = TerningTheme.typography.button2,
- color = Black
- )
- }
-
- Column(
- modifier = modifier
- .weight(5f)
- .padding(start = 8.dp),
- verticalArrangement = Arrangement.spacedBy(4.dp, Alignment.Top),
- ) {
- qualificationList.forEach { qualification ->
- Text(
- text = qualification,
- style = TerningTheme.typography.body4,
- color = Grey400,
- )
- }
- }
+ internInfoList.forEach { (title, value) ->
+ InternInfoRow(title, value)
}
}
+
+ Spacer(modifier = modifier.padding(top = 16.dp))
+
+ InternPageTitle(
+ modifier = modifier,
+ text = stringResource(id = R.string.intern_info_request)
+ )
+
Column(
- modifier = modifier
- .padding(horizontal = 24.dp)
- .fillMaxWidth(),
- verticalArrangement = Arrangement.Top,
- horizontalAlignment = Alignment.Start,
+ modifier = modifier.padding(
+ top = 4.dp,
+ bottom = 4.dp,
+ start = 10.dp
+ )
) {
- Row(
- modifier = modifier.fillMaxWidth(),
- horizontalArrangement = Arrangement.spacedBy(
- 3.dp,
- Alignment.Start
- ),
- verticalAlignment = Alignment.Top
- ) {
- Row(
- modifier = modifier
- .weight(2f),
- verticalAlignment = Alignment.CenterVertically,
- horizontalArrangement = Arrangement.Start
- ) {
- Icon(
- painter = painterResource(id = R.drawable.ic_second_info_20),
- contentDescription = null,
- )
- Text(
- text = stringResource(id = R.string.intern_info_work),
- style = TerningTheme.typography.button2,
- color = Black
- )
- }
-
- Column(
- modifier = modifier
- .weight(5f)
- .padding(start = 8.dp),
- verticalArrangement = Arrangement.spacedBy(4.dp, Alignment.Top),
- ) {
- jobTypeList.forEach { jobType ->
- Text(
- text = jobType,
- style = TerningTheme.typography.body4,
- color = Grey400,
- )
- }
- }
+ qualificationList.forEach { (title, value) ->
+ InternInfoRow(title, value)
}
}
+
+ Spacer(modifier = modifier.padding(top = 16.dp))
+
InternPageTitle(
modifier = modifier,
text = stringResource(id = R.string.intern_sub_title_intern_detail)
)
+
Column(
modifier = modifier.padding(
- start = 24.dp,
- end = 24.dp,
+ start = 10.dp,
+ top = 5.dp,
bottom = 20.dp
)
) {
- Text(
- text = internInfoModel.detail.trimIndent(),
- style = TerningTheme.typography.detail1,
- color = Grey400
- )
+ SelectionContainer {
+ Text(
+ text = internInfoModel.detail.trimIndent(),
+ style = TerningTheme.typography.body3,
+ color = Grey400
+ )
+ }
}
}
}
}
- if (internState.isScrapDialogVisible) {
+
+ if (internUiState.isScrapDialogVisible) {
TerningBasicDialog(
onDismissRequest = {
viewModel.updateScrapDialogVisible(false)
},
- content = {
- when (internInfoModel.scrapId != null) {
- true -> InternCancelDialog(
- onDismissRequest = { viewModel.updateScrapDialogVisible(false) },
- onClickScrapCancel = {
- viewModel.deleteScrap(
- internInfoModel.scrapId,
- announcementId
- )
- }
- )
-
- else -> ScrapDialogContent(
- internInfoList = internInfoList,
- dDay = internInfoModel.dDay,
- title = internInfoModel.title,
- companyImage = internInfoModel.companyImage,
- announcementId = announcementId,
- type = 0
- )
- }
- },
+ content = {},
)
}
}
diff --git a/feature/src/main/java/com/terning/feature/intern/InternViewModel.kt b/feature/src/main/java/com/terning/feature/intern/InternViewModel.kt
index 13e71a697..7322223a9 100644
--- a/feature/src/main/java/com/terning/feature/intern/InternViewModel.kt
+++ b/feature/src/main/java/com/terning/feature/intern/InternViewModel.kt
@@ -9,11 +9,10 @@ import com.terning.domain.repository.InternRepository
import com.terning.domain.repository.ScrapRepository
import com.terning.feature.R
import com.terning.feature.intern.model.InternScrapState
-import com.terning.feature.intern.model.InternViewState
+import com.terning.feature.intern.model.InternUiState
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
@@ -25,9 +24,8 @@ class InternViewModel @Inject constructor(
private val internRepository: InternRepository,
private val scrapRepository: ScrapRepository,
) : ViewModel() {
- private val _internState: MutableStateFlow =
- MutableStateFlow(InternViewState())
- val internState: StateFlow = _internState.asStateFlow()
+ private val _internUiState = MutableStateFlow(InternUiState())
+ val internUiState get() = _internUiState.asStateFlow()
private val _scrapState: MutableStateFlow =
MutableStateFlow(InternScrapState())
@@ -37,20 +35,19 @@ class InternViewModel @Inject constructor(
fun getInternInfo(id: Long) {
viewModelScope.launch {
- internRepository.getInternInfo(
- id
- ).onSuccess { internInfo ->
- _internState.update {
- it.copy(internInfo = UiState.Success(internInfo))
+ internRepository.getInternInfo(id)
+ .onSuccess { internInfoModel ->
+ _internUiState.update { currentState ->
+ currentState.copy(loadState = UiState.Success(internInfoModel))
+ }
+ }
+ .onFailure {
+ _sideEffect.emit(InternViewSideEffect.Toast(R.string.server_failure))
}
- }.onFailure {
- _sideEffect.emit(
- InternViewSideEffect.Toast(R.string.server_failure)
- )
- }
}
}
+
fun postScrap(
id: Long,
color: Int,
@@ -100,31 +97,31 @@ class InternViewModel @Inject constructor(
}
fun updateSelectColor(newColor: Color) {
- _internState.update {
+ _internUiState.update {
it.copy(selectedColor = newColor)
}
}
fun updateScrapDialogVisible(visible: Boolean) {
- _internState.update {
+ _internUiState.update {
it.copy(isScrapDialogVisible = visible)
}
}
fun updatePaletteOpen(open: Boolean) {
- _internState.update {
+ _internUiState.update {
it.copy(isPaletteOpen = open)
}
}
fun updateColorChange(change: Boolean) {
- _internState.update {
+ _internUiState.update {
it.copy(isColorChange = change)
}
}
fun updateShowWeb(show: Boolean) {
- _internState.update {
+ _internUiState.update {
it.copy(showWeb = show)
}
}
diff --git a/feature/src/main/java/com/terning/feature/intern/component/InternCompanyInfo.kt b/feature/src/main/java/com/terning/feature/intern/component/InternCompanyInfo.kt
index afee51466..39d31b248 100644
--- a/feature/src/main/java/com/terning/feature/intern/component/InternCompanyInfo.kt
+++ b/feature/src/main/java/com/terning/feature/intern/component/InternCompanyInfo.kt
@@ -22,8 +22,8 @@ import androidx.compose.ui.unit.dp
import coil.compose.AsyncImage
import coil.request.ImageRequest
import com.terning.core.designsystem.theme.Black
-import com.terning.core.designsystem.theme.Grey300
-import com.terning.core.designsystem.theme.TerningMain
+import com.terning.core.designsystem.theme.Grey150
+import com.terning.core.designsystem.theme.Grey350
import com.terning.core.designsystem.theme.TerningTheme
import com.terning.feature.R
@@ -36,70 +36,55 @@ fun InternCompanyInfo(
company: String,
companyCategory: String,
) {
- Row(
- modifier = modifier.padding(
- start = 20.dp,
- )
+ Column(
+ modifier = Modifier
+ .fillMaxWidth(),
+ verticalArrangement = Arrangement.Top,
+ horizontalAlignment = Alignment.CenterHorizontally,
) {
Row(
verticalAlignment = Alignment.CenterVertically,
- ) {
- Column(
- verticalArrangement = Arrangement.spacedBy(
- 2.dp,
- Alignment.CenterVertically
- ),
- horizontalAlignment = Alignment.Start,
- ) {
- Row(
- verticalAlignment = Alignment.CenterVertically,
- modifier = Modifier
- .size(60.dp)
- .border(
- width = 1.dp,
- color = TerningMain,
- shape = RoundedCornerShape(size = 30.dp)
- )
- ) {
- AsyncImage(
- model = ImageRequest.Builder(LocalContext.current)
- .data(companyImage)
- .crossfade(true)
- .build(),
- contentDescription = stringResource(id = R.string.search_image),
- contentScale = ContentScale.Fit,
- modifier = modifier
- .fillMaxWidth()
- .clip(CircleShape),
- )
- }
- }
- Column(
- verticalArrangement = Arrangement.spacedBy(
- 3.dp,
- Alignment.Bottom
- ),
- horizontalAlignment = Alignment.Start,
- modifier = modifier
- .padding(
- horizontal = 12.dp
- )
- ) {
- Text(
- text = company,
- style = TerningTheme.typography.title4,
- color = Black,
- modifier = modifier.padding(top = 11.dp),
- maxLines = MAX_LINES,
- overflow = TextOverflow.Ellipsis
- )
- Text(
- text = companyCategory,
- style = TerningTheme.typography.body4,
- color = Grey300,
- modifier = modifier.padding(bottom = 6.dp)
+ modifier = Modifier
+ .size(128.dp)
+ .border(
+ width = 1.dp,
+ color = Grey150,
+ shape = RoundedCornerShape(size = 20.dp)
)
- }
+ ) {
+ AsyncImage(
+ model = ImageRequest.Builder(LocalContext.current)
+ .crossfade(true)
+ .data(companyImage)
+ .build(),
+ contentDescription = stringResource(id = R.string.search_image),
+ contentScale = ContentScale.Fit,
+ modifier = Modifier
+ .fillMaxWidth()
+ .clip(CircleShape),
+ )
+ }
+ Column(
+ verticalArrangement = Arrangement.spacedBy(
+ 4.dp,
+ Alignment.Bottom
+ ),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ ) {
+ Text(
+ text = company,
+ style = TerningTheme.typography.title4,
+ color = Black,
+ modifier = modifier.padding(top = 20.dp),
+ maxLines = MAX_LINES,
+ overflow = TextOverflow.Ellipsis
+ )
+ Text(
+ text = companyCategory,
+ style = TerningTheme.typography.body4,
+ color = Grey350,
+ modifier = modifier.padding(bottom = 8.dp)
+ )
}
}
}
\ No newline at end of file
diff --git a/feature/src/main/java/com/terning/feature/intern/component/InternInfoRow.kt b/feature/src/main/java/com/terning/feature/intern/component/InternInfoRow.kt
index 073e4ae7b..756b4c097 100644
--- a/feature/src/main/java/com/terning/feature/intern/component/InternInfoRow.kt
+++ b/feature/src/main/java/com/terning/feature/intern/component/InternInfoRow.kt
@@ -13,13 +13,13 @@ import com.terning.core.designsystem.theme.TerningTheme
@Composable
fun InternInfoRow(title: String, value: String) {
Row(
- horizontalArrangement = Arrangement.spacedBy(12.dp, Alignment.Start),
+ horizontalArrangement = Arrangement.spacedBy(23.dp, Alignment.Start),
verticalAlignment = Alignment.Top,
) {
Text(
text = title,
style = TerningTheme.typography.body2,
- color = Grey400,
+ color = Grey500,
)
Text(
text = value,
diff --git a/feature/src/main/java/com/terning/feature/intern/component/InternPageTitle.kt b/feature/src/main/java/com/terning/feature/intern/component/InternPageTitle.kt
index 011191a5a..79aa47b82 100644
--- a/feature/src/main/java/com/terning/feature/intern/component/InternPageTitle.kt
+++ b/feature/src/main/java/com/terning/feature/intern/component/InternPageTitle.kt
@@ -1,39 +1,43 @@
package com.terning.feature.intern.component
-import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
+import androidx.compose.material3.VerticalDivider
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
+import com.terning.core.designsystem.theme.Black
import com.terning.core.designsystem.theme.TerningMain
-import com.terning.core.designsystem.theme.TerningSub4
import com.terning.core.designsystem.theme.TerningTheme
@Composable
fun InternPageTitle(
modifier: Modifier,
- text: String
+ text: String,
) {
Row(
modifier = modifier
+ .height(IntrinsicSize.Min)
.fillMaxWidth()
.padding(
- top = 16.dp,
- bottom = 16.dp
+ top = 7.dp,
+ bottom = 6.dp,
)
- .background(TerningSub4)
) {
+ VerticalDivider(
+ color = TerningMain,
+ thickness = 2.dp,
+ )
Text(
text = text,
style = TerningTheme.typography.title4,
- color = TerningMain,
+ color = Black,
modifier = modifier.padding(
- top = 7.dp,
- bottom = 6.dp,
- start = 20.dp
+ start = 8.dp
)
)
}
diff --git a/feature/src/main/java/com/terning/feature/intern/component/InternTitle.kt b/feature/src/main/java/com/terning/feature/intern/component/InternTitle.kt
new file mode 100644
index 000000000..0d6a34e7c
--- /dev/null
+++ b/feature/src/main/java/com/terning/feature/intern/component/InternTitle.kt
@@ -0,0 +1,82 @@
+package com.terning.feature.intern.component
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+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.stringResource
+import androidx.compose.ui.unit.dp
+import com.terning.core.designsystem.component.image.TerningImage
+import com.terning.core.designsystem.theme.Black
+import com.terning.core.designsystem.theme.Grey375
+import com.terning.core.designsystem.theme.TerningMain
+import com.terning.core.designsystem.theme.TerningSub3
+import com.terning.core.designsystem.theme.TerningTheme
+import com.terning.feature.R
+
+
+@Composable
+fun InternTitle(
+ modifier: Modifier,
+ dDay: String,
+ title: String,
+ viewCount: String,
+) {
+ Column(
+ modifier = modifier
+ .fillMaxWidth(),
+ ) {
+ Row(
+ modifier = Modifier
+ .background(
+ color = TerningSub3,
+ shape = RoundedCornerShape(size = 5.dp)
+ ),
+ horizontalArrangement = Arrangement.Center,
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Text(
+ text = dDay,
+ style = TerningTheme.typography.title3,
+ color = TerningMain,
+ modifier = Modifier.padding(
+ horizontal = 19.5.dp,
+ vertical = 1.5.dp
+ )
+ )
+ }
+
+ Text(
+ text = title,
+ style = TerningTheme.typography.heading2,
+ color = Black,
+ modifier = modifier.padding(
+ top = 8.dp,
+ bottom = 4.dp
+ )
+ )
+
+ Row(
+ horizontalArrangement = Arrangement.spacedBy(3.dp, Alignment.Start),
+ verticalAlignment = Alignment.CenterVertically,
+ modifier = Modifier
+ .fillMaxWidth()
+ ) {
+ TerningImage(
+ painter = R.drawable.ic_view_count_14
+ )
+ Text(
+ text = stringResource(id = R.string.intern_view_count_detail, viewCount),
+ style = TerningTheme.typography.detail2,
+ color = Grey375,
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/feature/src/main/java/com/terning/feature/intern/component/ScrapDialogContent.kt b/feature/src/main/java/com/terning/feature/intern/component/ScrapDialogContent.kt
index 49f107b0b..3746f5f13 100644
--- a/feature/src/main/java/com/terning/feature/intern/component/ScrapDialogContent.kt
+++ b/feature/src/main/java/com/terning/feature/intern/component/ScrapDialogContent.kt
@@ -65,7 +65,7 @@ fun ScrapDialogContent(
announcementId: Long,
type: Int,
) {
- val state by viewModel.internState.collectAsStateWithLifecycle()
+ val state by viewModel.internUiState.collectAsStateWithLifecycle()
val colorList = listOf(
CalRed,
diff --git a/feature/src/main/java/com/terning/feature/intern/model/InternViewState.kt b/feature/src/main/java/com/terning/feature/intern/model/InternUiState.kt
similarity index 83%
rename from feature/src/main/java/com/terning/feature/intern/model/InternViewState.kt
rename to feature/src/main/java/com/terning/feature/intern/model/InternUiState.kt
index 499fe2c6f..16f8afcc3 100644
--- a/feature/src/main/java/com/terning/feature/intern/model/InternViewState.kt
+++ b/feature/src/main/java/com/terning/feature/intern/model/InternUiState.kt
@@ -5,8 +5,8 @@ import com.terning.core.designsystem.theme.CalRed
import com.terning.core.state.UiState
import com.terning.domain.entity.response.InternInfoModel
-data class InternViewState(
- var internInfo: UiState = UiState.Loading,
+data class InternUiState(
+ val loadState: UiState = UiState.Loading,
val isColorChange: Boolean = false,
val isPaletteOpen: Boolean = false,
val selectedColor: Color = CalRed,
diff --git a/feature/src/main/java/com/terning/feature/intern/navigation/InternNavigation.kt b/feature/src/main/java/com/terning/feature/intern/navigation/InternNavigation.kt
index 486134573..7bc5c14c3 100644
--- a/feature/src/main/java/com/terning/feature/intern/navigation/InternNavigation.kt
+++ b/feature/src/main/java/com/terning/feature/intern/navigation/InternNavigation.kt
@@ -41,8 +41,8 @@ fun NavGraphBuilder.internNavGraph(
) {
val args = it.toRoute()
InternRoute(
- navController = navHostController,
announcementId = args.announcementId,
+ navController = navHostController
)
}
}
diff --git a/feature/src/main/java/com/terning/feature/main/MainNavigator.kt b/feature/src/main/java/com/terning/feature/main/MainNavigator.kt
index 901d0fed0..f0598bf1f 100644
--- a/feature/src/main/java/com/terning/feature/main/MainNavigator.kt
+++ b/feature/src/main/java/com/terning/feature/main/MainNavigator.kt
@@ -11,7 +11,7 @@ import androidx.navigation.compose.rememberNavController
import androidx.navigation.navOptions
import com.terning.feature.calendar.calendar.navigation.navigateCalendar
import com.terning.feature.home.home.navigation.navigateHome
-import com.terning.feature.mypage.navigation.navigateMyPage
+import com.terning.feature.mypage.mypage.navigation.navigateMyPage
import com.terning.feature.onboarding.splash.navigation.Splash
import com.terning.feature.search.search.navigation.navigateSearch
diff --git a/feature/src/main/java/com/terning/feature/main/MainScreen.kt b/feature/src/main/java/com/terning/feature/main/MainScreen.kt
index e5fbb5d02..d78934eba 100644
--- a/feature/src/main/java/com/terning/feature/main/MainScreen.kt
+++ b/feature/src/main/java/com/terning/feature/main/MainScreen.kt
@@ -1,23 +1,24 @@
package com.terning.feature.main
import androidx.compose.animation.AnimatedVisibility
-import androidx.compose.animation.core.tween
-import androidx.compose.animation.expandVertically
-import androidx.compose.animation.shrinkVertically
-import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.animation.EnterTransition
+import androidx.compose.animation.ExitTransition
+import androidx.compose.animation.fadeIn
+import androidx.compose.animation.fadeOut
+import androidx.compose.animation.slideIn
+import androidx.compose.animation.slideOut
import androidx.compose.foundation.layout.Column
-import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Icon
import androidx.compose.material3.NavigationBar
import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Scaffold
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.res.stringResource
-import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.sp
import androidx.navigation.compose.NavHost
import com.terning.core.designsystem.theme.Grey300
@@ -33,7 +34,8 @@ import com.terning.feature.filtering.starthome.navigation.startHomeNavGraph
import com.terning.feature.home.changefilter.navigation.changeFilterNavGraph
import com.terning.feature.home.home.navigation.homeNavGraph
import com.terning.feature.intern.navigation.internNavGraph
-import com.terning.feature.mypage.navigation.myPageNavGraph
+import com.terning.feature.mypage.mypage.navigation.myPageNavGraph
+import com.terning.feature.mypage.profileedit.navigation.profileEditNavGraph
import com.terning.feature.onboarding.signin.navigation.signInNavGraph
import com.terning.feature.onboarding.signup.navigation.signUpNavGraph
import com.terning.feature.onboarding.splash.navigation.splashNavGraph
@@ -53,31 +55,72 @@ fun MainScreen(
onTabSelected = navigator::navigate
)
},
- ) { innerPadding ->
+ ) { paddingValues ->
Column(
- modifier = Modifier
- .padding(innerPadding),
- verticalArrangement = Arrangement.spacedBy(16.dp),
+ modifier = Modifier.fillMaxSize()
) {
NavHost(
+ enterTransition = {
+ EnterTransition.None
+ },
+ exitTransition = {
+ ExitTransition.None
+ },
+ popEnterTransition = {
+ EnterTransition.None
+ },
+ popExitTransition = {
+ ExitTransition.None
+ },
navController = navigator.navController,
startDestination = navigator.startDestination
) {
- splashNavGraph(navHostController = navigator.navController)
- homeNavGraph(navHostController = navigator.navController)
+ splashNavGraph(
+ paddingValues = paddingValues,
+ navHostController = navigator.navController
+ )
+ homeNavGraph(
+ paddingValues = paddingValues,
+ navHostController = navigator.navController
+ )
calendarNavGraph(navHostController = navigator.navController)
searchNavGraph(navHostController = navigator.navController)
- myPageNavGraph(navHostController = navigator.navController)
- signInNavGraph(navHostController = navigator.navController)
- signUpNavGraph(navHostController = navigator.navController)
- filteringOneNavGraph(navHostController = navigator.navController)
- filteringTwoNavGraph(navHostController = navigator.navController)
- filteringThreeNavGraph(navHostController = navigator.navController)
+ signInNavGraph(
+ paddingValues = paddingValues,
+ navHostController = navigator.navController
+ )
+ signUpNavGraph(
+ paddingValues = paddingValues,
+ navHostController = navigator.navController
+ )
+ startFilteringNavGraph(
+ paddingValues = paddingValues,
+ navHostController = navigator.navController
+ )
+ startHomeNavGraph(
+ paddingValues = paddingValues,
+ navHostController = navigator.navController
+ )
+ filteringOneNavGraph(
+ paddingValues = paddingValues,
+ navHostController = navigator.navController
+ )
+ filteringTwoNavGraph(
+ paddingValues = paddingValues,
+ navHostController = navigator.navController
+ )
+ filteringThreeNavGraph(
+ paddingValues = paddingValues,
+ navHostController = navigator.navController
+ )
searchProcessNavGraph(navHostController = navigator.navController)
changeFilterNavGraph(navHostController = navigator.navController)
- startFilteringNavGraph(navHostController = navigator.navController)
- startHomeNavGraph(navHostController = navigator.navController)
internNavGraph(navHostController = navigator.navController)
+ myPageNavGraph(
+ paddingValues = paddingValues,
+ navHostController = navigator.navController
+ )
+ profileEditNavGraph(navHostController = navigator.navController)
}
}
}
@@ -92,10 +135,8 @@ private fun MainBottomBar(
) {
AnimatedVisibility(
visible = isVisible,
- enter = expandVertically(expandFrom = Alignment.Top) { 20 },
- exit = shrinkVertically(animationSpec = tween()) { fullHeight ->
- fullHeight / 2
- },
+ enter = fadeIn() + slideIn { IntOffset(0, 0) },
+ exit = fadeOut() + slideOut { IntOffset(0, 0) }
) {
NavigationBar(containerColor = White) {
tabs.forEach { itemType ->
diff --git a/feature/src/main/java/com/terning/feature/main/MainTab.kt b/feature/src/main/java/com/terning/feature/main/MainTab.kt
index 179669c64..993a7c47a 100644
--- a/feature/src/main/java/com/terning/feature/main/MainTab.kt
+++ b/feature/src/main/java/com/terning/feature/main/MainTab.kt
@@ -8,7 +8,7 @@ import com.terning.core.navigation.Route
import com.terning.feature.R
import com.terning.feature.calendar.calendar.navigation.Calendar
import com.terning.feature.home.home.navigation.Home
-import com.terning.feature.mypage.navigation.MyPage
+import com.terning.feature.mypage.mypage.navigation.MyPage
import com.terning.feature.search.search.navigation.Search
enum class MainTab(
diff --git a/feature/src/main/java/com/terning/feature/mypage/MyPageRoute.kt b/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageRoute.kt
similarity index 77%
rename from feature/src/main/java/com/terning/feature/mypage/MyPageRoute.kt
rename to feature/src/main/java/com/terning/feature/mypage/mypage/MyPageRoute.kt
index bf41f671d..e520d3504 100644
--- a/feature/src/main/java/com/terning/feature/mypage/MyPageRoute.kt
+++ b/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageRoute.kt
@@ -1,9 +1,10 @@
-package com.terning.feature.mypage
+package com.terning.feature.mypage.mypage
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.IntrinsicSize
+import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
@@ -14,11 +15,9 @@ import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Text
import androidx.compose.material3.VerticalDivider
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.SideEffect
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.platform.LocalContext
@@ -26,7 +25,9 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
+import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import androidx.lifecycle.flowWithLifecycle
import com.google.accompanist.systemuicontroller.rememberSystemUiController
import com.terning.core.designsystem.component.bottomsheet.MyPageLogoutBottomSheet
import com.terning.core.designsystem.component.bottomsheet.MyPageQuitBottomSheet
@@ -41,19 +42,18 @@ import com.terning.core.designsystem.theme.White
import com.terning.core.extension.noRippleClickable
import com.terning.core.state.UiState
import com.terning.feature.R
-import com.terning.feature.mypage.component.MyPageItem
import com.terning.feature.mypage.component.MyPageProfile
+import com.terning.feature.mypage.mypage.component.MyPageItem
@Composable
fun MyPageRoute(
+ paddingValues: PaddingValues,
+ navigateToProfileEdit: (String, Int) -> Unit,
viewModel: MyPageViewModel = hiltViewModel(),
) {
val state by viewModel.state.collectAsStateWithLifecycle()
val context = LocalContext.current
-
- var name by remember { mutableStateOf(state.name) }
- // TODO: 프로필로 바꾸기
- var profile by remember { mutableStateOf(state.authType) }
+ val lifecycleOwner = LocalLifecycleOwner.current
val systemUiController = rememberSystemUiController()
@@ -63,6 +63,18 @@ fun MyPageRoute(
)
}
+ LaunchedEffect(viewModel.sideEffects, lifecycleOwner) {
+ viewModel.sideEffects.flowWithLifecycle(lifecycle = lifecycleOwner.lifecycle)
+ .collect { sideEffect ->
+ when (sideEffect) {
+ is MyPageSideEffect.NavigateToProfileEdit -> navigateToProfileEdit(
+ state.name,
+ state.profile
+ )
+ }
+ }
+ }
+
if (state.showLogoutBottomSheet) {
MyPageLogoutBottomSheet(
onDismiss = { viewModel.fetchShowLogoutBottomSheet(false) },
@@ -93,9 +105,18 @@ fun MyPageRoute(
when (state.isGetSuccess) {
is UiState.Success -> {
- name = state.name
- // TODO: 프로필로 바꾸기
- profile = state.authType
+ MyPageScreen(
+ paddingValues = paddingValues,
+ onEditClick = { viewModel.navigateToProfileEdit() },
+ onLogoutClick = { viewModel.fetchShowLogoutBottomSheet(true) },
+ onQuitClick = { viewModel.fetchShowQuitBottomSheet(true) },
+ onNoticeClick = { viewModel.fetchShowNotice(true) },
+ onOpinionClick = { viewModel.fetchShowOpinion(true) },
+ onServiceClick = {},
+ onPersonalClick = {},
+ name = state.name,
+ profile = state.profile
+ )
}
is UiState.Loading -> {}
@@ -112,33 +133,26 @@ fun MyPageRoute(
viewModel.navigateToOpinionWebView(context)
viewModel.fetchShowOpinion(false)
}
-
- MyPageScreen(
- onLogoutClick = { viewModel.fetchShowLogoutBottomSheet(true) },
- onQuitClick = { viewModel.fetchShowQuitBottomSheet(true) },
- onNoticeClick = { viewModel.fetchShowNotice(true) },
- onOpinionClick = { viewModel.fetchShowOpinion(true) },
- onEditClick = { /*TODO: 프로필 수정으로 이동*/ },
- name = name,
- profile = profile
- )
}
@Composable
fun MyPageScreen(
+ onEditClick: () -> Unit,
onLogoutClick: () -> Unit,
onQuitClick: () -> Unit,
onNoticeClick: () -> Unit,
onOpinionClick: () -> Unit,
- onEditClick: () -> Unit,
- modifier: Modifier = Modifier,
+ onServiceClick: () -> Unit,
+ onPersonalClick: () -> Unit,
+ paddingValues: PaddingValues = PaddingValues(),
name: String = "",
- profile: String = ""
+ profile: Int = 0
) {
Column(
- modifier = modifier
+ modifier = Modifier
.fillMaxSize()
.background(Back)
+ .padding(paddingValues)
) {
UserProfile(
name = name,
@@ -146,12 +160,12 @@ fun MyPageScreen(
onEditClick = onEditClick
)
TerningCommunity(
- onNoticeClick = onNoticeClick,
+ onNoticeClick = onNoticeClick,
onOpinionClick = onOpinionClick
)
ServiceInfo(
- onNoticeClick = onNoticeClick,
- onOpinionClick = onOpinionClick
+ onServiceClick = onServiceClick,
+ onPersonalClick = onPersonalClick
)
Row(
modifier = Modifier
@@ -195,7 +209,7 @@ fun UserProfile(
name: String,
onEditClick: () -> Unit,
modifier: Modifier = Modifier,
- profile: String = "PROFILE_00",
+ profile: Int = 0,
) {
Row(
modifier = modifier.padding(
@@ -215,10 +229,12 @@ fun UserProfile(
bottom = 7.dp
)
)
- Row(verticalAlignment = Alignment.CenterVertically,
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.noRippleClickable {
onEditClick()
- }) {
+ }
+ ) {
Text(
text = stringResource(id = R.string.my_page_edit_profile),
modifier = Modifier.padding(start = 16.dp, end = 7.dp),
@@ -267,20 +283,19 @@ fun TerningCommunity(
modifier = Modifier.padding(bottom = 20.dp)
)
MyPageItem(
- text = stringResource(id = R.string.my_page_information),
+ text = stringResource(id = R.string.my_page_notice),
icon = R.drawable.ic_my_page_notice,
- onButtonClick = { onNoticeClick() }
+ onButtonClick = onNoticeClick
)
HorizontalDivider(
- modifier = Modifier
- .padding(vertical = 20.dp),
+ modifier = Modifier.padding(vertical = 20.dp),
thickness = 1.dp,
color = Grey150
)
MyPageItem(
text = stringResource(id = R.string.my_page_opinion),
icon = R.drawable.ic_my_page_opinion,
- onButtonClick = { onOpinionClick() }
+ onButtonClick = onOpinionClick
)
}
}
@@ -289,8 +304,8 @@ fun TerningCommunity(
@Composable
fun ServiceInfo(
modifier: Modifier = Modifier,
- onNoticeClick: () -> Unit,
- onOpinionClick: () -> Unit
+ onServiceClick: () -> Unit,
+ onPersonalClick: () -> Unit
) {
Column(
modifier = modifier
@@ -321,24 +336,22 @@ fun ServiceInfo(
modifier = Modifier.padding(bottom = 20.dp)
)
MyPageItem(
- text = stringResource(id = R.string.my_page_notice),
- icon = R.drawable.ic_my_page_notice,
- onButtonClick = { onNoticeClick() }
+ text = stringResource(id = R.string.my_page_service),
+ icon = R.drawable.ic_my_page_service,
+ onButtonClick = onServiceClick
)
HorizontalDivider(
- modifier = Modifier
- .padding(vertical = 20.dp),
+ modifier = Modifier.padding(vertical = 20.dp),
thickness = 1.dp,
color = Grey150
)
MyPageItem(
- text = stringResource(id = R.string.my_page_private_information),
- icon = R.drawable.ic_my_page_opinion,
- onButtonClick = { onOpinionClick() }
+ text = stringResource(id = R.string.my_page_personal),
+ icon = R.drawable.ic_my_page_personal,
+ onButtonClick = onPersonalClick
)
HorizontalDivider(
- modifier = Modifier
- .padding(vertical = 20.dp),
+ modifier = Modifier.padding(vertical = 20.dp),
thickness = 1.dp,
color = Grey150
)
@@ -363,7 +376,9 @@ fun MyPageScreenPreview() {
onOpinionClick = {},
onLogoutClick = {},
onQuitClick = {},
- onEditClick = {}
+ onEditClick = {},
+ onServiceClick = {},
+ onPersonalClick = {},
)
}
}
\ No newline at end of file
diff --git a/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageSideEffect.kt b/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageSideEffect.kt
new file mode 100644
index 000000000..26d1e5856
--- /dev/null
+++ b/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageSideEffect.kt
@@ -0,0 +1,5 @@
+package com.terning.feature.mypage.mypage
+
+sealed class MyPageSideEffect {
+ data object NavigateToProfileEdit : MyPageSideEffect()
+}
\ No newline at end of file
diff --git a/feature/src/main/java/com/terning/feature/mypage/MyPageState.kt b/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageState.kt
similarity index 79%
rename from feature/src/main/java/com/terning/feature/mypage/MyPageState.kt
rename to feature/src/main/java/com/terning/feature/mypage/mypage/MyPageState.kt
index e74a16fe8..bf072cb13 100644
--- a/feature/src/main/java/com/terning/feature/mypage/MyPageState.kt
+++ b/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageState.kt
@@ -1,4 +1,4 @@
-package com.terning.feature.mypage
+package com.terning.feature.mypage.mypage
import com.terning.core.state.UiState
@@ -6,7 +6,8 @@ data class MyPageState(
val isLogoutAndQuitSuccess: UiState = UiState.Loading,
val isGetSuccess: UiState = UiState.Loading,
val name: String = "",
- val authType: String = "",
+ val profile: Int = 0,
+ val authType : String ="",
val showNotice: Boolean = false,
val showOpinion: Boolean = false,
val showLogoutBottomSheet : Boolean = false,
diff --git a/feature/src/main/java/com/terning/feature/mypage/MyPageViewModel.kt b/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt
similarity index 83%
rename from feature/src/main/java/com/terning/feature/mypage/MyPageViewModel.kt
rename to feature/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt
index d5e87497b..b4f39bb61 100644
--- a/feature/src/main/java/com/terning/feature/mypage/MyPageViewModel.kt
+++ b/feature/src/main/java/com/terning/feature/mypage/mypage/MyPageViewModel.kt
@@ -1,4 +1,4 @@
-package com.terning.feature.mypage
+package com.terning.feature.mypage.mypage
import android.content.Context
import android.content.Intent
@@ -15,8 +15,11 @@ import com.terning.domain.repository.MyPageRepository
import com.terning.domain.repository.TokenRepository
import com.terning.feature.main.MainActivity
import dagger.hilt.android.lifecycle.HiltViewModel
+import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject
@@ -34,6 +37,9 @@ class MyPageViewModel @Inject constructor(
private val _state: MutableStateFlow = MutableStateFlow(MyPageState())
val state: StateFlow get() = _state.asStateFlow()
+ private val _sideEffects = MutableSharedFlow()
+ val sideEffects: SharedFlow get() = _sideEffects.asSharedFlow()
+
fun logoutKakao() {
UserApiClient.instance.logout { error ->
if (error == null) {
@@ -95,14 +101,14 @@ class MyPageViewModel @Inject constructor(
viewModelScope.launch {
myPageRepository.getProfile()
.onSuccess { response ->
- _state.value = _state.value.copy(
- isGetSuccess = UiState.Success(true),
- name = response.name,
- authType = response.authType
- )
- }.onFailure {
- _state.value = _state.value.copy(isGetSuccess = UiState.Failure(it.toString()))
- }
+ _state.value = _state.value.copy(
+ isGetSuccess = UiState.Success(true),
+ name = response.name,
+ authType = response.authType
+ )
+ }.onFailure {
+ _state.value = _state.value.copy(isGetSuccess = UiState.Failure(it.toString()))
+ }
}
}
@@ -134,6 +140,9 @@ class MyPageViewModel @Inject constructor(
customTabsIntent.launchUrl(context, url)
}
+ fun navigateToProfileEdit() =
+ viewModelScope.launch { _sideEffects.emit(MyPageSideEffect.NavigateToProfileEdit) }
+
companion object {
private const val NOTICE_URL =
"https://abundant-quiver-13f.notion.site/69109213e7db4873be6b9600f2f5163a"
diff --git a/feature/src/main/java/com/terning/feature/mypage/component/MyPageItem.kt b/feature/src/main/java/com/terning/feature/mypage/mypage/component/MyPageItem.kt
similarity index 97%
rename from feature/src/main/java/com/terning/feature/mypage/component/MyPageItem.kt
rename to feature/src/main/java/com/terning/feature/mypage/mypage/component/MyPageItem.kt
index 10346d75d..ca15cd033 100644
--- a/feature/src/main/java/com/terning/feature/mypage/component/MyPageItem.kt
+++ b/feature/src/main/java/com/terning/feature/mypage/mypage/component/MyPageItem.kt
@@ -1,4 +1,4 @@
-package com.terning.feature.mypage.component
+package com.terning.feature.mypage.mypage.component
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
diff --git a/feature/src/main/java/com/terning/feature/mypage/component/MyPageProfile.kt b/feature/src/main/java/com/terning/feature/mypage/mypage/component/MyPageProfile.kt
similarity index 67%
rename from feature/src/main/java/com/terning/feature/mypage/component/MyPageProfile.kt
rename to feature/src/main/java/com/terning/feature/mypage/mypage/component/MyPageProfile.kt
index c57969e3c..cd12d2623 100644
--- a/feature/src/main/java/com/terning/feature/mypage/component/MyPageProfile.kt
+++ b/feature/src/main/java/com/terning/feature/mypage/mypage/component/MyPageProfile.kt
@@ -1,18 +1,20 @@
package com.terning.feature.mypage.component
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
+import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import com.terning.core.R
-import com.terning.core.designsystem.component.image.TerningImage
@Composable
fun MyPageProfile(
modifier: Modifier = Modifier,
- profile: String
+ profile: Int
) {
val options = listOf(
R.drawable.ic_terning_profile_00,
@@ -24,18 +26,20 @@ fun MyPageProfile(
)
val option = when (profile) {
- "PROFILE_00" -> options[0]
- "PROFILE_01" -> options[1]
- "PROFILE_02" -> options[2]
- "PROFILE_03" -> options[3]
- "PROFILE_04" -> options[4]
+ 0 -> options[0]
+ 1 -> options[1]
+ 2 -> options[2]
+ 3 -> options[3]
+ 4 -> options[4]
else -> options[5]
}
- TerningImage(
- painter = option,
+ Image(
+ painter = painterResource(id = option),
modifier = modifier
.size(72.dp)
.clip(shape = CircleShape)
+ .aspectRatio(1f),
+ contentDescription = "profile image"
)
}
diff --git a/feature/src/main/java/com/terning/feature/mypage/navigation/MyPageNavigation.kt b/feature/src/main/java/com/terning/feature/mypage/mypage/navigation/MyPageNavigation.kt
similarity index 50%
rename from feature/src/main/java/com/terning/feature/mypage/navigation/MyPageNavigation.kt
rename to feature/src/main/java/com/terning/feature/mypage/mypage/navigation/MyPageNavigation.kt
index c028d5967..7248c8a2a 100644
--- a/feature/src/main/java/com/terning/feature/mypage/navigation/MyPageNavigation.kt
+++ b/feature/src/main/java/com/terning/feature/mypage/mypage/navigation/MyPageNavigation.kt
@@ -1,14 +1,14 @@
-package com.terning.feature.mypage.navigation
+package com.terning.feature.mypage.mypage.navigation
-import androidx.compose.animation.EnterTransition
-import androidx.compose.animation.ExitTransition
+import androidx.compose.foundation.layout.PaddingValues
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.NavOptions
import androidx.navigation.compose.composable
import com.terning.core.navigation.MainTabRoute
-import com.terning.feature.mypage.MyPageRoute
+import com.terning.feature.mypage.mypage.MyPageRoute
+import com.terning.feature.mypage.profileedit.navigation.navigateProfileEdit
import kotlinx.serialization.Serializable
fun NavController.navigateMyPage(navOptions: NavOptions? = null) {
@@ -19,23 +19,19 @@ fun NavController.navigateMyPage(navOptions: NavOptions? = null) {
}
fun NavGraphBuilder.myPageNavGraph(
+ paddingValues: PaddingValues,
navHostController: NavHostController,
) {
- composable(
- exitTransition = {
- ExitTransition.None
- },
- popEnterTransition = {
- EnterTransition.None
- },
- enterTransition = {
- EnterTransition.None
- },
- popExitTransition = {
- ExitTransition.None
- }
- ) {
- MyPageRoute()
+ composable {
+ MyPageRoute(
+ paddingValues = paddingValues,
+ navigateToProfileEdit = { name, profile ->
+ navHostController.navigateProfileEdit(
+ name,
+ profile
+ )
+ }
+ )
}
}
diff --git a/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditRoute.kt b/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditRoute.kt
new file mode 100644
index 000000000..577c5689b
--- /dev/null
+++ b/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditRoute.kt
@@ -0,0 +1,197 @@
+package com.terning.feature.mypage.profileedit
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.navigationBarsPadding
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.statusBarsPadding
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.SideEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.platform.LocalFocusManager
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.hilt.navigation.compose.hiltViewModel
+import androidx.lifecycle.compose.LocalLifecycleOwner
+import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import androidx.lifecycle.flowWithLifecycle
+import com.google.accompanist.systemuicontroller.rememberSystemUiController
+import com.terning.core.designsystem.component.bottomsheet.ProfileBottomSheet
+import com.terning.core.designsystem.component.button.RectangleButton
+import com.terning.core.designsystem.component.item.ProfileWithPlusButton
+import com.terning.core.designsystem.component.textfield.NameTextField
+import com.terning.core.designsystem.component.topappbar.BackButtonTopAppBar
+import com.terning.core.designsystem.theme.Grey500
+import com.terning.core.designsystem.theme.TerningPointTheme
+import com.terning.core.designsystem.theme.TerningTheme
+import com.terning.core.designsystem.theme.White
+import com.terning.core.extension.addFocusCleaner
+import com.terning.core.extension.noRippleClickable
+import com.terning.feature.R
+
+@Composable
+fun ProfileEditRoute(
+ navigateUp: () -> Unit,
+ initialName: String,
+ initialProfile: Int,
+ viewModel: ProfileEditViewModel = hiltViewModel(),
+) {
+ val state by viewModel.state.collectAsStateWithLifecycle()
+
+ val lifecycleOwner = LocalLifecycleOwner.current
+
+ val systemUiController = rememberSystemUiController()
+
+ SideEffect {
+ systemUiController.setStatusBarColor(
+ color = White
+ )
+ }
+
+ LaunchedEffect(key1 = true) {
+ viewModel.updateInitialInfo(initialName = initialName, initialProfile = initialProfile)
+ }
+
+ LaunchedEffect(viewModel.sideEffects, lifecycleOwner) {
+ viewModel.sideEffects.flowWithLifecycle(lifecycle = lifecycleOwner.lifecycle)
+ .collect { sideEffect ->
+ when (sideEffect) {
+ is ProfileEditSideEffect.NavigateUp -> navigateUp()
+ }
+ }
+ }
+
+ if (state.showBottomSheet) {
+ ProfileBottomSheet(
+ onDismiss = { viewModel.updateBottomSheet(false) },
+ onSaveClick = { index ->
+ viewModel.updateBottomSheet(false)
+ viewModel.updateProfile(index)
+ },
+ initialSelectedOption = state.profile
+ )
+ }
+
+ ProfileEditScreen(
+ profileEditState = state,
+ onProfileEditClick = { isVisible ->
+ viewModel.updateBottomSheet(isVisible)
+ },
+ onInputChange = { editName ->
+ viewModel.updateName(editName)
+ },
+ onSaveClick = { viewModel.navigateUp() },
+ name = state.name,
+ onBackButtonClick = { viewModel.navigateUp() },
+ onValidationChanged = { isValid ->
+ viewModel.updateButtonValidation(isValid)
+ }
+ )
+}
+
+@Composable
+fun ProfileEditScreen(
+ profileEditState: ProfileEditState,
+ onProfileEditClick: (Boolean) -> Unit,
+ onInputChange: (String) -> Unit,
+ onSaveClick: () -> Unit,
+ name: String,
+ onBackButtonClick: () -> Unit,
+ onValidationChanged: (Boolean) -> Unit,
+) {
+ val focusManager = LocalFocusManager.current
+
+ Column(
+ modifier = Modifier
+ .statusBarsPadding()
+ .navigationBarsPadding()
+ .fillMaxSize()
+ .addFocusCleaner(focusManager)
+ .background(White)
+ ) {
+ BackButtonTopAppBar(
+ onBackButtonClick = { onBackButtonClick() },
+ title = stringResource(id = R.string.profile_edit_title),
+ )
+ Spacer(modifier = Modifier.height(24.dp))
+ Column(
+ modifier = Modifier.padding(horizontal = 24.dp)
+ ) {
+ Text(
+ text = stringResource(id = R.string.sign_up_profile_image),
+ style = TerningTheme.typography.body2,
+ color = Grey500
+ )
+ Spacer(modifier = Modifier.height(20.dp))
+ ProfileWithPlusButton(
+ modifier = Modifier
+ .noRippleClickable {
+ onProfileEditClick(true)
+ }
+ .align(Alignment.CenterHorizontally),
+ index = profileEditState.profile
+ )
+ Spacer(modifier = Modifier.height(48.dp))
+ Text(
+ text = stringResource(id = R.string.sign_up_name),
+ color = Grey500
+ )
+ Spacer(modifier = Modifier.height(20.dp))
+ NameTextField(
+ value = name,
+ onValueChange = { editName ->
+ onInputChange(editName)
+ },
+ hint = stringResource(id = R.string.sign_up_hint),
+ onValidationChanged = { isValid ->
+ onValidationChanged(isValid)
+ },
+ initialView = profileEditState.initialView
+ )
+ Spacer(modifier = Modifier.height(48.dp))
+ Text(
+ text = stringResource(id = R.string.profile_edit_auth_type),
+ style = TerningTheme.typography.body2,
+ color = Grey500,
+ )
+ Spacer(modifier = Modifier.height(11.dp))
+ Text(
+ text = profileEditState.authType,
+ style = TerningTheme.typography.detail0
+ )
+ }
+ Spacer(modifier = Modifier.weight(1f))
+ RectangleButton(
+ style = TerningTheme.typography.button1,
+ paddingVertical = 20.dp,
+ text = R.string.profile_edit_save,
+ onButtonClick = onSaveClick,
+ isEnabled = profileEditState.isButtonValid,
+ )
+ Spacer(modifier = Modifier.height(12.dp))
+ }
+}
+
+@Preview(showBackground = true)
+@Composable
+fun ProfileEditScreenPreview() {
+ TerningPointTheme {
+ ProfileEditScreen(
+ profileEditState = ProfileEditState(),
+ onProfileEditClick = {},
+ onInputChange = {},
+ onSaveClick = {},
+ name = "터닝이",
+ onBackButtonClick = {},
+ onValidationChanged = {}
+ )
+ }
+}
\ No newline at end of file
diff --git a/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditSideEffect.kt b/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditSideEffect.kt
new file mode 100644
index 000000000..6fd2f3668
--- /dev/null
+++ b/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditSideEffect.kt
@@ -0,0 +1,5 @@
+package com.terning.feature.mypage.profileedit
+
+sealed class ProfileEditSideEffect {
+ data object NavigateUp : ProfileEditSideEffect()
+}
\ No newline at end of file
diff --git a/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditState.kt b/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditState.kt
new file mode 100644
index 000000000..eb34b9548
--- /dev/null
+++ b/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditState.kt
@@ -0,0 +1,11 @@
+package com.terning.feature.mypage.profileedit
+
+data class ProfileEditState(
+ val name: String = "",
+ val initialName: String = "",
+ val profile: Int = 0,
+ val initialView: Boolean = true,
+ val isButtonValid: Boolean = false,
+ val authType: String = "",
+ val showBottomSheet: Boolean = false
+)
\ No newline at end of file
diff --git a/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditViewModel.kt b/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditViewModel.kt
new file mode 100644
index 000000000..58bf6349f
--- /dev/null
+++ b/feature/src/main/java/com/terning/feature/mypage/profileedit/ProfileEditViewModel.kt
@@ -0,0 +1,50 @@
+package com.terning.feature.mypage.profileedit
+
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import dagger.hilt.android.lifecycle.HiltViewModel
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharedFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asSharedFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.launch
+import javax.inject.Inject
+
+@HiltViewModel
+class ProfileEditViewModel @Inject constructor() : ViewModel() {
+
+ private val _state: MutableStateFlow = MutableStateFlow(ProfileEditState())
+ val state: StateFlow get() = _state.asStateFlow()
+
+ private val _sideEffects = MutableSharedFlow()
+ val sideEffects: SharedFlow get() = _sideEffects.asSharedFlow()
+
+ fun navigateUp() = viewModelScope.launch { _sideEffects.emit(ProfileEditSideEffect.NavigateUp) }
+
+ fun updateBottomSheet(isVisible: Boolean) {
+ _state.value = _state.value.copy(showBottomSheet = isVisible)
+ }
+
+ fun updateInitialInfo(initialName: String, initialProfile: Int) {
+ _state.value = _state.value.copy(
+ name = initialName,
+ initialName = initialName,
+ profile = initialProfile,
+ )
+ }
+
+ fun updateName(name: String) {
+ _state.value = _state.value.copy(name = name, initialView = false)
+ }
+
+ fun updateProfile(profile: Int) {
+ _state.value = _state.value.copy(profile = profile, initialView = false)
+ }
+
+ fun updateButtonValidation(isValid: Boolean) {
+ _state.value = _state.value.copy(isButtonValid = isValid)
+ }
+
+}
\ No newline at end of file
diff --git a/feature/src/main/java/com/terning/feature/mypage/profileedit/navigation/ProfileEditNavigation.kt b/feature/src/main/java/com/terning/feature/mypage/profileedit/navigation/ProfileEditNavigation.kt
new file mode 100644
index 000000000..71ef7f910
--- /dev/null
+++ b/feature/src/main/java/com/terning/feature/mypage/profileedit/navigation/ProfileEditNavigation.kt
@@ -0,0 +1,58 @@
+package com.terning.feature.mypage.profileedit.navigation
+
+import androidx.compose.animation.core.LinearOutSlowInEasing
+import androidx.compose.animation.core.tween
+import androidx.compose.animation.slideInHorizontally
+import androidx.compose.animation.slideOutHorizontally
+import androidx.navigation.NavController
+import androidx.navigation.NavGraphBuilder
+import androidx.navigation.NavHostController
+import androidx.navigation.NavOptions
+import androidx.navigation.compose.composable
+import androidx.navigation.toRoute
+import com.terning.core.navigation.Route
+import com.terning.feature.mypage.profileedit.ProfileEditRoute
+import kotlinx.serialization.Serializable
+
+fun NavController.navigateProfileEdit(
+ name: String,
+ profile: Int,
+ navOptions: NavOptions? = null
+) {
+ navigate(
+ route = ProfileEdit(name = name, profile = profile),
+ navOptions = navOptions
+ )
+}
+
+fun NavGraphBuilder.profileEditNavGraph(
+ navHostController: NavHostController,
+) {
+ composable(
+ enterTransition = {
+ slideInHorizontally(
+ initialOffsetX = { it },
+ animationSpec = tween(durationMillis = 700, easing = LinearOutSlowInEasing)
+ )
+ },
+ popExitTransition = {
+ slideOutHorizontally(
+ targetOffsetX = { it },
+ animationSpec = tween(durationMillis = 700, easing = LinearOutSlowInEasing)
+ )
+ },
+ ) {
+ val args = it.toRoute()
+ ProfileEditRoute(
+ initialName = args.name,
+ initialProfile = args.profile,
+ navigateUp = { navHostController.navigateUp() }
+ )
+ }
+}
+
+@Serializable
+data class ProfileEdit(
+ val name: String,
+ val profile: Int
+) : Route
\ No newline at end of file
diff --git a/feature/src/main/java/com/terning/feature/onboarding/signin/SignInRoute.kt b/feature/src/main/java/com/terning/feature/onboarding/signin/SignInRoute.kt
index 43b79c8c6..9b946f9f5 100644
--- a/feature/src/main/java/com/terning/feature/onboarding/signin/SignInRoute.kt
+++ b/feature/src/main/java/com/terning/feature/onboarding/signin/SignInRoute.kt
@@ -3,6 +3,7 @@ package com.terning.feature.onboarding.signin
import android.content.Context
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
@@ -31,6 +32,7 @@ import com.terning.feature.onboarding.signin.component.KakaoButton
@Composable
fun SignInRoute(
+ paddingValues: PaddingValues,
navigateToHome: () -> Unit,
navigateToSignUp: (String) -> Unit,
viewModel: SignInViewModel = hiltViewModel(),
@@ -79,6 +81,7 @@ fun SignInRoute(
}
SignInScreen(
+ paddingValues = paddingValues,
onSignInClick = {
viewModel.startKakaoLogIn(
isKakaoAvailable = UserApiClient.instance.isKakaoTalkLoginAvailable(
@@ -91,29 +94,28 @@ fun SignInRoute(
@Composable
fun SignInScreen(
- modifier: Modifier = Modifier,
- onSignInClick: () -> Unit = {},
+ onSignInClick: () -> Unit,
+ paddingValues: PaddingValues = PaddingValues(),
) {
Column(
- modifier = modifier
+ modifier = Modifier
.fillMaxSize()
.background(color = White)
+ .padding(paddingValues)
.padding(horizontal = 20.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
- Spacer(modifier = modifier.weight(1f))
+ Spacer(modifier = Modifier.weight(1f))
TerningImage(
painter = R.drawable.ic_terning_login,
modifier = Modifier.fillMaxWidth()
)
- Spacer(modifier = modifier.weight(1f))
+ Spacer(modifier = Modifier.weight(1f))
KakaoButton(
title = stringResource(id = R.string.sign_in_kakao_button),
- onSignInClick = {
- onSignInClick()
- }
+ onSignInClick = onSignInClick
)
- Spacer(modifier = modifier.weight(1f))
+ Spacer(modifier = Modifier.weight(1f))
}
}
@@ -154,6 +156,8 @@ private const val KAKAO_NOT_LOGGED_IN = "statusCode=302"
@Composable
fun SignInScreenPreview() {
TerningPointTheme {
- SignInScreen()
+ SignInScreen(
+ onSignInClick = {}
+ )
}
}
\ No newline at end of file
diff --git a/feature/src/main/java/com/terning/feature/onboarding/signin/navigation/SignInNavigation.kt b/feature/src/main/java/com/terning/feature/onboarding/signin/navigation/SignInNavigation.kt
index f9ee42532..49f367ab3 100644
--- a/feature/src/main/java/com/terning/feature/onboarding/signin/navigation/SignInNavigation.kt
+++ b/feature/src/main/java/com/terning/feature/onboarding/signin/navigation/SignInNavigation.kt
@@ -1,5 +1,6 @@
package com.terning.feature.onboarding.signin.navigation
+import androidx.compose.foundation.layout.PaddingValues
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
@@ -19,10 +20,12 @@ fun NavController.navigateSignIn(navOptions: NavOptions? = null) {
}
fun NavGraphBuilder.signInNavGraph(
+ paddingValues: PaddingValues,
navHostController: NavHostController,
) {
composable {
SignInRoute(
+ paddingValues = paddingValues,
navigateToHome = { navHostController.navigateHome() },
navigateToSignUp = { authId -> navHostController.navigateSignUp(authId) }
)
diff --git a/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpRoute.kt b/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpRoute.kt
index 61dce1b1d..9a963fe57 100644
--- a/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpRoute.kt
+++ b/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpRoute.kt
@@ -1,16 +1,15 @@
package com.terning.feature.onboarding.signup
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
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.platform.LocalContext
@@ -22,30 +21,32 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.flowWithLifecycle
-import com.terning.core.designsystem.component.bottomsheet.SignUpBottomSheet
+import com.terning.core.designsystem.component.bottomsheet.ProfileBottomSheet
import com.terning.core.designsystem.component.button.RectangleButton
+import com.terning.core.designsystem.component.item.ProfileWithPlusButton
import com.terning.core.designsystem.component.textfield.NameTextField
+import com.terning.core.designsystem.theme.Grey500
import com.terning.core.designsystem.theme.TerningPointTheme
import com.terning.core.designsystem.theme.TerningTheme
import com.terning.core.extension.addFocusCleaner
import com.terning.core.extension.noRippleClickable
import com.terning.core.extension.toast
import com.terning.feature.R
-import com.terning.feature.onboarding.signup.component.SignUpProfile
@Composable
fun SignUpRoute(
+ paddingValues: PaddingValues,
authId: String,
navigateToStartFiltering: (String) -> Unit,
viewModel: SignUpViewModel = hiltViewModel(),
) {
- val signUpState by viewModel.state.collectAsStateWithLifecycle()
+ val state by viewModel.state.collectAsStateWithLifecycle()
val context = LocalContext.current
val lifecycleOwner = LocalLifecycleOwner.current
LaunchedEffect(key1 = true) {
- viewModel.fetchAuthId(authId)
+ viewModel.updateAuthId(authId)
}
LaunchedEffect(viewModel.sideEffects, lifecycleOwner) {
@@ -54,110 +55,106 @@ fun SignUpRoute(
when (sideEffect) {
is SignUpSideEffect.ShowToast -> context.toast(sideEffect.message)
is SignUpSideEffect.NavigateToStartFiltering ->
- navigateToStartFiltering(signUpState.name)
+ navigateToStartFiltering(state.name)
}
}
}
+ if (state.showBottomSheet) {
+ ProfileBottomSheet(
+ onDismiss = { viewModel.updateBottomSheet(false) },
+ onSaveClick = { index ->
+ viewModel.updateBottomSheet(false)
+ viewModel.updateProfileImage(index)
+ },
+ initialSelectedOption = state.profileImage
+ )
+ }
+
SignUpScreen(
- signUpState = signUpState,
+ paddingValues = paddingValues,
+ state = state,
onSignUpClick = {
viewModel.postSignUpWithServer()
},
onInputChange = { name ->
- viewModel.isInputValid(name)
+ viewModel.updateName(name)
},
- onFetchCharacter = { index ->
- viewModel.fetchCharacter(index)
+ onProfileEditClick = { isVisible ->
+ viewModel.updateBottomSheet(isVisible)
+ },
+ onValidationChanged = { isVisible ->
+ viewModel.updateButtonValidation(isVisible)
}
)
}
@Composable
fun SignUpScreen(
- signUpState: SignUpState,
+ state: SignUpState,
onSignUpClick: () -> Unit,
onInputChange: (String) -> Unit,
- onFetchCharacter: (Int) -> Unit,
- modifier: Modifier = Modifier,
+ onProfileEditClick: (Boolean) -> Unit,
+ onValidationChanged: (Boolean) -> Unit,
+ paddingValues: PaddingValues = PaddingValues(),
) {
val focusManager = LocalFocusManager.current
- var showBottomSheet by remember { mutableStateOf(false) }
Column(
- modifier = modifier
+ modifier = Modifier
.fillMaxSize()
.addFocusCleaner(focusManager)
+ .padding(paddingValues)
) {
- Spacer(modifier = modifier.weight(1f))
+ Spacer(modifier = Modifier.height(56.dp))
Text(
text = stringResource(id = R.string.sign_up_title),
style = TerningTheme.typography.heading2,
- modifier = modifier.padding(
- bottom = 42.dp,
- start = 24.dp
- )
+ modifier = Modifier.padding(start = 24.dp)
)
- if (showBottomSheet) {
- SignUpBottomSheet(
- onDismiss = { showBottomSheet = false },
- onSaveClick = { index ->
- showBottomSheet = false
- onFetchCharacter(index)
- },
- initialSelectedOption = signUpState.character
- )
- }
+ Spacer(modifier = Modifier.height(36.dp))
Text(
text = stringResource(id = R.string.sign_up_profile_image),
style = TerningTheme.typography.body2,
- modifier = modifier
- .padding(
- start = 24.dp,
- bottom = 20.dp
- )
+ modifier = Modifier.padding(start = 24.dp),
+ color = Grey500
)
+ Spacer(modifier = Modifier.height(20.dp))
Column(
- modifier = modifier
- .align(Alignment.CenterHorizontally)
- .padding(bottom = 52.dp)
+ modifier = Modifier.align(Alignment.CenterHorizontally)
) {
- SignUpProfile(
- modifier = modifier.noRippleClickable {
- showBottomSheet = true
+ Spacer(modifier = Modifier.height(48.dp))
+ ProfileWithPlusButton(
+ modifier = Modifier.noRippleClickable {
+ onProfileEditClick(true)
},
- index = signUpState.character
+ index = state.profileImage
)
}
Column(
- modifier = modifier
+ modifier = Modifier
.align(Alignment.CenterHorizontally)
.padding(horizontal = 24.dp)
) {
- Text(
- text = stringResource(id = R.string.sign_up_name),
- modifier = modifier.padding(bottom = 20.dp)
- )
+ Text(text = stringResource(id = R.string.sign_up_name))
+ Spacer(modifier = Modifier.height(20.dp))
NameTextField(
- value = signUpState.name,
+ value = state.name,
onValueChange = { name ->
onInputChange(name)
},
hint = stringResource(id = R.string.sign_up_hint),
- drawLineColor = signUpState.drawLineColor,
- helperMessage = signUpState.helper,
- helperIcon = signUpState.helperIcon,
- helperColor = signUpState.helperColor
+ onValidationChanged = { isValid -> onValidationChanged(isValid) }
)
}
- Spacer(modifier = modifier.weight(5f))
+ Spacer(modifier = Modifier.weight(1f))
RectangleButton(
style = TerningTheme.typography.button1,
paddingVertical = 20.dp,
text = R.string.sign_up_next_button,
onButtonClick = { onSignUpClick() },
- modifier = modifier.padding(bottom = 12.dp),
- isEnabled = signUpState.isButtonValid
+ modifier = Modifier.padding(bottom = 12.dp),
+ isEnabled = state.isButtonValid
)
}
}
@@ -167,10 +164,11 @@ fun SignUpScreen(
fun SignUpScreenPreview() {
TerningPointTheme {
SignUpScreen(
- signUpState = SignUpState(),
+ state = SignUpState(),
onSignUpClick = {},
onInputChange = {},
- onFetchCharacter = {}
+ onProfileEditClick = {},
+ onValidationChanged = {}
)
}
}
\ No newline at end of file
diff --git a/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpState.kt b/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpState.kt
index 9874f996d..5a3f8b253 100644
--- a/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpState.kt
+++ b/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpState.kt
@@ -1,18 +1,9 @@
package com.terning.feature.onboarding.signup
-import androidx.annotation.StringRes
-import androidx.compose.ui.graphics.Color
-import com.terning.core.designsystem.theme.Grey400
-import com.terning.core.designsystem.theme.Grey500
-import com.terning.feature.R
-
data class SignUpState(
val name: String = "",
- val character: Int = 0,
- val drawLineColor: Color = Grey500,
- @StringRes val helper: Int = R.string.sign_up_helper,
- val helperIcon: Int? = null,
- val helperColor: Color = Grey400,
+ val profileImage: Int = 0,
val isButtonValid: Boolean = false,
- val authId: String = ""
+ val authId: String = "",
+ val showBottomSheet: Boolean = false
)
\ No newline at end of file
diff --git a/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpViewModel.kt b/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpViewModel.kt
index 52f46f86f..504bf3ada 100644
--- a/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpViewModel.kt
+++ b/feature/src/main/java/com/terning/feature/onboarding/signup/SignUpViewModel.kt
@@ -2,10 +2,6 @@ package com.terning.feature.onboarding.signup
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
-import com.terning.core.designsystem.theme.Grey400
-import com.terning.core.designsystem.theme.Grey500
-import com.terning.core.designsystem.theme.TerningMain
-import com.terning.core.designsystem.theme.WarningRed
import com.terning.domain.entity.onboarding.SignUpRequest
import com.terning.domain.repository.AuthRepository
import com.terning.domain.repository.TokenRepository
@@ -32,59 +28,19 @@ class SignUpViewModel @Inject constructor(
private val _sideEffects = MutableSharedFlow()
val sideEffects: SharedFlow get() = _sideEffects.asSharedFlow()
- fun isInputValid(name: String) {
- val nameErrorRegex = Regex(NAME_ERROR)
- var trimmedName = ""
- var outOfBoundName = false
- if (name.length > MAX_LENGTH) {
- trimmedName = name.substring(0, MAX_LENGTH)
- outOfBoundName = true
- } else trimmedName = name
-
- when {
- nameErrorRegex.containsMatchIn(trimmedName) -> _state.value = _state.value.copy(
- name = trimmedName,
- drawLineColor = WarningRed,
- helper = R.string.sign_up_helper_error,
- helperIcon = R.drawable.ic_sign_up_error,
- helperColor = WarningRed,
- isButtonValid = false
- )
-
- trimmedName.isEmpty() || trimmedName.isBlank() -> _state.value = _state.value.copy(
- name = trimmedName,
- drawLineColor = Grey500,
- helper = R.string.sign_up_helper,
- helperIcon = null,
- helperColor = Grey400,
- isButtonValid = false
- )
-
- outOfBoundName -> _state.value = _state.value.copy(
- name = trimmedName,
- drawLineColor =WarningRed,
- helper = R.string.sign_up_helper_out,
- helperIcon = R.drawable.ic_sign_up_error,
- helperColor = WarningRed,
- isButtonValid = false
- )
+ fun updateButtonValidation(isValid: Boolean) {
+ _state.value = _state.value.copy(isButtonValid = isValid)
+ }
- else -> _state.value = _state.value.copy(
- name = trimmedName,
- drawLineColor = TerningMain,
- helper = R.string.sign_up_helper_available,
- helperIcon = R.drawable.ic_check,
- helperColor = TerningMain,
- isButtonValid = true
- )
- }
+ fun updateName(name: String) {
+ _state.value = _state.value.copy(name = name)
}
- fun fetchCharacter(character: Int) {
- _state.value = _state.value.copy(character = character)
+ fun updateProfileImage(profileImage: Int) {
+ _state.value = _state.value.copy(profileImage = profileImage)
}
- fun fetchAuthId(authId: String) {
+ fun updateAuthId(authId: String) {
_state.value = _state.value.copy(authId = authId)
}
@@ -95,7 +51,7 @@ class SignUpViewModel @Inject constructor(
state.value.run {
SignUpRequest(
name = name,
- profileImage = character,
+ profileImage = profileImage,
authType = KAKA0
)
}
@@ -113,9 +69,11 @@ class SignUpViewModel @Inject constructor(
}
}
+ fun updateBottomSheet(isVisible: Boolean) {
+ _state.value = _state.value.copy(showBottomSheet = isVisible)
+ }
+
companion object {
- const val NAME_ERROR = "[!@#\$%^&*(),.?\":{}|<>\\[\\]\\\\/\\-=+~`\\p{S}\\p{P}]"
- private const val MAX_LENGTH = 12
private const val KAKA0 = "KAKAO"
}
}
\ No newline at end of file
diff --git a/feature/src/main/java/com/terning/feature/onboarding/signup/navigation/SignUpNavigation.kt b/feature/src/main/java/com/terning/feature/onboarding/signup/navigation/SignUpNavigation.kt
index 479e02eda..34308cc81 100644
--- a/feature/src/main/java/com/terning/feature/onboarding/signup/navigation/SignUpNavigation.kt
+++ b/feature/src/main/java/com/terning/feature/onboarding/signup/navigation/SignUpNavigation.kt
@@ -1,5 +1,6 @@
package com.terning.feature.onboarding.signup.navigation
+import androidx.compose.foundation.layout.PaddingValues
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
@@ -22,14 +23,15 @@ fun NavController.navigateSignUp(
}
fun NavGraphBuilder.signUpNavGraph(
+ paddingValues: PaddingValues,
navHostController: NavHostController
) {
composable {
val args = it.toRoute()
SignUpRoute(
+ paddingValues = paddingValues,
authId = args.authId,
navigateToStartFiltering = { name -> navHostController.navigateFilteringOne(name) }
-
)
}
}
diff --git a/feature/src/main/java/com/terning/feature/onboarding/splash/SplashRoute.kt b/feature/src/main/java/com/terning/feature/onboarding/splash/SplashRoute.kt
index da523a392..ba79374e2 100644
--- a/feature/src/main/java/com/terning/feature/onboarding/splash/SplashRoute.kt
+++ b/feature/src/main/java/com/terning/feature/onboarding/splash/SplashRoute.kt
@@ -1,24 +1,28 @@
package com.terning.feature.onboarding.splash
+import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.SideEffect
import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.lifecycle.flowWithLifecycle
import com.google.accompanist.systemuicontroller.rememberSystemUiController
-import com.terning.core.designsystem.component.image.TerningImage
import com.terning.core.designsystem.theme.TerningMain
import com.terning.core.designsystem.theme.TerningPointTheme
import com.terning.feature.R
@Composable
fun SplashRoute(
+ paddingValues: PaddingValues,
navigateToHome: () -> Unit,
navigateToSignIn: () -> Unit,
viewModel: SplashViewModel = hiltViewModel(),
@@ -52,21 +56,23 @@ fun SplashRoute(
}
}
- SplashScreen()
+ SplashScreen(paddingValues = paddingValues)
}
@Composable
fun SplashScreen(
- modifier: Modifier = Modifier,
+ paddingValues: PaddingValues = PaddingValues(),
) {
Column(
- modifier = modifier
+ modifier = Modifier
+ .padding(paddingValues)
.fillMaxSize()
.background(TerningMain),
) {
- TerningImage(
- painter = R.drawable.ic_splash,
- modifier = Modifier.fillMaxSize()
+ Image(
+ painter = painterResource(id = R.drawable.ic_splash),
+ modifier = Modifier.fillMaxSize(),
+ contentDescription = "splash screen"
)
}
}
diff --git a/feature/src/main/java/com/terning/feature/onboarding/splash/navigation/SplashNavigation.kt b/feature/src/main/java/com/terning/feature/onboarding/splash/navigation/SplashNavigation.kt
index fa1610589..37dfeca9c 100644
--- a/feature/src/main/java/com/terning/feature/onboarding/splash/navigation/SplashNavigation.kt
+++ b/feature/src/main/java/com/terning/feature/onboarding/splash/navigation/SplashNavigation.kt
@@ -1,7 +1,6 @@
package com.terning.feature.onboarding.splash.navigation
-import androidx.compose.animation.EnterTransition
-import androidx.compose.animation.ExitTransition
+import androidx.compose.foundation.layout.PaddingValues
import androidx.navigation.NavController
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
@@ -21,23 +20,12 @@ fun NavController.navigateSplash(navOptions: NavOptions? = null) {
}
fun NavGraphBuilder.splashNavGraph(
+ paddingValues: PaddingValues,
navHostController: NavHostController,
) {
- composable(
- popExitTransition = {
- ExitTransition.None
- },
- exitTransition = {
- ExitTransition.None
- },
- enterTransition = {
- EnterTransition.None
- },
- popEnterTransition = {
- EnterTransition.None
- }
- ) {
+ composable {
SplashRoute(
+ paddingValues = paddingValues,
navigateToHome = {
navHostController.navigateHome(
navOptions = NavOptions.Builder().setPopUpTo(
diff --git a/feature/src/main/res/drawable/ic_my_page_notice.xml b/feature/src/main/res/drawable/ic_my_page_notice.xml
index 6f049a9e3..3e56590a0 100644
--- a/feature/src/main/res/drawable/ic_my_page_notice.xml
+++ b/feature/src/main/res/drawable/ic_my_page_notice.xml
@@ -1,26 +1,21 @@
+ android:width="22dp"
+ android:height="22dp"
+ android:viewportWidth="22"
+ android:viewportHeight="22">
+ android:pathData="M2.17,6.609H3.44V10.929H2.17C1.5,10.929 0.96,10.389 0.96,9.719V7.819C0.96,7.149 1.5,6.609 2.17,6.609Z"
+ android:fillColor="#1EAC61"/>
+ android:pathData="M12.76,20.279H11.23C10.87,20.279 10.56,19.989 10.45,19.569L7.77,8.449H10.99L13.54,18.999C13.69,19.639 13.31,20.289 12.76,20.289V20.279Z"
+ android:fillColor="#1EAC61"/>
+ android:pathData="M5.84,4.641H15.44V12.911H5.84C4.38,12.911 3.2,11.731 3.2,10.271V7.271C3.2,5.811 4.38,4.631 5.84,4.631V4.641Z"
+ android:fillColor="#65DB9B"/>
+ android:pathData="M19.75,10.291H18.78V7.261H19.75C20.59,7.261 21.27,7.941 21.27,8.781C21.27,9.621 20.59,10.301 19.75,10.301V10.291Z"
+ android:fillColor="#0D8443"/>
+ android:pathData="M13.27,4.7V12.85L19.03,15.79C19.33,15.94 19.65,15.67 19.65,15.27V2.29C19.65,1.89 19.32,1.61 19.03,1.77L13.27,4.71V4.7Z"
+ android:fillColor="#1EAC61"/>
diff --git a/feature/src/main/res/drawable/ic_my_page_opinion.xml b/feature/src/main/res/drawable/ic_my_page_opinion.xml
index 41512f23e..848db9d9a 100644
--- a/feature/src/main/res/drawable/ic_my_page_opinion.xml
+++ b/feature/src/main/res/drawable/ic_my_page_opinion.xml
@@ -1,26 +1,21 @@
+ android:width="22dp"
+ android:height="22dp"
+ android:viewportWidth="22"
+ android:viewportHeight="22">
+ android:pathData="M21.1,14.81V11.63C21.1,10 19.78,8.68 18.15,8.68H10.3C8.67,8.68 7.35,10 7.35,11.63V14.81C7.35,16.44 8.67,17.76 10.3,17.76H16.75C18.67,19.74 20.97,19.93 20.97,19.93C20.09,19.11 19.58,18.25 19.28,17.54C20.35,17.1 21.11,16.05 21.11,14.81H21.1Z"
+ android:fillColor="#1EAC61"/>
+ android:pathData="M0.9,9.26V5.53C0.9,3.62 2.57,2.07 4.62,2.07H14.52C16.57,2.07 18.24,3.62 18.24,5.53V9.26C18.24,11.17 16.57,12.72 14.52,12.72H6.4C3.98,15.04 1.08,15.27 1.08,15.27C2.19,14.31 2.83,13.3 3.21,12.46C1.86,11.94 0.9,10.71 0.9,9.26Z"
+ android:fillColor="#65DB9B"/>
+ android:pathData="M9.63,8.379C10.072,8.379 10.43,8.021 10.43,7.579C10.43,7.137 10.072,6.779 9.63,6.779C9.188,6.779 8.83,7.137 8.83,7.579C8.83,8.021 9.188,8.379 9.63,8.379Z"
+ android:fillColor="#1EAC61"/>
+ android:pathData="M12.71,8.379C13.152,8.379 13.51,8.021 13.51,7.579C13.51,7.137 13.152,6.779 12.71,6.779C12.268,6.779 11.91,7.137 11.91,7.579C11.91,8.021 12.268,8.379 12.71,8.379Z"
+ android:fillColor="#1EAC61"/>
+ android:pathData="M6.55,8.379C6.992,8.379 7.35,8.021 7.35,7.579C7.35,7.137 6.992,6.779 6.55,6.779C6.108,6.779 5.75,7.137 5.75,7.579C5.75,8.021 6.108,8.379 6.55,8.379Z"
+ android:fillColor="#1EAC61"/>
diff --git a/feature/src/main/res/drawable/ic_my_page_personal.xml b/feature/src/main/res/drawable/ic_my_page_personal.xml
new file mode 100644
index 000000000..62f540bf0
--- /dev/null
+++ b/feature/src/main/res/drawable/ic_my_page_personal.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
diff --git a/feature/src/main/res/drawable/ic_my_page_service.xml b/feature/src/main/res/drawable/ic_my_page_service.xml
new file mode 100644
index 000000000..ea3583ef0
--- /dev/null
+++ b/feature/src/main/res/drawable/ic_my_page_service.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
diff --git a/feature/src/main/res/drawable/ic_my_page_version.xml b/feature/src/main/res/drawable/ic_my_page_version.xml
index f264846fb..1d70ec4c2 100644
--- a/feature/src/main/res/drawable/ic_my_page_version.xml
+++ b/feature/src/main/res/drawable/ic_my_page_version.xml
@@ -1,34 +1,21 @@
+ android:width="22dp"
+ android:height="22dp"
+ android:viewportWidth="22"
+ android:viewportHeight="22">
+ android:pathData="M15.21,0.711H6.79C5.244,0.711 3.99,1.965 3.99,3.511V18.491C3.99,20.037 5.244,21.291 6.79,21.291H15.21C16.756,21.291 18.01,20.037 18.01,18.491V3.511C18.01,1.965 16.756,0.711 15.21,0.711Z"
+ android:fillColor="#1EAC61"/>
+ android:pathData="M15.73,3.85H6.28C5.855,3.85 5.51,4.194 5.51,4.62V16.19C5.51,16.615 5.855,16.96 6.28,16.96H15.73C16.155,16.96 16.5,16.615 16.5,16.19V4.62C16.5,4.194 16.155,3.85 15.73,3.85Z"
+ android:fillColor="#65DB9B"/>
+ android:pathData="M8.38,2.6C8.656,2.6 8.88,2.376 8.88,2.1C8.88,1.823 8.656,1.6 8.38,1.6C8.104,1.6 7.88,1.823 7.88,2.1C7.88,2.376 8.104,2.6 8.38,2.6Z"
+ android:fillColor="#0D8443"/>
+ android:pathData="M13.62,1.6H9.97C9.694,1.6 9.47,1.823 9.47,2.1C9.47,2.376 9.694,2.6 9.97,2.6H13.62C13.896,2.6 14.12,2.376 14.12,2.1C14.12,1.823 13.896,1.6 13.62,1.6Z"
+ android:fillColor="#0D8443"/>
-
-
+ android:pathData="M11,20.511C11.635,20.511 12.15,19.996 12.15,19.361C12.15,18.726 11.635,18.211 11,18.211C10.365,18.211 9.85,18.726 9.85,19.361C9.85,19.996 10.365,20.511 11,20.511Z"
+ android:fillColor="#0D8443"/>
diff --git a/feature/src/main/res/drawable/ic_terning_profile_00.xml b/feature/src/main/res/drawable/ic_terning_profile_00.xml
index f34f8769c..99edfdf96 100644
--- a/feature/src/main/res/drawable/ic_terning_profile_00.xml
+++ b/feature/src/main/res/drawable/ic_terning_profile_00.xml
@@ -1,137 +1,60 @@
-
-
-
-
-
-
-
+ android:width="76dp"
+ android:height="76dp"
+ android:viewportWidth="76"
+ android:viewportHeight="76">
+ android:pathData="M38,0L38,0A38,38 0,0 1,76 38L76,38A38,38 0,0 1,38 76L38,76A38,38 0,0 1,0 38L0,38A38,38 0,0 1,38 0z"/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:pathData="M76,0H0V76H76V0Z"
+ android:fillColor="#FBF8CB"/>
-
-
-
-
+ android:pathData="M57.95,77.966L67.64,49.542C68.314,47.472 67.574,45.192 65.807,43.909L41.971,26.59C40.204,25.308 37.819,25.308 36.053,26.59L12.217,43.909C10.45,45.192 9.718,47.462 10.384,49.542L19.494,77.567C20.169,79.638 22.097,81.045 24.282,81.045H53.751"
+ android:fillColor="#ffffff"/>
-
-
-
-
-
-
+ android:pathData="M57.95,77.966L67.64,49.542C68.314,47.472 67.574,45.192 65.807,43.909L41.971,26.59C40.204,25.308 37.819,25.308 36.053,26.59L12.217,43.909C10.45,45.192 9.718,47.462 10.384,49.542L19.494,77.567C20.169,79.638 22.097,81.045 24.282,81.045H53.751"
+ android:strokeWidth="1.425"
+ android:fillColor="#00000000"
+ android:strokeColor="#171717"
+ android:strokeLineCap="round"/>
+
+
+
+
+
+
+
+
+ android:pathData="M35.444,53.884C35.444,53.884 36.243,55.613 38.114,55.613C39.986,55.613 40.565,53.884 40.565,53.884"
+ android:strokeWidth="1.425"
+ android:fillColor="#00000000"
+ android:strokeColor="#171717"
+ android:strokeLineCap="round"/>
-
diff --git a/feature/src/main/res/drawable/ic_terning_profile_01.xml b/feature/src/main/res/drawable/ic_terning_profile_01.xml
index 557c169b6..0bfcc7b29 100644
--- a/feature/src/main/res/drawable/ic_terning_profile_01.xml
+++ b/feature/src/main/res/drawable/ic_terning_profile_01.xml
@@ -1,132 +1,80 @@
-
-
-
-
-
-
+ android:width="76dp"
+ android:height="76dp"
+ android:viewportWidth="76"
+ android:viewportHeight="76">
+ android:pathData="M38,0L38,0A38,38 0,0 1,76 38L76,38A38,38 0,0 1,38 76L38,76A38,38 0,0 1,0 38L0,38A38,38 0,0 1,38 0z"/>
+ android:pathData="M76,0H0V76H76V0Z"
+ android:fillColor="#ECF9CA"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/feature/src/main/res/drawable/ic_terning_profile_02.xml b/feature/src/main/res/drawable/ic_terning_profile_02.xml
index 1ad3e5dd8..8ba5ffc15 100644
--- a/feature/src/main/res/drawable/ic_terning_profile_02.xml
+++ b/feature/src/main/res/drawable/ic_terning_profile_02.xml
@@ -1,98 +1,75 @@
-
-
-
-
-
-
+ android:width="76dp"
+ android:height="76dp"
+ android:viewportWidth="76"
+ android:viewportHeight="76">
+ android:pathData="M38,0L38,0A38,38 0,0 1,76 38L76,38A38,38 0,0 1,38 76L38,76A38,38 0,0 1,0 38L0,38A38,38 0,0 1,38 0z"/>
+ android:pathData="M76,0H0V76H76V0Z"
+ android:fillColor="#D4F9DE"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/feature/src/main/res/drawable/ic_terning_profile_03.xml b/feature/src/main/res/drawable/ic_terning_profile_03.xml
index fc45cad6a..25e878efb 100644
--- a/feature/src/main/res/drawable/ic_terning_profile_03.xml
+++ b/feature/src/main/res/drawable/ic_terning_profile_03.xml
@@ -1,131 +1,76 @@
-
-
-
-
-
+ android:width="76dp"
+ android:height="76dp"
+ android:viewportWidth="76"
+ android:viewportHeight="76">
+ android:pathData="M38,0L38,0A38,38 0,0 1,76 38L76,38A38,38 0,0 1,38 76L38,76A38,38 0,0 1,0 38L0,38A38,38 0,0 1,38 0z"/>
+ android:pathData="M76.209,0H0.209V76H76.209V0Z"
+ android:fillColor="#C5DEF2"/>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/feature/src/main/res/drawable/ic_terning_profile_04.xml b/feature/src/main/res/drawable/ic_terning_profile_04.xml
index 228909ea8..8b27c5c6c 100644
--- a/feature/src/main/res/drawable/ic_terning_profile_04.xml
+++ b/feature/src/main/res/drawable/ic_terning_profile_04.xml
@@ -1,150 +1,74 @@
+ android:width="76dp"
+ android:height="76dp"
+ android:viewportWidth="76"
+ android:viewportHeight="76">
+ android:pathData="M76,0H0V76H76V0Z"
+ android:fillColor="#E9F1E4"/>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ android:pathData="M64.676,32.956H11.324V85.035H64.676V32.956Z"
+ android:strokeLineJoin="round"
+ android:strokeWidth="1.425"
+ android:fillColor="#ffffff"
+ android:strokeColor="#171717"
+ android:strokeLineCap="round"/>
+ android:pathData="M31.663,53.447C31.663,53.779 31.616,54.131 31.502,54.416C31.388,54.701 31.036,54.872 30.808,55.1C30.58,55.328 30.409,55.623 30.105,55.746C29.801,55.869 29.488,55.841 29.155,55.841C28.823,55.841 28.509,55.822 28.224,55.699C27.939,55.575 27.654,55.395 27.426,55.167C27.198,54.938 26.999,54.682 26.875,54.378C26.752,54.074 26.638,53.761 26.638,53.438C26.638,53.114 26.837,52.811 26.961,52.526C27.084,52.241 27.274,52.003 27.502,51.775C27.73,51.547 27.939,51.319 28.234,51.195C28.528,51.072 28.832,51.072 29.165,51.072C29.497,51.072 29.801,51.082 30.086,51.205C30.371,51.328 30.647,51.509 30.875,51.728C31.103,51.946 31.293,52.212 31.416,52.507C31.54,52.801 31.682,53.105 31.682,53.438L31.663,53.447Z"
+ android:fillColor="#F9DBDE"/>
+ android:pathData="M31.663,53.447C31.663,53.779 31.616,54.131 31.502,54.416C31.388,54.701 31.036,54.872 30.808,55.1C30.58,55.328 30.409,55.623 30.105,55.746C29.801,55.869 29.488,55.841 29.155,55.841C28.823,55.841 28.509,55.822 28.224,55.699C27.939,55.575 27.654,55.395 27.426,55.167C27.198,54.938 26.999,54.682 26.875,54.378C26.752,54.074 26.638,53.761 26.638,53.438C26.638,53.114 26.837,52.811 26.961,52.526C27.084,52.241 27.274,52.003 27.502,51.775C27.73,51.547 27.939,51.319 28.234,51.195C28.528,51.072 28.832,51.072 29.165,51.072C29.497,51.072 29.801,51.082 30.086,51.205C30.371,51.328 30.647,51.509 30.875,51.728C31.103,51.946 31.293,52.212 31.416,52.507C31.54,52.801 31.682,53.105 31.682,53.438L31.663,53.447Z"
+ android:strokeWidth="0.7315"
+ android:fillColor="#00000000"
+ android:strokeColor="#F9DBDE"/>
+ android:pathData="M49.343,53.267C49.343,53.599 49.267,53.932 49.143,54.226C49.02,54.521 48.839,54.825 48.611,55.043C48.383,55.262 48.079,55.433 47.785,55.556C47.49,55.68 47.167,55.651 46.835,55.651C46.502,55.651 46.217,55.585 45.923,55.461C45.628,55.338 45.267,55.281 45.049,55.053C44.83,54.825 44.669,54.511 44.545,54.217C44.422,53.922 44.422,53.599 44.422,53.267C44.422,52.934 44.45,52.611 44.564,52.326C44.678,52.041 44.897,51.775 45.125,51.557C45.353,51.338 45.638,51.215 45.932,51.091C46.227,50.968 46.502,50.92 46.835,50.92C47.167,50.92 47.49,50.863 47.785,50.987C48.079,51.11 48.355,51.3 48.583,51.528C48.811,51.756 49.01,52.022 49.134,52.326C49.257,52.63 49.343,52.944 49.343,53.276V53.267Z"
+ android:fillColor="#F9DBDE"/>
+ android:strokeColor="#F9DBDE"/>
+ android:pathData="M37.506,63.441H38.598C38.988,63.441 39.32,63.707 39.396,64.077L41.762,75.8C41.828,76.199 41.705,76.608 41.42,76.902L39.016,79.372C38.503,79.895 37.648,79.914 37.126,79.401L34.618,76.978C34.314,76.684 34.171,76.256 34.247,75.838L36.717,64.077C36.793,63.707 37.126,63.441 37.515,63.441H37.506Z"
+ android:strokeWidth="1.425"
+ android:fillColor="#A6B7FF"
+ android:strokeColor="#171717"/>
+ android:pathData="M39.168,63.907H36.955C36.518,63.907 36.147,63.603 36.053,63.185L35.54,60.952C35.407,60.373 35.853,59.812 36.442,59.812H39.701C40.299,59.812 40.745,60.373 40.603,60.952L40.071,63.185C39.976,63.603 39.596,63.897 39.168,63.897V63.907Z"
+ android:strokeWidth="1.425"
+ android:fillColor="#A6B7FF"
+ android:strokeColor="#171717"/>
+ android:pathData="M34.818,52.497C35.384,52.497 35.843,51.791 35.843,50.92C35.843,50.049 35.384,49.343 34.818,49.343C34.251,49.343 33.792,50.049 33.792,50.92C33.792,51.791 34.251,52.497 34.818,52.497Z"
+ android:fillColor="#171717"/>
+ android:pathData="M41.182,52.497C41.749,52.497 42.208,51.791 42.208,50.92C42.208,50.049 41.749,49.343 41.182,49.343C40.616,49.343 40.157,50.049 40.157,50.92C40.157,51.791 40.616,52.497 41.182,52.497Z"
+ android:fillColor="#171717"/>
+
diff --git a/feature/src/main/res/drawable/ic_terning_profile_05.xml b/feature/src/main/res/drawable/ic_terning_profile_05.xml
index 2d21f7990..9a32c789e 100644
--- a/feature/src/main/res/drawable/ic_terning_profile_05.xml
+++ b/feature/src/main/res/drawable/ic_terning_profile_05.xml
@@ -1,111 +1,73 @@
-
-
-
-
+ android:width="76dp"
+ android:height="76dp"
+ android:viewportWidth="76"
+ android:viewportHeight="76">
+ android:pathData="M38,0L38,0A38,38 0,0 1,76 38L76,38A38,38 0,0 1,38 76L38,76A38,38 0,0 1,0 38L0,38A38,38 0,0 1,38 0z"/>
+ android:pathData="M76,0H0V76H76V0Z"
+ android:fillColor="#E6FFF6"/>
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/feature/src/main/res/drawable/ic_view_count_14.xml b/feature/src/main/res/drawable/ic_view_count_14.xml
new file mode 100644
index 000000000..3f6e68ef5
--- /dev/null
+++ b/feature/src/main/res/drawable/ic_view_count_14.xml
@@ -0,0 +1,20 @@
+
+
+
+
diff --git a/feature/src/main/res/values/strings.xml b/feature/src/main/res/values/strings.xml
index 9f970dce3..e258ad031 100644
--- a/feature/src/main/res/values/strings.xml
+++ b/feature/src/main/res/values/strings.xml
@@ -23,10 +23,6 @@
이름
이름을 입력해 주세요
다음으로
- 12자리 이내, 문자/숫자 가능, 특수문자/기호 입력불가
- 이름에 특수문자는 입력할 수 없어요
- 사용 가능한 이름이에요
- 이름은 12자리 이내로 설정해 주세요
관심있는 인턴 공고 키워드를 검색해 보세요
@@ -137,16 +133,15 @@
공유 아이콘
지원 사이트로 이동하기
공고 정보
- 조회수
%s회
서류 마감
근무 기간
근무 시작
- 공고 정보
공고 요약
+ 자격 요건
상세 정보
- 자격요건
- 직무
+ 모집대상
+ 모집직무
관심 공고가 캘린더에 스크랩되었어요!
관심 공고가 캘린더에서 사라졌어요!
@@ -155,12 +150,17 @@
탈퇴하기
프로필 수정
터닝 커뮤니티
- 공지사항
+ 공지사항
의견보내기
서비스 정보
- 서비스 이용약관
- 개인정보 처리방침
+ 서비스 이용약관
+ 개인정보 처리방침
버전정보
+
+ 프로필 수정
+ 저장하기
+ 연동 계정
+