Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
f7703c6
[Refactor] 이메일 로그인 컴포즈 적용 시작
language7606 Dec 26, 2024
cb1f06e
[Refactor] 이메일 로그인 컴포즈 적용 시작
language7606 Dec 27, 2024
ebfcf93
[Refactor] 소셜로그인 리팩토링
language7606 Dec 27, 2024
e968b8d
[Refactor] EmailLoginScreen 의 매개변수 추가
language7606 Dec 27, 2024
6746567
[Refactor] EmailLoginLoading 컴포넌트 구현
language7606 Dec 27, 2024
3389623
[Refactor] EmailLoginScrollArrow 컴포넌트 구현
language7606 Dec 27, 2024
beb7768
[Refactor] EmailTextField 컴포넌트 구현
language7606 Dec 27, 2024
80dfa4b
[Refactor] PasswordTextField 컴포넌트 구현
language7606 Dec 27, 2024
12ec8af
[Refactor] EmailAutoLoginCheckBox 구현
language7606 Dec 28, 2024
6e4138d
[Refactor] 이메일찾기와 비밀번호 찾기 버튼 구현
language7606 Dec 28, 2024
6613309
[Refactor] 축약했던 프래그먼트 이름 풀어서 작성
language7606 Dec 28, 2024
a05c9bc
[Refactor] EmailLoginScreen 에 각 컴포넌트 반영 및 화면 전환 상태 전달 구현.
language7606 Dec 28, 2024
79a3637
[Refactor] social, email 패키지를 잘못 참조하고 있는 dpToSp 함수 조정
language7606 Dec 28, 2024
fc7e1df
[Refactor] social, email 패키지를 잘못 참조하고 있는 dpToSp 함수 조정
language7606 Dec 28, 2024
b52291e
[Refactor] 이메일 로그인 버튼 컴포넌트 생성
language7606 Dec 28, 2024
54b0655
[Refactor] 돌아가기 버튼 컴포넌트 생성
language7606 Dec 28, 2024
0c05490
[Refactor] 회원가입 버튼 컴포넌트 생성
language7606 Dec 28, 2024
06f9998
[Refactor] EmailLoginScreen에 각 컴포넌트 적용
language7606 Dec 28, 2024
937a4a6
[Refactor] 로딩 화면 테스트용 프리뷰 생성
language7606 Dec 28, 2024
95e7fd2
[Refactor] 이메일로그인 뷰모델 관찰코드 컴포즈로 변경
language7606 Jan 2, 2025
f2e8f2c
[Refactor] 이메일로그인 Modifier 계층 적용
language7606 Jan 11, 2025
08c3ad8
[Refactor] Modifier 및 컴포넌트 수정
language7606 Jan 23, 2025
8e5905d
[Refactor] 컴포넌트 구조 수정
language7606 Jan 24, 2025
da626a8
[Refactor] 뷰바인딩 코드 제거 및 뷰모델 관련 코드 컴포즈로 전환
language7606 Mar 22, 2025
35c1981
[Refactor] EamilLoginScreen에 ViewModel 적용
language7606 Mar 22, 2025
9180015
[Refactor] AnimateEnterExit 와 DpToSp 파일 분리
language7606 Mar 24, 2025
a37a02f
[Refactor] 백그라운드 컬러 화이트 적용
language7606 Mar 24, 2025
8e908b2
[chore] 이전 팀원들 PR 적용
language7606 Mar 24, 2025
6bc3b63
Merge branch 'improve' of https://github.com/APP-Android2/FinalProjec…
language7606 Mar 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package kr.co.lion.modigm.ui.login.component

import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Clear
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat
import kr.co.lion.modigm.R
import kr.co.lion.modigm.ui.login.util.dpToSp

@Composable
fun EmailTextField(
modifier: Modifier = Modifier,
userEmail: String,
onValueChange: (String) -> Unit,
placeholder: @Composable () -> Unit,
errorMessage: String = ""
) {
val isEmailInputError = errorMessage != ""
val pointColor = Color(ContextCompat.getColor(LocalContext.current, R.color.pointColor))

OutlinedTextField(
modifier = modifier,
value = userEmail,
onValueChange = { onValueChange(it) },
textStyle = LocalTextStyle.current.copy(fontSize = dpToSp(16.dp)),
colors = TextFieldDefaults.colors(
focusedTextColor = Color.Black,
unfocusedTextColor = Color.Black,
focusedContainerColor = Color.White,
unfocusedContainerColor = Color.White,
focusedIndicatorColor = pointColor,
unfocusedIndicatorColor = Color.Black,
errorContainerColor = Color.White,
),
placeholder = placeholder,
leadingIcon = {
Icon(
painter = painterResource(id = R.drawable.icon_mail_24px),
contentDescription = "이메일 리딩 아이콘"
)
},
trailingIcon = {
if (userEmail.isNotEmpty()) {
IconButton(
onClick = { onValueChange("") }
) {
Icon(
imageVector = Icons.Default.Clear,
contentDescription = "이메일 초기화 아이콘"
)
}
}
},
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Email,
imeAction = ImeAction.Next,
),
singleLine = true,
isError = isEmailInputError,
)
if (isEmailInputError) {
Text(
text = errorMessage,
color = Color.Red,
fontSize = dpToSp(12.dp),
modifier = Modifier.padding(start = 16.dp, top = 4.dp)
)
}
}

@Preview(showBackground = true)
@Composable
fun EmailTextFieldPreview() {
EmailTextField(
userEmail = "",
onValueChange = {},
placeholder = {}
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package kr.co.lion.modigm.ui.login.component

import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable

@Composable
fun ErrorAlertDialog(
title: String,
message: String,
confirmButtonText: String = "확인",
onConfirmClick: () -> Unit,
onDismissRequest: () -> Unit = {},
dismissOnBackPress: Boolean = false,
dismissOnClickOutside: Boolean = false,
) {
AlertDialog(
onDismissRequest = {
if (dismissOnBackPress || dismissOnClickOutside) {
onDismissRequest()
}
},
title = { Text(text = title) },
text = { Text(text = message) },
confirmButton = {
TextButton(onClick = {
onConfirmClick()
onDismissRequest()
}) {
Text(text = confirmButtonText)
}
}
)
}
Original file line number Diff line number Diff line change
@@ -1,29 +1,34 @@
package kr.co.lion.modigm.ui.login.social.component
package kr.co.lion.modigm.ui.login.component

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.tooling.preview.Preview

@Composable
fun SocialLoginLoading(
fun LoginLoading(
modifier: Modifier = Modifier,
isLoading: Boolean
) {
if (isLoading) {
Box(
modifier = modifier
.fillMaxSize()
.background(Color.Black.copy(alpha = 0.5f))
.pointerInput(Unit) { },
contentAlignment = Alignment.Center
) {
CircularProgressIndicator(color = Color.White)
}
}
}

@Preview(showBackground = true)
@Composable
fun LoginLoadingPreview() {
LoginLoading(isLoading = true)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package kr.co.lion.modigm.ui.login.component

import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Visibility
import androidx.compose.material.icons.filled.VisibilityOff
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat
import kr.co.lion.modigm.R
import kr.co.lion.modigm.ui.login.util.dpToSp

@Composable
fun PasswordTextField(
modifier: Modifier = Modifier,
userPassword: String,
onValueChange: (String) -> Unit,
placeholder: @Composable () -> Unit,
errorMessage: String = ""
) {
var isPasswordVisible by remember { mutableStateOf(false) }
val pointColor = Color(ContextCompat.getColor(LocalContext.current, R.color.pointColor))
val isPasswordInputError = errorMessage != ""

OutlinedTextField(
modifier = modifier,
value = userPassword,
onValueChange = {
onValueChange(it)
isPasswordVisible = it.isEmpty()
},
textStyle = LocalTextStyle.current.copy(fontSize = dpToSp(16.dp)),
colors = TextFieldDefaults.colors(
focusedTextColor = Color.Black,
unfocusedTextColor = Color.Black,
focusedContainerColor = Color.White,
unfocusedContainerColor = Color.White,
focusedIndicatorColor = pointColor,
unfocusedIndicatorColor = Color.Black,
errorContainerColor = Color.White,
),
placeholder = placeholder,
leadingIcon = {
Icon(
painter = painterResource(id = R.drawable.icon_key_24px),
contentDescription = "비밀번호"
)
},
trailingIcon = {
IconButton(onClick = { isPasswordVisible = !isPasswordVisible }) {
Icon(
imageVector = if (isPasswordVisible) Icons.Default.Visibility else Icons.Default.VisibilityOff,
contentDescription = if (isPasswordVisible) "비밀번호 숨김" else "비밀번호 보임"
)
}
},
visualTransformation = if (isPasswordVisible) VisualTransformation.None else PasswordVisualTransformation(),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Password,
imeAction = ImeAction.Done
),
singleLine = true,
isError = isPasswordInputError,
)
if (isPasswordInputError) {
Text(
text = errorMessage,
color = Color.Red,
fontSize = dpToSp(12.dp),
modifier = Modifier.padding(start = 16.dp, top = 4.dp)
)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package kr.co.lion.modigm.ui.login.component

import androidx.compose.foundation.Image
import androidx.compose.foundation.ScrollState
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.launch
import kr.co.lion.modigm.R
import kr.co.lion.modigm.ui.login.util.animateEnterExit

@Composable
fun ScrollArrow(
scrollState: ScrollState,
modifier: Modifier = Modifier
) {
val isVisible = remember { mutableStateOf(false) }
val coroutineScope = rememberCoroutineScope()

LaunchedEffect(scrollState) {
snapshotFlow { scrollState.canScrollForward }
.collect { canScrollForward ->
isVisible.value = canScrollForward
}
}

Box(
modifier = modifier
.fillMaxWidth()
.height(50.dp)
.background(Color.Transparent),
contentAlignment = Alignment.Center
) {
if (isVisible.value) {
Image(
painter = painterResource(id = R.drawable.arrow_down_24px),
contentDescription = "Scroll Arrow",
modifier = Modifier
.size(24.dp)
.clickable {
coroutineScope.launch {
scrollState.animateScrollTo(scrollState.maxValue)
}
}
.animateEnterExit(),
colorFilter = ColorFilter.tint(Color.White)
)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package kr.co.lion.modigm.ui.login.component

import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonColors
import androidx.compose.material3.ButtonDefaults
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp

@Composable
fun SocialLoginButton(
modifier: Modifier = Modifier,
onClick: () -> Unit,
colors: ButtonColors,
content: @Composable () -> Unit
) {
Button(
onClick = onClick,
modifier = modifier,
colors = colors,
contentPadding = PaddingValues(0.dp),
shape = RoundedCornerShape(8.dp),
content = { content() }
)
}

@Preview(showBackground = true)
@Composable
fun SocialLoginButtonPreview() {
SocialLoginButton(
onClick = {},
colors = ButtonDefaults.buttonColors(),
content = {}
)
}
Loading