Untitled
unknown
plain_text
2 months ago
12 kB
4
Indexable
package com.example.senderos import android.net.Uri import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.core.view.WindowCompat import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.foundation.Image import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.Button import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TextButton import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import coil.compose.rememberAsyncImagePainter import com.example.senderos.ui.theme.SenderosTheme // Importa la clase Routes (ya definida en Routes.kt) import com.example.senderos.Routes // Objeto global para almacenar datos del perfil (solo para demostración) object ProfileState { var name by mutableStateOf("") var description by mutableStateOf("") var imageUri by mutableStateOf<Uri?>(null) } class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Habilita edge-to-edge usando WindowCompat WindowCompat.setDecorFitsSystemWindows(window, false) setContent { SenderosTheme { Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> Box(modifier = Modifier.padding(innerPadding)) { AppNavigator() } } } } } } @Composable fun AppNavigator() { val navController = rememberNavController() NavHost(navController = navController, startDestination = Routes.Login.route) { composable(Routes.Login.route) { LoginScreen(navController) } composable(Routes.Register.route) { RegisterScreen(navController) } composable(Routes.Profile.route) { ProfileScreen(navController) } composable(Routes.ProfileDisplay.route) { ProfileDisplayScreen(navController) } } } @Composable fun LoginScreen(navController: NavHostController) { var email by remember { mutableStateOf("") } var password by remember { mutableStateOf("") } Column( modifier = Modifier .fillMaxSize() .padding(20.dp), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { Text("Iniciar sesión", style = MaterialTheme.typography.headlineLarge) Spacer(modifier = Modifier.height(16.dp)) OutlinedTextField( value = email, onValueChange = { email = it }, label = { Text("Correo electrónico") }, singleLine = true, keyboardOptions = KeyboardOptions( keyboardType = KeyboardType.Email, imeAction = ImeAction.Next ), modifier = Modifier.fillMaxWidth(0.9f) ) Spacer(modifier = Modifier.height(16.dp)) OutlinedTextField( value = password, onValueChange = { password = it }, label = { Text("Contraseña") }, singleLine = true, keyboardOptions = KeyboardOptions( keyboardType = KeyboardType.Password, imeAction = ImeAction.Done ), modifier = Modifier.fillMaxWidth(0.9f) ) Spacer(modifier = Modifier.height(24.dp)) Button( onClick = { // Simula un login exitoso y navega a la pantalla de edición de perfil navController.navigate(Routes.Profile.route) }, modifier = Modifier.fillMaxWidth(0.9f) ) { Text("Ingresar") } Spacer(modifier = Modifier.height(16.dp)) TextButton(onClick = { navController.navigate(Routes.Register.route) }) { Text("¿No tienes una cuenta? Regístrate") } } } @Composable fun RegisterScreen(navController: NavHostController) { var email by remember { mutableStateOf("") } var password by remember { mutableStateOf("") } var confirmPassword by remember { mutableStateOf("") } var errorMessage by remember { mutableStateOf("") } Column( modifier = Modifier .fillMaxSize() .padding(20.dp), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { Text("Registro", style = MaterialTheme.typography.headlineLarge) Spacer(modifier = Modifier.height(16.dp)) OutlinedTextField( value = email, onValueChange = { email = it }, label = { Text("Correo electrónico") }, singleLine = true, keyboardOptions = KeyboardOptions( keyboardType = KeyboardType.Email, imeAction = ImeAction.Next ), modifier = Modifier.fillMaxWidth(0.9f) ) Spacer(modifier = Modifier.height(16.dp)) OutlinedTextField( value = password, onValueChange = { password = it }, label = { Text("Contraseña") }, singleLine = true, keyboardOptions = KeyboardOptions( keyboardType = KeyboardType.Password, imeAction = ImeAction.Next ), modifier = Modifier.fillMaxWidth(0.9f) ) Spacer(modifier = Modifier.height(16.dp)) OutlinedTextField( value = confirmPassword, onValueChange = { confirmPassword = it }, label = { Text("Confirmar contraseña") }, singleLine = true, keyboardOptions = KeyboardOptions( keyboardType = KeyboardType.Password, imeAction = ImeAction.Done ), modifier = Modifier.fillMaxWidth(0.9f) ) Spacer(modifier = Modifier.height(24.dp)) Button( onClick = { if (email.isNotBlank() && password.isNotBlank() && password == confirmPassword) { // Simula un registro exitoso y vuelve a la pantalla de login navController.popBackStack() } else { errorMessage = "Verifica que los campos estén completos y que las contraseñas coincidan." } }, modifier = Modifier.fillMaxWidth(0.9f) ) { Text("Registrarse") } Spacer(modifier = Modifier.height(16.dp)) if (errorMessage.isNotEmpty()) { Text(text = errorMessage, color = MaterialTheme.colorScheme.error) Spacer(modifier = Modifier.height(16.dp)) } TextButton(onClick = { navController.popBackStack() }) { Text("Volver a iniciar sesión") } } } @Composable fun ProfileScreen(navController: NavHostController) { // Pantalla para editar (crear) el perfil var name by remember { mutableStateOf("") } var description by remember { mutableStateOf("") } var imageUri by remember { mutableStateOf<Uri?>(null) } // Launcher para seleccionar imagen desde la galería val launcher = rememberLauncherForActivityResult( contract = ActivityResultContracts.GetContent() ) { uri: Uri? -> imageUri = uri } Column( modifier = Modifier .fillMaxSize() .padding(20.dp), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { Text("Editar Perfil", style = MaterialTheme.typography.headlineLarge) Spacer(modifier = Modifier.height(16.dp)) OutlinedTextField( value = name, onValueChange = { name = it }, label = { Text("Nombre") }, singleLine = true, modifier = Modifier.fillMaxWidth(0.9f) ) Spacer(modifier = Modifier.height(16.dp)) OutlinedTextField( value = description, onValueChange = { description = it }, label = { Text("Descripción") }, modifier = Modifier.fillMaxWidth(0.9f) ) Spacer(modifier = Modifier.height(16.dp)) Button( onClick = { launcher.launch("image/*") }, modifier = Modifier.fillMaxWidth(0.9f) ) { Text("Seleccionar foto") } Spacer(modifier = Modifier.height(16.dp)) imageUri?.let { uri -> Image( painter = rememberAsyncImagePainter(uri), contentDescription = "Foto de perfil", modifier = Modifier .fillMaxWidth(0.9f) .height(200.dp), contentScale = ContentScale.Crop ) Spacer(modifier = Modifier.height(16.dp)) } Button( onClick = { // Guarda los datos en el objeto global (solo para demostración) ProfileState.name = name ProfileState.description = description ProfileState.imageUri = imageUri // Navega a la pantalla de visualización del perfil (sin botón de guardar) navController.navigate(Routes.ProfileDisplay.route) }, modifier = Modifier.fillMaxWidth(0.9f) ) { Text("Guardar cambios") } } } @Composable fun ProfileDisplayScreen(navController: NavHostController) { // Pantalla para mostrar el perfil guardado (sin botón de guardar) Column( modifier = Modifier .fillMaxSize() .padding(20.dp), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { Text("Perfil Guardado", style = MaterialTheme.typography.headlineLarge) Spacer(modifier = Modifier.height(16.dp)) Text("Nombre: ${ProfileState.name}") Spacer(modifier = Modifier.height(8.dp)) Text("Descripción: ${ProfileState.description}") Spacer(modifier = Modifier.height(16.dp)) ProfileState.imageUri?.let { uri -> Image( painter = rememberAsyncImagePainter(uri), contentDescription = "Foto de perfil", modifier = Modifier .fillMaxWidth(0.9f) .height(200.dp), contentScale = ContentScale.Crop ) } } }
Editor is loading...
Leave a Comment