Skip to content

Commit

Permalink
Merge pull request #27 from Noostak/feature/#25-mypage-ui
Browse files Browse the repository at this point in the history
[Feature/#25] 마이페이지 UI 구현
  • Loading branch information
Eonji-sw authored Jan 22, 2025
2 parents 83a4679 + c579be3 commit cefb4e7
Show file tree
Hide file tree
Showing 24 changed files with 667 additions and 148 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ fun NoostakCategoryChip(

NoostakChip(
text = text,
textStyle = NoostakTheme.typography.c2SemiBold,
textStyle = NoostakTheme.typography.c3SemiBold,
textColor = NoostakTheme.colors.white,
backgroundColor = resolvedBackgroundColor,
borderColor = Color.Transparent,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
package com.sopt.core.designsystem.component.dialog

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Card
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Text
import androidx.compose.material3.VerticalDivider
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.res.dimensionResource
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.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import com.sopt.core.R
import com.sopt.core.designsystem.theme.NoostakAndroidTheme
import com.sopt.core.designsystem.theme.NoostakTheme
import com.sopt.core.type.DialogType
import com.sopt.core.util.NoRippleInteractionSource

@Composable
fun NoostakDialog(
dialogType: DialogType,
onClick: () -> Unit = {},
onDismissRequest: () -> Unit = {}
) {
Dialog(
onDismissRequest = { onDismissRequest() },
properties = DialogProperties(
dismissOnBackPress = true,
dismissOnClickOutside = true
)
) {
Card(
shape = RoundedCornerShape(dimensionResource(id = R.dimen.dialog_radius))
) {
Column(
modifier = Modifier
.width(274.dp)
.wrapContentHeight()
.background(
color = NoostakTheme.colors.white
),
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(
modifier = Modifier.height(
when (dialogType) {
DialogType.LOGOUT -> 41.dp
DialogType.WITHDRAWAL -> 30.dp
else -> 24.dp
}
)
)
Text(
text = stringResource(dialogType.content),
textAlign = TextAlign.Center,
style = if (dialogType == DialogType.LOGOUT || dialogType == DialogType.WITHDRAWAL) {
NoostakTheme.typography.b4Regular
} else {
NoostakTheme.typography.c3Regular
}
)
Spacer(
modifier = Modifier.height(
when (dialogType) {
DialogType.LOGOUT -> 36.dp
DialogType.WITHDRAWAL -> 26.dp
else -> 20.dp
}
)
)
HorizontalDivider(
modifier = Modifier.fillMaxWidth(),
color = NoostakTheme.colors.gray200,
thickness = 1.dp
)
Row(
modifier = Modifier
.fillMaxWidth()
.height(IntrinsicSize.Min) // Row의 높이를 내부 컴포넌트에 맞춤
) {
Button(
onClick = { onDismissRequest() },
shape = RectangleShape,
modifier = Modifier
.weight(1f)
.fillMaxHeight(),
colors = ButtonDefaults.buttonColors(
containerColor = NoostakTheme.colors.white,
contentColor = NoostakTheme.colors.gray900,
disabledContainerColor = NoostakTheme.colors.white,
disabledContentColor = NoostakTheme.colors.gray900
),
interactionSource = NoRippleInteractionSource
) {
Text(
text = stringResource(dialogType.dismissText),
textAlign = TextAlign.Center,
style = NoostakTheme.typography.c3SemiBold
)
}

VerticalDivider(
modifier = Modifier.fillMaxHeight(),
color = NoostakTheme.colors.gray200,
thickness = 1.dp
)

Button(
onClick = { onClick() },
shape = RectangleShape,
modifier = Modifier
.weight(1f)
.fillMaxHeight(),
colors = ButtonDefaults.buttonColors(
containerColor = NoostakTheme.colors.white,
contentColor = NoostakTheme.colors.gray900,
disabledContainerColor = NoostakTheme.colors.white,
disabledContentColor = NoostakTheme.colors.gray900
),
interactionSource = NoRippleInteractionSource
) {
Text(
text = stringResource(dialogType.confirmText),
textAlign = TextAlign.Center,
style = NoostakTheme.typography.c3SemiBold,
color = NoostakTheme.colors.blue
)
}
}
}
}
}
}

@Preview(showBackground = true)
@Composable
fun NoostakDialogPreview() {
NoostakAndroidTheme {
NoostakDialog(dialogType = DialogType.LOGOUT, onClick = {}, onDismissRequest = {})
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.sopt.core.designsystem.component.textfield

import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
Expand Down Expand Up @@ -36,6 +36,7 @@ import com.sopt.core.R
import com.sopt.core.designsystem.theme.NoostakAndroidTheme
import com.sopt.core.designsystem.theme.NoostakTheme
import com.sopt.core.type.TextFieldType
import com.sopt.core.util.NoRippleInteractionSource

@Composable
fun NoostakTextField(
Expand All @@ -44,9 +45,10 @@ fun NoostakTextField(
onValueChange: (String) -> Unit = { _ -> },
placeholderColor: Color = NoostakTheme.colors.gray600,
textStyle: TextStyle = NoostakTheme.typography.b5Regular,
lengthTextStyle: TextStyle = NoostakTheme.typography.b5Regular,
shape: Shape = RoundedCornerShape(6.dp),
cursorColor: Color = NoostakTheme.colors.gray600,
focusedBorderColor: Color = NoostakTheme.colors.gray900,
focusedBorderColor: Color = NoostakTheme.colors.blue600,
unfocusedWithInputBorderColor: Color = NoostakTheme.colors.gray700,
unfocusedBorderColor: Color = NoostakTheme.colors.gray500,
maxLength: Int = 30,
Expand All @@ -56,6 +58,9 @@ fun NoostakTextField(
keyboardActions: KeyboardActions = KeyboardActions.Default
) {
var isFocused by remember { mutableStateOf(false) }
var hasInvalidInput by remember { mutableStateOf(false) }

val validInputRegex = "^[a-zA-Z0-9가-힣]*$".toRegex()

Column {
Box(
Expand All @@ -64,6 +69,7 @@ fun NoostakTextField(
.border(
width = 1.dp,
color = when {
hasInvalidInput -> NoostakTheme.colors.red02
isFocused -> focusedBorderColor // 포커스된 경우
value.isNotEmpty() -> unfocusedWithInputBorderColor // 텍스트가 입력되고 포커스 안된 경우
else -> unfocusedBorderColor // 포커스되지 않은 경우
Expand All @@ -78,10 +84,16 @@ fun NoostakTextField(
value = value,
textStyle = textStyle,
onValueChange = { newValue ->
if (newValue.replace(" ", "").length <= maxLength) {
onValueChange(
newValue
)
if (textFieldType != TextFieldType.SIGNUP) {
if (newValue.replace(" ", "").length <= maxLength) {
onValueChange(newValue)
}
} else {
hasInvalidInput = !validInputRegex.matches(newValue)

if (newValue.length <= maxLength) {
onValueChange(newValue)
}
}
},
placeholder = {
Expand Down Expand Up @@ -118,7 +130,8 @@ fun NoostakTextField(
modifier = Modifier
.padding(end = 12.dp)
.size(24.dp),
onClick = { onValueChange("") }
onClick = { onValueChange("") },
interactionSource = NoRippleInteractionSource
) {
Icon(
painter = painterResource(id = R.drawable.ic_text_field_delete),
Expand All @@ -131,25 +144,27 @@ fun NoostakTextField(
}

Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
modifier = Modifier.fillMaxWidth()
) {
Text(
text = if (textFieldType == TextFieldType.SIGNUP) stringResource(R.string.text_noostak_text_field_sign_up_example) else "",
color = NoostakTheme.colors.gray800,
style = NoostakTheme.typography.b5Regular,
modifier = modifier.padding(top = 6.dp),
maxLines = 1
)
if (textFieldType == TextFieldType.SIGNUP && hasInvalidInput) {
Text(
text = stringResource(R.string.text_noostak_text_field_sign_up_condition),
color = NoostakTheme.colors.red02,
style = NoostakTheme.typography.c3SemiBold,
modifier = modifier.padding(top = 6.dp),
maxLines = 1
)
}

Spacer(modifier = Modifier.weight(1f))
Text(
text = stringResource(
R.string.text_noostak_text_field_count,
value.length,
maxLength
),
color = NoostakTheme.colors.gray800,
style = NoostakTheme.typography.b5Regular,
style = lengthTextStyle,
modifier = modifier.padding(top = 6.dp),
maxLines = 1
)
Expand All @@ -161,8 +176,6 @@ fun NoostakTextField(
@Composable
fun NoostakTextFieldPreview() {
NoostakAndroidTheme {
Column {
NoostakTextField(textFieldType = TextFieldType.GROUP, value = "누스탁")
}
NoostakTextField(textFieldType = TextFieldType.SIGNUP, value = "누스탁")
}
}
12 changes: 6 additions & 6 deletions core/src/main/java/com/sopt/core/designsystem/theme/Type.kt
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class NoostakTypography internal constructor(
b4Regular: TextStyle,
b5Regular: TextStyle,
c1Bold: TextStyle,
c2SemiBold: TextStyle,
c3SemiBold: TextStyle,
c3Regular: TextStyle,
c4Regular: TextStyle
) {
Expand Down Expand Up @@ -86,7 +86,7 @@ class NoostakTypography internal constructor(
private set
var c1Bold: TextStyle by mutableStateOf(c1Bold)
private set
var c2SemiBold: TextStyle by mutableStateOf(c2SemiBold)
var c3SemiBold: TextStyle by mutableStateOf(c3SemiBold)
private set
var c3Regular: TextStyle by mutableStateOf(c3Regular)
private set
Expand All @@ -113,7 +113,7 @@ class NoostakTypography internal constructor(
b4Regular: TextStyle = this.b4Regular,
b5Regular: TextStyle = this.b5Regular,
c1Bold: TextStyle = this.c1Bold,
c2SemiBold: TextStyle = this.c2SemiBold,
c3SemiBold: TextStyle = this.c3SemiBold,
c3Regular: TextStyle = this.c3Regular,
c4Regular: TextStyle = this.c4Regular
): NoostakTypography = NoostakTypography(
Expand All @@ -136,7 +136,7 @@ class NoostakTypography internal constructor(
b4Regular = b4Regular,
b5Regular = b5Regular,
c1Bold = c1Bold,
c2SemiBold = c2SemiBold,
c3SemiBold = c3SemiBold,
c3Regular = c3Regular,
c4Regular = c4Regular
)
Expand All @@ -161,7 +161,7 @@ class NoostakTypography internal constructor(
b4Regular = other.b4Regular
b5Regular = other.b5Regular
c1Bold = other.c1Bold
c2SemiBold = other.c2SemiBold
c3SemiBold = other.c3SemiBold
c3Regular = other.c3Regular
c4Regular = other.c4Regular
}
Expand Down Expand Up @@ -304,7 +304,7 @@ fun noostakTypography(): NoostakTypography {
fontSize = 13.sp,
lineHeight = 18.sp
),
c2SemiBold = noostakTextStyle(
c3SemiBold = noostakTextStyle(
fontFamily = PretendardSemiBold,
fontWeight = FontWeight.SemiBold,
fontSize = 13.sp,
Expand Down
36 changes: 36 additions & 0 deletions core/src/main/java/com/sopt/core/type/DialogType.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.sopt.core.type

import androidx.annotation.StringRes
import com.sopt.core.R

enum class DialogType(
@StringRes val content: Int,
@StringRes val dismissText: Int,
@StringRes val confirmText: Int
) {
LOGIN_KAKAO(
content = R.string.text_dialog_type_login_kakao_content,
dismissText = R.string.text_dialog_type_dismiss_cancel,
confirmText = R.string.text_dialog_type_confirm_retry
),
LOGIN_GOOGLE(
content = R.string.text_dialog_type_login_google_content,
dismissText = R.string.text_dialog_type_dismiss_cancel,
confirmText = R.string.text_dialog_type_confirm_retry
),
GROUP(
content = R.string.text_dialog_type_group_content,
dismissText = R.string.text_dialog_type_dismiss_cancel,
confirmText = R.string.text_dialog_type_confirm_retry
),
LOGOUT(
content = R.string.text_dialog_type_logout_content,
dismissText = R.string.text_dialog_type_dismiss_cancel,
confirmText = R.string.text_dialog_type_confirm_logout
),
WITHDRAWAL(
content = R.string.text_dialog_type_withdrawal_content,
dismissText = R.string.text_dialog_type_dismiss_cancel,
confirmText = R.string.text_dialog_type_confirm_withdrawal
)
}
2 changes: 2 additions & 0 deletions core/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@
<dimen name="appbar_height">48dp</dimen>
<dimen name="appbar_start_padding">8dp</dimen>

<dimen name="dialog_radius">20dp</dimen>

</resources>
Loading

0 comments on commit cefb4e7

Please sign in to comment.