This is a dating app
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

938 lines
34 KiB

package com.example.dattingapp
import android.content.Intent
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.animation.*
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.runtime.snapshots.SnapshotStateList
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import java.text.SimpleDateFormat
import java.util.*
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Explore
import androidx.compose.material.icons.outlined.FavoriteBorder
import androidx.compose.material.icons.outlined.Group
import androidx.compose.material.icons.outlined.LocalBar
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.text.style.TextAlign
import com.example.dattingapp.registration.UploadProfileImageActivity
// Global Email Validation Regex
val EMAIL_PATTERN_REGEX = Regex("^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$")
data class VibeOption(
val title: String,
val subtitle: String,
val icon: ImageVector,
val iconBgColor: Color,
val iconTintColor: Color
)
class RegistrationScreen : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState)
setContent {
MaterialTheme {
FullscreenRegistrationWizard()
}
}
}
}
@Composable
fun FullscreenRegistrationWizard() {
// Active step state
var currentStep by remember { mutableIntStateOf(1) }
val totalSteps = 7
// Form Field States
var isPhoneSelected by remember { mutableStateOf(false) }
var countryCode by remember { mutableStateOf("+880") }
var contactInput by remember { mutableStateOf("") }
var contactError by remember { mutableStateOf<String?>(null) }
var passwordInput by remember { mutableStateOf("") }
var confirmPasswordInput by remember { mutableStateOf("") }
var passwordError by remember { mutableStateOf<String?>(null) }
var nameInput by remember { mutableStateOf("") }
var nameError by remember { mutableStateOf<String?>(null) }
var dobInput by remember { mutableStateOf("") }
var dobError by remember { mutableStateOf<String?>(null) }
var genderInput by remember { mutableStateOf("") }
var genderError by remember { mutableStateOf<String?>(null) }
val selectedInterests = remember { mutableStateListOf<String>() }
var interestsError by remember { mutableStateOf<String?>(null) }
var vibeInput by remember { mutableStateOf("") }
var vibeError by remember { mutableStateOf<String?>(null) }
// Inside your FullscreenRegistrationWizard composable:
val context = LocalContext.current
// Validation & Navigation
fun validateAndProceed() {
when (currentStep) {
1 -> {
if (nameInput.trim().isBlank()) {
nameError = "Please enter your name"
} else {
nameError = null
currentStep = 2
}
}
2 -> {
if (isPhoneSelected) {
when {
contactInput.isBlank() -> contactError = "Please enter a phone number"
contactInput.length < 7 || contactInput.length > 15 -> contactError = "Enter 7-15 digits"
else -> { contactError = null; currentStep = 2 }
}
} else {
val trimmedEmail = contactInput.trim()
when {
trimmedEmail.isBlank() -> contactError = "Please enter an email address"
!EMAIL_PATTERN_REGEX.matches(trimmedEmail) -> contactError = "Invalid email format"
else -> { contactError = null; currentStep = 4 }
}
}
}
3 -> {
when {
passwordInput.length < 6 -> passwordError = "Password must be at least 6 characters"
passwordInput != confirmPasswordInput -> passwordError = "Passwords do not match"
else -> { passwordError = null; currentStep = 3 }
}
}
4 -> {
if (dobInput.isBlank()) {
dobError = "Please select your date of birth"
} else {
dobError = null
currentStep = 5
}
}
5 -> {
if (genderInput.isBlank()) {
genderError = "Please select your gender"
} else {
genderError = null
currentStep = 6
}
}
6 -> {
if (selectedInterests.size < 2) {
interestsError = "Please select at least 2 interests"
} else {
interestsError = null
// Submit registration payload
currentStep = 7
}
}
7 -> {
if (vibeInput.isBlank()) {
vibeError = "Please select your vibe to continue"
} else {
vibeError = null
// Launch UploadImageActivity with all collected data
val intent = Intent(context, UploadProfileImageActivity::class.java).apply {
putExtra("EXTRA_IS_PHONE", isPhoneSelected)
putExtra("EXTRA_COUNTRY_CODE", countryCode)
putExtra("EXTRA_CONTACT_VALUE", contactInput)
putExtra("EXTRA_PASSWORD", passwordInput)
putExtra("EXTRA_NAME", nameInput)
putExtra("EXTRA_DOB", dobInput)
putExtra("EXTRA_GENDER", genderInput)
putExtra("EXTRA_INTERESTS", ArrayList(selectedInterests))
putExtra("EXTRA_VIBE", vibeInput)
}
context.startActivity(intent)
}
}
}
}
Box(
modifier = Modifier
.fillMaxSize()
.background(Color(0xFFF8F9FA))
.systemBarsPadding()
) {
Column(modifier = Modifier.fillMaxSize()) {
// TOP BAR & PROGRESS
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 20.dp, vertical = 16.dp)
) {
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
if (currentStep > 1) {
TextButton(
onClick = { currentStep-- },
contentPadding = PaddingValues(0.dp)
) {
Text("Back", color = Color.Gray, fontSize = 16.sp)
}
} else {
Spacer(modifier = Modifier.width(48.dp))
}
Text(
text = "Step $currentStep of $totalSteps",
fontWeight = FontWeight.Bold,
fontSize = 16.sp,
color = Color.Black
)
Spacer(modifier = Modifier.width(48.dp))
}
Spacer(modifier = Modifier.height(12.dp))
LinearProgressIndicator(
progress = { currentStep / totalSteps.toFloat() },
modifier = Modifier
.fillMaxWidth()
.height(6.dp),
color = Color.Black,
trackColor = Color(0xFFE0E0E0)
)
}
// SLIDING CONTENT CONTAINER
Box(
modifier = Modifier
.weight(1f)
.fillMaxWidth()
.padding(horizontal = 24.dp),
contentAlignment = Alignment.Center
) {
AnimatedContent(
targetState = currentStep,
transitionSpec = {
if (targetState > initialState) {
slideIntoContainer(
AnimatedContentTransitionScope.SlideDirection.Left,
animationSpec = tween(400)
) + fadeIn(animationSpec = tween(400)) togetherWith
slideOutOfContainer(
AnimatedContentTransitionScope.SlideDirection.Left,
animationSpec = tween(400)
) + fadeOut(animationSpec = tween(400))
} else {
slideIntoContainer(
AnimatedContentTransitionScope.SlideDirection.Right,
animationSpec = tween(400)
) + fadeIn(animationSpec = tween(400)) togetherWith
slideOutOfContainer(
AnimatedContentTransitionScope.SlideDirection.Right,
animationSpec = tween(400)
) + fadeOut(animationSpec = tween(400))
}
},
label = "WizardSlideAnimation"
) { step ->
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
when (step) {
1 -> NameInputWidget(
name = nameInput,
onNameChange = { nameInput = it; nameError = null },
errorMessage = nameError
)
2 -> ContactInputWidget(
isPhoneSelected = isPhoneSelected,
onModeChange = { isPhoneSelected = it; contactError = null },
countryCode = countryCode,
onCountryCodeChange = { countryCode = it },
contactValue = contactInput,
onContactChange = { contactInput = it; contactError = null },
errorMessage = contactError
)
3 -> PasswordInputWidget(
password = passwordInput,
onPasswordChange = { passwordInput = it; passwordError = null },
confirmPassword = confirmPasswordInput,
onConfirmPasswordChange = { confirmPasswordInput = it; passwordError = null },
errorMessage = passwordError
)
4 -> DobInputWidget(
dob = dobInput,
onDobChange = { dobInput = it; dobError = null },
errorMessage = dobError
)
5 -> GenderInputWidget(
selectedGender = genderInput,
onGenderSelect = { genderInput = it; genderError = null },
errorMessage = genderError
)
6 -> InterestsInputWidget(
selectedInterests = selectedInterests,
errorMessage = interestsError,
onSelectionChanged = { interestsError = null }
)
7 -> VibeCheckWidget(
selectedVibe = vibeInput,
onVibeSelected = {
vibeInput = it
vibeError = null
},
errorMessage = vibeError
)
}
}
}
}
// BOTTOM ACTION BUTTON
Box(
modifier = Modifier
.fillMaxWidth()
.padding(20.dp)
) {
Button(
onClick = { validateAndProceed() },
modifier = Modifier
.fillMaxWidth()
.height(54.dp),
shape = RoundedCornerShape(16.dp),
colors = ButtonDefaults.buttonColors(containerColor = Color.Black)
) {
Text(
text = if (currentStep == totalSteps) "Complete Registration" else "Continue",
color = Color.White,
fontSize = 16.sp,
fontWeight = FontWeight.Bold
)
}
}
}
}
}
// ==================== STEP WIDGET COMPOSABLES ====================
@Composable
fun ContactInputWidget(
isPhoneSelected: Boolean,
onModeChange: (Boolean) -> Unit,
countryCode: String,
onCountryCodeChange: (String) -> Unit,
contactValue: String,
onContactChange: (String) -> Unit,
errorMessage: String?
) {
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
Text(
text = "ENTER YOUR CONTACT INFORMATION",
fontSize = 11.sp,
fontWeight = FontWeight.Bold,
color = Color.Gray
)
Row(
modifier = Modifier
.fillMaxWidth()
.height(48.dp)
.clip(RoundedCornerShape(24.dp))
.background(Color(0xFFEFEFEF))
.padding(4.dp),
verticalAlignment = Alignment.CenterVertically
) {
Box(
modifier = Modifier
.weight(1f)
.fillMaxHeight()
.clip(RoundedCornerShape(20.dp))
.background(if (isPhoneSelected) Color.Black else Color.Transparent)
.clickable { onModeChange(true) },
contentAlignment = Alignment.Center
) {
Text(
text = "Phone",
fontWeight = FontWeight.Bold,
fontSize = 14.sp,
color = if (isPhoneSelected) Color.White else Color.DarkGray
)
}
Box(
modifier = Modifier
.weight(1f)
.fillMaxHeight()
.clip(RoundedCornerShape(20.dp))
.background(if (!isPhoneSelected) Color.Black else Color.Transparent)
.clickable { onModeChange(false) },
contentAlignment = Alignment.Center
) {
Text(
text = "Email",
fontWeight = FontWeight.Bold,
fontSize = 14.sp,
color = if (!isPhoneSelected) Color.White else Color.DarkGray
)
}
}
if (isPhoneSelected) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
OutlinedTextField(
value = countryCode,
onValueChange = { if (it.length <= 4) onCountryCodeChange(it) },
placeholder = { Text("+880") },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Phone),
singleLine = true,
isError = errorMessage != null,
modifier = Modifier.width(90.dp),
shape = RoundedCornerShape(12.dp),
colors = OutlinedTextFieldDefaults.colors(
focusedContainerColor = Color.White,
unfocusedContainerColor = Color.White
)
)
OutlinedTextField(
value = contactValue,
onValueChange = { if (it.length <= 15) onContactChange(it) },
placeholder = { Text("Phone number") },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number),
singleLine = true,
isError = errorMessage != null,
modifier = Modifier.weight(1f),
shape = RoundedCornerShape(12.dp),
colors = OutlinedTextFieldDefaults.colors(
focusedContainerColor = Color.White,
unfocusedContainerColor = Color.White
)
)
}
} else {
OutlinedTextField(
value = contactValue,
onValueChange = onContactChange,
placeholder = { Text("Enter email address") },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email),
singleLine = true,
isError = errorMessage != null,
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(12.dp),
colors = OutlinedTextFieldDefaults.colors(
focusedContainerColor = Color.White,
unfocusedContainerColor = Color.White
)
)
}
if (errorMessage != null) {
Text(
text = errorMessage,
color = MaterialTheme.colorScheme.error,
fontSize = 12.sp,
fontWeight = FontWeight.Medium,
modifier = Modifier.padding(start = 4.dp)
)
}
}
}
@Composable
fun PasswordInputWidget(
password: String,
onPasswordChange: (String) -> Unit,
confirmPassword: String,
onConfirmPasswordChange: (String) -> Unit,
errorMessage: String?
) {
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
Text(
text = "CREATE A PASSWORD",
fontSize = 11.sp,
fontWeight = FontWeight.Bold,
color = Color.Gray
)
OutlinedTextField(
value = password,
onValueChange = onPasswordChange,
placeholder = { Text("Enter password") },
visualTransformation = PasswordVisualTransformation(),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
singleLine = true,
isError = errorMessage != null,
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(12.dp),
colors = OutlinedTextFieldDefaults.colors(
focusedContainerColor = Color.White,
unfocusedContainerColor = Color.White
)
)
OutlinedTextField(
value = confirmPassword,
onValueChange = onConfirmPasswordChange,
placeholder = { Text("Confirm password") },
visualTransformation = PasswordVisualTransformation(),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
singleLine = true,
isError = errorMessage != null,
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(12.dp),
colors = OutlinedTextFieldDefaults.colors(
focusedContainerColor = Color.White,
unfocusedContainerColor = Color.White
)
)
if (errorMessage != null) {
Text(
text = errorMessage,
color = MaterialTheme.colorScheme.error,
fontSize = 12.sp,
fontWeight = FontWeight.Medium,
modifier = Modifier.padding(start = 4.dp)
)
}
}
}
@Composable
fun NameInputWidget(
name: String,
onNameChange: (String) -> Unit,
errorMessage: String?
) {
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
Text(
text = "WHAT IS YOUR NAME?",
fontSize = 11.sp,
fontWeight = FontWeight.Bold,
color = Color.Gray
)
OutlinedTextField(
value = name,
onValueChange = onNameChange,
placeholder = { Text("Enter your full name") },
singleLine = true,
isError = errorMessage != null,
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(12.dp),
colors = OutlinedTextFieldDefaults.colors(
focusedContainerColor = Color.White,
unfocusedContainerColor = Color.White
)
)
if (errorMessage != null) {
Text(
text = errorMessage,
color = MaterialTheme.colorScheme.error,
fontSize = 12.sp,
fontWeight = FontWeight.Medium,
modifier = Modifier.padding(start = 4.dp)
)
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun DobInputWidget(
dob: String,
onDobChange: (String) -> Unit,
errorMessage: String?
) {
var showDatePicker by remember { mutableStateOf(false) }
val datePickerState = rememberDatePickerState()
if (showDatePicker) {
DatePickerDialog(
onDismissRequest = { showDatePicker = false },
confirmButton = {
TextButton(onClick = {
datePickerState.selectedDateMillis?.let { millis ->
val formatter = SimpleDateFormat("dd/MM/yyyy", Locale.getDefault())
onDobChange(formatter.format(Date(millis)))
}
showDatePicker = false
}) {
Text("OK")
}
},
dismissButton = {
TextButton(onClick = { showDatePicker = false }) {
Text("Cancel")
}
}
) {
DatePicker(state = datePickerState)
}
}
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
Text(
text = "YOUR DATE OF BIRTH",
fontSize = 11.sp,
fontWeight = FontWeight.Bold,
color = Color.Gray
)
Box(modifier = Modifier.fillMaxWidth()) {
OutlinedTextField(
value = dob,
onValueChange = {},
readOnly = true,
placeholder = { Text("DD/MM/YYYY") },
isError = errorMessage != null,
modifier = Modifier.fillMaxWidth(),
shape = RoundedCornerShape(12.dp),
colors = OutlinedTextFieldDefaults.colors(
focusedContainerColor = Color.White,
unfocusedContainerColor = Color.White
)
)
Box(
modifier = Modifier
.matchParentSize()
.clickable { showDatePicker = true }
)
}
if (errorMessage != null) {
Text(
text = errorMessage,
color = MaterialTheme.colorScheme.error,
fontSize = 12.sp,
fontWeight = FontWeight.Medium,
modifier = Modifier.padding(start = 4.dp)
)
}
}
}
@Composable
fun GenderInputWidget(
selectedGender: String,
onGenderSelect: (String) -> Unit,
errorMessage: String?
) {
val options = listOf("Male", "Female", "Other")
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
Text(
text = "SELECT YOUR GENDER",
fontSize = 11.sp,
fontWeight = FontWeight.Bold,
color = Color.Gray
)
options.forEach { gender ->
val isSelected = selectedGender == gender
Card(
shape = RoundedCornerShape(12.dp),
colors = CardDefaults.cardColors(
containerColor = if (isSelected) Color.Black else Color.White
),
modifier = Modifier
.fillMaxWidth()
.clickable { onGenderSelect(gender) }
) {
Box(
modifier = Modifier.padding(16.dp),
contentAlignment = Alignment.CenterStart
) {
Text(
text = gender,
color = if (isSelected) Color.White else Color.Black,
fontWeight = FontWeight.SemiBold,
fontSize = 15.sp
)
}
}
}
if (errorMessage != null) {
Text(
text = errorMessage,
color = MaterialTheme.colorScheme.error,
fontSize = 12.sp,
fontWeight = FontWeight.Medium,
modifier = Modifier.padding(start = 4.dp)
)
}
}
}
@OptIn(ExperimentalLayoutApi::class)
@Composable
fun InterestsInputWidget(
selectedInterests: SnapshotStateList<String>,
errorMessage: String? = null,
onSelectionChanged: () -> Unit = {}
) {
val allInterests = listOf("Photography", "Dogs", "Travel", "Music", "Gaming", "Fitness", "Cooking")
Card(
shape = RoundedCornerShape(16.dp),
colors = CardDefaults.cardColors(containerColor = Color.White),
modifier = Modifier.fillMaxWidth()
) {
Column(modifier = Modifier.padding(16.dp)) {
Text(
text = "INTERESTS (SELECT AT LEAST 2)",
fontSize = 11.sp,
fontWeight = FontWeight.Bold,
color = Color.Gray
)
Spacer(modifier = Modifier.height(12.dp))
FlowRow(
horizontalArrangement = Arrangement.spacedBy(8.dp),
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
allInterests.forEach { interest ->
val isSelected = selectedInterests.contains(interest)
FilterChip(
selected = isSelected,
onClick = {
if (isSelected) selectedInterests.remove(interest)
else selectedInterests.add(interest)
onSelectionChanged()
},
label = { Text(interest) }
)
}
}
if (errorMessage != null) {
Spacer(modifier = Modifier.height(8.dp))
Text(
text = errorMessage,
color = MaterialTheme.colorScheme.error,
fontSize = 12.sp,
fontWeight = FontWeight.Medium
)
}
}
}
}
@Composable
fun VibeCheckWidget(
selectedVibe: String,
onVibeSelected: (String) -> Unit,
errorMessage: String? = null
) {
val options = listOf(
VibeOption("Serious Relationship", "Looking for the one", Icons.Outlined.FavoriteBorder, Color(0xFFFFEAEA), Color(0xFFE91E63)),
VibeOption("Casual Dates", "Drinks & good times", Icons.Outlined.LocalBar, Color(0xFFEDE7F6), Color(0xFF673AB7)),
VibeOption("New Friends", "Expand my circle", Icons.Outlined.Group, Color(0xFFFFECB3), Color(0xFFFF8F00)),
VibeOption("Marraige", "Seeing where things go", Icons.Outlined.Explore, Color(0xFFE0F2F1), Color(0xFF00897B))
)
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
// App Title / Brand Header
Text(
text = "VibeCheck",
fontSize = 24.sp,
fontWeight = FontWeight.Bold,
color = Color(0xFFC2185B)
)
Spacer(modifier = Modifier.height(8.dp))
// Three Indicator Bars
Row(
horizontalArrangement = Arrangement.spacedBy(6.dp),
verticalAlignment = Alignment.CenterVertically
) {
Box(modifier = Modifier.width(20.dp).height(4.dp).background(Color(0xFFE0E0E0), CircleShape))
Box(modifier = Modifier.width(20.dp).height(4.dp).background(Color(0xFFC2185B), CircleShape))
Box(modifier = Modifier.width(20.dp).height(4.dp).background(Color(0xFFE0E0E0), CircleShape))
}
Spacer(modifier = Modifier.height(20.dp))
// Title & Description
Text(
text = "What's your vibe?",
fontSize = 20.sp,
fontWeight = FontWeight.Bold,
color = Color.Black
)
Spacer(modifier = Modifier.height(8.dp))
Text(
text = "Select your main goal right now to help us find the right connections.",
fontSize = 13.sp,
color = Color.Gray,
textAlign = TextAlign.Center,
modifier = Modifier.padding(horizontal = 16.dp)
)
Spacer(modifier = Modifier.height(24.dp))
// Vibe Cards List
Column(
verticalArrangement = Arrangement.spacedBy(12.dp),
modifier = Modifier.fillMaxWidth()
) {
options.forEach { option ->
val isSelected = selectedVibe == option.title
Card(
shape = RoundedCornerShape(16.dp),
colors = CardDefaults.cardColors(containerColor = Color.White),
border = BorderStroke(
width = if (isSelected) 2.dp else 1.dp,
color = if (isSelected) Color(0xFFC2185B) else Color(0xFFEEEEEE)
),
modifier = Modifier
.fillMaxWidth()
.clickable { onVibeSelected(option.title) }
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
verticalAlignment = Alignment.CenterVertically
) {
// Round Icon Container
Box(
modifier = Modifier
.size(42.dp)
.background(option.iconBgColor, CircleShape),
contentAlignment = Alignment.Center
) {
Icon(
imageVector = option.icon,
contentDescription = option.title,
tint = option.iconTintColor,
modifier = Modifier.size(22.dp)
)
}
Spacer(modifier = Modifier.width(16.dp))
// Text Labels
Column {
Text(
text = option.title,
fontSize = 15.sp,
fontWeight = FontWeight.Bold,
color = Color.Black
)
Text(
text = option.subtitle,
fontSize = 12.sp,
color = Color.Gray
)
}
}
}
}
}
if (errorMessage != null) {
Spacer(modifier = Modifier.height(12.dp))
Text(
text = errorMessage,
color = MaterialTheme.colorScheme.error,
fontSize = 12.sp,
fontWeight = FontWeight.Medium
)
}
Spacer(modifier = Modifier.height(16.dp))
Text(
text = "You can always change this later in your profile.",
fontSize = 11.sp,
color = Color.Gray
)
}
}
@Preview(
name = "Light Mode - Full Wizard",
showBackground = true,
showSystemUi = true
)
@Composable
fun FullscreenRegistrationWizardPreview() {
Surface(modifier = Modifier.fillMaxSize()) {
FullscreenRegistrationWizard()
}
}