Cambiar la pantalla de login de despues de iniciar sesion

This commit is contained in:
2026-07-13 13:41:20 +02:00
parent fcb8869e0a
commit 25d6ef6cdb
7 changed files with 144 additions and 21 deletions
+1
View File
@@ -41,6 +41,7 @@ Saludapp es una aplicación Android moderna enfocada en la salud y el bienestar,
- `StartScreen.kt`: Pantalla de bienvenida. - `StartScreen.kt`: Pantalla de bienvenida.
- `LoginScreen.kt`: Inicio de sesión con validación de credenciales encriptadas. - `LoginScreen.kt`: Inicio de sesión con validación de credenciales encriptadas.
- `RegisterScreen.kt`: Registro de nuevos usuarios con soporte para nombre completo. - `RegisterScreen.kt`: Registro de nuevos usuarios con soporte para nombre completo.
- `HomeScreen.kt`: Dashboard principal con resumen de salud (pasos, sueño, agua, etc.).
- `theme/`: Configuración estética de Material 3. - `theme/`: Configuración estética de Material 3.
--- ---
+1
View File
@@ -42,6 +42,7 @@ dependencies {
implementation(platform(libs.androidx.compose.bom)) implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.activity.compose) implementation(libs.androidx.activity.compose)
implementation(libs.androidx.compose.material3) implementation(libs.androidx.compose.material3)
implementation(libs.androidx.compose.material.icons.extended)
implementation(libs.androidx.compose.ui) implementation(libs.androidx.compose.ui)
implementation(libs.androidx.compose.ui.graphics) implementation(libs.androidx.compose.ui.graphics)
implementation(libs.androidx.compose.ui.tooling.preview) implementation(libs.androidx.compose.ui.tooling.preview)
@@ -4,15 +4,11 @@ import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Text
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import com.example.saludapp.ui.HomeScreen
import androidx.compose.ui.Modifier
import com.example.saludapp.ui.LoginScreen import com.example.saludapp.ui.LoginScreen
import com.example.saludapp.ui.RegisterScreen import com.example.saludapp.ui.RegisterScreen
import com.example.saludapp.ui.StartScreen import com.example.saludapp.ui.StartScreen
@@ -25,27 +21,30 @@ class MainActivity : ComponentActivity() {
setContent { setContent {
SaludappTheme { SaludappTheme {
var currentScreen by remember { mutableStateOf("start") } var currentScreen by remember { mutableStateOf("start") }
var loggedInUserName by remember { mutableStateOf("") }
when (currentScreen) { when (currentScreen) {
"start" -> StartScreen { "start" -> StartScreen {
currentScreen = "login" currentScreen = "login"
} }
"login" -> LoginScreen( "login" -> LoginScreen(
onLoginSuccess = { currentScreen = "home" }, onLoginSuccess = { name ->
loggedInUserName = name
currentScreen = "home"
},
onNavigateToRegister = { currentScreen = "register" } onNavigateToRegister = { currentScreen = "register" }
) )
"register" -> RegisterScreen( "register" -> RegisterScreen(
onRegisterSuccess = { currentScreen = "login" }, onRegisterSuccess = { currentScreen = "login" },
onBackToLogin = { currentScreen = "login" } onBackToLogin = { currentScreen = "login" }
) )
"home" -> { "home" -> HomeScreen(
Box( userName = loggedInUserName,
modifier = Modifier.fillMaxSize(), onLogout = {
contentAlignment = Alignment.Center loggedInUserName = ""
) { currentScreen = "start"
Text("Bienvenido a Saludapp")
} }
} )
} }
} }
} }
@@ -19,14 +19,14 @@ object DatabaseHelper {
return digest.fold("") { str, it -> str + "%02x".format(it) } return digest.fold("") { str, it -> str + "%02x".format(it) }
} }
suspend fun validateLogin(user: String, pass: String): Boolean = withContext(Dispatchers.IO) { suspend fun validateLogin(user: String, pass: String): String? = withContext(Dispatchers.IO) {
var connection: Connection? = null var connection: Connection? = null
try { try {
Class.forName("org.mariadb.jdbc.Driver") Class.forName("org.mariadb.jdbc.Driver")
connection = DriverManager.getConnection(URL, USER, PASSWORD) connection = DriverManager.getConnection(URL, USER, PASSWORD)
val hashedPass = hashPassword(pass) val hashedPass = hashPassword(pass)
val query = "SELECT COUNT(*) FROM usuarios WHERE (username = ? OR email = ?) AND password = ?" val query = "SELECT nombre_completo FROM usuarios WHERE (username = ? OR email = ?) AND password = ?"
connection.prepareStatement(query).use { statement -> connection.prepareStatement(query).use { statement ->
statement.setString(1, user) statement.setString(1, user)
statement.setString(2, user) statement.setString(2, user)
@@ -34,7 +34,7 @@ object DatabaseHelper {
val resultSet = statement.executeQuery() val resultSet = statement.executeQuery()
if (resultSet.next()) { if (resultSet.next()) {
return@withContext resultSet.getInt(1) > 0 return@withContext resultSet.getString("nombre_completo") ?: user
} }
} }
} catch (e: Exception) { } catch (e: Exception) {
@@ -46,7 +46,7 @@ object DatabaseHelper {
e.printStackTrace() e.printStackTrace()
} }
} }
return@withContext false return@withContext null
} }
suspend fun registerUser(user: String, email: String, pass: String, fullName: String): Boolean = withContext(Dispatchers.IO) { suspend fun registerUser(user: String, email: String, pass: String, fullName: String): Boolean = withContext(Dispatchers.IO) {
@@ -0,0 +1,121 @@
package com.example.saludapp.ui
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.DirectionsRun
import androidx.compose.material.icons.automirrored.filled.ExitToApp
import androidx.compose.material.icons.filled.*
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun HomeScreen(userName: String, onLogout: () -> Unit) {
Scaffold(
topBar = {
TopAppBar(
title = { Text("Saludapp", fontWeight = FontWeight.Bold) },
actions = {
IconButton(onClick = onLogout) {
Icon(Icons.AutoMirrored.Filled.ExitToApp, contentDescription = "Cerrar sesión")
}
},
colors = TopAppBarDefaults.topAppBarColors(
containerColor = MaterialTheme.colorScheme.primaryContainer,
titleContentColor = MaterialTheme.colorScheme.onPrimaryContainer
)
)
}
) { padding ->
Column(
modifier = Modifier
.fillMaxSize()
.padding(padding)
.padding(16.dp)
) {
Text(
text = "Hola, $userName 👋",
style = MaterialTheme.typography.headlineMedium,
fontWeight = FontWeight.Bold
)
Text(
text = "Aquí tienes tu resumen de hoy",
style = MaterialTheme.typography.bodyLarge,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Spacer(modifier = Modifier.height(24.dp))
LazyVerticalGrid(
columns = GridCells.Fixed(2),
horizontalArrangement = Arrangement.spacedBy(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier.fillMaxSize()
) {
item {
StatCard("Pasos", "8,432", Icons.AutoMirrored.Filled.DirectionsRun, MaterialTheme.colorScheme.primary)
}
item {
StatCard("Sueño", "7h 20m", Icons.Default.Bedtime, MaterialTheme.colorScheme.secondary)
}
item {
StatCard("Agua", "1.5L", Icons.Default.LocalDrink, MaterialTheme.colorScheme.tertiary)
}
item {
StatCard("Calorías", "1,200 kcal", Icons.Default.Whatshot, MaterialTheme.colorScheme.error)
}
item {
StatCard("Corazón", "72 bpm", Icons.Default.Favorite, MaterialTheme.colorScheme.primary)
}
item {
StatCard("Peso", "70 kg", Icons.Default.MonitorWeight, MaterialTheme.colorScheme.secondary)
}
}
}
}
}
@Composable
fun StatCard(title: String, value: String, icon: ImageVector, color: androidx.compose.ui.graphics.Color) {
Card(
modifier = Modifier
.fillMaxWidth()
.height(140.dp),
colors = CardDefaults.cardColors(containerColor = color.copy(alpha = 0.1f))
) {
Column(
modifier = Modifier
.padding(16.dp)
.fillMaxSize(),
verticalArrangement = Arrangement.SpaceBetween
) {
Icon(
imageVector = icon,
contentDescription = null,
tint = color,
modifier = Modifier.size(32.dp)
)
Column {
Text(
text = value,
style = MaterialTheme.typography.titleLarge,
fontWeight = FontWeight.Bold,
color = color
)
Text(
text = title,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
}
}
}
@@ -11,7 +11,7 @@ import com.example.saludapp.data.DatabaseHelper
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@Composable @Composable
fun LoginScreen(onLoginSuccess: () -> Unit, onNavigateToRegister: () -> Unit) { fun LoginScreen(onLoginSuccess: (String) -> Unit, onNavigateToRegister: () -> Unit) {
var email by remember { mutableStateOf("") } var email by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") } var password by remember { mutableStateOf("") }
var isLoading by remember { mutableStateOf(false) } var isLoading by remember { mutableStateOf(false) }
@@ -73,10 +73,10 @@ fun LoginScreen(onLoginSuccess: () -> Unit, onNavigateToRegister: () -> Unit) {
scope.launch { scope.launch {
isLoading = true isLoading = true
errorMessage = null errorMessage = null
val success = DatabaseHelper.validateLogin(email, password) val userName = DatabaseHelper.validateLogin(email, password)
isLoading = false isLoading = false
if (success) { if (userName != null) {
onLoginSuccess() onLoginSuccess(userName)
} else { } else {
errorMessage = "Usuario o contraseña incorrectos" errorMessage = "Usuario o contraseña incorrectos"
} }
+1
View File
@@ -26,6 +26,7 @@ androidx-compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "u
androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } androidx-compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } androidx-compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" } androidx-compose-material3 = { group = "androidx.compose.material3", name = "material3" }
androidx-compose-material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended" }
[plugins] [plugins]
android-application = { id = "com.android.application", version.ref = "agp" } android-application = { id = "com.android.application", version.ref = "agp" }