untitled

Pasted Nov 9, 2026, 4:12 AM1 file486 lines

Scan to open on your phone

Point a camera at the QR code - it opens this exact paste, no app needed.

https://codepastes.com/zzgs9bfhnacy4hf5
untitled
package com.negocio.desinfectantes.ui.inactivos

import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.Restore
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import com.negocio.desinfectantes.data.*

private val CardBlue = Color(0xFF1B2D4A)
private val AccentBlue = Color(0xFF2585F5)
private val SoftBlue = Color(0xFFA9BEDB)

@Composable
fun RegistrosInactivosScreen(
    productos: List<ProductoEntity>,
    aromas: List<AromaEntity>,
    presentaciones: List<PresentacionEntity>,
    todosProductos: List<ProductoEntity>,
    todosAromas: List<AromaEntity>,
    onVolver: () -> Unit,
    onReactivarProducto: (ProductoEntity) -> Unit,
    onReactivarAroma: (AromaEntity) -> Unit,
    onReactivarPresentacion: (PresentacionEntity) -> Unit
) {
    var categoria by remember { mutableStateOf("Productos") }

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(20.dp)
    ) {
        Row(verticalAlignment = Alignment.CenterVertically) {
            IconButton(onClick = onVolver) {
                Icon(
                    Icons.Default.ArrowBack,
                    contentDescription = "Volver",
                    tint = Color.White
                )
            }

            Text(
                "Registros inactivos",
                color = Color.White,
                style = MaterialTheme.typography.headlineSmall
            )
        }

        Spacer(modifier = Modifier.height(16.dp))

        SingleChoiceSegmentedButtonRow(
            modifier = Modifier.fillMaxWidth()
        ) {
            listOf("Productos", "Aromas", "Presentaciones")
                .forEachIndexed { index, nombre ->
                    SegmentedButton(
                        selected = categoria == nombre,
                        onClick = { categoria = nombre },
                        shape = SegmentedButtonDefaults.itemShape(
                            index = index,
                            count = 3
                        )
                    ) {
                        Text(
                            nombre,
                            style = MaterialTheme.typography.labelSmall
                        )
                    }
                }
        }

        Spacer(modifier = Modifier.height(16.dp))

        when (categoria) {
            "Productos" -> {
                if (productos.isEmpty()) {
                    MensajeVacio("No hay productos inactivos")
                } else {
                    LazyColumn(
                        verticalArrangement = Arrangement.spacedBy(12.dp)
                    ) {
                        items(productos) { producto ->
                            TarjetaInactiva(
                                nombre = producto.nombre,
                                detalle = "Producto inactivo",
                                icono = "🧴",
                                onReactivar = {
                                    onReactivarProducto(producto)
                                }
                            )
                        }
                    }
                }
            }

            "Aromas" -> {
                if (aromas.isEmpty()) {
                    MensajeVacio("No hay aromas inactivos")
                } else {
                    LazyColumn(
                        verticalArrangement = Arrangement.spacedBy(12.dp)
                    ) {
                        items(aromas) { aroma ->
                            val nombreProducto = todosProductos
                                .find { it.id == aroma.productoId }
                                ?.nombre ?: "Producto no encontrado"

                            TarjetaInactiva(
                                nombre = aroma.nombre,
                                detalle = "Producto: $nombreProducto",
                                icono = "🌸",
                                onReactivar = {
                                    onReactivarAroma(aroma)
                                }
                            )
                        }
                    }
                }
            }

            "Presentaciones" -> {
                if (presentaciones.isEmpty()) {
                    MensajeVacio("No hay presentaciones inactivas")
                } else {
                    LazyColumn(
                        verticalArrangement = Arrangement.spacedBy(12.dp)
                    ) {
                        items(presentaciones) { presentacion ->
                            val aroma = todosAromas.find {
                                it.id == presentacion.aromaId
                            }

                            val producto = todosProductos.find {
                                it.id == aroma?.productoId
                            }

                            TarjetaInactiva(
                                nombre = presentacion.nombre,
                                detalle = "${producto?.nombre ?: "Producto desconocido"} • ${aroma?.nombre ?: "Aroma desconocido"}",
                                icono = "📦",
                                onReactivar = {
                                    onReactivarPresentacion(presentacion)
                                }
                            )
                        }
                    }
                }
            }
        }
    }
}

@Composable
private fun MensajeVacio(mensaje: String) {
    Card(
        modifier = Modifier.fillMaxWidth(),
        colors = CardDefaults.cardColors(
            containerColor = CardBlue
        ),
        shape = RoundedCornerShape(18.dp)
    ) {
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .padding(24.dp),
            horizontalAlignment = Alignment.CenterHorizontally
        ) {
            Text("📦", style = MaterialTheme.typography.displayMedium)

            Spacer(modifier = Modifier.height(12.dp))

            Text(
                mensaje,
                color = Color.White,
                style = MaterialTheme.typography.titleMedium
            )
        }
    }
}

@Composable
private fun TarjetaInactiva(
    nombre: String,
    detalle: String,
    icono: String,
    onReactivar: () -> Unit
) {
    Card(
        modifier = Modifier.fillMaxWidth(),
        colors = CardDefaults.cardColors(
            containerColor = CardBlue
        ),
        shape = RoundedCornerShape(18.dp)
    ) {
        Row(
            modifier = Modifier
                .fillMaxWidth()
                .padding(16.dp),
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text(
                icono,
                style = MaterialTheme.typography.headlineMedium
            )

            Spacer(modifier = Modifier.width(14.dp))

            Column(
                modifier = Modifier.weight(1f)
            ) {
                Text(
                    nombre,
                    color = Color.White,
                    style = MaterialTheme.typography.titleMedium
                )

                Text(
                    detalle,
                    color = SoftBlue,
                    style = MaterialTheme.typography.bodySmall
                )
            }

            IconButton(onClick = onReactivar) {
                Icon(
                    Icons.Default.Restore,
                    contentDescription = "Reactivar",
                    tint = AccentBlue
                )
            }
        }
    }
}

package com.negocio.desinfectantes.ui.productos

import androidx.compose.foundation.layout.*
import androidx.compose.foundation.background
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.material.icons.filled.Save
import androidx.compose.material.icons.filled.Delete
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.unit.dp
import com.negocio.desinfectantes.data.PresentacionEntity

private val Navy = Color(0xFF101D35)
private val CardBlue = Color(0xFF1B2D4A)
private val AccentBlue = Color(0xFF2585F5)
private val SoftBlue = Color(0xFFA9BEDB)

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun EditarPresentacionScreen(
    nombreProducto: String,
    nombreAroma: String,
    presentacion: PresentacionEntity,
    onVolver: () -> Unit,
    onGuardar: (String, Int, Double) -> Unit,
    onEliminar: () -> Unit
) {
    var nombre by remember(presentacion.id) {
        mutableStateOf(presentacion.nombre)
    }

    var contenido by remember(presentacion.id) {
        mutableStateOf(presentacion.contenidoMl.toString())
    }

    var precio by remember(presentacion.id) {
        mutableStateOf(
            presentacion.precio.toString().removeSuffix(".0")
        )
    }
    var mostrarConfirmacionEliminar by remember {
        mutableStateOf(false)
    }

    val contenidoValido = contenido.toIntOrNull()?.let { it > 0 } ?: false
    val precioValido = precio.toDoubleOrNull()?.let { it >= 0 } ?: false

    Column(
        modifier = Modifier
            .fillMaxSize()
            .background(Navy)
            .verticalScroll(rememberScrollState())
            .padding(20.dp)
    ) {
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.Start
        ) {
            IconButton(onClick = onVolver) {
                Icon(
                    imageVector = Icons.Default.ArrowBack,
                    contentDescription = "Volver",
                    tint = Color.White
                )
            }
        }

        Spacer(modifier = Modifier.height(10.dp))

        Text(
            text = "Editar presentación",
            color = Color.White,
            style = MaterialTheme.typography.headlineSmall
        )

        Spacer(modifier = Modifier.height(8.dp))

        Text(
            text = "$nombreProducto  •  $nombreAroma",
            color = SoftBlue,
            style = MaterialTheme.typography.bodyMedium
        )

        Spacer(modifier = Modifier.height(24.dp))

        OutlinedTextField(
            value = nombre,
            onValueChange = { nombre = it },
            label = { Text("Nombre de la presentación") },
            modifier = Modifier.fillMaxWidth(),
            singleLine = true,
            colors = OutlinedTextFieldDefaults.colors(
                focusedTextColor = Color.White,
                unfocusedTextColor = Color.White,
                focusedBorderColor = AccentBlue,
                unfocusedBorderColor = SoftBlue,
                focusedLabelColor = AccentBlue,
                unfocusedLabelColor = SoftBlue,
                cursorColor = AccentBlue
            )
        )

        Spacer(modifier = Modifier.height(16.dp))

        OutlinedTextField(
            value = contenido,
            onValueChange = { contenido = it },
            label = { Text("Contenido en mililitros (ml)") },
            modifier = Modifier.fillMaxWidth(),
            singleLine = true,
            keyboardOptions = KeyboardOptions(
                keyboardType = KeyboardType.Number
            ),
            colors = OutlinedTextFieldDefaults.colors(
                focusedTextColor = Color.White,
                unfocusedTextColor = Color.White,
                focusedBorderColor = AccentBlue,
                unfocusedBorderColor = SoftBlue,
                focusedLabelColor = AccentBlue,
                unfocusedLabelColor = SoftBlue,
                cursorColor = AccentBlue
            )
        )

        Spacer(modifier = Modifier.height(16.dp))

        OutlinedTextField(
            value = precio,
            onValueChange = { precio = it },
            label = { Text("Precio de venta") },
            modifier = Modifier.fillMaxWidth(),
            singleLine = true,
            keyboardOptions = KeyboardOptions(
                keyboardType = KeyboardType.Decimal
            ),
            colors = OutlinedTextFieldDefaults.colors(
                focusedTextColor = Color.White,
                unfocusedTextColor = Color.White,
                focusedBorderColor = AccentBlue,
                unfocusedBorderColor = SoftBlue,
                focusedLabelColor = AccentBlue,
                unfocusedLabelColor = SoftBlue,
                cursorColor = AccentBlue
            )
        )

        Spacer(modifier = Modifier.height(28.dp))

        Button(
            onClick = {
                onGuardar(
                    nombre.trim(),
                    contenido.toInt(),
                    precio.toDouble()
                )
            },
            modifier = Modifier
                .fillMaxWidth()
                .height(54.dp),
            enabled = nombre.isNotBlank() && contenidoValido && precioValido,
            colors = ButtonDefaults.buttonColors(
                containerColor = AccentBlue
            )
        ) {
            Icon(
                imageVector = Icons.Default.Save,
                contentDescription = null
            )

            Spacer(modifier = Modifier.width(8.dp))

            Text("Guardar cambios")
        }
        Spacer(modifier = Modifier.height(14.dp))

        OutlinedButton(
            onClick = {
                mostrarConfirmacionEliminar = true
            },
            modifier = Modifier
                .fillMaxWidth()
                .height(54.dp),
            colors = ButtonDefaults.outlinedButtonColors(
                contentColor = Color.Red
            )
        ) {
            Icon(
                imageVector = Icons.Default.Delete,
                contentDescription = null
            )

            Spacer(modifier = Modifier.width(8.dp))

            Text("Eliminar presentación")
        }
    }
    if (mostrarConfirmacionEliminar) {
        AlertDialog(
            onDismissRequest = {
                mostrarConfirmacionEliminar = false
            },
            title = {
                Text("Eliminar presentación")
            },
            text = {
                Text(
                    "¿Estás seguro de que deseas eliminar " +
                            "${presentacion.nombre}? Esta acción no se puede deshacer."
                )
            },
            confirmButton = {
                TextButton(
                    onClick = {
                        mostrarConfirmacionEliminar = false
                        onEliminar()
                    }
                ) {
                    Text(
                        "Eliminar",
                        color = Color.Red
                    )
                }
            },
            dismissButton = {
                TextButton(
                    onClick = {
                        mostrarConfirmacionEliminar = false
                    }
                ) {
                    Text("Cancelar")
                }
            }
        )
    }
}

15,650 chars · codepastes.com