Separate the registration and sign in screens
This commit is contained in:
parent
ffd58cac7a
commit
bab607a898
7 changed files with 158 additions and 235 deletions
|
@ -9,9 +9,9 @@ import androidx.navigation.compose.NavHost
|
||||||
import androidx.navigation.compose.composable
|
import androidx.navigation.compose.composable
|
||||||
import androidx.navigation.compose.rememberNavController
|
import androidx.navigation.compose.rememberNavController
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import software.makeshift.debtpirate.screens.login.`LoginFormViewModel.kt`
|
import software.makeshift.debtpirate.screens.login.LoginFormViewModel
|
||||||
import software.makeshift.debtpirate.screens.login.LoginScreen
|
import software.makeshift.debtpirate.screens.login.LoginScreen
|
||||||
import software.makeshift.debtpirate.screens.login.SignUpFormViewModel
|
import software.makeshift.debtpirate.screens.login.signup.SignUpFormViewModel
|
||||||
import software.makeshift.debtpirate.ui.theme.DebtPirateTheme
|
import software.makeshift.debtpirate.ui.theme.DebtPirateTheme
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
|
@ -28,8 +28,8 @@ class MainActivity : ComponentActivity() {
|
||||||
NavHost(navController = navController, startDestination = LoginRoute) {
|
NavHost(navController = navController, startDestination = LoginRoute) {
|
||||||
composable<LoginRoute> {
|
composable<LoginRoute> {
|
||||||
LoginScreen(
|
LoginScreen(
|
||||||
`loginFormViewModel.kt` = viewModel<`LoginFormViewModel.kt`>(),
|
loginFormViewModel = viewModel<LoginFormViewModel>(),
|
||||||
viewModel = viewModel<SignUpFormViewModel>()
|
signUpFormViewModel = viewModel<SignUpFormViewModel>()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,8 @@ import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
import androidx.compose.foundation.layout.ExperimentalLayoutApi
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
@ -21,6 +23,7 @@ import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.SecondaryTabRow
|
import androidx.compose.material3.SecondaryTabRow
|
||||||
import androidx.compose.material3.Tab
|
import androidx.compose.material3.Tab
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextButton
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
|
@ -29,65 +32,77 @@ import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import software.makeshift.debtpirate.R
|
import software.makeshift.debtpirate.R
|
||||||
|
import software.makeshift.debtpirate.screens.login.signup.SignUpForm
|
||||||
|
import software.makeshift.debtpirate.screens.login.signup.SignUpFormViewModel
|
||||||
|
|
||||||
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
|
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
|
||||||
@Composable
|
@Composable
|
||||||
fun LoginScreen(
|
fun LoginScreen(
|
||||||
`loginFormViewModel.kt`: `LoginFormViewModel.kt`,
|
loginFormViewModel: LoginFormViewModel,
|
||||||
viewModel: SignUpFormViewModel
|
signUpFormViewModel: SignUpFormViewModel
|
||||||
) {
|
) {
|
||||||
Scaffold(modifier = Modifier.fillMaxSize()) {
|
Scaffold(
|
||||||
|
modifier = Modifier.fillMaxSize()
|
||||||
|
) { innerPadding ->
|
||||||
Column {
|
Column {
|
||||||
Banner(
|
LoginTopBar(
|
||||||
|
innerPadding,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.weight(1f)
|
.weight(1f)
|
||||||
)
|
)
|
||||||
|
|
||||||
LoginAndSignUpForms(
|
val displayName = signUpFormViewModel.displayName.collectAsState()
|
||||||
`loginFormViewModel.kt`,
|
val emailAddress = signUpFormViewModel.emailAddress.collectAsState()
|
||||||
viewModel,
|
SignUpForm(
|
||||||
|
displayName,
|
||||||
|
onDisplayNameUpdate = signUpFormViewModel::updateDisplayName,
|
||||||
|
emailAddress,
|
||||||
|
onEmailAddressUpdate = signUpFormViewModel::updateEmailAddress,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.weight(3f)
|
.weight(3f)
|
||||||
|
.padding(16.dp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun Banner(modifier: Modifier = Modifier) {
|
private fun LoginTopBar(innerPadding: PaddingValues, modifier: Modifier = Modifier) {
|
||||||
Box(modifier = modifier.background(Color.Green)) {
|
Box(modifier = modifier.background(Color.Green)) {
|
||||||
Text(
|
Text(
|
||||||
text = "Hello from Login! I'm in a box!",
|
text = "Hello from Login! I'm in a box!",
|
||||||
modifier = Modifier.align(Alignment.Center)
|
modifier = Modifier.align(Alignment.Center)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Row(
|
||||||
|
modifier = Modifier
|
||||||
|
.align(Alignment.TopEnd)
|
||||||
|
.padding(innerPadding)
|
||||||
|
.padding(16.dp)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
TextButton(onClick = { /*TODO*/ }) {
|
||||||
|
Text("Sign In")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalLayoutApi::class)
|
@OptIn(ExperimentalLayoutApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun LoginAndSignUpForms(
|
private fun LoginAndSignUpForms(
|
||||||
`loginFormViewModel.kt`: `LoginFormViewModel.kt`,
|
loginFormViewModel: LoginFormViewModel,
|
||||||
viewModel: SignUpFormViewModel,
|
signUpFormViewModel: SignUpFormViewModel,
|
||||||
modifier: Modifier = Modifier
|
modifier: Modifier = Modifier
|
||||||
) {
|
) {
|
||||||
Column(modifier = modifier) {
|
Column(modifier = modifier) {
|
||||||
val pagerState = rememberPagerState(initialPage = 0) { 2 }
|
val pagerState = rememberPagerState(initialPage = 0) { 1 }
|
||||||
|
|
||||||
SecondaryTabRow(
|
SecondaryTabRow(
|
||||||
selectedTabIndex = pagerState.currentPage,
|
selectedTabIndex = pagerState.currentPage,
|
||||||
modifier = Modifier.height(48.dp)
|
modifier = Modifier.height(48.dp)
|
||||||
) {
|
) {
|
||||||
Tab(
|
|
||||||
selected = pagerState.currentPage == 0,
|
|
||||||
onClick = { pagerState.requestScrollToPage(0) },
|
|
||||||
text = {
|
|
||||||
Text(
|
|
||||||
text = stringResource(id = R.string.login_screen__login)
|
|
||||||
)
|
|
||||||
},
|
|
||||||
modifier = Modifier.fillMaxHeight()
|
|
||||||
)
|
|
||||||
Tab(
|
Tab(
|
||||||
selected = pagerState.currentPage == 1,
|
selected = pagerState.currentPage == 1,
|
||||||
onClick = { pagerState.requestScrollToPage(1) },
|
onClick = { pagerState.requestScrollToPage(1) },
|
||||||
|
@ -98,6 +113,16 @@ private fun LoginAndSignUpForms(
|
||||||
},
|
},
|
||||||
modifier = Modifier.fillMaxHeight()
|
modifier = Modifier.fillMaxHeight()
|
||||||
)
|
)
|
||||||
|
// Tab(
|
||||||
|
// selected = pagerState.currentPage == 0,
|
||||||
|
// onClick = { pagerState.requestScrollToPage(0) },
|
||||||
|
// text = {
|
||||||
|
// Text(
|
||||||
|
// text = stringResource(id = R.string.login_screen__login)
|
||||||
|
// )
|
||||||
|
// },
|
||||||
|
// modifier = Modifier.fillMaxHeight()
|
||||||
|
// )
|
||||||
}
|
}
|
||||||
|
|
||||||
HorizontalPager(
|
HorizontalPager(
|
||||||
|
@ -114,24 +139,11 @@ private fun LoginAndSignUpForms(
|
||||||
|
|
||||||
when (page) {
|
when (page) {
|
||||||
0 -> {
|
0 -> {
|
||||||
LoginForm(
|
|
||||||
`loginFormViewModel.kt`.username,
|
|
||||||
`loginFormViewModel.kt`.password,
|
|
||||||
`loginFormViewModel.kt`::updateUsername,
|
|
||||||
`loginFormViewModel.kt`::updateLoginPassword,
|
|
||||||
formContainerModifier
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
1 -> {
|
|
||||||
val signUpState = viewModel.signUpState.collectAsState()
|
|
||||||
SignUpForm(
|
SignUpForm(
|
||||||
state = signUpState,
|
signUpFormViewModel.displayName.collectAsState(),
|
||||||
viewModel::updateFirstName,
|
signUpFormViewModel::updateDisplayName,
|
||||||
viewModel::updateLastName,
|
signUpFormViewModel.emailAddress.collectAsState(),
|
||||||
viewModel::updateEmailAddress,
|
signUpFormViewModel::updateEmailAddress,
|
||||||
viewModel::updatePassword,
|
|
||||||
viewModel::updateConfirmPassword,
|
|
||||||
formContainerModifier
|
formContainerModifier
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,136 +0,0 @@
|
||||||
package software.makeshift.debtpirate.screens.login
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.rememberScrollState
|
|
||||||
import androidx.compose.foundation.text.KeyboardOptions
|
|
||||||
import androidx.compose.foundation.verticalScroll
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.outlined.Lock
|
|
||||||
import androidx.compose.material.icons.outlined.Mail
|
|
||||||
import androidx.compose.material.icons.outlined.Password
|
|
||||||
import androidx.compose.material.icons.outlined.Person
|
|
||||||
import androidx.compose.material3.Button
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.OutlinedTextField
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.State
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.text.input.ImeAction
|
|
||||||
import androidx.compose.ui.text.input.KeyboardCapitalization
|
|
||||||
import androidx.compose.ui.text.input.KeyboardType
|
|
||||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import software.makeshift.debtpirate.R
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
internal fun SignUpForm(
|
|
||||||
state: State<SignUpState>,
|
|
||||||
onFirstNameUpdate: (String) -> Unit,
|
|
||||||
onLastNameUpdate: (String) -> Unit,
|
|
||||||
onEmailUpdate: (String) -> Unit,
|
|
||||||
onPasswordUpdate: (String) -> Unit,
|
|
||||||
onPasswordConfirmedUpdate: (String) -> Unit,
|
|
||||||
modifier: Modifier = Modifier
|
|
||||||
) {
|
|
||||||
Column(modifier.verticalScroll(rememberScrollState()))
|
|
||||||
{
|
|
||||||
OutlinedTextField(
|
|
||||||
value = state.value.firstName,
|
|
||||||
label = { Text(stringResource(id = R.string.login_screen__first_name)) },
|
|
||||||
placeholder = { Text(stringResource(id = R.string.login_screen__first_name)) },
|
|
||||||
leadingIcon = { Icon(Icons.Outlined.Person, "person") },
|
|
||||||
singleLine = true,
|
|
||||||
keyboardOptions = KeyboardOptions(
|
|
||||||
capitalization = KeyboardCapitalization.Words,
|
|
||||||
keyboardType = KeyboardType.Text,
|
|
||||||
imeAction = ImeAction.Next
|
|
||||||
),
|
|
||||||
onValueChange = onFirstNameUpdate,
|
|
||||||
modifier = Modifier.fillMaxWidth()
|
|
||||||
)
|
|
||||||
|
|
||||||
OutlinedTextField(
|
|
||||||
value = state.value.lastName,
|
|
||||||
label = { Text(stringResource(id = R.string.login_screen__last_name)) },
|
|
||||||
placeholder = { Text(stringResource(id = R.string.login_screen__last_name)) },
|
|
||||||
leadingIcon = { Icon(Icons.Outlined.Person, "person") },
|
|
||||||
singleLine = true,
|
|
||||||
keyboardOptions = KeyboardOptions(
|
|
||||||
capitalization = KeyboardCapitalization.Words,
|
|
||||||
keyboardType = KeyboardType.Text,
|
|
||||||
imeAction = ImeAction.Next
|
|
||||||
),
|
|
||||||
onValueChange = onLastNameUpdate,
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(PaddingValues(top = 8.dp))
|
|
||||||
)
|
|
||||||
|
|
||||||
OutlinedTextField(
|
|
||||||
value = state.value.email,
|
|
||||||
label = { Text(stringResource(id = R.string.login_screen__email)) },
|
|
||||||
placeholder = { Text(stringResource(id = R.string.login_screen__email)) },
|
|
||||||
leadingIcon = { Icon(Icons.Outlined.Mail, "email") },
|
|
||||||
singleLine = true,
|
|
||||||
keyboardOptions = KeyboardOptions(
|
|
||||||
capitalization = KeyboardCapitalization.Unspecified,
|
|
||||||
keyboardType = KeyboardType.Email,
|
|
||||||
imeAction = ImeAction.Next
|
|
||||||
),
|
|
||||||
onValueChange = onEmailUpdate,
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(PaddingValues(top = 8.dp))
|
|
||||||
)
|
|
||||||
|
|
||||||
OutlinedTextField(
|
|
||||||
value = state.value.password,
|
|
||||||
label = { Text(stringResource(id = R.string.login_screen__password)) },
|
|
||||||
placeholder = { Text(stringResource(id = R.string.login_screen__password)) },
|
|
||||||
leadingIcon = { Icon(Icons.Outlined.Lock, "password") },
|
|
||||||
singleLine = true,
|
|
||||||
keyboardOptions = KeyboardOptions(
|
|
||||||
capitalization = KeyboardCapitalization.Unspecified,
|
|
||||||
keyboardType = KeyboardType.Password,
|
|
||||||
imeAction = ImeAction.Next
|
|
||||||
),
|
|
||||||
visualTransformation = PasswordVisualTransformation(),
|
|
||||||
onValueChange = onPasswordUpdate,
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(PaddingValues(top = 8.dp))
|
|
||||||
)
|
|
||||||
|
|
||||||
OutlinedTextField(
|
|
||||||
value = state.value.passwordConfirmed,
|
|
||||||
label = { Text(stringResource(id = R.string.login_screen__confirm_password)) },
|
|
||||||
placeholder = { Text(stringResource(id = R.string.login_screen__confirm_password)) },
|
|
||||||
leadingIcon = { Icon(Icons.Outlined.Password, "confirm password") },
|
|
||||||
singleLine = true,
|
|
||||||
keyboardOptions = KeyboardOptions(
|
|
||||||
capitalization = KeyboardCapitalization.Unspecified,
|
|
||||||
keyboardType = KeyboardType.Password,
|
|
||||||
imeAction = ImeAction.Send
|
|
||||||
),
|
|
||||||
visualTransformation = PasswordVisualTransformation(),
|
|
||||||
onValueChange = onPasswordConfirmedUpdate,
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(PaddingValues(top = 8.dp))
|
|
||||||
)
|
|
||||||
|
|
||||||
Button(
|
|
||||||
onClick = { /*TODO*/ },
|
|
||||||
modifier = Modifier
|
|
||||||
.padding(PaddingValues(top = 32.dp))
|
|
||||||
.fillMaxWidth()
|
|
||||||
) {
|
|
||||||
Text(stringResource(id = R.string.login_screen__signup))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,55 +0,0 @@
|
||||||
package software.makeshift.debtpirate.screens.login
|
|
||||||
|
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
|
||||||
|
|
||||||
data class SignUpState(
|
|
||||||
val firstName: String = "",
|
|
||||||
val lastName: String = "",
|
|
||||||
val email: String = "",
|
|
||||||
val password: String = "",
|
|
||||||
val passwordConfirmed: String = ""
|
|
||||||
)
|
|
||||||
|
|
||||||
class SignUpFormViewModel : ViewModel() {
|
|
||||||
private val _firstName = MutableStateFlow("")
|
|
||||||
val firstName = _firstName.asStateFlow()
|
|
||||||
|
|
||||||
private val _lastName = MutableStateFlow("")
|
|
||||||
val lastName = _lastName.asStateFlow()
|
|
||||||
|
|
||||||
private val _emailAddress = MutableStateFlow("")
|
|
||||||
val emailAddress = _emailAddress.asStateFlow()
|
|
||||||
|
|
||||||
private val _password = MutableStateFlow("")
|
|
||||||
val password = _password.asStateFlow()
|
|
||||||
|
|
||||||
private val _confirmPassword = MutableStateFlow("")
|
|
||||||
val confirmPassword = _confirmPassword.asStateFlow()
|
|
||||||
|
|
||||||
|
|
||||||
fun updateFirstName(firstName: String) {
|
|
||||||
_firstName.value = firstName
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateLastName(lastName: String) {
|
|
||||||
_lastName.value = lastName
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateEmailAddress(emailAddress: String) {
|
|
||||||
_emailAddress.value = emailAddress
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updatePassword(password: String) {
|
|
||||||
_password.value = password
|
|
||||||
}
|
|
||||||
|
|
||||||
fun updateConfirmPassword(confirmPassword: String) {
|
|
||||||
_confirmPassword.value = confirmPassword
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isValidPassword() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
package software.makeshift.debtpirate.screens.login.signup
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.rememberScrollState
|
||||||
|
import androidx.compose.foundation.text.KeyboardOptions
|
||||||
|
import androidx.compose.foundation.verticalScroll
|
||||||
|
import androidx.compose.material.icons.Icons
|
||||||
|
import androidx.compose.material.icons.outlined.Mail
|
||||||
|
import androidx.compose.material.icons.outlined.Person
|
||||||
|
import androidx.compose.material3.Button
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.OutlinedTextField
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.State
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.text.input.ImeAction
|
||||||
|
import androidx.compose.ui.text.input.KeyboardCapitalization
|
||||||
|
import androidx.compose.ui.text.input.KeyboardType
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import software.makeshift.debtpirate.R
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
internal fun SignUpForm(
|
||||||
|
displayName: State<String>,
|
||||||
|
onDisplayNameUpdate: (String) -> Unit,
|
||||||
|
emailAddress: State<String>,
|
||||||
|
onEmailAddressUpdate: (String) -> Unit,
|
||||||
|
modifier: Modifier = Modifier
|
||||||
|
) {
|
||||||
|
Column(modifier.verticalScroll(rememberScrollState()))
|
||||||
|
{
|
||||||
|
OutlinedTextField(
|
||||||
|
value = displayName.value,
|
||||||
|
label = { Text(stringResource(id = R.string.login_screen__display_name)) },
|
||||||
|
placeholder = { Text(stringResource(id = R.string.login_screen__display_name)) },
|
||||||
|
leadingIcon = { Icon(Icons.Outlined.Person, "person") },
|
||||||
|
singleLine = true,
|
||||||
|
keyboardOptions = KeyboardOptions(
|
||||||
|
capitalization = KeyboardCapitalization.Words,
|
||||||
|
keyboardType = KeyboardType.Text,
|
||||||
|
imeAction = ImeAction.Next
|
||||||
|
),
|
||||||
|
onValueChange = onDisplayNameUpdate,
|
||||||
|
modifier = Modifier.fillMaxWidth()
|
||||||
|
)
|
||||||
|
|
||||||
|
OutlinedTextField(
|
||||||
|
value = emailAddress.value,
|
||||||
|
label = { Text(stringResource(id = R.string.login_screen__email)) },
|
||||||
|
placeholder = { Text(stringResource(id = R.string.login_screen__email)) },
|
||||||
|
leadingIcon = { Icon(Icons.Outlined.Mail, "email") },
|
||||||
|
singleLine = true,
|
||||||
|
keyboardOptions = KeyboardOptions(
|
||||||
|
capitalization = KeyboardCapitalization.Unspecified,
|
||||||
|
keyboardType = KeyboardType.Email,
|
||||||
|
imeAction = ImeAction.Next
|
||||||
|
),
|
||||||
|
onValueChange = onEmailAddressUpdate,
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(PaddingValues(top = 8.dp))
|
||||||
|
)
|
||||||
|
|
||||||
|
Button(
|
||||||
|
onClick = { /*TODO*/ },
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(PaddingValues(top = 32.dp))
|
||||||
|
.fillMaxWidth()
|
||||||
|
) {
|
||||||
|
Text(stringResource(id = R.string.login_screen__signup))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package software.makeshift.debtpirate.screens.login.signup
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
|
|
||||||
|
class SignUpFormViewModel : ViewModel() {
|
||||||
|
private val _displayName = MutableStateFlow("")
|
||||||
|
val displayName = _displayName.asStateFlow()
|
||||||
|
|
||||||
|
private val _emailAddress = MutableStateFlow("")
|
||||||
|
val emailAddress = _emailAddress.asStateFlow()
|
||||||
|
|
||||||
|
fun updateDisplayName(firstName: String) {
|
||||||
|
_displayName.value = firstName
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateEmailAddress(emailAddress: String) {
|
||||||
|
_emailAddress.value = emailAddress
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isValidPassword() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,8 +8,7 @@
|
||||||
<string name="login_screen__email">Email Address</string>
|
<string name="login_screen__email">Email Address</string>
|
||||||
<string name="login_screen__password">Password</string>
|
<string name="login_screen__password">Password</string>
|
||||||
<string name="login_screen__confirm_password">Confirm Password</string>
|
<string name="login_screen__confirm_password">Confirm Password</string>
|
||||||
<string name="login_screen__first_name">First Name</string>
|
<string name="login_screen__display_name">Display Name</string>
|
||||||
<string name="login_screen__last_name">Last Name</string>
|
|
||||||
<string name="login_screen__forgot_password">Forgot Password?</string>
|
<string name="login_screen__forgot_password">Forgot Password?</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
Loading…
Add table
Reference in a new issue