Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -296,4 +296,7 @@
<string name="delete_scope">Eliminar Scope</string>

<string name="chat_whit_ai">Habla con MoreStuff IA.</string>

<string name="resend_code">Reenviar código</string>
<string name="seconds_to_resend">Podrás reenviar el código en %s segundos</string>
</resources>
4 changes: 4 additions & 0 deletions composeApp/src/commonMain/composeResources/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -311,4 +311,8 @@
<string name="error_invalid_email">The email address is invalid or does not exist.</string>
<string name="error_generic">An error occurred. Please try again.</string>
<string name="chat_whit_ai">Chat with MoreStuff AI.</string>


<string name="resend_code">Resend code</string>
<string name="seconds_to_resend">You can resend the code in %s seconds</string>
</resources>
Original file line number Diff line number Diff line change
@@ -1,31 +1,39 @@
package io.middlepoint.morestuff.shared.ui.screen.onboarding

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Email
import androidx.compose.material.icons.filled.VpnKey
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
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.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.TextFieldValue
Expand All @@ -35,6 +43,8 @@ import io.github.jan.supabase.SupabaseClient
import io.github.jan.supabase.auth.OtpType
import io.github.jan.supabase.auth.auth
import io.github.jan.supabase.auth.providers.builtin.OTP
import io.middlepoint.morestuff.shared.ui.theme.onBoardingBrush
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import morestuff.composeapp.generated.resources.Res
import morestuff.composeapp.generated.resources.`continue`
Expand All @@ -43,8 +53,12 @@ import morestuff.composeapp.generated.resources.enter_code_sent_to_email
import morestuff.composeapp.generated.resources.enter_your_email
import morestuff.composeapp.generated.resources.error_generic
import morestuff.composeapp.generated.resources.error_invalid_email
import morestuff.composeapp.generated.resources.ms_sign_in
import morestuff.composeapp.generated.resources.resend_code
import morestuff.composeapp.generated.resources.seconds_to_resend
import morestuff.composeapp.generated.resources.six_digit_code_label
import morestuff.composeapp.generated.resources.verify
import org.jetbrains.compose.resources.painterResource
import org.jetbrains.compose.resources.stringResource
import org.koin.compose.koinInject
import org.koin.core.parameter.parametersOf
Expand All @@ -65,6 +79,11 @@ fun SignInEmailScreen(
var otpCode by remember { mutableStateOf("") }
var isLoading by remember { mutableStateOf(false) }

var canResendOtp by remember { mutableStateOf(false) }
var secondsRemaining by remember { mutableStateOf(60) }
var hasResentOtp by remember { mutableStateOf(false) }


val sendOtpToEmail: (String, () -> Unit, (String) -> Unit) -> Unit = { email, onSent, onError ->
scope.launch {
isLoading = true
Expand All @@ -73,6 +92,8 @@ fun SignInEmailScreen(
this.email = email
}
onSent()
secondsRemaining = 60
canResendOtp = false
} catch (e: Exception) {
logger.e(e) { "Error sending otp to email" }
emailError = when {
Expand Down Expand Up @@ -109,23 +130,48 @@ fun SignInEmailScreen(
}
}

LaunchedEffect(isEmailSent) {
if (isEmailSent && !hasResentOtp) {
secondsRemaining = 60
canResendOtp = false
while (secondsRemaining > 0) {
delay(1000)
secondsRemaining--
}
canResendOtp = true
}
}

val background = remember { onBoardingBrush }

Box(
modifier = Modifier
.fillMaxSize()
.background(background)
.imePadding()
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(32.dp),
.windowInsetsPadding(WindowInsets.safeDrawing)
.padding(horizontal = 32.dp)
.padding(bottom = 150.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
verticalArrangement = Arrangement.SpaceBetween
) {
Spacer(modifier = Modifier.weight(0.4f))
Icon(
painter = painterResource(Res.drawable.ms_sign_in),
tint = Color.Unspecified,
contentDescription = "signIn",
)
//Spacer(modifier = Modifier.height(32.dp))
Spacer(modifier = Modifier.weight(0.6f))
Text(
text = if (!isEmailSent) stringResource(Res.string.enter_your_email)
else stringResource(Res.string.enter_code_sent_to_email, email.text),
style = MaterialTheme.typography.titleMedium,
color = MaterialTheme.colorScheme.onSurface
color = Color.White
)
Spacer(modifier = Modifier.height(16.dp))

Expand All @@ -137,12 +183,12 @@ fun SignInEmailScreen(
emailError = null
}
},
label = { Text(stringResource(Res.string.email_label)) },
label = { Text(text = stringResource(Res.string.email_label), color = Color.White) },
leadingIcon = {
Icon(
imageVector = Icons.Default.Email,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary
tint = Color.White
)
},
singleLine = true,
Expand Down Expand Up @@ -170,12 +216,17 @@ fun SignInEmailScreen(
OutlinedTextField(
value = otpCode,
onValueChange = { if (it.length <= 6) otpCode = it },
label = { Text(stringResource(Res.string.six_digit_code_label)) },
label = {
Text(
text = stringResource(Res.string.six_digit_code_label),
color = Color.White
)
},
leadingIcon = {
Icon(
imageVector = Icons.Default.VpnKey,
contentDescription = null,
tint = MaterialTheme.colorScheme.primary
tint = Color.White
)
},
singleLine = true,
Expand All @@ -186,6 +237,45 @@ fun SignInEmailScreen(
),
modifier = Modifier.fillMaxWidth()
)


Spacer(modifier = Modifier.height(8.dp))
if (!hasResentOtp) {
if (!canResendOtp) {
Text(
text = stringResource(Res.string.seconds_to_resend).replace(
"%s",
"$secondsRemaining"
),
color = Color.White.copy(alpha = 0.7f),
style = MaterialTheme.typography.bodySmall
)
} else {
TextButton(
onClick = {
sendOtpToEmail(
email.text,
{
hasResentOtp = true
canResendOtp = false
},
{}
)
},
enabled = !isLoading,
colors = ButtonDefaults.outlinedButtonColors(
contentColor = Color.White,
containerColor = Color(0xFF393AC5),
disabledContainerColor = Color(0xFF393AC5).copy(alpha = 0.5f)
),
) {
Text(
text = stringResource(Res.string.resend_code),
color = Color.White
)
}
}
}
}

Spacer(modifier = Modifier.height(24.dp))
Expand All @@ -199,10 +289,15 @@ fun SignInEmailScreen(
{}
)
},
colors = ButtonDefaults.outlinedButtonColors(
contentColor = Color.White,
containerColor = Color(0xFF393AC5),
disabledContainerColor = Color(0xFF393AC5).copy(alpha = 0.5f)
),
enabled = isValidEmail(email.text) && !isLoading,
modifier = Modifier.fillMaxWidth()
) {
Text(stringResource(Res.string.`continue`))
Text(text = stringResource(Res.string.`continue`), color = Color.White)
}
} else {
Button(
Expand All @@ -212,10 +307,15 @@ fun SignInEmailScreen(
otpCode
) { }
},
colors = ButtonDefaults.outlinedButtonColors(
contentColor = Color.White,
containerColor = Color(0xFF393AC5),
disabledContainerColor = Color(0xFF393AC5).copy(alpha = 0.5f)
),
enabled = otpCode.length == 6 && !isLoading,
modifier = Modifier.fillMaxWidth()
) {
Text(stringResource(Res.string.verify))
Text(text = stringResource(Res.string.verify), color = Color.White)
}
}
}
Expand Down
Loading