Cambiar la pantalla de login de despues de iniciar sesion
This commit is contained in:
@@ -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.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -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"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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" }
|
||||||
|
|||||||
Reference in New Issue
Block a user