Aplicacion terminada
This commit is contained in:
@@ -43,17 +43,29 @@ CREATE TABLE SAIs (
|
||||
);
|
||||
|
||||
-- Table for Batteries
|
||||
CREATE TABLE baterias (
|
||||
CREATE TABLE Bateria (
|
||||
id_bateria INT AUTO_INCREMENT PRIMARY KEY,
|
||||
modelo VARCHAR(255) NOT NULL,
|
||||
estado VARCHAR(255) NOT NULL
|
||||
id_sai INT,
|
||||
marca VARCHAR(255),
|
||||
fecha_instalacion DATETIME,
|
||||
FOREIGN KEY (id_sai) REFERENCES SAIs(id_sai)
|
||||
);
|
||||
|
||||
-- Table for People
|
||||
CREATE TABLE personas (
|
||||
CREATE TABLE Persona (
|
||||
id_persona INT AUTO_INCREMENT PRIMARY KEY,
|
||||
nombre VARCHAR(255) NOT NULL,
|
||||
puesto VARCHAR(255) NOT NULL
|
||||
nombre VARCHAR(255) NOT NULL
|
||||
);
|
||||
|
||||
-- Table for Assignments
|
||||
CREATE TABLE Asignado (
|
||||
id_asignacion INT AUTO_INCREMENT PRIMARY KEY,
|
||||
id_sai INT,
|
||||
id_persona INT,
|
||||
fecha_asignado DATE,
|
||||
fecha_devolucion DATE,
|
||||
FOREIGN KEY (id_sai) REFERENCES SAIs(id_sai),
|
||||
FOREIGN KEY (id_persona) REFERENCES Persona(id_persona)
|
||||
);
|
||||
```
|
||||
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
package com.example.saipp.data
|
||||
|
||||
import com.example.saipp.data.model.Assignment
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.sql.SQLException
|
||||
import java.sql.Types
|
||||
|
||||
class AssignmentRepository {
|
||||
suspend fun getAll(): Result<List<Assignment>> = withContext(Dispatchers.IO) {
|
||||
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
||||
try {
|
||||
val sql = """
|
||||
SELECT a.id_asignacion, a.id_sai, a.id_persona, a.fecha_asignado, a.fecha_devolucion,
|
||||
s.ns as sai_ns, p.nombre as person_name
|
||||
FROM Asignado a
|
||||
LEFT JOIN SAIs s ON a.id_sai = s.id_sai
|
||||
LEFT JOIN Persona p ON a.id_persona = p.id_persona
|
||||
""".trimIndent()
|
||||
val statement = connection.prepareStatement(sql)
|
||||
val resultSet = statement.executeQuery()
|
||||
val items = mutableListOf<Assignment>()
|
||||
while (resultSet.next()) {
|
||||
items.add(Assignment(
|
||||
id = resultSet.getInt("id_asignacion"),
|
||||
idSai = resultSet.getInt("id_sai"),
|
||||
idPersona = resultSet.getInt("id_persona"),
|
||||
assignedDate = resultSet.getString("fecha_asignado"),
|
||||
returnDate = resultSet.getString("fecha_devolucion"),
|
||||
saiNs = resultSet.getString("sai_ns"),
|
||||
personName = resultSet.getString("person_name")
|
||||
))
|
||||
}
|
||||
Result.success(items)
|
||||
} catch (e: SQLException) {
|
||||
Result.failure(e)
|
||||
} finally {
|
||||
connection.close()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getById(id: Int): Result<Assignment> = withContext(Dispatchers.IO) {
|
||||
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
||||
try {
|
||||
val sql = "SELECT id_asignacion, id_sai, id_persona, fecha_asignado, fecha_devolucion FROM Asignado WHERE id_asignacion = ?"
|
||||
val statement = connection.prepareStatement(sql)
|
||||
statement.setInt(1, id)
|
||||
val resultSet = statement.executeQuery()
|
||||
if (resultSet.next()) {
|
||||
Result.success(Assignment(
|
||||
id = resultSet.getInt("id_asignacion"),
|
||||
idSai = resultSet.getInt("id_sai"),
|
||||
idPersona = resultSet.getInt("id_persona"),
|
||||
assignedDate = resultSet.getString("fecha_asignado"),
|
||||
returnDate = resultSet.getString("fecha_devolucion")
|
||||
))
|
||||
} else {
|
||||
Result.failure(Exception("not_found"))
|
||||
}
|
||||
} catch (e: SQLException) {
|
||||
Result.failure(e)
|
||||
} finally {
|
||||
connection.close()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun insert(item: Assignment): Result<Unit> = withContext(Dispatchers.IO) {
|
||||
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
||||
try {
|
||||
val sql = "INSERT INTO Asignado (id_sai, id_persona, fecha_asignado, fecha_devolucion) VALUES (?, ?, ?, ?)"
|
||||
val statement = connection.prepareStatement(sql)
|
||||
statement.setInt(1, item.idSai)
|
||||
statement.setInt(2, item.idPersona)
|
||||
statement.setString(3, item.assignedDate)
|
||||
statement.setString(4, item.returnDate)
|
||||
|
||||
if (statement.executeUpdate() > 0) Result.success(Unit)
|
||||
else Result.failure(Exception("no_rows_inserted"))
|
||||
} catch (e: SQLException) {
|
||||
Result.failure(e)
|
||||
} finally {
|
||||
connection.close()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun update(item: Assignment): Result<Unit> = withContext(Dispatchers.IO) {
|
||||
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
||||
try {
|
||||
val sql = "UPDATE Asignado SET id_sai = ?, id_persona = ?, fecha_asignado = ?, fecha_devolucion = ? WHERE id_asignacion = ?"
|
||||
val statement = connection.prepareStatement(sql)
|
||||
statement.setInt(1, item.idSai)
|
||||
statement.setInt(2, item.idPersona)
|
||||
statement.setString(3, item.assignedDate)
|
||||
statement.setString(4, item.returnDate)
|
||||
statement.setInt(5, item.id)
|
||||
|
||||
if (statement.executeUpdate() > 0) Result.success(Unit)
|
||||
else Result.failure(Exception("update_failed"))
|
||||
} catch (e: SQLException) {
|
||||
Result.failure(e)
|
||||
} finally {
|
||||
connection.close()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun delete(id: Int): Result<Unit> = withContext(Dispatchers.IO) {
|
||||
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
||||
try {
|
||||
val sql = "DELETE FROM Asignado WHERE id_asignacion = ?"
|
||||
val statement = connection.prepareStatement(sql)
|
||||
statement.setInt(1, id)
|
||||
if (statement.executeUpdate() > 0) Result.success(Unit)
|
||||
else Result.failure(Exception("delete_failed"))
|
||||
} catch (e: SQLException) {
|
||||
Result.failure(e)
|
||||
} finally {
|
||||
connection.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,20 +4,22 @@ import com.example.saipp.data.model.Battery
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.sql.SQLException
|
||||
import java.sql.Types
|
||||
|
||||
class BatteryRepository {
|
||||
suspend fun getAll(): Result<List<Battery>> = withContext(Dispatchers.IO) {
|
||||
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
||||
try {
|
||||
val sql = "SELECT id_bateria, modelo, estado FROM baterias"
|
||||
val sql = "SELECT id_bateria, id_sai, marca, fecha_instalacion FROM Bateria"
|
||||
val statement = connection.prepareStatement(sql)
|
||||
val resultSet = statement.executeQuery()
|
||||
val items = mutableListOf<Battery>()
|
||||
while (resultSet.next()) {
|
||||
items.add(Battery(
|
||||
id = resultSet.getInt("id_bateria"),
|
||||
model = resultSet.getString("modelo"),
|
||||
status = resultSet.getString("estado")
|
||||
idSai = resultSet.getInt("id_sai").takeIf { !resultSet.wasNull() },
|
||||
brand = resultSet.getString("marca"),
|
||||
installDate = resultSet.getString("fecha_instalacion")
|
||||
))
|
||||
}
|
||||
Result.success(items)
|
||||
@@ -31,10 +33,12 @@ class BatteryRepository {
|
||||
suspend fun insert(item: Battery): Result<Unit> = withContext(Dispatchers.IO) {
|
||||
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
||||
try {
|
||||
val sql = "INSERT INTO baterias (modelo, estado) VALUES (?, ?)"
|
||||
val sql = "INSERT INTO Bateria (id_sai, marca, fecha_instalacion) VALUES (?, ?, ?)"
|
||||
val statement = connection.prepareStatement(sql)
|
||||
statement.setString(1, item.model)
|
||||
statement.setString(2, item.status)
|
||||
if (item.idSai != null) statement.setInt(1, item.idSai) else statement.setNull(1, Types.INTEGER)
|
||||
statement.setString(2, item.brand)
|
||||
statement.setString(3, item.installDate)
|
||||
|
||||
if (statement.executeUpdate() > 0) Result.success(Unit)
|
||||
else Result.failure(Exception("no_rows_inserted"))
|
||||
} catch (e: SQLException) {
|
||||
@@ -47,11 +51,13 @@ class BatteryRepository {
|
||||
suspend fun update(item: Battery): Result<Unit> = withContext(Dispatchers.IO) {
|
||||
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
||||
try {
|
||||
val sql = "UPDATE baterias SET modelo = ?, estado = ? WHERE id_bateria = ?"
|
||||
val sql = "UPDATE Bateria SET id_sai = ?, marca = ?, fecha_instalacion = ? WHERE id_bateria = ?"
|
||||
val statement = connection.prepareStatement(sql)
|
||||
statement.setString(1, item.model)
|
||||
statement.setString(2, item.status)
|
||||
statement.setInt(3, item.id)
|
||||
if (item.idSai != null) statement.setInt(1, item.idSai) else statement.setNull(1, Types.INTEGER)
|
||||
statement.setString(2, item.brand)
|
||||
statement.setString(3, item.installDate)
|
||||
statement.setInt(4, item.id)
|
||||
|
||||
if (statement.executeUpdate() > 0) Result.success(Unit)
|
||||
else Result.failure(Exception("update_failed"))
|
||||
} catch (e: SQLException) {
|
||||
@@ -64,7 +70,7 @@ class BatteryRepository {
|
||||
suspend fun delete(id: Int): Result<Unit> = withContext(Dispatchers.IO) {
|
||||
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
||||
try {
|
||||
val sql = "DELETE FROM baterias WHERE id_bateria = ?"
|
||||
val sql = "DELETE FROM Bateria WHERE id_bateria = ?"
|
||||
val statement = connection.prepareStatement(sql)
|
||||
statement.setInt(1, id)
|
||||
if (statement.executeUpdate() > 0) Result.success(Unit)
|
||||
@@ -75,4 +81,28 @@ class BatteryRepository {
|
||||
connection.close()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getById(id: Int): Result<Battery> = withContext(Dispatchers.IO) {
|
||||
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
||||
try {
|
||||
val sql = "SELECT id_bateria, id_sai, marca, fecha_instalacion FROM Bateria WHERE id_bateria = ?"
|
||||
val statement = connection.prepareStatement(sql)
|
||||
statement.setInt(1, id)
|
||||
val resultSet = statement.executeQuery()
|
||||
if (resultSet.next()) {
|
||||
Result.success(Battery(
|
||||
id = resultSet.getInt("id_bateria"),
|
||||
idSai = resultSet.getInt("id_sai").takeIf { !resultSet.wasNull() },
|
||||
brand = resultSet.getString("marca"),
|
||||
installDate = resultSet.getString("fecha_instalacion")
|
||||
))
|
||||
} else {
|
||||
Result.failure(Exception("not_found"))
|
||||
}
|
||||
} catch (e: SQLException) {
|
||||
Result.failure(e)
|
||||
} finally {
|
||||
connection.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,15 +9,14 @@ class PersonRepository {
|
||||
suspend fun getAll(): Result<List<Person>> = withContext(Dispatchers.IO) {
|
||||
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
||||
try {
|
||||
val sql = "SELECT id_persona, nombre, puesto FROM personas"
|
||||
val sql = "SELECT id_persona, nombre FROM Persona"
|
||||
val statement = connection.prepareStatement(sql)
|
||||
val resultSet = statement.executeQuery()
|
||||
val items = mutableListOf<Person>()
|
||||
while (resultSet.next()) {
|
||||
items.add(Person(
|
||||
id = resultSet.getInt("id_persona"),
|
||||
name = resultSet.getString("nombre"),
|
||||
position = resultSet.getString("puesto")
|
||||
name = resultSet.getString("nombre")
|
||||
))
|
||||
}
|
||||
Result.success(items)
|
||||
@@ -31,10 +30,9 @@ class PersonRepository {
|
||||
suspend fun insert(item: Person): Result<Unit> = withContext(Dispatchers.IO) {
|
||||
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
||||
try {
|
||||
val sql = "INSERT INTO personas (nombre, puesto) VALUES (?, ?)"
|
||||
val sql = "INSERT INTO Persona (nombre) VALUES (?)"
|
||||
val statement = connection.prepareStatement(sql)
|
||||
statement.setString(1, item.name)
|
||||
statement.setString(2, item.position)
|
||||
if (statement.executeUpdate() > 0) Result.success(Unit)
|
||||
else Result.failure(Exception("no_rows_inserted"))
|
||||
} catch (e: SQLException) {
|
||||
@@ -47,11 +45,10 @@ class PersonRepository {
|
||||
suspend fun update(item: Person): Result<Unit> = withContext(Dispatchers.IO) {
|
||||
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
||||
try {
|
||||
val sql = "UPDATE personas SET nombre = ?, puesto = ? WHERE id_persona = ?"
|
||||
val sql = "UPDATE Persona SET nombre = ? WHERE id_persona = ?"
|
||||
val statement = connection.prepareStatement(sql)
|
||||
statement.setString(1, item.name)
|
||||
statement.setString(2, item.position)
|
||||
statement.setInt(3, item.id)
|
||||
statement.setInt(2, item.id)
|
||||
if (statement.executeUpdate() > 0) Result.success(Unit)
|
||||
else Result.failure(Exception("update_failed"))
|
||||
} catch (e: SQLException) {
|
||||
@@ -64,7 +61,7 @@ class PersonRepository {
|
||||
suspend fun delete(id: Int): Result<Unit> = withContext(Dispatchers.IO) {
|
||||
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
||||
try {
|
||||
val sql = "DELETE FROM personas WHERE id_persona = ?"
|
||||
val sql = "DELETE FROM Persona WHERE id_persona = ?"
|
||||
val statement = connection.prepareStatement(sql)
|
||||
statement.setInt(1, id)
|
||||
if (statement.executeUpdate() > 0) Result.success(Unit)
|
||||
@@ -75,4 +72,26 @@ class PersonRepository {
|
||||
connection.close()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getById(id: Int): Result<Person> = withContext(Dispatchers.IO) {
|
||||
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
||||
try {
|
||||
val sql = "SELECT id_persona, nombre FROM Persona WHERE id_persona = ?"
|
||||
val statement = connection.prepareStatement(sql)
|
||||
statement.setInt(1, id)
|
||||
val resultSet = statement.executeQuery()
|
||||
if (resultSet.next()) {
|
||||
Result.success(Person(
|
||||
id = resultSet.getInt("id_persona"),
|
||||
name = resultSet.getString("nombre")
|
||||
))
|
||||
} else {
|
||||
Result.failure(Exception("not_found"))
|
||||
}
|
||||
} catch (e: SQLException) {
|
||||
Result.failure(e)
|
||||
} finally {
|
||||
connection.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,4 +74,23 @@ class SaiRepository {
|
||||
connection.close()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getById(id: Int): Result<Sai> = withContext(Dispatchers.IO) {
|
||||
val connection = MariaDbConnection.getConnection() ?: return@withContext Result.failure(Exception("db_connection_error"))
|
||||
try {
|
||||
val sql = "SELECT id_sai, ns FROM SAIs WHERE id_sai = ?"
|
||||
val statement = connection.prepareStatement(sql)
|
||||
statement.setInt(1, id)
|
||||
val resultSet = statement.executeQuery()
|
||||
if (resultSet.next()) {
|
||||
Result.success(Sai(id = resultSet.getInt("id_sai"), ns = resultSet.getString("ns")))
|
||||
} else {
|
||||
Result.failure(Exception("not_found"))
|
||||
}
|
||||
} catch (e: SQLException) {
|
||||
Result.failure(e)
|
||||
} finally {
|
||||
connection.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.example.saipp.data.model
|
||||
|
||||
data class Assignment(
|
||||
val id: Int = 0,
|
||||
val idSai: Int,
|
||||
val idPersona: Int,
|
||||
val assignedDate: String? = null,
|
||||
val returnDate: String? = null,
|
||||
// Optional display fields for joining data
|
||||
val saiNs: String? = null,
|
||||
val personName: String? = null
|
||||
)
|
||||
@@ -2,6 +2,7 @@ package com.example.saipp.data.model
|
||||
|
||||
data class Battery(
|
||||
val id: Int = 0,
|
||||
val model: String,
|
||||
val status: String
|
||||
val idSai: Int? = null,
|
||||
val brand: String? = null,
|
||||
val installDate: String? = null
|
||||
)
|
||||
|
||||
@@ -2,6 +2,5 @@ package com.example.saipp.data.model
|
||||
|
||||
data class Person(
|
||||
val id: Int = 0,
|
||||
val name: String,
|
||||
val position: String
|
||||
val name: String
|
||||
)
|
||||
|
||||
@@ -1,19 +1,35 @@
|
||||
package com.example.saipp.ui
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import androidx.navigation.navArgument
|
||||
import com.example.saipp.ui.management.*
|
||||
|
||||
sealed class Screen(val route: String) {
|
||||
object Home : Screen("home")
|
||||
object SaiList : Screen("sai_list")
|
||||
object SaiScanner : Screen("sai_scanner")
|
||||
object EditSai : Screen("edit_sai/{saiId}") {
|
||||
fun createRoute(id: Int) = "edit_sai/$id"
|
||||
}
|
||||
object BatteryList : Screen("battery_list")
|
||||
object AddBattery : Screen("add_battery")
|
||||
object EditBattery : Screen("edit_battery/{batteryId}") {
|
||||
fun createRoute(id: Int) = "edit_battery/$id"
|
||||
}
|
||||
object PersonList : Screen("person_list")
|
||||
object AddPerson : Screen("add_person")
|
||||
object EditPerson : Screen("edit_person/{personId}") {
|
||||
fun createRoute(id: Int) = "edit_person/$id"
|
||||
}
|
||||
object AssignmentList : Screen("assignment_list")
|
||||
object AddAssignment : Screen("add_assignment")
|
||||
object EditAssignment : Screen("edit_assignment/{assignmentId}") {
|
||||
fun createRoute(id: Int) = "edit_assignment/$id"
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@@ -25,13 +41,17 @@ fun AppNavigation() {
|
||||
HomeScreen(
|
||||
onNavigateToSais = { navController.navigate(Screen.SaiList.route) },
|
||||
onNavigateToBatteries = { navController.navigate(Screen.BatteryList.route) },
|
||||
onNavigateToPeople = { navController.navigate(Screen.PersonList.route) }
|
||||
onNavigateToPeople = { navController.navigate(Screen.PersonList.route) },
|
||||
onNavigateToAssignments = { navController.navigate(Screen.AssignmentList.route) }
|
||||
)
|
||||
}
|
||||
|
||||
// SAIs
|
||||
composable(Screen.SaiList.route) {
|
||||
SaiListScreen(
|
||||
onNavigateBack = { navController.popBackStack() },
|
||||
onNavigateToScan = { navController.navigate(Screen.SaiScanner.route) }
|
||||
onNavigateToScan = { navController.navigate(Screen.SaiScanner.route) },
|
||||
onNavigateToEdit = { id -> navController.navigate(Screen.EditSai.createRoute(id)) }
|
||||
)
|
||||
}
|
||||
composable(Screen.SaiScanner.route) {
|
||||
@@ -39,27 +59,69 @@ fun AppNavigation() {
|
||||
onNavigateBack = { navController.popBackStack() }
|
||||
)
|
||||
}
|
||||
composable(
|
||||
route = Screen.EditSai.route,
|
||||
arguments = listOf(navArgument("saiId") { type = NavType.IntType })
|
||||
) { backStackEntry ->
|
||||
val id = backStackEntry.arguments?.getInt("saiId") ?: 0
|
||||
EditSaiScreen(saiId = id, onNavigateBack = { navController.popBackStack() })
|
||||
}
|
||||
|
||||
// Batteries
|
||||
composable(Screen.BatteryList.route) {
|
||||
BatteryListScreen(
|
||||
onNavigateBack = { navController.popBackStack() },
|
||||
onNavigateToAdd = { navController.navigate(Screen.AddBattery.route) }
|
||||
onNavigateToAdd = { navController.navigate(Screen.AddBattery.route) },
|
||||
onNavigateToEdit = { id -> navController.navigate(Screen.EditBattery.createRoute(id)) }
|
||||
)
|
||||
}
|
||||
composable(Screen.AddBattery.route) {
|
||||
AddBatteryScreen(
|
||||
onNavigateBack = { navController.popBackStack() }
|
||||
)
|
||||
AddBatteryScreen(onNavigateBack = { navController.popBackStack() })
|
||||
}
|
||||
composable(
|
||||
route = Screen.EditBattery.route,
|
||||
arguments = listOf(navArgument("batteryId") { type = NavType.IntType })
|
||||
) { backStackEntry ->
|
||||
val id = backStackEntry.arguments?.getInt("batteryId") ?: 0
|
||||
EditBatteryScreen(batteryId = id, onNavigateBack = { navController.popBackStack() })
|
||||
}
|
||||
|
||||
// People
|
||||
composable(Screen.PersonList.route) {
|
||||
PersonListScreen(
|
||||
onNavigateBack = { navController.popBackStack() },
|
||||
onNavigateToAdd = { navController.navigate(Screen.AddPerson.route) }
|
||||
onNavigateToAdd = { navController.navigate(Screen.AddPerson.route) },
|
||||
onNavigateToEdit = { id -> navController.navigate(Screen.EditPerson.createRoute(id)) }
|
||||
)
|
||||
}
|
||||
composable(Screen.AddPerson.route) {
|
||||
AddPersonScreen(
|
||||
onNavigateBack = { navController.popBackStack() }
|
||||
AddPersonScreen(onNavigateBack = { navController.popBackStack() })
|
||||
}
|
||||
composable(
|
||||
route = Screen.EditPerson.route,
|
||||
arguments = listOf(navArgument("personId") { type = NavType.IntType })
|
||||
) { backStackEntry ->
|
||||
val id = backStackEntry.arguments?.getInt("personId") ?: 0
|
||||
EditPersonScreen(personId = id, onNavigateBack = { navController.popBackStack() })
|
||||
}
|
||||
|
||||
// Assignments
|
||||
composable(Screen.AssignmentList.route) {
|
||||
AssignmentListScreen(
|
||||
onNavigateBack = { navController.popBackStack() },
|
||||
onNavigateToAdd = { navController.navigate(Screen.AddAssignment.route) },
|
||||
onNavigateToEdit = { id -> navController.navigate(Screen.EditAssignment.createRoute(id)) }
|
||||
)
|
||||
}
|
||||
composable(Screen.AddAssignment.route) {
|
||||
AddAssignmentScreen(onNavigateBack = { navController.popBackStack() })
|
||||
}
|
||||
composable(
|
||||
route = Screen.EditAssignment.route,
|
||||
arguments = listOf(navArgument("assignmentId") { type = NavType.IntType })
|
||||
) { backStackEntry ->
|
||||
val id = backStackEntry.arguments?.getInt("assignmentId") ?: 0
|
||||
EditAssignmentScreen(assignmentId = id, onNavigateBack = { navController.popBackStack() })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
package com.example.saipp.ui.management
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.example.saipp.R
|
||||
import com.example.saipp.data.AssignmentRepository
|
||||
import com.example.saipp.data.PersonRepository
|
||||
import com.example.saipp.data.SaiRepository
|
||||
import com.example.saipp.data.model.Assignment
|
||||
import com.example.saipp.data.model.Person
|
||||
import com.example.saipp.data.model.Sai
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun AddAssignmentScreen(
|
||||
onNavigateBack: () -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
val repository = remember { AssignmentRepository() }
|
||||
val saiRepository = remember { SaiRepository() }
|
||||
val personRepository = remember { PersonRepository() }
|
||||
|
||||
var selectedSaiId by remember { mutableStateOf<Int?>(null) }
|
||||
var selectedPersonId by remember { mutableStateOf<Int?>(null) }
|
||||
var assignedDate by remember { mutableStateOf("") }
|
||||
var returnDate by remember { mutableStateOf("") }
|
||||
|
||||
var sais by remember { mutableStateOf<List<Sai>>(emptyList()) }
|
||||
var people by remember { mutableStateOf<List<Person>>(emptyList()) }
|
||||
var isSaving by remember { mutableStateOf(false) }
|
||||
var saiExpanded by remember { mutableStateOf(false) }
|
||||
var personExpanded by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
saiRepository.getAll().onSuccess { sais = it }
|
||||
personRepository.getAll().onSuccess { people = it }
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text("Añadir Asignación") },
|
||||
navigationIcon = {
|
||||
IconButton(onClick = onNavigateBack) {
|
||||
Icon(Icons.Default.ArrowBack, contentDescription = "Atrás")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
) { padding ->
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(16.dp)
|
||||
) {
|
||||
// SAI Selection
|
||||
ExposedDropdownMenuBox(
|
||||
expanded = saiExpanded,
|
||||
onExpandedChange = { saiExpanded = !saiExpanded }
|
||||
) {
|
||||
val selectedSai = sais.find { it.id == selectedSaiId }
|
||||
OutlinedTextField(
|
||||
value = selectedSai?.ns ?: stringResource(R.string.select_sai),
|
||||
onValueChange = {},
|
||||
readOnly = true,
|
||||
label = { Text(stringResource(R.string.label_sai)) },
|
||||
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = saiExpanded) },
|
||||
modifier = Modifier.menuAnchor().fillMaxWidth()
|
||||
)
|
||||
ExposedDropdownMenu(
|
||||
expanded = saiExpanded,
|
||||
onDismissRequest = { saiExpanded = false }
|
||||
) {
|
||||
sais.forEach { sai ->
|
||||
DropdownMenuItem(
|
||||
text = { Text(sai.ns) },
|
||||
onClick = {
|
||||
selectedSaiId = sai.id
|
||||
saiExpanded = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
// Person Selection
|
||||
ExposedDropdownMenuBox(
|
||||
expanded = personExpanded,
|
||||
onExpandedChange = { personExpanded = !personExpanded }
|
||||
) {
|
||||
val selectedPerson = people.find { it.id == selectedPersonId }
|
||||
OutlinedTextField(
|
||||
value = selectedPerson?.name ?: stringResource(R.string.select_person),
|
||||
onValueChange = {},
|
||||
readOnly = true,
|
||||
label = { Text(stringResource(R.string.label_person)) },
|
||||
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = personExpanded) },
|
||||
modifier = Modifier.menuAnchor().fillMaxWidth()
|
||||
)
|
||||
ExposedDropdownMenu(
|
||||
expanded = personExpanded,
|
||||
onDismissRequest = { personExpanded = false }
|
||||
) {
|
||||
people.forEach { person ->
|
||||
DropdownMenuItem(
|
||||
text = { Text(person.name) },
|
||||
onClick = {
|
||||
selectedPersonId = person.id
|
||||
personExpanded = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
OutlinedTextField(
|
||||
value = assignedDate,
|
||||
onValueChange = { assignedDate = it },
|
||||
label = { Text(stringResource(R.string.label_assigned_date)) },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
OutlinedTextField(
|
||||
value = returnDate,
|
||||
onValueChange = { returnDate = it },
|
||||
label = { Text(stringResource(R.string.label_return_date)) },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
|
||||
Button(
|
||||
onClick = {
|
||||
if (selectedSaiId != null && selectedPersonId != null) {
|
||||
isSaving = true
|
||||
scope.launch {
|
||||
repository.insert(
|
||||
Assignment(
|
||||
idSai = selectedSaiId!!,
|
||||
idPersona = selectedPersonId!!,
|
||||
assignedDate = assignedDate.takeIf { it.isNotBlank() },
|
||||
returnDate = returnDate.takeIf { it.isNotBlank() }
|
||||
)
|
||||
).onSuccess {
|
||||
Toast.makeText(context, "Asignación guardada", Toast.LENGTH_SHORT).show()
|
||||
onNavigateBack()
|
||||
}.onFailure {
|
||||
Toast.makeText(context, "Error: ${it.message}", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
isSaving = false
|
||||
}
|
||||
}
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = !isSaving && selectedSaiId != null && selectedPersonId != null
|
||||
) {
|
||||
if (isSaving) CircularProgressIndicator(modifier = Modifier.size(24.dp))
|
||||
else Text("Guardar")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,9 +8,13 @@ import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.example.saipp.R
|
||||
import com.example.saipp.data.BatteryRepository
|
||||
import com.example.saipp.data.SaiRepository
|
||||
import com.example.saipp.data.model.Battery
|
||||
import com.example.saipp.data.model.Sai
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@@ -20,11 +24,20 @@ fun AddBatteryScreen(
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
val repository = remember { BatteryRepository() }
|
||||
val batteryRepository = remember { BatteryRepository() }
|
||||
val saiRepository = remember { SaiRepository() }
|
||||
|
||||
var model by remember { mutableStateOf("") }
|
||||
var status by remember { mutableStateOf("") }
|
||||
var brand by remember { mutableStateOf("") }
|
||||
var installDate by remember { mutableStateOf("") }
|
||||
var selectedSaiId by remember { mutableStateOf<Int?>(null) }
|
||||
|
||||
var sais by remember { mutableStateOf<List<Sai>>(emptyList()) }
|
||||
var isSaving by remember { mutableStateOf(false) }
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
saiRepository.getAll().onSuccess { sais = it }
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
@@ -44,33 +57,80 @@ fun AddBatteryScreen(
|
||||
.padding(padding)
|
||||
.padding(16.dp)
|
||||
) {
|
||||
OutlinedTextField(
|
||||
value = model,
|
||||
onValueChange = { model = it },
|
||||
label = { Text("Modelo") },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
// SAI Selection
|
||||
ExposedDropdownMenuBox(
|
||||
expanded = expanded,
|
||||
onExpandedChange = { expanded = !expanded }
|
||||
) {
|
||||
val selectedSai = sais.find { it.id == selectedSaiId }
|
||||
OutlinedTextField(
|
||||
value = selectedSai?.ns ?: stringResource(R.string.no_sai),
|
||||
onValueChange = {},
|
||||
readOnly = true,
|
||||
label = { Text(stringResource(R.string.label_sai)) },
|
||||
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
|
||||
modifier = Modifier.menuAnchor().fillMaxWidth()
|
||||
)
|
||||
ExposedDropdownMenu(
|
||||
expanded = expanded,
|
||||
onDismissRequest = { expanded = false }
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
text = { Text(stringResource(R.string.no_sai)) },
|
||||
onClick = {
|
||||
selectedSaiId = null
|
||||
expanded = false
|
||||
}
|
||||
)
|
||||
sais.forEach { sai ->
|
||||
DropdownMenuItem(
|
||||
text = { Text(sai.ns) },
|
||||
onClick = {
|
||||
selectedSaiId = sai.id
|
||||
expanded = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
OutlinedTextField(
|
||||
value = status,
|
||||
onValueChange = { status = it },
|
||||
label = { Text("Estado") },
|
||||
value = brand,
|
||||
onValueChange = { brand = it },
|
||||
label = { Text(stringResource(R.string.label_brand)) },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
OutlinedTextField(
|
||||
value = installDate,
|
||||
onValueChange = { installDate = it },
|
||||
label = { Text(stringResource(R.string.label_install_date)) },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
|
||||
Button(
|
||||
onClick = {
|
||||
if (model.isNotBlank() && status.isNotBlank()) {
|
||||
isSaving = true
|
||||
scope.launch {
|
||||
repository.insert(Battery(model = model, status = status))
|
||||
.onSuccess {
|
||||
Toast.makeText(context, "Batería añadida", Toast.LENGTH_SHORT).show()
|
||||
onNavigateBack()
|
||||
}
|
||||
.onFailure { Toast.makeText(context, "Error: ${it.message}", Toast.LENGTH_SHORT).show() }
|
||||
isSaving = false
|
||||
isSaving = true
|
||||
scope.launch {
|
||||
batteryRepository.insert(
|
||||
Battery(
|
||||
idSai = selectedSaiId,
|
||||
brand = brand,
|
||||
installDate = installDate.takeIf { it.isNotBlank() }
|
||||
)
|
||||
).onSuccess {
|
||||
Toast.makeText(context, "Batería añadida", Toast.LENGTH_SHORT).show()
|
||||
onNavigateBack()
|
||||
}.onFailure {
|
||||
Toast.makeText(context, "Error: ${it.message}", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
isSaving = false
|
||||
}
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
|
||||
@@ -23,7 +23,6 @@ fun AddPersonScreen(
|
||||
val repository = remember { PersonRepository() }
|
||||
|
||||
var name by remember { mutableStateOf("") }
|
||||
var position by remember { mutableStateOf("") }
|
||||
var isSaving by remember { mutableStateOf(false) }
|
||||
|
||||
Scaffold(
|
||||
@@ -50,20 +49,13 @@ fun AddPersonScreen(
|
||||
label = { Text("Nombre") },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
OutlinedTextField(
|
||||
value = position,
|
||||
onValueChange = { position = it },
|
||||
label = { Text("Puesto") },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
Button(
|
||||
onClick = {
|
||||
if (name.isNotBlank() && position.isNotBlank()) {
|
||||
if (name.isNotBlank()) {
|
||||
isSaving = true
|
||||
scope.launch {
|
||||
repository.insert(Person(name = name, position = position))
|
||||
repository.insert(Person(name = name))
|
||||
.onSuccess {
|
||||
Toast.makeText(context, "Persona añadida", Toast.LENGTH_SHORT).show()
|
||||
onNavigateBack()
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
package com.example.saipp.ui.management
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material.icons.filled.Edit
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.example.saipp.data.AssignmentRepository
|
||||
import com.example.saipp.data.model.Assignment
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun AssignmentListScreen(
|
||||
onNavigateBack: () -> Unit,
|
||||
onNavigateToAdd: () -> Unit,
|
||||
onNavigateToEdit: (Int) -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
val repository = remember { AssignmentRepository() }
|
||||
var items by remember { mutableStateOf<List<Assignment>>(emptyList()) }
|
||||
var isLoading by remember { mutableStateOf(true) }
|
||||
|
||||
fun loadItems() {
|
||||
scope.launch {
|
||||
isLoading = true
|
||||
repository.getAll()
|
||||
.onSuccess { items = it }
|
||||
.onFailure { Toast.makeText(context, "Error: ${it.message}", Toast.LENGTH_SHORT).show() }
|
||||
isLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
loadItems()
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text("Listado de Asignaciones") },
|
||||
navigationIcon = {
|
||||
IconButton(onClick = onNavigateBack) {
|
||||
Icon(Icons.Default.ArrowBack, contentDescription = "Atrás")
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
floatingActionButton = {
|
||||
FloatingActionButton(onClick = onNavigateToAdd) {
|
||||
Icon(Icons.Default.Add, contentDescription = "Añadir Asignación")
|
||||
}
|
||||
}
|
||||
) { padding ->
|
||||
if (isLoading) {
|
||||
Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
} else {
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
) {
|
||||
items(items) { item ->
|
||||
ListItem(
|
||||
headlineContent = { Text("${item.personName ?: "Persona desconocida"}") },
|
||||
supportingContent = {
|
||||
Column {
|
||||
Text("SAI: ${item.saiNs ?: "N/A"}")
|
||||
Text("Asignado: ${item.assignedDate ?: "N/A"}")
|
||||
if (item.returnDate != null) {
|
||||
Text("Devolución: ${item.returnDate}")
|
||||
}
|
||||
}
|
||||
},
|
||||
trailingContent = {
|
||||
Row {
|
||||
IconButton(onClick = { onNavigateToEdit(item.id) }) {
|
||||
Icon(Icons.Default.Edit, contentDescription = "Editar")
|
||||
}
|
||||
IconButton(onClick = {
|
||||
scope.launch {
|
||||
repository.delete(item.id).onSuccess { loadItems() }
|
||||
}
|
||||
}) {
|
||||
Icon(Icons.Default.Delete, contentDescription = "Eliminar")
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
HorizontalDivider()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material.icons.filled.Edit
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -22,7 +23,8 @@ import kotlinx.coroutines.launch
|
||||
@Composable
|
||||
fun BatteryListScreen(
|
||||
onNavigateBack: () -> Unit,
|
||||
onNavigateToAdd: () -> Unit
|
||||
onNavigateToAdd: () -> Unit,
|
||||
onNavigateToEdit: (Int) -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
@@ -73,15 +75,25 @@ fun BatteryListScreen(
|
||||
) {
|
||||
items(items) { item ->
|
||||
ListItem(
|
||||
headlineContent = { Text("Modelo: ${item.model}") },
|
||||
supportingContent = { Text("Estado: ${item.status}") },
|
||||
headlineContent = { Text("Marca: ${item.brand ?: "Desconocida"}") },
|
||||
supportingContent = {
|
||||
Column {
|
||||
Text("Instalación: ${item.installDate ?: "N/A"}")
|
||||
item.idSai?.let { Text("SAI ID: $it") }
|
||||
}
|
||||
},
|
||||
trailingContent = {
|
||||
IconButton(onClick = {
|
||||
scope.launch {
|
||||
repository.delete(item.id).onSuccess { loadItems() }
|
||||
Row {
|
||||
IconButton(onClick = { onNavigateToEdit(item.id) }) {
|
||||
Icon(Icons.Default.Edit, contentDescription = "Editar")
|
||||
}
|
||||
IconButton(onClick = {
|
||||
scope.launch {
|
||||
repository.delete(item.id).onSuccess { loadItems() }
|
||||
}
|
||||
}) {
|
||||
Icon(Icons.Default.Delete, contentDescription = "Eliminar")
|
||||
}
|
||||
}) {
|
||||
Icon(Icons.Default.Delete, contentDescription = "Eliminar")
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -0,0 +1,203 @@
|
||||
package com.example.saipp.ui.management
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.example.saipp.R
|
||||
import com.example.saipp.data.AssignmentRepository
|
||||
import com.example.saipp.data.PersonRepository
|
||||
import com.example.saipp.data.SaiRepository
|
||||
import com.example.saipp.data.model.Assignment
|
||||
import com.example.saipp.data.model.Person
|
||||
import com.example.saipp.data.model.Sai
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun EditAssignmentScreen(
|
||||
assignmentId: Int,
|
||||
onNavigateBack: () -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
val repository = remember { AssignmentRepository() }
|
||||
val saiRepository = remember { SaiRepository() }
|
||||
val personRepository = remember { PersonRepository() }
|
||||
|
||||
var selectedSaiId by remember { mutableStateOf<Int?>(null) }
|
||||
var selectedPersonId by remember { mutableStateOf<Int?>(null) }
|
||||
var assignedDate by remember { mutableStateOf("") }
|
||||
var returnDate by remember { mutableStateOf("") }
|
||||
|
||||
var sais by remember { mutableStateOf<List<Sai>>(emptyList()) }
|
||||
var people by remember { mutableStateOf<List<Person>>(emptyList()) }
|
||||
var isLoading by remember { mutableStateOf(true) }
|
||||
var isSaving by remember { mutableStateOf(false) }
|
||||
var saiExpanded by remember { mutableStateOf(false) }
|
||||
var personExpanded by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(assignmentId) {
|
||||
val assignmentResult = repository.getById(assignmentId)
|
||||
val saisResult = saiRepository.getAll()
|
||||
val peopleResult = personRepository.getAll()
|
||||
|
||||
if (assignmentResult.isSuccess) {
|
||||
val item = assignmentResult.getOrNull()!!
|
||||
selectedSaiId = item.idSai
|
||||
selectedPersonId = item.idPersona
|
||||
assignedDate = item.assignedDate ?: ""
|
||||
returnDate = item.returnDate ?: ""
|
||||
sais = saisResult.getOrDefault(emptyList())
|
||||
people = peopleResult.getOrDefault(emptyList())
|
||||
isLoading = false
|
||||
} else {
|
||||
Toast.makeText(context, "Error al cargar asignación", Toast.LENGTH_SHORT).show()
|
||||
onNavigateBack()
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text("Editar Asignación") },
|
||||
navigationIcon = {
|
||||
IconButton(onClick = onNavigateBack) {
|
||||
Icon(Icons.Default.ArrowBack, contentDescription = "Atrás")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
) { padding ->
|
||||
if (isLoading) {
|
||||
Box(modifier = Modifier.fillMaxSize().padding(padding), contentAlignment = androidx.compose.ui.Alignment.Center) {
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
} else {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(16.dp)
|
||||
) {
|
||||
// SAI Selection
|
||||
ExposedDropdownMenuBox(
|
||||
expanded = saiExpanded,
|
||||
onExpandedChange = { saiExpanded = !saiExpanded }
|
||||
) {
|
||||
val selectedSai = sais.find { it.id == selectedSaiId }
|
||||
OutlinedTextField(
|
||||
value = selectedSai?.ns ?: stringResource(R.string.select_sai),
|
||||
onValueChange = {},
|
||||
readOnly = true,
|
||||
label = { Text(stringResource(R.string.label_sai)) },
|
||||
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = saiExpanded) },
|
||||
modifier = Modifier.menuAnchor().fillMaxWidth()
|
||||
)
|
||||
ExposedDropdownMenu(
|
||||
expanded = saiExpanded,
|
||||
onDismissRequest = { saiExpanded = false }
|
||||
) {
|
||||
sais.forEach { sai ->
|
||||
DropdownMenuItem(
|
||||
text = { Text(sai.ns) },
|
||||
onClick = {
|
||||
selectedSaiId = sai.id
|
||||
saiExpanded = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
// Person Selection
|
||||
ExposedDropdownMenuBox(
|
||||
expanded = personExpanded,
|
||||
onExpandedChange = { personExpanded = !personExpanded }
|
||||
) {
|
||||
val selectedPerson = people.find { it.id == selectedPersonId }
|
||||
OutlinedTextField(
|
||||
value = selectedPerson?.name ?: stringResource(R.string.select_person),
|
||||
onValueChange = {},
|
||||
readOnly = true,
|
||||
label = { Text(stringResource(R.string.label_person)) },
|
||||
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = personExpanded) },
|
||||
modifier = Modifier.menuAnchor().fillMaxWidth()
|
||||
)
|
||||
ExposedDropdownMenu(
|
||||
expanded = personExpanded,
|
||||
onDismissRequest = { personExpanded = false }
|
||||
) {
|
||||
people.forEach { person ->
|
||||
DropdownMenuItem(
|
||||
text = { Text(person.name) },
|
||||
onClick = {
|
||||
selectedPersonId = person.id
|
||||
personExpanded = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
OutlinedTextField(
|
||||
value = assignedDate,
|
||||
onValueChange = { assignedDate = it },
|
||||
label = { Text(stringResource(R.string.label_assigned_date)) },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
OutlinedTextField(
|
||||
value = returnDate,
|
||||
onValueChange = { returnDate = it },
|
||||
label = { Text(stringResource(R.string.label_return_date)) },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
|
||||
Button(
|
||||
onClick = {
|
||||
if (selectedSaiId != null && selectedPersonId != null) {
|
||||
isSaving = true
|
||||
scope.launch {
|
||||
repository.update(
|
||||
Assignment(
|
||||
id = assignmentId,
|
||||
idSai = selectedSaiId!!,
|
||||
idPersona = selectedPersonId!!,
|
||||
assignedDate = assignedDate.takeIf { it.isNotBlank() },
|
||||
returnDate = returnDate.takeIf { it.isNotBlank() }
|
||||
)
|
||||
).onSuccess {
|
||||
Toast.makeText(context, "Asignación actualizada", Toast.LENGTH_SHORT).show()
|
||||
onNavigateBack()
|
||||
}.onFailure {
|
||||
Toast.makeText(context, "Error: ${it.message}", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
isSaving = false
|
||||
}
|
||||
}
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = !isSaving && selectedSaiId != null && selectedPersonId != null
|
||||
) {
|
||||
if (isSaving) CircularProgressIndicator(modifier = Modifier.size(24.dp))
|
||||
else Text("Guardar Cambios")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
package com.example.saipp.ui.management
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.example.saipp.R
|
||||
import com.example.saipp.data.BatteryRepository
|
||||
import com.example.saipp.data.SaiRepository
|
||||
import com.example.saipp.data.model.Battery
|
||||
import com.example.saipp.data.model.Sai
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun EditBatteryScreen(
|
||||
batteryId: Int,
|
||||
onNavigateBack: () -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
val batteryRepository = remember { BatteryRepository() }
|
||||
val saiRepository = remember { SaiRepository() }
|
||||
|
||||
var brand by remember { mutableStateOf("") }
|
||||
var installDate by remember { mutableStateOf("") }
|
||||
var selectedSaiId by remember { mutableStateOf<Int?>(null) }
|
||||
|
||||
var sais by remember { mutableStateOf<List<Sai>>(emptyList()) }
|
||||
var isLoading by remember { mutableStateOf(true) }
|
||||
var isSaving by remember { mutableStateOf(false) }
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(batteryId) {
|
||||
val batteryResult = batteryRepository.getById(batteryId)
|
||||
val saisResult = saiRepository.getAll()
|
||||
|
||||
if (batteryResult.isSuccess) {
|
||||
val battery = batteryResult.getOrNull()!!
|
||||
brand = battery.brand ?: ""
|
||||
installDate = battery.installDate ?: ""
|
||||
selectedSaiId = battery.idSai
|
||||
sais = saisResult.getOrDefault(emptyList())
|
||||
isLoading = false
|
||||
} else {
|
||||
Toast.makeText(context, "Error al cargar batería", Toast.LENGTH_SHORT).show()
|
||||
onNavigateBack()
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text("Editar Batería") },
|
||||
navigationIcon = {
|
||||
IconButton(onClick = onNavigateBack) {
|
||||
Icon(Icons.Default.ArrowBack, contentDescription = "Atrás")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
) { padding ->
|
||||
if (isLoading) {
|
||||
Box(modifier = Modifier.fillMaxSize().padding(padding), contentAlignment = androidx.compose.ui.Alignment.Center) {
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
} else {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(16.dp)
|
||||
) {
|
||||
// SAI Selection
|
||||
ExposedDropdownMenuBox(
|
||||
expanded = expanded,
|
||||
onExpandedChange = { expanded = !expanded }
|
||||
) {
|
||||
val selectedSai = sais.find { it.id == selectedSaiId }
|
||||
OutlinedTextField(
|
||||
value = selectedSai?.ns ?: stringResource(R.string.no_sai),
|
||||
onValueChange = {},
|
||||
readOnly = true,
|
||||
label = { Text(stringResource(R.string.label_sai)) },
|
||||
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
|
||||
modifier = Modifier.menuAnchor().fillMaxWidth()
|
||||
)
|
||||
ExposedDropdownMenu(
|
||||
expanded = expanded,
|
||||
onDismissRequest = { expanded = false }
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
text = { Text(stringResource(R.string.no_sai)) },
|
||||
onClick = {
|
||||
selectedSaiId = null
|
||||
expanded = false
|
||||
}
|
||||
)
|
||||
sais.forEach { sai ->
|
||||
DropdownMenuItem(
|
||||
text = { Text(sai.ns) },
|
||||
onClick = {
|
||||
selectedSaiId = sai.id
|
||||
expanded = false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
OutlinedTextField(
|
||||
value = brand,
|
||||
onValueChange = { brand = it },
|
||||
label = { Text(stringResource(R.string.label_brand)) },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
OutlinedTextField(
|
||||
value = installDate,
|
||||
onValueChange = { installDate = it },
|
||||
label = { Text(stringResource(R.string.label_install_date)) },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
|
||||
Button(
|
||||
onClick = {
|
||||
isSaving = true
|
||||
scope.launch {
|
||||
batteryRepository.update(
|
||||
Battery(
|
||||
id = batteryId,
|
||||
idSai = selectedSaiId,
|
||||
brand = brand,
|
||||
installDate = installDate.takeIf { it.isNotBlank() }
|
||||
)
|
||||
).onSuccess {
|
||||
Toast.makeText(context, "Batería actualizada", Toast.LENGTH_SHORT).show()
|
||||
onNavigateBack()
|
||||
}.onFailure {
|
||||
Toast.makeText(context, "Error: ${it.message}", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
isSaving = false
|
||||
}
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = !isSaving
|
||||
) {
|
||||
if (isSaving) CircularProgressIndicator(modifier = Modifier.size(24.dp))
|
||||
else Text("Guardar Cambios")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.example.saipp.ui.management
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.example.saipp.data.PersonRepository
|
||||
import com.example.saipp.data.model.Person
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun EditPersonScreen(
|
||||
personId: Int,
|
||||
onNavigateBack: () -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
val repository = remember { PersonRepository() }
|
||||
|
||||
var name by remember { mutableStateOf("") }
|
||||
var isLoading by remember { mutableStateOf(true) }
|
||||
var isSaving by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(personId) {
|
||||
repository.getById(personId).onSuccess {
|
||||
name = it.name
|
||||
isLoading = false
|
||||
}.onFailure {
|
||||
Toast.makeText(context, "Error al cargar persona", Toast.LENGTH_SHORT).show()
|
||||
onNavigateBack()
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text("Editar Persona") },
|
||||
navigationIcon = {
|
||||
IconButton(onClick = onNavigateBack) {
|
||||
Icon(Icons.Default.ArrowBack, contentDescription = "Atrás")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
) { padding ->
|
||||
if (isLoading) {
|
||||
Box(modifier = Modifier.fillMaxSize().padding(padding), contentAlignment = androidx.compose.ui.Alignment.Center) {
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
} else {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(16.dp)
|
||||
) {
|
||||
OutlinedTextField(
|
||||
value = name,
|
||||
onValueChange = { name = it },
|
||||
label = { Text("Nombre") },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
Button(
|
||||
onClick = {
|
||||
if (name.isNotBlank()) {
|
||||
isSaving = true
|
||||
scope.launch {
|
||||
repository.update(Person(id = personId, name = name))
|
||||
.onSuccess {
|
||||
Toast.makeText(context, "Persona actualizada", Toast.LENGTH_SHORT).show()
|
||||
onNavigateBack()
|
||||
}
|
||||
.onFailure { Toast.makeText(context, "Error: ${it.message}", Toast.LENGTH_SHORT).show() }
|
||||
isSaving = false
|
||||
}
|
||||
}
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = !isSaving
|
||||
) {
|
||||
if (isSaving) CircularProgressIndicator(modifier = Modifier.size(24.dp))
|
||||
else Text("Guardar Cambios")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.example.saipp.ui.management
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.example.saipp.data.SaiRepository
|
||||
import com.example.saipp.data.model.Sai
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun EditSaiScreen(
|
||||
saiId: Int,
|
||||
onNavigateBack: () -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
val repository = remember { SaiRepository() }
|
||||
|
||||
var ns by remember { mutableStateOf("") }
|
||||
var isLoading by remember { mutableStateOf(true) }
|
||||
var isSaving by remember { mutableStateOf(false) }
|
||||
|
||||
LaunchedEffect(saiId) {
|
||||
repository.getById(saiId).onSuccess {
|
||||
ns = it.ns
|
||||
isLoading = false
|
||||
}.onFailure {
|
||||
Toast.makeText(context, "Error al cargar SAI", Toast.LENGTH_SHORT).show()
|
||||
onNavigateBack()
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text("Editar SAI") },
|
||||
navigationIcon = {
|
||||
IconButton(onClick = onNavigateBack) {
|
||||
Icon(Icons.Default.ArrowBack, contentDescription = "Atrás")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
) { padding ->
|
||||
if (isLoading) {
|
||||
Box(modifier = Modifier.fillMaxSize().padding(padding), contentAlignment = androidx.compose.ui.Alignment.Center) {
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
} else {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(padding)
|
||||
.padding(16.dp)
|
||||
) {
|
||||
OutlinedTextField(
|
||||
value = ns,
|
||||
onValueChange = { ns = it },
|
||||
label = { Text("Número de Serie") },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
Button(
|
||||
onClick = {
|
||||
if (ns.isNotBlank()) {
|
||||
isSaving = true
|
||||
scope.launch {
|
||||
repository.update(Sai(id = saiId, ns = ns))
|
||||
.onSuccess {
|
||||
Toast.makeText(context, "SAI actualizado", Toast.LENGTH_SHORT).show()
|
||||
onNavigateBack()
|
||||
}
|
||||
.onFailure { Toast.makeText(context, "Error: ${it.message}", Toast.LENGTH_SHORT).show() }
|
||||
isSaving = false
|
||||
}
|
||||
}
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
enabled = !isSaving
|
||||
) {
|
||||
if (isSaving) CircularProgressIndicator(modifier = Modifier.size(24.dp))
|
||||
else Text("Guardar Cambios")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.example.saipp.ui.ConnectionIndicator
|
||||
@@ -17,7 +16,8 @@ import com.example.saipp.data.MariaDbConnection
|
||||
fun HomeScreen(
|
||||
onNavigateToSais: () -> Unit,
|
||||
onNavigateToBatteries: () -> Unit,
|
||||
onNavigateToPeople: () -> Unit
|
||||
onNavigateToPeople: () -> Unit,
|
||||
onNavigateToAssignments: () -> Unit
|
||||
) {
|
||||
var connectionStatus by remember { mutableStateOf<Result<Unit>?>(null) }
|
||||
var isCheckingConnection by remember { mutableStateOf(true) }
|
||||
@@ -49,7 +49,7 @@ fun HomeScreen(
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
|
||||
MenuButton(
|
||||
text = "Gestión de SAIs",
|
||||
text = stringResource(R.string.menu_sais),
|
||||
onClick = onNavigateToSais,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
@@ -57,7 +57,7 @@ fun HomeScreen(
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
MenuButton(
|
||||
text = "Gestión de Baterías",
|
||||
text = stringResource(R.string.menu_batteries),
|
||||
onClick = onNavigateToBatteries,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
@@ -65,10 +65,18 @@ fun HomeScreen(
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
MenuButton(
|
||||
text = "Gestión de Personas",
|
||||
text = stringResource(R.string.menu_people),
|
||||
onClick = onNavigateToPeople,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
MenuButton(
|
||||
text = stringResource(R.string.menu_assignments),
|
||||
onClick = onNavigateToAssignments,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material.icons.filled.Edit
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -22,7 +23,8 @@ import kotlinx.coroutines.launch
|
||||
@Composable
|
||||
fun PersonListScreen(
|
||||
onNavigateBack: () -> Unit,
|
||||
onNavigateToAdd: () -> Unit
|
||||
onNavigateToAdd: () -> Unit,
|
||||
onNavigateToEdit: (Int) -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
@@ -74,14 +76,18 @@ fun PersonListScreen(
|
||||
items(items) { item ->
|
||||
ListItem(
|
||||
headlineContent = { Text(item.name) },
|
||||
supportingContent = { Text(item.position) },
|
||||
trailingContent = {
|
||||
IconButton(onClick = {
|
||||
scope.launch {
|
||||
repository.delete(item.id).onSuccess { loadItems() }
|
||||
Row {
|
||||
IconButton(onClick = { onNavigateToEdit(item.id) }) {
|
||||
Icon(Icons.Default.Edit, contentDescription = "Editar")
|
||||
}
|
||||
IconButton(onClick = {
|
||||
scope.launch {
|
||||
repository.delete(item.id).onSuccess { loadItems() }
|
||||
}
|
||||
}) {
|
||||
Icon(Icons.Default.Delete, contentDescription = "Eliminar")
|
||||
}
|
||||
}) {
|
||||
Icon(Icons.Default.Delete, contentDescription = "Eliminar")
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -8,6 +8,7 @@ import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Add
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.Delete
|
||||
import androidx.compose.material.icons.filled.Edit
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -22,7 +23,8 @@ import kotlinx.coroutines.launch
|
||||
@Composable
|
||||
fun SaiListScreen(
|
||||
onNavigateBack: () -> Unit,
|
||||
onNavigateToScan: () -> Unit
|
||||
onNavigateToScan: () -> Unit,
|
||||
onNavigateToEdit: (Int) -> Unit
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val scope = rememberCoroutineScope()
|
||||
@@ -75,12 +77,17 @@ fun SaiListScreen(
|
||||
ListItem(
|
||||
headlineContent = { Text("NS: ${sai.ns}") },
|
||||
trailingContent = {
|
||||
IconButton(onClick = {
|
||||
scope.launch {
|
||||
repository.delete(sai.id).onSuccess { loadSais() }
|
||||
Row {
|
||||
IconButton(onClick = { onNavigateToEdit(sai.id) }) {
|
||||
Icon(Icons.Default.Edit, contentDescription = "Editar")
|
||||
}
|
||||
IconButton(onClick = {
|
||||
scope.launch {
|
||||
repository.delete(sai.id).onSuccess { loadSais() }
|
||||
}
|
||||
}) {
|
||||
Icon(Icons.Default.Delete, contentDescription = "Eliminar")
|
||||
}
|
||||
}) {
|
||||
Icon(Icons.Default.Delete, contentDescription = "Eliminar")
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -13,4 +13,19 @@
|
||||
<string name="db_connection_failed">No se pudo establecer conexión con el servidor</string>
|
||||
<string name="db_connection_error">Error de conexión a la base de datos</string>
|
||||
<string name="no_rows_inserted">No se insertaron filas en la base de datos</string>
|
||||
<string name="label_sai">SAI</string>
|
||||
<string name="label_brand">Marca</string>
|
||||
<string name="label_install_date">Fecha Instalación (AAAA-MM-DD HH:MM:SS)</string>
|
||||
<string name="select_sai">Seleccionar SAI</string>
|
||||
<string name="no_sai">Ninguno</string>
|
||||
|
||||
<string name="menu_sais">Gestión de SAIs</string>
|
||||
<string name="menu_batteries">Gestión de Baterías</string>
|
||||
<string name="menu_people">Gestión de Personas</string>
|
||||
<string name="menu_assignments">Gestión de Asignaciones</string>
|
||||
|
||||
<string name="label_person">Persona</string>
|
||||
<string name="label_assigned_date">Fecha Asignación (AAAA-MM-DD)</string>
|
||||
<string name="label_return_date">Fecha Devolución (AAAA-MM-DD)</string>
|
||||
<string name="select_person">Seleccionar Persona</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user