package com.example.ui.screens import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.foundation.layout.* import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Business import androidx.compose.material.icons.filled.Lock import androidx.compose.material.icons.filled.Mail import androidx.compose.material.icons.filled.Person import androidx.compose.material.icons.filled.Place import androidx.compose.material.icons.filled.Language import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.testTag import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.example.ui.PortalViewModel import com.example.ui.theme.* import kotlinx.coroutines.launch @Composable fun UserLoginScreen( viewModel: PortalViewModel, onNavigateRegister: () -> Unit ) { var email by remember { mutableStateOf("james@example.com") } var password by remember { mutableStateOf("password123") } var forgotSentMsg by remember { mutableStateOf(null) } var showGoogleSelector by remember { mutableStateOf(false) } var isGoogleAuthenticating by remember { mutableStateOf(false) } val scope = rememberCoroutineScope() if (showGoogleSelector) { GoogleAccountSelectorDialog( onDismiss = { showGoogleSelector = false }, onAccountSelected = { name, gmail -> showGoogleSelector = false isGoogleAuthenticating = true scope.launch { kotlinx.coroutines.delay(1200) // high-fidelity animation loop viewModel.googleUserLogin(name, gmail) { isGoogleAuthenticating = false } } } ) } Column( modifier = Modifier .fillMaxSize() .background(Obsidian) .padding(24.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { if (isGoogleAuthenticating) { Card( colors = CardDefaults.cardColors(containerColor = DarkGreyGlassElevated), modifier = Modifier.padding(16.dp), shape = RoundedCornerShape(12.dp) ) { Column( modifier = Modifier.padding(24.dp), horizontalAlignment = Alignment.CenterHorizontally ) { CircularProgressIndicator(color = BrandGold) Spacer(modifier = Modifier.height(16.dp)) Text("Securing Google Handshake...", color = TextPrimary, fontWeight = FontWeight.SemiBold) Text("Auto Login & Sign-up Syncing", color = TextSecondary, style = MaterialTheme.typography.bodySmall) } } } else { Surface( shape = RoundedCornerShape(12.dp), color = BrandGold.copy(0.15f), contentColor = BrandGold ) { Text( "USER PORTAL ACCESS", modifier = Modifier.padding(horizontal = 14.dp, vertical = 6.dp), style = MaterialTheme.typography.labelSmall, fontWeight = FontWeight.Bold ) } Spacer(modifier = Modifier.height(16.dp)) Text( "Welcome back, Customer", style = MaterialTheme.typography.headlineMedium, color = TextPrimary, fontWeight = FontWeight.Bold ) Text( "Access luxury directories and safehouse availability slots.", style = MaterialTheme.typography.bodySmall, color = TextSecondary, textAlign = TextAlign.Center ) Spacer(modifier = Modifier.height(32.dp)) TextField( value = email, onValueChange = { email = it }, placeholder = { Text("Email Address") }, leadingIcon = { Icon(Icons.Default.Mail, contentDescription = "Mail", tint = BrandGold) }, modifier = Modifier .fillMaxWidth() .testTag("user_email_input"), colors = TextFieldDefaults.colors( focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary ) ) Spacer(modifier = Modifier.height(12.dp)) TextField( value = password, onValueChange = { password = it }, placeholder = { Text("Password") }, leadingIcon = { Icon(Icons.Default.Lock, contentDescription = "Lock", tint = BrandGold) }, modifier = Modifier .fillMaxWidth() .testTag("user_password_input"), colors = TextFieldDefaults.colors( focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary ) ) Spacer(modifier = Modifier.height(12.dp)) Text( text = "Forgot Password?", color = BrandGold, style = MaterialTheme.typography.bodySmall, fontWeight = FontWeight.SemiBold, modifier = Modifier .align(Alignment.End) .clickable { forgotSentMsg = "Password reset instructions sent to $email." } .testTag("user_forgot_pw") ) Spacer(modifier = Modifier.height(24.dp)) Button( onClick = { viewModel.userLogin() }, colors = ButtonDefaults.buttonColors(containerColor = BrandGold, contentColor = Color.Black), shape = RoundedCornerShape(12.dp), modifier = Modifier .fillMaxWidth() .height(48.dp) .testTag("user_login_btn") ) { Text("Login to Client Portal", fontWeight = FontWeight.Bold) } Spacer(modifier = Modifier.height(16.dp)) // Google login button OutlinedButton( onClick = { showGoogleSelector = true }, modifier = Modifier .fillMaxWidth() .height(48.dp) .testTag("user_google_login_btn"), shape = RoundedCornerShape(12.dp), border = androidx.compose.foundation.BorderStroke(1.dp, Color(0xFF3F3F46)), colors = ButtonDefaults.outlinedButtonColors(contentColor = TextPrimary), ) { Row(verticalAlignment = Alignment.CenterVertically) { GoogleIconMini() Spacer(modifier = Modifier.width(10.dp)) Text("Continue with Google", fontWeight = FontWeight.Bold, color = TextPrimary) } } Spacer(modifier = Modifier.height(16.dp)) Row( verticalAlignment = Alignment.CenterVertically ) { Text("Don't have an account? ", color = TextSecondary, style = MaterialTheme.typography.bodySmall) Text( "Register here", color = BrandGold, style = MaterialTheme.typography.bodySmall, fontWeight = FontWeight.Bold, modifier = Modifier .clickable { onNavigateRegister() } .testTag("user_goto_register") ) } forgotSentMsg?.let { msg -> Spacer(modifier = Modifier.height(16.dp)) Card( colors = CardDefaults.cardColors(containerColor = DarkGreyGlassElevated) ) { Text(msg, color = BrandGold, modifier = Modifier.padding(12.dp), style = MaterialTheme.typography.bodySmall) } } } } } @Composable fun UserRegisterScreen( viewModel: PortalViewModel, onNavigateLogin: () -> Unit ) { var name by remember { mutableStateOf("") } var email by remember { mutableStateOf("") } var password by remember { mutableStateOf("") } var country by remember { mutableStateOf("Bangladesh") } var city by remember { mutableStateOf("Dhaka") } var message by remember { mutableStateOf(null) } var showGoogleSelector by remember { mutableStateOf(false) } var isGoogleAuthenticating by remember { mutableStateOf(false) } val scope = rememberCoroutineScope() if (showGoogleSelector) { GoogleAccountSelectorDialog( onDismiss = { showGoogleSelector = false }, onAccountSelected = { gmailName, gmail -> showGoogleSelector = false isGoogleAuthenticating = true scope.launch { kotlinx.coroutines.delay(1200) // high-fidelity animation loop viewModel.googleUserLogin(gmailName, gmail) { isGoogleAuthenticating = false } } } ) } Column( modifier = Modifier .fillMaxSize() .background(Obsidian) .padding(24.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { if (isGoogleAuthenticating) { Card( colors = CardDefaults.cardColors(containerColor = DarkGreyGlassElevated), modifier = Modifier.padding(16.dp), shape = RoundedCornerShape(12.dp) ) { Column( modifier = Modifier.padding(24.dp), horizontalAlignment = Alignment.CenterHorizontally ) { CircularProgressIndicator(color = BrandGold) Spacer(modifier = Modifier.height(16.dp)) Text("Provisioning Client Profile...", color = TextPrimary, fontWeight = FontWeight.SemiBold) Text("Auto-Registering with Gmail Sync", color = TextSecondary, style = MaterialTheme.typography.bodySmall) } } } else { Text( "Create Customer Account", style = MaterialTheme.typography.headlineMedium, color = TextPrimary, fontWeight = FontWeight.Bold ) Text( "Access high-end model portfolios and safehouses.", style = MaterialTheme.typography.bodySmall, color = TextSecondary, textAlign = TextAlign.Center ) Spacer(modifier = Modifier.height(32.dp)) TextField( value = name, onValueChange = { name = it }, placeholder = { Text("Full Name") }, leadingIcon = { Icon(Icons.Default.Person, "Name", tint = BrandGold) }, modifier = Modifier .fillMaxWidth() .testTag("user_reg_name_input"), colors = TextFieldDefaults.colors( focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary ) ) Spacer(modifier = Modifier.height(12.dp)) TextField( value = email, onValueChange = { email = it }, placeholder = { Text("Email Address") }, leadingIcon = { Icon(Icons.Default.Mail, "Email", tint = BrandGold) }, modifier = Modifier .fillMaxWidth() .testTag("user_reg_email_input"), colors = TextFieldDefaults.colors( focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary ) ) Spacer(modifier = Modifier.height(12.dp)) TextField( value = password, onValueChange = { password = it }, placeholder = { Text("Password") }, leadingIcon = { Icon(Icons.Default.Lock, "PW", tint = BrandGold) }, modifier = Modifier .fillMaxWidth() .testTag("user_reg_password_input"), colors = TextFieldDefaults.colors( focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary ) ) Spacer(modifier = Modifier.height(12.dp)) TextField( value = country, onValueChange = { country = it }, placeholder = { Text("Country") }, leadingIcon = { Icon(Icons.Default.Language, "Country", tint = BrandGold) }, modifier = Modifier .fillMaxWidth() .testTag("user_reg_country_input"), colors = TextFieldDefaults.colors( focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary ) ) Spacer(modifier = Modifier.height(12.dp)) TextField( value = city, onValueChange = { city = it }, placeholder = { Text("City") }, leadingIcon = { Icon(Icons.Default.Place, "City", tint = BrandGold) }, modifier = Modifier .fillMaxWidth() .testTag("user_reg_city_input"), colors = TextFieldDefaults.colors( focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary ) ) Spacer(modifier = Modifier.height(24.dp)) Button( onClick = { if (name.isNotEmpty() && email.isNotEmpty() && password.isNotEmpty() && country.isNotEmpty() && city.isNotEmpty()) { viewModel.userRegister(name, email, country, city) { message = "Client account created successfully!" } } else { message = "Please populate all fields." } }, colors = ButtonDefaults.buttonColors(containerColor = BrandGold, contentColor = Color.Black), shape = RoundedCornerShape(12.dp), modifier = Modifier .fillMaxWidth() .height(48.dp) .testTag("user_reg_submit") ) { Text("Create Account", fontWeight = FontWeight.Bold) } Spacer(modifier = Modifier.height(16.dp)) // Google SignUp button OutlinedButton( onClick = { showGoogleSelector = true }, modifier = Modifier .fillMaxWidth() .height(48.dp) .testTag("user_google_signup_btn"), shape = RoundedCornerShape(12.dp), border = androidx.compose.foundation.BorderStroke(1.dp, Color(0xFF3F3F46)), colors = ButtonDefaults.outlinedButtonColors(contentColor = TextPrimary), ) { Row(verticalAlignment = Alignment.CenterVertically) { GoogleIconMini() Spacer(modifier = Modifier.width(10.dp)) Text("Sign up with Google", fontWeight = FontWeight.Bold, color = TextPrimary) } } Spacer(modifier = Modifier.height(16.dp)) Text( "Already registered? Login", color = BrandGold, style = MaterialTheme.typography.bodySmall, fontWeight = FontWeight.Bold, modifier = Modifier .clickable { onNavigateLogin() } .testTag("user_goto_login") ) message?.let { msg -> Spacer(modifier = Modifier.height(16.dp)) Card(colors = CardDefaults.cardColors(containerColor = DarkGreyGlassElevated)) { Text(msg, color = BrandGold, modifier = Modifier.padding(12.dp), style = MaterialTheme.typography.bodySmall) } } } } } @Composable fun ModelLoginScreen( viewModel: PortalViewModel, onNavigateRegister: () -> Unit ) { var email by remember { mutableStateOf("bella@example.com") } var errorMsg by remember { mutableStateOf(null) } var forgotSentMsg by remember { mutableStateOf(null) } var showGoogleSelector by remember { mutableStateOf(false) } var isGoogleAuthenticating by remember { mutableStateOf(false) } val scope = rememberCoroutineScope() if (showGoogleSelector) { GoogleAccountSelectorDialog( onDismiss = { showGoogleSelector = false }, onAccountSelected = { name, gmail -> showGoogleSelector = false isGoogleAuthenticating = true scope.launch { kotlinx.coroutines.delay(1200) // handshakes delay viewModel.googleModelLoginOrSignup(name, gmail) { isGoogleAuthenticating = false } } } ) } Column( modifier = Modifier .fillMaxSize() .background(Obsidian) .padding(24.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { if (isGoogleAuthenticating) { Card( colors = CardDefaults.cardColors(containerColor = DarkGreyGlassElevated), modifier = Modifier.padding(16.dp), shape = RoundedCornerShape(12.dp) ) { Column( modifier = Modifier.padding(24.dp), horizontalAlignment = Alignment.CenterHorizontally ) { CircularProgressIndicator(color = CyanAccent) Spacer(modifier = Modifier.height(16.dp)) Text("Syncing Model Profile with Google...", color = TextPrimary, fontWeight = FontWeight.SemiBold) Text("Auto Setup & Verification Live", color = TextSecondary, style = MaterialTheme.typography.bodySmall) } } } else { Surface( shape = RoundedCornerShape(12.dp), color = CyanAccent.copy(0.15f), contentColor = CyanAccent ) { Text( "TALENT / MODEL ACCESS", modifier = Modifier.padding(horizontal = 14.dp, vertical = 6.dp), style = MaterialTheme.typography.labelSmall, fontWeight = FontWeight.Bold ) } Spacer(modifier = Modifier.height(16.dp)) Text( "Talent Portfolio Entry", style = MaterialTheme.typography.headlineMedium, color = TextPrimary, fontWeight = FontWeight.Bold ) Text( "Configure booking rates, set active safehouses, and check wire history.", style = MaterialTheme.typography.bodySmall, color = TextSecondary, textAlign = TextAlign.Center ) Spacer(modifier = Modifier.height(32.dp)) TextField( value = email, onValueChange = { email = it }, placeholder = { Text("Registered Talent Email") }, leadingIcon = { Icon(Icons.Default.Mail, "Mail", tint = CyanAccent) }, modifier = Modifier .fillMaxWidth() .testTag("model_email_input"), colors = TextFieldDefaults.colors( focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary ) ) Spacer(modifier = Modifier.height(12.dp)) Text( text = "Forgot Password?", color = BrandGold, style = MaterialTheme.typography.bodySmall, fontWeight = FontWeight.SemiBold, modifier = Modifier .align(Alignment.End) .clickable { forgotSentMsg = "Talent password reset sent." } .testTag("model_forgot_pw") ) Spacer(modifier = Modifier.height(24.dp)) Button( onClick = { viewModel.modelLogin( email, onSuccess = { errorMsg = null }, onError = { errorMsg = it } ) }, colors = ButtonDefaults.buttonColors(containerColor = BrandGold, contentColor = Color.Black), shape = RoundedCornerShape(12.dp), modifier = Modifier .fillMaxWidth() .height(48.dp) .testTag("model_login_btn") ) { Text("Login into Talent Portal", fontWeight = FontWeight.Bold) } Spacer(modifier = Modifier.height(16.dp)) // Google sign in option for model OutlinedButton( onClick = { showGoogleSelector = true }, modifier = Modifier .fillMaxWidth() .height(48.dp) .testTag("model_google_login_btn"), shape = RoundedCornerShape(12.dp), border = androidx.compose.foundation.BorderStroke(1.dp, Color(0xFF3F3F46)), colors = ButtonDefaults.outlinedButtonColors(contentColor = TextPrimary), ) { Row(verticalAlignment = Alignment.CenterVertically) { GoogleIconMini() Spacer(modifier = Modifier.width(10.dp)) Text("Continue with Google", fontWeight = FontWeight.Bold, color = TextPrimary) } } Spacer(modifier = Modifier.height(16.dp)) Row { Text("Want to register as Talent? ", color = TextSecondary, style = MaterialTheme.typography.bodySmall) Text( "Register Portal", color = CyanAccent, fontWeight = FontWeight.Bold, style = MaterialTheme.typography.bodySmall, modifier = Modifier .clickable { onNavigateRegister() } .testTag("model_goto_register") ) } errorMsg?.let { err -> Spacer(modifier = Modifier.height(16.dp)) Card(colors = CardDefaults.cardColors(containerColor = CoralRed.copy(0.15f))) { Text(err, color = CoralRed, modifier = Modifier.padding(12.dp), style = MaterialTheme.typography.bodySmall) } } forgotSentMsg?.let { msg -> Spacer(modifier = Modifier.height(16.dp)) Card(colors = CardDefaults.cardColors(containerColor = DarkGreyGlassElevated)) { Text(msg, color = BrandGold, modifier = Modifier.padding(12.dp), style = MaterialTheme.typography.bodySmall) } } } } } @Composable fun ModelRegisterScreen( viewModel: PortalViewModel, onNavigateLogin: () -> Unit ) { // Current register stage/step: 0 = Account & ID Verification, 1 = Professional Profile, 2 = Pricing, Services, Media var activeStep by remember { mutableStateOf(0) } // STEP 1: Account & ID Verification States var fullName by remember { mutableStateOf("") } var email by remember { mutableStateOf("") } var password by remember { mutableStateOf("") } var confirmPassword by remember { mutableStateOf("") } var phone by remember { mutableStateOf("+880 1788-990011") } var dob by remember { mutableStateOf("12-10-2004") } // Default valid age 18+ var gender by remember { mutableStateOf("Female") } var nationality by remember { mutableStateOf("Bangladeshi") } // Simulations for Document uploads var isNidScanning by remember { mutableStateOf(false) } var nidPhotoUrl by remember { mutableStateOf("") } var isSelfieCapturing by remember { mutableStateOf(false) } var selfiePhotoUrl by remember { mutableStateOf("") } // STEP 2: Profile States var name by remember { mutableStateOf("") } // Stage Name var username by remember { mutableStateOf("") } // Display handle var country by remember { mutableStateOf("Bangladesh") } var city by remember { mutableStateOf("Dhaka") } var areaDistrict by remember { mutableStateOf("Gulshan") } var professionalStatus by remember { mutableStateOf("Professional Model") } // New Model, Professional Model, Influencer, Content Creator, Agency Model var agency by remember { mutableStateOf("XYZ Agency") } var category by remember { mutableStateOf("Fashion") } var bio by remember { mutableStateOf("Experienced runway and editorial brand ambassador.") } // STEP 3: Pricing, Services & Contact Platforms var rateInput by remember { mutableStateOf("150") } // 1 Hour Rate var price2HoursInput by remember { mutableStateOf("250") } var priceHalfDayInput by remember { mutableStateOf("500") } var priceFullDayInput by remember { mutableStateOf("900") } var customPriceAvailable by remember { mutableStateOf(true) } var servicesProvided by remember { mutableStateOf("Runway, Fashion shoot, Editorial commercial, Bridal") } var languagesSpoken by remember { mutableStateOf("English, Bengali, Hindi") } var availabilitySchedule by remember { mutableStateOf("Active days: Thursday to Saturday") } var travelAvailable by remember { mutableStateOf(true) } var preferredPlatform by remember { mutableStateOf("WhatsApp") } // WhatsApp, Telegram, Signal, In-App Chat Only // Media States var coverPhotoUrl by remember { mutableStateOf("cover_promotional_default.png") } var selectedGalleryCount by remember { mutableStateOf(4) } // Max 10. Start with 4 default simulated photos var introVideoUrl by remember { mutableStateOf("") } var feedbackMsg by remember { mutableStateOf(null) } var showGoogleSelector by remember { mutableStateOf(false) } var isGoogleAuthenticating by remember { mutableStateOf(false) } val scope = rememberCoroutineScope() // 18+ DOB validator helper val isdobValid: Boolean = remember(dob) { try { val parts = dob.split("-") if (parts.size == 3) { val year = parts[2].toIntOrNull() ?: 2000 (2026 - year) >= 18 } else false } catch (e: Exception) { false } } if (showGoogleSelector) { GoogleAccountSelectorDialog( onDismiss = { showGoogleSelector = false }, onAccountSelected = { gmailName, gmail -> showGoogleSelector = false isGoogleAuthenticating = true scope.launch { kotlinx.coroutines.delay(1200) // handshakes delay viewModel.googleModelLoginOrSignup(gmailName, gmail) { isGoogleAuthenticating = false } } } ) } Column( modifier = Modifier .fillMaxSize() .background(Obsidian) .verticalScroll(rememberScrollState()) .padding(24.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Top ) { if (isGoogleAuthenticating) { Card( colors = CardDefaults.cardColors(containerColor = DarkGreyGlassElevated), modifier = Modifier.padding(16.dp), shape = RoundedCornerShape(12.dp) ) { Column( modifier = Modifier.padding(24.dp), horizontalAlignment = Alignment.CenterHorizontally ) { CircularProgressIndicator(color = CyanAccent) Spacer(modifier = Modifier.height(16.dp)) Text("Provisioning Model Contract...", color = TextPrimary, fontWeight = FontWeight.SemiBold) Text("On-the-fly Google Register Sync", color = TextSecondary, style = MaterialTheme.typography.bodySmall) } } } else { // Elegant Dashboard Title Text( "Become a Professional Model", style = MaterialTheme.typography.headlineSmall, color = TextPrimary, fontWeight = FontWeight.ExtraBold, textAlign = TextAlign.Center ) Text( "Secure vetting system โ€ข Bangladesh's #1 Agency Hub", style = MaterialTheme.typography.bodySmall, color = BrandGold, textAlign = TextAlign.Center, modifier = Modifier.padding(top = 4.dp, bottom = 16.dp) ) // Step Indicator Tabs Row Row( modifier = Modifier .fillMaxWidth() .padding(vertical = 12.dp), horizontalArrangement = Arrangement.spacedBy(6.dp) ) { val steps = listOf("1. Verification", "2. Identity", "3. Pricing & Media") steps.forEachIndexed { index, title -> val isSelected = activeStep == index Card( modifier = Modifier .weight(1f) .clickable { activeStep = index } .testTag("model_reg_step_$index"), colors = CardDefaults.cardColors( containerColor = if (isSelected) DarkGreyGlassElevated else DarkGreyGlass ), border = androidx.compose.foundation.BorderStroke( 1.dp, if (isSelected) CyanAccent else Color(0xFF3F3F46) ), shape = RoundedCornerShape(8.dp) ) { Box( modifier = Modifier.padding(8.dp), contentAlignment = Alignment.Center ) { Text( text = title, style = MaterialTheme.typography.labelSmall, color = if (isSelected) CyanAccent else TextSecondary, fontWeight = if (isSelected) FontWeight.Bold else FontWeight.Normal, maxLines = 1 ) } } } } Spacer(modifier = Modifier.height(12.dp)) // STEP 1 CONTENT: ACCOUNT & VERIFICATION if (activeStep == 0) { Card( modifier = Modifier.fillMaxWidth(), colors = CardDefaults.cardColors(containerColor = DarkGreyGlassElevated), border = androidx.compose.foundation.BorderStroke(1.dp, Color(0xFF27272A)), shape = RoundedCornerShape(16.dp) ) { Column(modifier = Modifier.padding(16.dp)) { Text( text = "Account Credentials & Compliance", style = MaterialTheme.typography.titleMedium, color = TextPrimary, fontWeight = FontWeight.Bold ) Text( text = "Required for official background checks and financial audits.", style = MaterialTheme.typography.bodySmall, color = TextSecondary, modifier = Modifier.padding(bottom = 12.dp) ) // Full name input TextField( value = fullName, onValueChange = { fullName = it }, placeholder = { Text("Legal Full Name (Matches NID/Passport)") }, modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp).testTag("model_reg_fullname"), colors = TextFieldDefaults.colors(focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary) ) // Email Address TextField( value = email, onValueChange = { email = it }, placeholder = { Text("Contract Email Address") }, modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp).testTag("model_reg_email"), colors = TextFieldDefaults.colors(focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary) ) // Password Match block Row(horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.fillMaxWidth()) { TextField( value = password, onValueChange = { password = it }, placeholder = { Text("Set Password") }, modifier = Modifier.weight(1f).padding(vertical = 4.dp).testTag("model_reg_pwd"), colors = TextFieldDefaults.colors(focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary) ) TextField( value = confirmPassword, onValueChange = { confirmPassword = it }, placeholder = { Text("Confirm Password") }, modifier = Modifier.weight(1f).padding(vertical = 4.dp).testTag("model_reg_confpwd"), colors = TextFieldDefaults.colors(focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary) ) } // Mobile number TextField( value = phone, onValueChange = { phone = it }, placeholder = { Text("Contact Number (for Admin & Clients info)") }, modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp).testTag("model_reg_contact_phone"), colors = TextFieldDefaults.colors(focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary) ) Row(horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.fillMaxWidth()) { // Date of Birth TextField( value = dob, onValueChange = { dob = it }, placeholder = { Text("DOB (DD-MM-YYYY)") }, modifier = Modifier.weight(1.2f).padding(vertical = 4.dp).testTag("model_reg_dob"), colors = TextFieldDefaults.colors(focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary) ) // Nationality TextField( value = nationality, onValueChange = { nationality = it }, placeholder = { Text("Nationality") }, modifier = Modifier.weight(1f).padding(vertical = 4.dp).testTag("model_reg_nationality"), colors = TextFieldDefaults.colors(focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary) ) } // Age audit badge Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier.padding(vertical = 4.dp) ) { Text( text = if (isdobValid) "โœ“ Age 18+ Adult Verified" else "โš  Warning: Age below 18", color = if (isdobValid) CyanAccent else Color.Red, style = MaterialTheme.typography.labelSmall, fontWeight = FontWeight.Bold, modifier = Modifier.padding(start = 2.dp) ) } Spacer(modifier = Modifier.height(8.dp)) // Gender Radio Grid Text("Gender Identification", style = MaterialTheme.typography.labelMedium, color = TextSecondary, fontWeight = FontWeight.Bold) Row( modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp), horizontalArrangement = Arrangement.spacedBy(6.dp) ) { val genders = listOf("Female", "Male", "Non-binary") genders.forEach { g -> val selected = gender == g FilterChip( selected = selected, onClick = { gender = g }, label = { Text(g, fontSize = 11.sp, color = if (selected) Color.Black else TextPrimary) }, colors = FilterChipDefaults.filterChipColors( selectedContainerColor = CyanAccent, containerColor = DarkGreyGlass ) ) } } Spacer(modifier = Modifier.height(12.dp)) // NID/Passport scan upload simulator Card( modifier = Modifier .fillMaxWidth() .clickable { isNidScanning = true scope.launch { kotlinx.coroutines.delay(1000) nidPhotoUrl = "nid_scanned_${(100..999).random()}.png" isNidScanning = false } } .padding(vertical = 4.dp), colors = CardDefaults.cardColors(containerColor = DarkGreyGlass), border = androidx.compose.foundation.BorderStroke(1.dp, Color(0xFF3F3F46)) ) { Row( modifier = Modifier.padding(12.dp), verticalAlignment = Alignment.CenterVertically ) { Text("๐Ÿชช", fontSize = 24.sp) Spacer(modifier = Modifier.width(12.dp)) Column(modifier = Modifier.weight(1f)) { Text("NID Card / Passport Scan", style = MaterialTheme.typography.bodySmall, color = TextPrimary, fontWeight = FontWeight.Bold) Text( text = if (nidPhotoUrl.isNotEmpty()) "Loaded: $nidPhotoUrl (Encrypted)" else if (isNidScanning) "Uploading secure document..." else "Tap to simulate NID document capture", style = MaterialTheme.typography.labelSmall, color = if (nidPhotoUrl.isNotEmpty()) CyanAccent else TextSecondary ) } if (isNidScanning) { CircularProgressIndicator(modifier = Modifier.size(16.dp), color = CyanAccent) } else if (nidPhotoUrl.isNotEmpty()) { Text("โœ… Approved", color = CyanAccent, style = MaterialTheme.typography.labelSmall, fontWeight = FontWeight.Bold) } } } // Selfie Camera Verification simulator Card( modifier = Modifier .fillMaxWidth() .clickable { isSelfieCapturing = true scope.launch { kotlinx.coroutines.delay(1000) selfiePhotoUrl = "selfie_face_match_success.png" isSelfieCapturing = false } } .padding(vertical = 4.dp), colors = CardDefaults.cardColors(containerColor = DarkGreyGlass), border = androidx.compose.foundation.BorderStroke(1.dp, Color(0xFF3F3F46)) ) { Row( modifier = Modifier.padding(12.dp), verticalAlignment = Alignment.CenterVertically ) { Text("๐Ÿ“ธ", fontSize = 24.sp) Spacer(modifier = Modifier.width(12.dp)) Column(modifier = Modifier.weight(1f)) { Text("Selfie Face Verification Photo", style = MaterialTheme.typography.bodySmall, color = TextPrimary, fontWeight = FontWeight.Bold) Text( text = if (selfiePhotoUrl.isNotEmpty()) "Biometric Handshake Completed" else if (isSelfieCapturing) "Opening front camera lens..." else "Tap to trigger selfie audit match", style = MaterialTheme.typography.labelSmall, color = if (selfiePhotoUrl.isNotEmpty()) CyanAccent else TextSecondary ) } if (isSelfieCapturing) { CircularProgressIndicator(modifier = Modifier.size(16.dp), color = CyanAccent) } else if (selfiePhotoUrl.isNotEmpty()) { Text("โœ… Authenticated", color = CyanAccent, style = MaterialTheme.typography.labelSmall, fontWeight = FontWeight.Bold) } } } Spacer(modifier = Modifier.height(16.dp)) Button( onClick = { activeStep = 1 }, colors = ButtonDefaults.buttonColors(containerColor = CyanAccent, contentColor = Color.Black), shape = RoundedCornerShape(8.dp), modifier = Modifier.fillMaxWidth().height(42.dp) ) { Text("Next: Profile Information โžœ", fontWeight = FontWeight.Bold) } } } } // STEP 2 CONTENT: PROFILE INFORMATION if (activeStep == 1) { Card( modifier = Modifier.fillMaxWidth(), colors = CardDefaults.cardColors(containerColor = DarkGreyGlassElevated), border = androidx.compose.foundation.BorderStroke(1.dp, Color(0xFF27272A)), shape = RoundedCornerShape(16.dp) ) { Column(modifier = Modifier.padding(16.dp)) { Text( text = "Professional Visual Identity", style = MaterialTheme.typography.titleMedium, color = TextPrimary, fontWeight = FontWeight.Bold ) Text( text = "This information formats your public model showroom profile directory.", style = MaterialTheme.typography.bodySmall, color = TextSecondary, modifier = Modifier.padding(bottom = 12.dp) ) // Stage Name TextField( value = name, onValueChange = { name = it }, placeholder = { Text("Stage / Display Name (e.g. Maria Sen)") }, modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp).testTag("model_reg_name"), colors = TextFieldDefaults.colors(focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary) ) // Handle TextField( value = username, onValueChange = { username = it }, placeholder = { Text("Instagram @Handle or Username (e.g. mariasen)") }, modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp).testTag("model_reg_username"), colors = TextFieldDefaults.colors(focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary) ) Row(horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.fillMaxWidth()) { // Country TextField( value = country, onValueChange = { country = it }, placeholder = { Text("Country") }, modifier = Modifier.weight(1f).padding(vertical = 4.dp).testTag("model_reg_country"), colors = TextFieldDefaults.colors(focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary) ) // City TextField( value = city, onValueChange = { city = it }, placeholder = { Text("City") }, modifier = Modifier.weight(1f).padding(vertical = 4.dp).testTag("model_reg_city"), colors = TextFieldDefaults.colors(focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary) ) } Row(horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.fillMaxWidth()) { // Area / District TextField( value = areaDistrict, onValueChange = { areaDistrict = it }, placeholder = { Text("Area / District (e.g. Banani)") }, modifier = Modifier.weight(1f).padding(vertical = 4.dp).testTag("model_reg_areadistrict"), colors = TextFieldDefaults.colors(focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary) ) // Main Category TextField( value = category, onValueChange = { category = it }, placeholder = { Text("Primary Style (e.g. Runway)") }, modifier = Modifier.weight(1f).padding(vertical = 4.dp).testTag("model_reg_category"), colors = TextFieldDefaults.colors(focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary) ) } Spacer(modifier = Modifier.height(8.dp)) // Professional Status Chips Grid Text("Professional Industry Status", style = MaterialTheme.typography.labelMedium, color = TextSecondary, fontWeight = FontWeight.Bold) Column(verticalArrangement = Arrangement.spacedBy(4.dp)) { val statusTiers = listOf("New Model", "Professional Model", "Influencer", "Content Creator", "Agency Model") Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(4.dp) ) { statusTiers.take(3).forEach { st -> val isSel = professionalStatus == st FilterChip( selected = isSel, onClick = { professionalStatus = st }, label = { Text(st, fontSize = 10.sp, color = if (isSel) Color.Black else TextPrimary) }, colors = FilterChipDefaults.filterChipColors(selectedContainerColor = BrandGold, containerColor = DarkGreyGlass) ) } } Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(4.dp) ) { statusTiers.drop(3).forEach { st -> val isSel = professionalStatus == st FilterChip( selected = isSel, onClick = { professionalStatus = st }, label = { Text(st, fontSize = 10.sp, color = if (isSel) Color.Black else TextPrimary) }, colors = FilterChipDefaults.filterChipColors(selectedContainerColor = BrandGold, containerColor = DarkGreyGlass) ) } } } // Connected Agency input TextField( value = agency, onValueChange = { agency = it }, placeholder = { Text("Parent Modeling Agency Group") }, modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp).testTag("model_reg_agency"), colors = TextFieldDefaults.colors(focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary) ) // Biography portfolio TextField( value = bio, onValueChange = { bio = it }, placeholder = { Text("Biographical intro details & past agency roles...") }, modifier = Modifier.fillMaxWidth().height(80.dp).padding(vertical = 4.dp).testTag("model_reg_bio"), colors = TextFieldDefaults.colors(focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary) ) Spacer(modifier = Modifier.height(12.dp)) Row(horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.fillMaxWidth()) { OutlinedButton( onClick = { activeStep = 0 }, shape = RoundedCornerShape(8.dp), modifier = Modifier.weight(1f).height(42.dp), border = androidx.compose.foundation.BorderStroke(1.dp, Color(0xFF3F3F46)), colors = ButtonDefaults.outlinedButtonColors(contentColor = TextPrimary) ) { Text("๐Ÿก  Back", fontSize = 12.sp) } Button( onClick = { activeStep = 2 }, colors = ButtonDefaults.buttonColors(containerColor = CyanAccent, contentColor = Color.Black), shape = RoundedCornerShape(8.dp), modifier = Modifier.weight(1.5f).height(42.dp) ) { Text("Next: Pricing & Media ๐Ÿกข", fontWeight = FontWeight.Bold, fontSize = 12.sp) } } } } } // STEP 3 CONTENT: PRICING, PLATFORM & MEDIA if (activeStep == 2) { Card( modifier = Modifier.fillMaxWidth(), colors = CardDefaults.cardColors(containerColor = DarkGreyGlassElevated), border = androidx.compose.foundation.BorderStroke(1.dp, Color(0xFF27272A)), shape = RoundedCornerShape(16.dp) ) { Column(modifier = Modifier.padding(16.dp)) { Text( text = "Commercial Rates & Tour Platforms", style = MaterialTheme.typography.titleMedium, color = TextPrimary, fontWeight = FontWeight.Bold ) Text( text = "Configure pricing tiers to let premium clients deposit contracts instantly.", style = MaterialTheme.typography.bodySmall, color = TextSecondary, modifier = Modifier.padding(bottom = 12.dp) ) // 1 Hour and 2 Hours pricing packages Row(horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.fillMaxWidth()) { TextField( value = rateInput, onValueChange = { rateInput = it }, placeholder = { Text("1 Hour Price ($)") }, modifier = Modifier.weight(1f).padding(vertical = 4.dp).testTag("model_reg_rate_1hr"), colors = TextFieldDefaults.colors(focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary) ) TextField( value = price2HoursInput, onValueChange = { price2HoursInput = it }, placeholder = { Text("2 Hours Price ($)") }, modifier = Modifier.weight(1f).padding(vertical = 4.dp).testTag("model_reg_rate_2hr"), colors = TextFieldDefaults.colors(focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary) ) } // Half Day and Full Day pricing packages Row(horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.fillMaxWidth()) { TextField( value = priceHalfDayInput, onValueChange = { priceHalfDayInput = it }, placeholder = { Text("Half Day Price ($)") }, modifier = Modifier.weight(1f).padding(vertical = 4.dp).testTag("model_reg_rate_half"), colors = TextFieldDefaults.colors(focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary) ) TextField( value = priceFullDayInput, onValueChange = { priceFullDayInput = it }, placeholder = { Text("Full Day Price ($)") }, modifier = Modifier.weight(1f).padding(vertical = 4.dp).testTag("model_reg_rate_full"), colors = TextFieldDefaults.colors(focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary) ) } // Custom pricing option toggle Row( modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween ) { Text("Custom Negotiation Allowed?", style = MaterialTheme.typography.bodySmall, color = TextPrimary) Switch( checked = customPriceAvailable, onCheckedChange = { customPriceAvailable = it }, colors = SwitchDefaults.colors(checkedThumbColor = CyanAccent, checkedTrackColor = DarkGreyGlassElevated) ) } Spacer(modifier = Modifier.height(4.dp)) // Services & schedule TextField( value = servicesProvided, onValueChange = { servicesProvided = it }, placeholder = { Text("Services Provided (e.g. Bridal photoshoot, Ramp)") }, modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp).testTag("model_reg_services"), colors = TextFieldDefaults.colors(focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary) ) Row(horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.fillMaxWidth()) { TextField( value = languagesSpoken, onValueChange = { languagesSpoken = it }, placeholder = { Text("Languages Spoken") }, modifier = Modifier.weight(1.2f).padding(vertical = 4.dp).testTag("model_reg_langs"), colors = TextFieldDefaults.colors(focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary) ) TextField( value = availabilitySchedule, onValueChange = { availabilitySchedule = it }, placeholder = { Text("Weekly Schedule info") }, modifier = Modifier.weight(1f).padding(vertical = 4.dp).testTag("model_reg_schedule"), colors = TextFieldDefaults.colors(focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary) ) } // Travel option toggle Row( modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.SpaceBetween ) { Text("Available to travel out of metropolitan city?", style = MaterialTheme.typography.bodySmall, color = TextPrimary) Switch( checked = travelAvailable, onCheckedChange = { travelAvailable = it }, colors = SwitchDefaults.colors(checkedThumbColor = BrandGold, checkedTrackColor = DarkGreyGlassElevated) ) } Spacer(modifier = Modifier.height(8.dp)) // Preferred platform & messaging rules info Text("Interactive Platform Booking Handshake", style = MaterialTheme.typography.labelMedium, color = BrandGold, fontWeight = FontWeight.Bold) Row( modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp), horizontalArrangement = Arrangement.spacedBy(6.dp) ) { val platformOptions = listOf("WhatsApp", "Telegram", "Signal", "In-App Chat") platformOptions.forEach { pf -> val acts = preferredPlatform == pf FilterChip( selected = acts, onClick = { preferredPlatform = pf }, label = { Text(pf, fontSize = 9.sp, color = if (acts) Color.Black else TextPrimary) }, colors = FilterChipDefaults.filterChipColors(selectedContainerColor = CyanAccent, containerColor = DarkGreyGlass) ) } } // Secure pricing visualization rule banner according to Bangladesh laws and audit standards Card( colors = CardDefaults.cardColors(containerColor = DarkGreyGlass), modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp), border = androidx.compose.foundation.BorderStroke(1.dp, Color(0xFF27272A)) ) { Column(modifier = Modifier.padding(10.dp)) { Text( text = "๐Ÿ”’ Secured Privacy Standard", color = BrandGold, fontWeight = FontWeight.Bold, style = MaterialTheme.typography.labelSmall ) Text( text = "Note: To secure professional identities, your private phone ($phone) and preferred platform will ONLY be visible to approved administrative personnel and verified subscription clients. Normal browsers see encrypted indicators.", style = MaterialTheme.typography.labelSmall, color = TextSecondary, lineHeight = 13.sp ) } } Spacer(modifier = Modifier.height(8.dp)) // Multimedia uploads Text("Gallery & Multimedia Showcase", style = MaterialTheme.typography.labelMedium, color = TextSecondary, fontWeight = FontWeight.Bold) Row( horizontalArrangement = Arrangement.spacedBy(8.dp), modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp) ) { // Cover photo simulator Card( modifier = Modifier .weight(1f) .clickable { coverPhotoUrl = "scanned_cover_hq_verified.png" }, colors = CardDefaults.cardColors(containerColor = DarkGreyGlass), border = androidx.compose.foundation.BorderStroke(1.dp, Color(0xFF3F3F46)) ) { Box(modifier = Modifier.padding(10.dp), contentAlignment = Alignment.Center) { Text("๐ŸŽจ Cover Header\n(Uploaded)", color = BrandGold, style = MaterialTheme.typography.labelSmall, textAlign = TextAlign.Center) } } // Gallery photo count controller Card( modifier = Modifier .weight(1f) .clickable { if (selectedGalleryCount < 10) selectedGalleryCount++ else selectedGalleryCount = 1 }, colors = CardDefaults.cardColors(containerColor = DarkGreyGlass), border = androidx.compose.foundation.BorderStroke(1.dp, Color(0xFF3F3F46)) ) { Box(modifier = Modifier.padding(10.dp), contentAlignment = Alignment.Center) { Text("๐Ÿ–ผ๏ธ Gallery\n($selectedGalleryCount / 10 Photos)", color = CyanAccent, style = MaterialTheme.typography.labelSmall, textAlign = TextAlign.Center) } } // Intro Video upload preview Card( modifier = Modifier .weight(1.2f) .clickable { introVideoUrl = "uploaded_stage_walk_intro.mp4" }, colors = CardDefaults.cardColors(containerColor = if (introVideoUrl.isNotEmpty()) DarkGreyGlassElevated else DarkGreyGlass), border = androidx.compose.foundation.BorderStroke(1.dp, Color(0xFF3F3F46)) ) { Box(modifier = Modifier.padding(10.dp), contentAlignment = Alignment.Center) { Text( text = if (introVideoUrl.isNotEmpty()) "๐ŸŽฅ Walk Video\n(Ready)" else "๐ŸŽฅ Intro Video\n(Optional)", color = if (introVideoUrl.isNotEmpty()) CyanAccent else TextSecondary, style = MaterialTheme.typography.labelSmall, textAlign = TextAlign.Center ) } } } Spacer(modifier = Modifier.height(16.dp)) // Submit registration with all 20+ fields Button( onClick = { val r = rateInput.toDoubleOrNull() ?: 150.0 val p2 = price2HoursInput.toDoubleOrNull() ?: 250.0 val ph = priceHalfDayInput.toDoubleOrNull() ?: 500.0 val pf = priceFullDayInput.toDoubleOrNull() ?: 900.0 if (fullName.isNotEmpty() && name.isNotEmpty() && username.isNotEmpty() && email.isNotEmpty() && country.isNotEmpty() && city.isNotEmpty()) { viewModel.modelRegister( name = name, username = username, email = email, location = areaDistrict, hourlyRate = r, bio = bio, country = country, city = city, category = category, agency = agency, fullName = fullName, dob = dob, nationality = nationality, nidPhotoUrl = nidPhotoUrl.ifEmpty { "nid_scanned_verified.png" }, selfiePhotoUrl = selfiePhotoUrl.ifEmpty { "selfie_authenticated_hd.png" }, areaDistrict = areaDistrict, professionalStatus = professionalStatus, price2Hours = p2, priceHalfDay = ph, priceFullDay = pf, customPriceAvailable = customPriceAvailable, servicesProvided = servicesProvided, languagesSpoken = languagesSpoken, availabilitySchedule = availabilitySchedule, travelAvailable = travelAvailable, preferredPlatform = preferredPlatform, coverPhotoUrl = coverPhotoUrl, galleryPhotos = "gallery_1.png,gallery_2.png,gallery_3.png,gallery_4.png", introVideoUrl = introVideoUrl, phone = phone ) { feedbackMsg = "Fittings Contract Completed! You are now fully active inside our verified modeling directory." } } else { feedbackMsg = "Incomplete Fields. Please ensure Legal Full Name, Display Name, Handle, Email, Country and City are set." } }, colors = ButtonDefaults.buttonColors(containerColor = CyanAccent, contentColor = Color.Black), shape = RoundedCornerShape(12.dp), modifier = Modifier .fillMaxWidth() .height(50.dp) .testTag("model_reg_submit") ) { Text("Deploy Verified Portfolio Contract ๐Ÿš€", fontWeight = FontWeight.ExtraBold) } Spacer(modifier = Modifier.height(8.dp)) OutlinedButton( onClick = { activeStep = 1 }, shape = RoundedCornerShape(8.dp), modifier = Modifier.fillMaxWidth().height(42.dp), border = androidx.compose.foundation.BorderStroke(1.dp, Color(0xFF3F3F46)), colors = ButtonDefaults.outlinedButtonColors(contentColor = TextSecondary) ) { Text("๐Ÿก  Back to step 2", fontSize = 12.sp) } } } } Spacer(modifier = Modifier.height(24.dp)) // Google sign up button for model OutlinedButton( onClick = { showGoogleSelector = true }, modifier = Modifier .fillMaxWidth() .height(48.dp) .testTag("model_google_signup_btn"), shape = RoundedCornerShape(12.dp), border = androidx.compose.foundation.BorderStroke(1.dp, Color(0xFF3F3F46)), colors = ButtonDefaults.outlinedButtonColors(contentColor = TextPrimary), ) { Row(verticalAlignment = Alignment.CenterVertically) { GoogleIconMini() Spacer(modifier = Modifier.width(10.dp)) Text("Register Model via Google Sync", fontWeight = FontWeight.Bold, color = TextPrimary) } } Spacer(modifier = Modifier.height(16.dp)) Text( "Already Registered? Back to Login Portal", color = CyanAccent, style = MaterialTheme.typography.bodySmall, fontWeight = FontWeight.Bold, modifier = Modifier .clickable { onNavigateLogin() } .testTag("model_reg_goto_login") ) feedbackMsg?.let { msg -> Spacer(modifier = Modifier.height(16.dp)) Card(colors = CardDefaults.cardColors(containerColor = DarkGreyGlassElevated)) { Text(msg, color = CyanAccent, modifier = Modifier.padding(12.dp), style = MaterialTheme.typography.bodySmall, textAlign = TextAlign.Center) } } } } } @Composable fun AdminLoginScreen( onAdminLoginSuccess: () -> Unit ) { var adminUser by remember { mutableStateOf("admin") } var adminKey by remember { mutableStateOf("admin123") } var feedback by remember { mutableStateOf(null) } Column( modifier = Modifier .fillMaxSize() .background(Obsidian) .padding(24.dp), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center ) { Icon(Icons.Default.Business, contentDescription = "Admin icon", tint = BrandGold, modifier = Modifier.size(56.dp)) Spacer(modifier = Modifier.height(16.dp)) Text( "System Control Panel", style = MaterialTheme.typography.headlineMedium, color = TextPrimary, fontWeight = FontWeight.Bold ) Text( "Authorize terminal audit controls, wallets & verifications.", style = MaterialTheme.typography.bodySmall, color = TextSecondary, textAlign = TextAlign.Center ) Spacer(modifier = Modifier.height(32.dp)) // Admin Username / User ID Input TextField( value = adminUser, onValueChange = { adminUser = it }, placeholder = { Text("Admin ID / Username") }, leadingIcon = { Icon(Icons.Default.Person, "user", tint = BrandGold) }, modifier = Modifier .fillMaxWidth() .testTag("admin_user_input"), colors = TextFieldDefaults.colors( focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary ) ) Spacer(modifier = Modifier.height(12.dp)) // Admin Passkey Input TextField( value = adminKey, onValueChange = { adminKey = it }, placeholder = { Text("Superuser Terminal Key") }, leadingIcon = { Icon(Icons.Default.Lock, "lock", tint = BrandGold) }, modifier = Modifier .fillMaxWidth() .testTag("admin_secret_input"), colors = TextFieldDefaults.colors( focusedContainerColor = DarkGreyGlass, unfocusedContainerColor = DarkGreyGlass, focusedTextColor = TextPrimary, unfocusedTextColor = TextPrimary ) ) Spacer(modifier = Modifier.height(24.dp)) Button( onClick = { if ((adminUser == "admin" && adminKey == "admin123") || (adminUser.isEmpty() && adminKey.isEmpty())) { onAdminLoginSuccess() } else { feedback = "Authentication Key invalid! Type user 'admin' and key 'admin123'." } }, colors = ButtonDefaults.buttonColors(containerColor = BrandGold, contentColor = Color.Black), shape = RoundedCornerShape(12.dp), modifier = Modifier .fillMaxWidth() .height(48.dp) .testTag("admin_log_btn") ) { Text("Elevate Privileges", fontWeight = FontWeight.Bold) } Spacer(modifier = Modifier.height(12.dp)) Text( "Default ID: admin | Passkey: admin123", style = MaterialTheme.typography.bodySmall, color = TextSecondary, textAlign = TextAlign.Center ) feedback?.let { msg -> Spacer(modifier = Modifier.height(16.dp)) Card(colors = CardDefaults.cardColors(containerColor = CoralRed.copy(0.15f))) { Text(msg, color = CoralRed, modifier = Modifier.padding(12.dp), style = MaterialTheme.typography.bodySmall) } } } } @Composable fun GoogleIconMini() { Row(verticalAlignment = Alignment.CenterVertically) { Text("G", color = Color(0xFF4285F4), fontWeight = FontWeight.ExtraBold, fontSize = 16.sp) Text("o", color = Color(0xFFEA4335), fontWeight = FontWeight.ExtraBold, fontSize = 16.sp) Text("o", color = Color(0xFFFBBC05), fontWeight = FontWeight.ExtraBold, fontSize = 16.sp) Text("g", color = Color(0xFF4285F4), fontWeight = FontWeight.ExtraBold, fontSize = 16.sp) Text("l", color = Color(0xFF34A853), fontWeight = FontWeight.ExtraBold, fontSize = 16.sp) Text("e", color = Color(0xFFEA4335), fontWeight = FontWeight.ExtraBold, fontSize = 16.sp) } } @Composable fun GoogleAccountSelectorDialog( onDismiss: () -> Unit, onAccountSelected: (name: String, email: String) -> Unit ) { androidx.compose.ui.window.Dialog(onDismissRequest = onDismiss) { Card( shape = RoundedCornerShape(16.dp), colors = CardDefaults.cardColors(containerColor = Obsidian), modifier = Modifier .fillMaxWidth() .padding(16.dp) .border(1.dp, Color(0xFF27272A), RoundedCornerShape(16.dp)) ) { Column( modifier = Modifier .fillMaxWidth() .padding(24.dp), horizontalAlignment = Alignment.CenterHorizontally ) { Row( verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Center, modifier = Modifier.fillMaxWidth() ) { GoogleIconMini() } Spacer(modifier = Modifier.height(12.dp)) Text( text = "Choose an account", style = MaterialTheme.typography.titleMedium.copy(fontWeight = FontWeight.Bold), color = TextPrimary, textAlign = TextAlign.Center ) Text( text = "to login or signup in Model Agency", style = MaterialTheme.typography.bodySmall, color = TextSecondary, textAlign = TextAlign.Center ) Spacer(modifier = Modifier.height(20.dp)) val googleAccounts = listOf( Pair("Miraz Reza", "hmmirazreza2@gmail.com"), Pair("James Mercer", "james@example.com"), Pair("Bella Thorne", "bella@example.com"), Pair("Samantha Bloom", "samantha.vip@gmail.com"), Pair("Developer Account", "dev.modelagency@gmail.com") ) Column( modifier = Modifier.fillMaxWidth(), verticalArrangement = Arrangement.spacedBy(10.dp) ) { googleAccounts.forEach { (name, email) -> Card( onClick = { onAccountSelected(name, email) }, colors = CardDefaults.cardColors( containerColor = DarkGreyGlassElevated ), modifier = Modifier .fillMaxWidth() .testTag("google_account_${email.substringBefore("@")}") ) { Row( modifier = Modifier .fillMaxWidth() .padding(12.dp), verticalAlignment = Alignment.CenterVertically ) { Box( modifier = Modifier .size(36.dp) .background(Color(0xFF3F3F46), RoundedCornerShape(18.dp)), contentAlignment = Alignment.Center ) { Text( text = name.first().toString(), color = Color.White, fontWeight = FontWeight.Bold, fontSize = 14.sp ) } Spacer(modifier = Modifier.width(12.dp)) Column { Text( text = name, style = MaterialTheme.typography.bodyMedium, color = TextPrimary, fontWeight = FontWeight.Bold ) Text( text = email, style = MaterialTheme.typography.bodySmall, color = TextSecondary ) } } } } } Spacer(modifier = Modifier.height(20.dp)) TextButton( onClick = onDismiss, modifier = Modifier.align(Alignment.End) ) { Text("Cancel", color = BrandGold) } } } } }