Skip to content

Commit

Permalink
#7 Feature: Login api
Browse files Browse the repository at this point in the history
  • Loading branch information
0se0 committed Nov 14, 2024
1 parent f8761a1 commit 6b25e42
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 39 deletions.
4 changes: 2 additions & 2 deletions app/src/main/java/org/sopt/and/feature/login/LoginEvent.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.sopt.and.feature.login

sealed class LoginEvent {
data class Success(val email: String) : LoginEvent()
data class Failure(val message: String) : LoginEvent()
data class Success(val token: String) : LoginEvent()
data class Failure(val message: String) : LoginEvent()
}
48 changes: 25 additions & 23 deletions app/src/main/java/org/sopt/and/feature/login/LoginRoute.kt
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ fun LoginRoute(
val snackbarHostState = remember { SnackbarHostState() }
val coroutineScope = rememberCoroutineScope()

var email by remember { mutableStateOf("") }
var username by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
var ispasswordVisible by remember { mutableStateOf(false) }
var isemailErrorVisible by remember { mutableStateOf(false) }
var ispasswordErrorVisible by remember { mutableStateOf(false) }
var isPasswordVisible by remember { mutableStateOf(false) }
var isUsernameErrorVisible by remember { mutableStateOf(false) }
var isPasswordErrorVisible by remember { mutableStateOf(false) }

LaunchedEffect(viewModel.loginEvent) {
viewModel.loginEvent.collect { event ->
Expand All @@ -82,19 +82,20 @@ fun LoginRoute(
}

LoginScreen(
email = email,
onEmailChange = { email = it },
username = username,
onUsernameChange = { username = it },
password = password,
onPasswordChange = { password = it },
passwordVisible = ispasswordVisible,
onPasswordVisibilityChange = { ispasswordVisible = !ispasswordVisible },
onLoginClick = { viewModel.onLoginClick(email, password) },
passwordErrorVisible = ispasswordErrorVisible,
onEmailFocusChanged = { isFocused ->
isemailErrorVisible = isFocused && email.isEmpty()
passwordVisible = isPasswordVisible,
onPasswordVisibilityChange = { isPasswordVisible = !isPasswordVisible },
onLoginClick = { viewModel.onLoginClick(username, password) },
usernameErrorVisible = isUsernameErrorVisible,
passwordErrorVisible = isPasswordErrorVisible,
onUsernameFocusChanged = { isFocused ->
isUsernameErrorVisible = isFocused && username.isEmpty()
},
onPasswordFocusChanged = { isFocused ->
ispasswordErrorVisible = isFocused && password.isEmpty()
isPasswordErrorVisible = isFocused && password.isEmpty()
},
onNavigateToSignUp = { navController.navigate("signup") },
snackbarHostState = snackbarHostState
Expand All @@ -103,20 +104,21 @@ fun LoginRoute(

@Composable
fun LoginScreen(
email: String,
onEmailChange: (String) -> Unit,
username: String,
onUsernameChange: (String) -> Unit,
password: String,
onPasswordChange: (String) -> Unit,
passwordVisible: Boolean,
onPasswordVisibilityChange: () -> Unit,
onLoginClick: () -> Unit,
usernameErrorVisible: Boolean,
passwordErrorVisible: Boolean,
onEmailFocusChanged: (Boolean) -> Unit,
onUsernameFocusChanged: (Boolean) -> Unit,
onPasswordFocusChanged: (Boolean) -> Unit,
onNavigateToSignUp: () -> Unit,
snackbarHostState: SnackbarHostState
) {
val emailFocusRequester = remember { FocusRequester() }
val usernameFocusRequester = remember { FocusRequester() }
val passwordFocusRequester = remember { FocusRequester() }
val loginButtonFocusRequester = remember { FocusRequester() }

Expand All @@ -139,15 +141,15 @@ fun LoginScreen(
)

WavveTextField(
value = email,
onValueChange = onEmailChange,
placeholder = "이메일 입력",
value = username,
onValueChange = onUsernameChange,
placeholder = "사용자 이름 입력",
onFocusChanged = { isFocused ->
onEmailFocusChanged(isFocused)
onUsernameFocusChanged(isFocused)
},
onNext = { passwordFocusRequester.requestFocus() },
keyboardOptions = KeyboardOptions.Default.copy(imeAction = Next),
modifier = Modifier.focusRequester(emailFocusRequester)
modifier = Modifier.focusRequester(usernameFocusRequester)
)

Spacer(modifier = Modifier.height(16.dp))
Expand Down Expand Up @@ -201,4 +203,4 @@ fun LoginScreen(
contentPadding = PaddingValues(horizontal = 16.dp, vertical = 16.dp)
)
}
}
}
31 changes: 17 additions & 14 deletions app/src/main/java/org/sopt/and/feature/login/LoginViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,25 @@ class LoginViewModel(private val userRepository: UserRepository) : ViewModel() {
private val _loginEvent = MutableSharedFlow<LoginEvent>()
val loginEvent = _loginEvent.asSharedFlow()

fun onLoginClick(email: String, password: String) {
fun onLoginClick(username: String, password: String) {
viewModelScope.launch {
val savedEmail = userRepository.getEmail()
val savedPassword = userRepository.getPassword()

if (email != savedEmail) {
_loginEvent.emit(LoginEvent.Failure("이메일이 다릅니다."))
return@launch
}

if (password != savedPassword) {
_loginEvent.emit(LoginEvent.Failure("비밀번호가 틀렸습니다."))
return@launch
runCatching {
userRepository.postLogin(username, password)
}.onSuccess { response ->
if (response.isSuccessful && response.body() != null) {
val token = response.body()?.result?.token
if (token != null) {
userRepository.saveUserToken(token)
_loginEvent.emit(LoginEvent.Success(token))
} else {
_loginEvent.emit(LoginEvent.Failure("토큰을 받아오지 못했습니다."))
}
} else {
_loginEvent.emit(LoginEvent.Failure("로그인 실패: ${response.errorBody()?.string() ?: "알 수 없는 오류"}"))
}
}.onFailure { exception ->
_loginEvent.emit(LoginEvent.Failure("네트워크 오류 발생: ${exception.message}"))
}

_loginEvent.emit(LoginEvent.Success(email))
}
}
}

0 comments on commit 6b25e42

Please sign in to comment.