diff --git a/composeApp/src/commonMain/composeResources/values-sk/strings.xml b/composeApp/src/commonMain/composeResources/values-sk/strings.xml
index f139777..4ca07ed 100644
--- a/composeApp/src/commonMain/composeResources/values-sk/strings.xml
+++ b/composeApp/src/commonMain/composeResources/values-sk/strings.xml
@@ -60,6 +60,7 @@
Všetko je pripravené!
Začať je ľahké – vyberte si, čo a kde by ste chceli zbierať. Tešíme sa na naše spoločné dobrodružstvá pri zbieraní!
Začnite používať aplikáciu!
+ Zadajte meno
Detaily zberu
Hlavný obrázok udalosti
Prihlásiť sa na zber
@@ -111,11 +112,13 @@
Názov je požadovaný
Kapacita je požadovaná
+ Kapacita nie je validná
Dátum je požadovaný
Čas je požadovaný
Dátum a čas musia byť v budúcnosti
Miesto je požadované
Suma platu je požadovaná
+ Suma platu nie je validná
Vytvoriť zber
Aktualizovať zber
diff --git a/composeApp/src/commonMain/composeResources/values/strings.xml b/composeApp/src/commonMain/composeResources/values/strings.xml
index 2eb9dab..cf0acc6 100644
--- a/composeApp/src/commonMain/composeResources/values/strings.xml
+++ b/composeApp/src/commonMain/composeResources/values/strings.xml
@@ -75,6 +75,7 @@
Everything is prepared!
Getting started is easy – choose what and where you'd like to harvest. We're excited for our shared gathering adventures!
Start using application!
+ Name cannot be empty!
Harvest Detail
Event featured image
@@ -130,11 +131,13 @@
Title is required
Capacity is required
+ Capacity is invalid
Date is required
Time is required
Date and time must be in future
Location is required
Salary amount is required
+ Salary amount is invalid
Create harvest
Update harvest
diff --git a/composeApp/src/commonMain/kotlin/auth/domain/AuthError.kt b/composeApp/src/commonMain/kotlin/auth/domain/AuthError.kt
index b84bc7f..bd111d0 100644
--- a/composeApp/src/commonMain/kotlin/auth/domain/AuthError.kt
+++ b/composeApp/src/commonMain/kotlin/auth/domain/AuthError.kt
@@ -14,4 +14,8 @@ sealed interface AuthError : Error {
enum class TokenError : AuthError {
EXPIRED
}
+
+ enum class ProfileError : AuthError {
+ EMPTY_NAME
+ }
}
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/auth/domain/AuthValidation.kt b/composeApp/src/commonMain/kotlin/auth/domain/AuthValidation.kt
index adc307f..2be2462 100644
--- a/composeApp/src/commonMain/kotlin/auth/domain/AuthValidation.kt
+++ b/composeApp/src/commonMain/kotlin/auth/domain/AuthValidation.kt
@@ -21,7 +21,8 @@ class AuthValidation {
if (password.length < 8) {
emit(ResultHandler.Error(AuthError.PasswordError.TOO_SHORT))
} else {
- val hasDigit = password.all { it.isDigit() }
+ println(password)
+ val hasDigit = password.any { it.isDigit() }
if (!hasDigit) {
emit(ResultHandler.Error(AuthError.PasswordError.NO_DIGIT))
} else {
@@ -36,8 +37,18 @@ class AuthValidation {
): Flow> = flow {
if (password != passwordRepeated) {
emit(ResultHandler.Error(AuthError.PasswordError.NO_MATCH))
+ } else {
+ emit(ResultHandler.Success(true))
}
+ }
- emit(ResultHandler.Success(true))
+ suspend fun validateName(
+ name: String,
+ ): Flow> = flow {
+ if (name.isEmpty()) {
+ emit(ResultHandler.Error(AuthError.ProfileError.EMPTY_NAME))
+ } else {
+ emit(ResultHandler.Success(true))
+ }
}
}
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/auth/presentation/login/component/LoginScreenComponent.kt b/composeApp/src/commonMain/kotlin/auth/presentation/login/component/LoginScreenComponent.kt
index 8279981..6295f00 100644
--- a/composeApp/src/commonMain/kotlin/auth/presentation/login/component/LoginScreenComponent.kt
+++ b/composeApp/src/commonMain/kotlin/auth/presentation/login/component/LoginScreenComponent.kt
@@ -42,16 +42,15 @@ class LoginScreenComponent(
}
is LoginScreenEvent.ClickLoginButton -> {
- println(_stateLogin.value)
-// validateEmail()
-// validatePassword()
-
- loginUser(
- login = Login(
- email = _stateLogin.value.email,
- password = _stateLogin.value.password
+ validateForm()
+ if (isFormValid()) {
+ loginUser(
+ login = Login(
+ email = _stateLogin.value.email,
+ password = _stateLogin.value.password
+ )
)
- )
+ }
}
is LoginScreenEvent.UpdateEmail -> {
@@ -71,24 +70,27 @@ class LoginScreenComponent(
}
private fun isFormValid(): Boolean {
- return _stateLogin.value.email.isNotEmpty() && _stateLogin.value.password.isNotEmpty() && _stateLogin.value.emailError != null && _stateLogin.value.passwordError != null
+ return _stateLogin.value.email.isNotEmpty() && _stateLogin.value.password.isNotEmpty() && _stateLogin.value.emailError == null && _stateLogin.value.passwordError == null
+ }
+
+ private fun validateForm() {
+ validateEmail()
+ if (_stateLogin.value.emailError == null) {
+ validatePassword()
+ }
}
private fun validateEmail() {
coroutineScope().launch {
authValidation.validateEmail(_stateLogin.value.email).collect { result ->
if (result is ResultHandler.Error) {
- println("Email result: $result")
_stateLogin.value = _stateLogin.value.copy(
emailError = result.error.asUiText().asNonCompString()
)
- println(result)
- println(_stateLogin.value)
} else if (result is ResultHandler.Success) {
_stateLogin.value = _stateLogin.value.copy(
emailError = null
)
- println(_stateLogin.value)
}
}
}
@@ -98,21 +100,16 @@ class LoginScreenComponent(
coroutineScope().launch {
authValidation.validatePassword(_stateLogin.value.password).collect { result ->
if (result is ResultHandler.Error) {
- println("Password result: $result")
_stateLogin.value = _stateLogin.value.copy(
passwordError = result.error.asUiText().asNonCompString()
)
- println(result)
- println(_stateLogin.value)
} else if (result is ResultHandler.Success) {
_stateLogin.value = _stateLogin.value.copy(
passwordError = null
)
- println(_stateLogin.value)
}
}
}
- println(_stateLogin.value)
}
private fun loginUser(login: Login) {
diff --git a/composeApp/src/commonMain/kotlin/auth/presentation/register/RegisterStep1Screen.kt b/composeApp/src/commonMain/kotlin/auth/presentation/register/RegisterStep1Screen.kt
index 1f03f6f..a498486 100644
--- a/composeApp/src/commonMain/kotlin/auth/presentation/register/RegisterStep1Screen.kt
+++ b/composeApp/src/commonMain/kotlin/auth/presentation/register/RegisterStep1Screen.kt
@@ -6,16 +6,26 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
+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.width
import androidx.compose.foundation.text.ClickableText
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Scaffold
+import androidx.compose.material.SnackbarDuration
+import androidx.compose.material.SnackbarHost
+import androidx.compose.material.SnackbarHostState
+import androidx.compose.material.SnackbarResult
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
@@ -31,6 +41,8 @@ import com.arkivanov.decompose.extensions.compose.subscribeAsState
import core.presentation.components.button_primary.ButtonPrimary
import core.presentation.components.filled_input.FilledInput
import core.presentation.components.logo.GrabItLogo
+import core.presentation.components.snackbar.CustomSnackbar
+import core.presentation.components.snackbar.SnackbarVisualWithError
import grabit.composeapp.generated.resources.Res
import grabit.composeapp.generated.resources.create_account
import grabit.composeapp.generated.resources.email
@@ -39,6 +51,7 @@ import grabit.composeapp.generated.resources.next_step
import grabit.composeapp.generated.resources.password
import grabit.composeapp.generated.resources.register_screen__has_account
import grabit.composeapp.generated.resources.repeat_password
+import kotlinx.coroutines.launch
import org.jetbrains.compose.resources.ExperimentalResourceApi
import org.jetbrains.compose.resources.stringResource
import ui.domain.ColorVariation
@@ -49,90 +62,131 @@ import ui.theme.LightOnOrange
fun RegisterStep1Screen(component: RegisterStep1ScreenComponent) {
val stateRegisterStep1 by component.stateRegisterStep1.subscribeAsState()
+ val coroutineScope = rememberCoroutineScope()
+ val snackbarHostState = remember { SnackbarHostState() }
+ val isVisible = remember { mutableStateOf(false) }
+
val focusManager = LocalFocusManager.current
- Column(
- modifier = Modifier.fillMaxHeight().background(MaterialTheme.colors.background)
- .padding(40.dp),
- horizontalAlignment = Alignment.CenterHorizontally
- ) {
- Spacer(modifier = Modifier.height(80.dp))
- GrabItLogo()
- Spacer(modifier = Modifier.height(48.dp))
- Text(
- stringResource(Res.string.create_account),
- style = MaterialTheme.typography.h2,
- color = MaterialTheme.colors.onBackground
- )
- Spacer(modifier = Modifier.height(24.dp))
+ if (!isVisible.value && stateRegisterStep1.error != null) {
+ coroutineScope.launch {
+ isVisible.value = true
+ val snackbarResult = snackbarHostState.showSnackbar(
+ message = stateRegisterStep1.error!!,
+ duration = SnackbarDuration.Short
+ )
+
+ when (snackbarResult) {
+ SnackbarResult.Dismissed -> {
+ isVisible.value = false
+ component.onEvent(RegisterStep1ScreenEvent.RemoveError)
+ }
+
+ SnackbarResult.ActionPerformed -> {
+ isVisible.value = false
+ component.onEvent(RegisterStep1ScreenEvent.RemoveError)
+ }
+ }
+ }
+ }
+ Scaffold(
+ modifier = Modifier.fillMaxSize().navigationBarsPadding(),
+ snackbarHost = {
+ SnackbarHost(hostState = snackbarHostState, snackbar = {
+ CustomSnackbar(
+ data = SnackbarVisualWithError(
+ snackbarData = it,
+ isError = true,
+ )
+ )
+ })
+ },
+ ) {
Column(
- verticalArrangement = Arrangement.spacedBy(12.dp),
+ modifier = Modifier.fillMaxHeight().background(MaterialTheme.colors.background)
+ .padding(40.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
- FilledInput(
- value = stateRegisterStep1.email,
- onValueChange = { component.onEvent(RegisterStep1ScreenEvent.UpdateEmail(it)) },
- label = stringResource(Res.string.email),
- keyboardOptions = KeyboardOptions(
- keyboardType = KeyboardType.Email,
- imeAction = ImeAction.Next
- )
+ Spacer(modifier = Modifier.height(80.dp))
+ GrabItLogo()
+ Spacer(modifier = Modifier.height(48.dp))
+ Text(
+ stringResource(Res.string.create_account),
+ style = MaterialTheme.typography.h2,
+ color = MaterialTheme.colors.onBackground
)
- FilledInput(
- value = stateRegisterStep1.password,
- onValueChange = { component.onEvent(RegisterStep1ScreenEvent.UpdatePassword(it)) },
- label = stringResource(Res.string.password),
- visualTransformation = PasswordVisualTransformation(),
- keyboardOptions = KeyboardOptions(
- keyboardType = KeyboardType.Password,
- imeAction = ImeAction.Next
+ Spacer(modifier = Modifier.height(24.dp))
+
+ Column(
+ verticalArrangement = Arrangement.spacedBy(12.dp),
+ horizontalAlignment = Alignment.CenterHorizontally
+ ) {
+ FilledInput(
+ value = stateRegisterStep1.email,
+ onValueChange = { component.onEvent(RegisterStep1ScreenEvent.UpdateEmail(it)) },
+ label = stringResource(Res.string.email),
+ keyboardOptions = KeyboardOptions(
+ keyboardType = KeyboardType.Email,
+ imeAction = ImeAction.Next
+ )
)
- )
- FilledInput(
- value = stateRegisterStep1.passwordRepeated,
- onValueChange = {
- component.onEvent(
- RegisterStep1ScreenEvent.UpdatePasswordRepeated(
- it
- )
+ FilledInput(
+ value = stateRegisterStep1.password,
+ onValueChange = { component.onEvent(RegisterStep1ScreenEvent.UpdatePassword(it)) },
+ label = stringResource(Res.string.password),
+ visualTransformation = PasswordVisualTransformation(),
+ keyboardOptions = KeyboardOptions(
+ keyboardType = KeyboardType.Password,
+ imeAction = ImeAction.Next
)
- },
- label = stringResource(Res.string.repeat_password),
- visualTransformation = PasswordVisualTransformation(),
- keyboardOptions = KeyboardOptions(
- keyboardType = KeyboardType.Text,
- imeAction = ImeAction.Done
- ),
- keyboardActions = KeyboardActions {
- focusManager.clearFocus()
- }
- )
- ButtonPrimary(
- type = ColorVariation.ORANGE,
- onClick = {
- component.onEvent(RegisterStep1ScreenEvent.ClickButtonNext)
- },
- text = stringResource(Res.string.next_step)
- )
- Row(verticalAlignment = Alignment.CenterVertically) {
- Text(
- stringResource(
- Res.string.register_screen__has_account
- ),
- style = MaterialTheme.typography.body2,
- color = MaterialTheme.colors.onBackground
)
- Spacer(Modifier.width(4.dp))
- ClickableText(
- text = AnnotatedString(stringResource(Res.string.login_screen__login)),
- onClick = { component.onEvent(RegisterStep1ScreenEvent.GoBackToLogin) },
- style = TextStyle(
- color = LightOnOrange,
- fontSize = MaterialTheme.typography.body2.fontSize,
- fontWeight = MaterialTheme.typography.body2.fontWeight
+ FilledInput(
+ value = stateRegisterStep1.passwordRepeated,
+ onValueChange = {
+ component.onEvent(
+ RegisterStep1ScreenEvent.UpdatePasswordRepeated(
+ it
+ )
+ )
+ },
+ label = stringResource(Res.string.repeat_password),
+ visualTransformation = PasswordVisualTransformation(),
+ keyboardOptions = KeyboardOptions(
+ keyboardType = KeyboardType.Text,
+ imeAction = ImeAction.Done
),
+ keyboardActions = KeyboardActions {
+ focusManager.clearFocus()
+ }
+ )
+ ButtonPrimary(
+ type = ColorVariation.ORANGE,
+ onClick = {
+ focusManager.clearFocus()
+ component.onEvent(RegisterStep1ScreenEvent.ClickButtonNext)
+ },
+ text = stringResource(Res.string.next_step)
)
+ Row(verticalAlignment = Alignment.CenterVertically) {
+ Text(
+ stringResource(
+ Res.string.register_screen__has_account
+ ),
+ style = MaterialTheme.typography.body2,
+ color = MaterialTheme.colors.onBackground
+ )
+ Spacer(Modifier.width(4.dp))
+ ClickableText(
+ text = AnnotatedString(stringResource(Res.string.login_screen__login)),
+ onClick = { component.onEvent(RegisterStep1ScreenEvent.GoBackToLogin) },
+ style = TextStyle(
+ color = LightOnOrange,
+ fontSize = MaterialTheme.typography.body2.fontSize,
+ fontWeight = MaterialTheme.typography.body2.fontWeight
+ ),
+ )
+ }
}
}
}
diff --git a/composeApp/src/commonMain/kotlin/auth/presentation/register/component/RegisterStep1ScreenComponent.kt b/composeApp/src/commonMain/kotlin/auth/presentation/register/component/RegisterStep1ScreenComponent.kt
index 6262af7..1ef820b 100644
--- a/composeApp/src/commonMain/kotlin/auth/presentation/register/component/RegisterStep1ScreenComponent.kt
+++ b/composeApp/src/commonMain/kotlin/auth/presentation/register/component/RegisterStep1ScreenComponent.kt
@@ -8,6 +8,8 @@ import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.value.MutableValue
import com.arkivanov.decompose.value.Value
import com.arkivanov.essenty.lifecycle.coroutines.coroutineScope
+import core.domain.ResultHandler
+import core.presentation.error_string_mapper.asUiText
import kotlinx.coroutines.launch
class RegisterStep1ScreenComponent(
@@ -22,29 +24,28 @@ class RegisterStep1ScreenComponent(
email = email,
password = "",
passwordRepeated = "",
- error = null
+ error = null,
)
)
val stateRegisterStep1: Value = _stateRegisterStep1
- private val _passwordsMatch = MutableValue(false)
- val passwordsMatch: Value = _passwordsMatch
-
- private val _isValid = MutableValue(false)
- val isValid: Value = _isValid
-
fun onEvent(event: RegisterStep1ScreenEvent) {
when (event) {
is RegisterStep1ScreenEvent.GoBackToLogin -> onNavigateBackToLoginScreen()
- is RegisterStep1ScreenEvent.ClickButtonNext -> onNavigateToRegisterStep2Screen(
- NewUser(
- email = _stateRegisterStep1.value.email,
- password = _stateRegisterStep1.value.password,
- accountType = AccountType.HARVESTER,
- name = "",
- phoneNumber = null
- )
- )
+ is RegisterStep1ScreenEvent.ClickButtonNext -> {
+ validateForm()
+ if (isFormValid()) {
+ onNavigateToRegisterStep2Screen(
+ NewUser(
+ email = _stateRegisterStep1.value.email,
+ password = _stateRegisterStep1.value.password,
+ accountType = AccountType.HARVESTER,
+ name = "",
+ phoneNumber = null
+ )
+ )
+ }
+ }
is RegisterStep1ScreenEvent.UpdateEmail -> {
_stateRegisterStep1.value = _stateRegisterStep1.value.copy(email = event.email)
@@ -61,10 +62,80 @@ class RegisterStep1ScreenComponent(
passwordRepeated = event.passwordRepeated
)
}
+
+ RegisterStep1ScreenEvent.RemoveError -> {
+ _stateRegisterStep1.value = _stateRegisterStep1.value.copy(
+ error = null
+ )
+ }
}
}
+ private fun isFormValid(): Boolean {
+ return _stateRegisterStep1.value.email.isNotEmpty()
+ && _stateRegisterStep1.value.password.isNotEmpty()
+ && _stateRegisterStep1.value.passwordRepeated.isNotEmpty()
+ && _stateRegisterStep1.value.error == null
+ }
+
private fun validateForm() {
-// authValidation.validateEmail(stateRegisterStep1.value.email)
+ validateEmail()
+ if (_stateRegisterStep1.value.error == null) {
+ validatePassword()
+ if (_stateRegisterStep1.value.error == null) {
+ validatePasswordMatch()
+ }
+ }
+ }
+
+ private fun validateEmail() {
+ coroutineScope().launch {
+ authValidation.validateEmail(_stateRegisterStep1.value.email).collect { result ->
+ if (result is ResultHandler.Error) {
+ _stateRegisterStep1.value = _stateRegisterStep1.value.copy(
+ error = result.error.asUiText().asNonCompString()
+ )
+ } else if (result is ResultHandler.Success) {
+ _stateRegisterStep1.value = _stateRegisterStep1.value.copy(
+ error = null
+ )
+ }
+ }
+ }
+ }
+
+ private fun validatePassword() {
+ coroutineScope().launch {
+ authValidation.validatePassword(_stateRegisterStep1.value.password).collect { result ->
+ if (result is ResultHandler.Error) {
+ _stateRegisterStep1.value = _stateRegisterStep1.value.copy(
+ error = result.error.asUiText().asNonCompString()
+ )
+ } else if (result is ResultHandler.Success) {
+ _stateRegisterStep1.value = _stateRegisterStep1.value.copy(
+ error = null
+ )
+ }
+ }
+ }
+ }
+
+ private fun validatePasswordMatch() {
+ coroutineScope().launch {
+ authValidation.matchPasswords(
+ _stateRegisterStep1.value.password,
+ _stateRegisterStep1.value.passwordRepeated
+ ).collect { result ->
+ if (result is ResultHandler.Error) {
+ _stateRegisterStep1.value = _stateRegisterStep1.value.copy(
+ error = result.error.asUiText().asNonCompString()
+ )
+ } else if (result is ResultHandler.Success) {
+ _stateRegisterStep1.value = _stateRegisterStep1.value.copy(
+ error = null
+ )
+ }
+ }
+ }
}
}
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/auth/presentation/register/component/RegisterStep1ScreenEvent.kt b/composeApp/src/commonMain/kotlin/auth/presentation/register/component/RegisterStep1ScreenEvent.kt
index 83faeff..63b96c4 100644
--- a/composeApp/src/commonMain/kotlin/auth/presentation/register/component/RegisterStep1ScreenEvent.kt
+++ b/composeApp/src/commonMain/kotlin/auth/presentation/register/component/RegisterStep1ScreenEvent.kt
@@ -6,4 +6,5 @@ sealed interface RegisterStep1ScreenEvent {
data class UpdateEmail(val email: String) : RegisterStep1ScreenEvent
data class UpdatePassword(val password: String) : RegisterStep1ScreenEvent
data class UpdatePasswordRepeated(val passwordRepeated: String) : RegisterStep1ScreenEvent
+ data object RemoveError : RegisterStep1ScreenEvent
}
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/auth/presentation/register/component/RegisterStep3ScreenComponent.kt b/composeApp/src/commonMain/kotlin/auth/presentation/register/component/RegisterStep3ScreenComponent.kt
index 99c4473..dc6e8e0 100644
--- a/composeApp/src/commonMain/kotlin/auth/presentation/register/component/RegisterStep3ScreenComponent.kt
+++ b/composeApp/src/commonMain/kotlin/auth/presentation/register/component/RegisterStep3ScreenComponent.kt
@@ -1,6 +1,7 @@
package auth.presentation.register.component
import auth.data.remote.dto.toUser
+import auth.domain.AuthValidation
import auth.domain.model.NewUser
import auth.domain.use_case.RegisterUserUseCase
import auth.presentation.register.RegisterStep3State
@@ -16,6 +17,7 @@ import kotlinx.coroutines.launch
class RegisterStep3ScreenComponent(
componentContext: ComponentContext,
private val registerUserUseCase: RegisterUserUseCase,
+ private val authValidation: AuthValidation,
newUser: NewUser,
private val databaseClient: SqlDelightDatabaseClient,
private val onNavigateToRegisterStepFinalScreen: () -> Unit
@@ -47,15 +49,17 @@ class RegisterStep3ScreenComponent(
}
is RegisterStep3ScreenEvent.ClickCreateAccountButton -> {
- createAccount(
- newUser = _stateRegisterStep3State.value.newUser.copy(
- name = _stateRegisterStep3State.value.name,
- phoneNumber = _stateRegisterStep3State.value.phoneNumber
+ validateForm()
+ if (isFormValid())
+ createAccount(
+ newUser = _stateRegisterStep3State.value.newUser.copy(
+ name = _stateRegisterStep3State.value.name,
+ phoneNumber = _stateRegisterStep3State.value.phoneNumber
+ )
)
- )
}
- RegisterStep3ScreenEvent.RemoveError -> {
+ is RegisterStep3ScreenEvent.RemoveError -> {
_stateRegisterStep3State.value = _stateRegisterStep3State.value.copy(
error = null
)
@@ -63,6 +67,30 @@ class RegisterStep3ScreenComponent(
}
}
+ private fun isFormValid(): Boolean {
+ return _stateRegisterStep3State.value.name.isNotEmpty() && _stateRegisterStep3State.value.error == null
+ }
+
+ private fun validateForm() {
+ validateName()
+ }
+
+ private fun validateName() {
+ coroutineScope().launch {
+ authValidation.validateName(_stateRegisterStep3State.value.name).collect { result ->
+ if (result is ResultHandler.Error) {
+ _stateRegisterStep3State.value = _stateRegisterStep3State.value.copy(
+ error = result.error.asUiText().asNonCompString()
+ )
+ } else if (result is ResultHandler.Success) {
+ _stateRegisterStep3State.value = _stateRegisterStep3State.value.copy(
+ error = null
+ )
+ }
+ }
+ }
+ }
+
private fun createAccount(newUser: NewUser) {
this@RegisterStep3ScreenComponent.coroutineScope().launch {
registerUserUseCase(newUser).collect { result ->
diff --git a/composeApp/src/commonMain/kotlin/core/presentation/error_string_mapper/ErrorTextMapper.kt b/composeApp/src/commonMain/kotlin/core/presentation/error_string_mapper/ErrorTextMapper.kt
index 7125552..0e63273 100644
--- a/composeApp/src/commonMain/kotlin/core/presentation/error_string_mapper/ErrorTextMapper.kt
+++ b/composeApp/src/commonMain/kotlin/core/presentation/error_string_mapper/ErrorTextMapper.kt
@@ -30,12 +30,15 @@ import grabit.composeapp.generated.resources.error__too_many_requests
import grabit.composeapp.generated.resources.error__unauthorised
import grabit.composeapp.generated.resources.error__unknown
import grabit.composeapp.generated.resources.event_create_update_screen__capacity_error
+import grabit.composeapp.generated.resources.event_create_update_screen__capacity_invalid_error
import grabit.composeapp.generated.resources.event_create_update_screen__date_error
import grabit.composeapp.generated.resources.event_create_update_screen__date_time_past
import grabit.composeapp.generated.resources.event_create_update_screen__location_error
import grabit.composeapp.generated.resources.event_create_update_screen__salary_amount_error
+import grabit.composeapp.generated.resources.event_create_update_screen__salary_invalid_amount_error
import grabit.composeapp.generated.resources.event_create_update_screen__time_error
import grabit.composeapp.generated.resources.event_create_update_screen__title_error
+import grabit.composeapp.generated.resources.register_screen__empty_name
import org.jetbrains.compose.resources.ExperimentalResourceApi
@OptIn(ExperimentalResourceApi::class)
@@ -150,6 +153,14 @@ fun Error.asUiText(): UiErrorText {
)
}
}
+
+ is ProfileError -> {
+ when (this) {
+ ProfileError.EMPTY_NAME -> UiErrorText.StringRes(
+ Res.string.register_screen__empty_name
+ )
+ }
+ }
}
}
@@ -186,6 +197,18 @@ fun Error.asUiText(): UiErrorText {
)
}
}
+
+ is InvalidFieldError -> {
+ when (this) {
+ InvalidFieldError.CAPACITY -> UiErrorText.StringRes(
+ Res.string.event_create_update_screen__capacity_invalid_error
+ )
+
+ InvalidFieldError.SALARY_AMOUNT -> UiErrorText.StringRes(
+ Res.string.event_create_update_screen__salary_invalid_amount_error
+ )
+ }
+ }
}
}
diff --git a/composeApp/src/commonMain/kotlin/event/domain/CreateUpdateEventValidation.kt b/composeApp/src/commonMain/kotlin/event/domain/CreateUpdateEventValidation.kt
index 21c88f2..c1bb08c 100644
--- a/composeApp/src/commonMain/kotlin/event/domain/CreateUpdateEventValidation.kt
+++ b/composeApp/src/commonMain/kotlin/event/domain/CreateUpdateEventValidation.kt
@@ -12,12 +12,16 @@ class CreateUpdateEventValidation {
suspend fun validateInput(
event: EventState,
update: Boolean
- ): Flow> =
+ ): Flow> =
flow {
if (event.title.isBlank()) {
emit(ResultHandler.Error(CreateUpdateFormError.MissingFieldError.TITLE))
} else if (event.capacity.isBlank()) {
emit(ResultHandler.Error(CreateUpdateFormError.MissingFieldError.CAPACITY))
+ } else if (event.capacity.isNotBlank()) {
+ if (event.capacity.toIntOrNull() == null) {
+ emit(ResultHandler.Error(CreateUpdateFormError.InvalidFieldError.CAPACITY))
+ }
} else if (event.date == null) {
emit(ResultHandler.Error(CreateUpdateFormError.MissingFieldError.DATE))
} else if (event.time == null) {
@@ -32,6 +36,10 @@ class CreateUpdateEventValidation {
emit(ResultHandler.Error(CreateUpdateFormError.MissingFieldError.LOCATION))
} else if (event.salaryAmount.isBlank()) {
emit(ResultHandler.Error(CreateUpdateFormError.MissingFieldError.SALARY_AMOUNT))
+ } else if (event.salaryAmount.isNotBlank()) {
+ if (event.salaryAmount.toFloatOrNull() == null) {
+ emit(ResultHandler.Error(CreateUpdateFormError.InvalidFieldError.SALARY_AMOUNT))
+ }
} else {
emit(ResultHandler.Success(true))
}
diff --git a/composeApp/src/commonMain/kotlin/event/domain/CreateUpdateFormError.kt b/composeApp/src/commonMain/kotlin/event/domain/CreateUpdateFormError.kt
index 3a460fd..4fc72dd 100644
--- a/composeApp/src/commonMain/kotlin/event/domain/CreateUpdateFormError.kt
+++ b/composeApp/src/commonMain/kotlin/event/domain/CreateUpdateFormError.kt
@@ -6,4 +6,8 @@ sealed interface CreateUpdateFormError : Error {
enum class MissingFieldError : CreateUpdateFormError {
TITLE, CAPACITY, DATE, TIME, DATE_TIME_PAST, LOCATION, SALARY_AMOUNT
}
+
+ enum class InvalidFieldError : CreateUpdateFormError {
+ CAPACITY, SALARY_AMOUNT
+ }
}
\ No newline at end of file
diff --git a/composeApp/src/commonMain/kotlin/navigation/RootComponent.kt b/composeApp/src/commonMain/kotlin/navigation/RootComponent.kt
index 327cbe8..9a64855 100644
--- a/composeApp/src/commonMain/kotlin/navigation/RootComponent.kt
+++ b/composeApp/src/commonMain/kotlin/navigation/RootComponent.kt
@@ -215,6 +215,7 @@ class RootComponent(
RegisterStep3ScreenComponent(
componentContext = context,
registerUserUseCase = registerUserUseCase,
+ authValidation = authValidation,
databaseClient = databaseClient,
newUser = config.newUser,
onNavigateToRegisterStepFinalScreen = {