feat: implement register feature
This commit is contained in:
parent
90df005a3f
commit
fc9c9614ba
|
|
@ -0,0 +1,6 @@
|
|||
package com.syaroful.agrilinkvocpro.data.model
|
||||
|
||||
data class RegisterResponse(
|
||||
val message: String?,
|
||||
val success: Boolean?
|
||||
)
|
||||
|
|
@ -5,6 +5,7 @@ import com.syaroful.agrilinkvocpro.presentation.screen.home.DynamicModuleViewMod
|
|||
import com.syaroful.agrilinkvocpro.presentation.screen.home.HomeViewModel
|
||||
import com.syaroful.agrilinkvocpro.presentation.screen.login.LoginViewModel
|
||||
import com.syaroful.agrilinkvocpro.presentation.screen.profile.ProfileViewModel
|
||||
import com.syaroful.agrilinkvocpro.presentation.screen.register.RegisterViewModel
|
||||
import org.koin.androidx.viewmodel.dsl.viewModel
|
||||
import org.koin.dsl.module
|
||||
|
||||
|
|
@ -14,4 +15,5 @@ val viewModelModule = module {
|
|||
viewModel { ProfileViewModel(get()) }
|
||||
viewModel { HomeViewModel(get(), get()) }
|
||||
viewModel { DetailViewModel(get(), get()) }
|
||||
viewModel { RegisterViewModel(get()) }
|
||||
}
|
||||
|
|
@ -55,7 +55,7 @@ fun SetupNavigation(
|
|||
}
|
||||
composable("register") {
|
||||
RegisterScreen(
|
||||
onLoginSuccess = {
|
||||
onRegisterSuccess = {
|
||||
navController.navigate("login") {
|
||||
popUpTo("login") { inclusive = true }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.syaroful.agrilinkvocpro.presentation.screen.login
|
|||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.syaroful.agrilinkvocpro.core.utils.ResultState
|
||||
import com.syaroful.agrilinkvocpro.core.utils.extention.mapToUserFriendlyError
|
||||
import com.syaroful.agrilinkvocpro.data.UserPreferences
|
||||
import com.syaroful.agrilinkvocpro.data.model.LoginResponse
|
||||
import com.syaroful.agrilinkvocpro.data.repository.AuthRepository
|
||||
|
|
@ -55,24 +56,4 @@ class LoginViewModel(
|
|||
fun resetLoginState() {
|
||||
_loginState.value = ResultState.Idle
|
||||
}
|
||||
|
||||
private fun mapToUserFriendlyError(e: Exception): String {
|
||||
return when (e) {
|
||||
is java.net.UnknownHostException -> "Tidak dapat terhubung ke server. Periksa koneksi internet Anda."
|
||||
is java.net.SocketTimeoutException -> "Waktu koneksi habis. Mohon coba lagi."
|
||||
is java.io.IOException -> "Terjadi kesalahan jaringan. Silakan cek koneksi Anda."
|
||||
is retrofit2.HttpException -> {
|
||||
// Kamu bisa cek kode HTTP di sini juga kalau mau
|
||||
when (e.code()) {
|
||||
401 -> "Akses ditolak. Silakan periksa kredensial login Anda."
|
||||
403 -> "Anda tidak memiliki izin untuk mengakses ini."
|
||||
404 -> "Data tidak ditemukan."
|
||||
500 -> "Terjadi kesalahan pada server. Silakan coba lagi nanti."
|
||||
else -> "Terjadi kesalahan. Kode: ${e.code()}"
|
||||
}
|
||||
}
|
||||
|
||||
else -> "Terjadi kesalahan. Silakan coba lagi."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,16 +12,25 @@ import androidx.compose.foundation.layout.imePadding
|
|||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Check
|
||||
import androidx.compose.material.icons.filled.Clear
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.SnackbarHost
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
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.graphics.Color
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
|
|
@ -30,23 +39,43 @@ import com.syaroful.agrilinkvocpro.R
|
|||
import com.syaroful.agrilinkvocpro.core.components.AppButton
|
||||
import com.syaroful.agrilinkvocpro.core.components.AppPasswordField
|
||||
import com.syaroful.agrilinkvocpro.core.components.AppTextField
|
||||
import com.syaroful.agrilinkvocpro.core.components.CustomSnackBarComponent
|
||||
import com.syaroful.agrilinkvocpro.core.components.textTheme
|
||||
import com.syaroful.agrilinkvocpro.core.utils.ResultState
|
||||
import com.syaroful.agrilinkvocpro.presentation.theme.DarkGrey
|
||||
import com.syaroful.agrilinkvocpro.presentation.theme.MainGreen
|
||||
import org.koin.androidx.compose.koinViewModel
|
||||
|
||||
@Composable
|
||||
fun RegisterScreen(
|
||||
onLoginSuccess: () -> Unit,
|
||||
registerViewModel: RegisterViewModel = koinViewModel(),
|
||||
onRegisterSuccess: () -> Unit,
|
||||
onNavigateToLogin: () -> Unit,
|
||||
) {
|
||||
|
||||
val signupState by registerViewModel.signupState.collectAsState()
|
||||
|
||||
val focusManager = LocalFocusManager.current
|
||||
|
||||
val snackBarHostState = remember { SnackbarHostState() }
|
||||
|
||||
var name by remember { mutableStateOf("") }
|
||||
var email by remember { mutableStateOf("") }
|
||||
var username by remember { mutableStateOf("") }
|
||||
var password by remember { mutableStateOf("") }
|
||||
var phone by remember { mutableStateOf("") }
|
||||
|
||||
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
|
||||
Scaffold(
|
||||
snackbarHost = {
|
||||
SnackbarHost(hostState = snackBarHostState) { data ->
|
||||
CustomSnackBarComponent(
|
||||
modifier = Modifier.padding(16.dp),
|
||||
message = data.visuals.message,
|
||||
icon = if (data.visuals.message.contains("Failed")) Icons.Default.Clear else Icons.Default.Check
|
||||
)
|
||||
}
|
||||
},
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) { innerPadding ->
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.verticalScroll(rememberScrollState())
|
||||
|
|
@ -108,8 +137,18 @@ fun RegisterScreen(
|
|||
)
|
||||
|
||||
AppButton(
|
||||
label = "Daftar",
|
||||
label = if (signupState is ResultState.Loading) "Memuat..." else "Daftar",
|
||||
isEnable = signupState !is ResultState.Loading,
|
||||
) {
|
||||
focusManager.clearFocus()
|
||||
registerViewModel.signup(name, username, email, password)
|
||||
}
|
||||
if (signupState is ResultState.Error) {
|
||||
Text(
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
text = (signupState as ResultState.Error).message,
|
||||
color = Color.Red
|
||||
)
|
||||
}
|
||||
|
||||
Row(
|
||||
|
|
@ -128,6 +167,17 @@ fun RegisterScreen(
|
|||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
|
||||
LaunchedEffect(signupState) {
|
||||
if (signupState is ResultState.Success<*>) {
|
||||
snackBarHostState.showSnackbar(message = "Pendaftaran Akun Berhasil")
|
||||
// Navigate to Home if Success
|
||||
onRegisterSuccess()
|
||||
registerViewModel.resetRegisterState()
|
||||
} else if (signupState is ResultState.Error) {
|
||||
snackBarHostState.showSnackbar(message = (signupState as ResultState.Error).message)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,26 +3,39 @@ package com.syaroful.agrilinkvocpro.presentation.screen.register
|
|||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.syaroful.agrilinkvocpro.core.utils.ResultState
|
||||
import com.syaroful.agrilinkvocpro.data.model.LoginResponse
|
||||
import com.syaroful.agrilinkvocpro.core.utils.extention.mapToUserFriendlyError
|
||||
import com.syaroful.agrilinkvocpro.data.model.RegisterResponse
|
||||
import com.syaroful.agrilinkvocpro.data.repository.AuthRepository
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class RegisterViewModel(
|
||||
authRepository: AuthRepository,
|
||||
) : ViewModel(){
|
||||
private val _signupState = MutableStateFlow<ResultState<LoginResponse>>(ResultState.Idle)
|
||||
val signupState: StateFlow<ResultState<LoginResponse>> = _signupState
|
||||
private val authRepository: AuthRepository,
|
||||
) : ViewModel() {
|
||||
private val _signupState = MutableStateFlow<ResultState<RegisterResponse>>(ResultState.Idle)
|
||||
val signupState: StateFlow<ResultState<RegisterResponse>> = _signupState
|
||||
|
||||
fun signup(name: String, username: String, email: String, password: String){
|
||||
fun signup(name: String, username: String, email: String, password: String) {
|
||||
_signupState.value = ResultState.Loading
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
|
||||
}catch (e: Exception){
|
||||
|
||||
val response = authRepository.register(username, password, email, name)
|
||||
if (response.isSuccessful) {
|
||||
_signupState.value = ResultState.Success(response.body())
|
||||
} else {
|
||||
val errorMessage = response.body()?.message ?: "Register Failed"
|
||||
_signupState.value = ResultState.Error(errorMessage)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
val errorMessage = mapToUserFriendlyError(e)
|
||||
_signupState.value = ResultState.Error(errorMessage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun resetRegisterState(){
|
||||
_signupState.value = ResultState.Idle
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,9 +1,11 @@
|
|||
package com.syaroful.agrilinkvocpro.control_feature.di
|
||||
|
||||
import com.syaroful.agrilinkvocpro.control_feature.presentation.control.ControlViewModel
|
||||
import com.syaroful.agrilinkvocpro.control_feature.presentation.history.ControlHistoryViewModel
|
||||
import org.koin.androidx.viewmodel.dsl.viewModel
|
||||
import org.koin.dsl.module
|
||||
|
||||
val viewModelModule = module {
|
||||
viewModel { ControlViewModel(get(), get()) }
|
||||
viewModel { ControlHistoryViewModel(get(), get()) }
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user