sin-titulo

Pasted Nov 8, 2026, 11:11 PM1 file1,235 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/zzgs9gwdt87bc2j5
sin-titulo
package com.negocio.desinfectantes.ui.inventario

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.negocio.desinfectantes.data.*

private val Navy = Color(0xFF101D35)
private val CardBlue = Color(0xFF1B2D4A)
private val AccentBlue = Color(0xFF2585F5)
private val SoftBlue = Color(0xFFA9BEDB)
private val GreenStock = Color(0xFF81C784)
private val OrangeReserved = Color(0xFFFFB74D)

@Composable
fun InventarioScreen(
    modifier: Modifier = Modifier,
    productos: List<ProductoEntity>,
    aromas: List<AromaEntity>,
    presentaciones: List<PresentacionEntity>,
    inventarios: List<InventarioEntity>,
    onVolver: () -> Unit
) {

    val totalDisponibleBarrancas = inventarios
        .filter { it.sede == "Barrancas" }
        .sumOf { it.cantidadDisponible }

    val totalReservadoBarrancas = inventarios
        .filter { it.sede == "Barrancas" }
        .sumOf { it.cantidadReservada }

    val totalDisponibleValledupar = inventarios
        .filter { it.sede == "Valledupar" }
        .sumOf { it.cantidadDisponible }

    val totalReservadoValledupar = inventarios
        .filter { it.sede == "Valledupar" }
        .sumOf { it.cantidadReservada }

    val totalDisponible = totalDisponibleBarrancas +
            totalDisponibleValledupar

    val totalReservado = totalReservadoBarrancas +
            totalReservadoValledupar

    val totalGeneral = totalDisponible + totalReservado

    Column(
        modifier = modifier
            .fillMaxSize()
            .background(Navy)
            .verticalScroll(rememberScrollState())
            .padding(20.dp)
    ) {

        // ENCABEZADO

        TextButton(onClick = onVolver) {
            Text("← Volver", color = SoftBlue)
        }

        Text(
            "Inventario",
            color = Color.White,
            style = MaterialTheme.typography.headlineMedium,
            fontWeight = FontWeight.Bold
        )

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

        Text(
            "Consulta las existencias disponibles y reservadas en cada sede.",
            color = SoftBlue,
            style = MaterialTheme.typography.bodyMedium
        )

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

        // RESUMEN POR SEDES

        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.spacedBy(10.dp)
        ) {

            // BARRANCAS

            Card(
                modifier = Modifier.weight(1f),
                colors = CardDefaults.cardColors(
                    containerColor = CardBlue
                ),
                shape = RoundedCornerShape(16.dp)
            ) {
                Column(
                    modifier = Modifier.padding(12.dp)
                ) {
                    Text(
                        "Barrancas",
                        color = SoftBlue,
                        style = MaterialTheme.typography.bodySmall
                    )

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

                    Text(
                        "$totalDisponibleBarrancas",
                        color = GreenStock,
                        style = MaterialTheme.typography.headlineMedium,
                        fontWeight = FontWeight.Bold
                    )

                    Text(
                        "Disponibles",
                        color = SoftBlue,
                        style = MaterialTheme.typography.bodySmall
                    )

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

                    Text(
                        "$totalReservadoBarrancas",
                        color = OrangeReserved,
                        style = MaterialTheme.typography.titleLarge,
                        fontWeight = FontWeight.Bold
                    )

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

            // VALLEDUPAR

            Card(
                modifier = Modifier.weight(1f),
                colors = CardDefaults.cardColors(
                    containerColor = CardBlue
                ),
                shape = RoundedCornerShape(16.dp)
            ) {
                Column(
                    modifier = Modifier.padding(12.dp)
                ) {
                    Text(
                        "Valledupar",
                        color = SoftBlue,
                        style = MaterialTheme.typography.bodySmall
                    )

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

                    Text(
                        "$totalDisponibleValledupar",
                        color = GreenStock,
                        style = MaterialTheme.typography.headlineMedium,
                        fontWeight = FontWeight.Bold
                    )

                    Text(
                        "Disponibles",
                        color = SoftBlue,
                        style = MaterialTheme.typography.bodySmall
                    )

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

                    Text(
                        "$totalReservadoValledupar",
                        color = OrangeReserved,
                        style = MaterialTheme.typography.titleLarge,
                        fontWeight = FontWeight.Bold
                    )

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

            // TOTAL GENERAL

            Card(
                modifier = Modifier.weight(1f),
                colors = CardDefaults.cardColors(
                    containerColor = AccentBlue
                ),
                shape = RoundedCornerShape(16.dp)
            ) {
                Column(
                    modifier = Modifier.padding(12.dp)
                ) {
                    Text(
                        "Total general",
                        color = Color.White,
                        style = MaterialTheme.typography.bodySmall
                    )

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

                    Text(
                        "$totalGeneral",
                        color = Color.White,
                        style = MaterialTheme.typography.headlineMedium,
                        fontWeight = FontWeight.Bold
                    )

                    Text(
                        "Existencias",
                        color = Color.White.copy(alpha = 0.85f),
                        style = MaterialTheme.typography.bodySmall
                    )

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

                    Text(
                        "$totalDisponible",
                        color = Color.White,
                        style = MaterialTheme.typography.titleLarge,
                        fontWeight = FontWeight.Bold
                    )

                    Text(
                        "Disponibles",
                        color = Color.White.copy(alpha = 0.85f),
                        style = MaterialTheme.typography.bodySmall
                    )

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

                    Text(
                        "$totalReservado",
                        color = Color.White,
                        style = MaterialTheme.typography.titleLarge,
                        fontWeight = FontWeight.Bold
                    )

                    Text(
                        "Reservadas",
                        color = Color.White.copy(alpha = 0.85f),
                        style = MaterialTheme.typography.bodySmall
                    )
                }
            }
        }

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

        // LISTADO DE PRESENTACIONES

        Text(
            "Existencias por presentación",
            color = Color.White,
            style = MaterialTheme.typography.titleLarge,
            fontWeight = FontWeight.Bold
        )

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

        if (presentaciones.isEmpty()) {

            Text(
                "Todavía no hay presentaciones registradas.",
                color = SoftBlue
            )

        } else {

            presentaciones
                .filter { it.activo }
                .forEach { presentacion ->

                    val aroma = aromas.firstOrNull {
                        it.id == presentacion.aromaId
                    }

                    val producto = productos.firstOrNull {
                        it.id == aroma?.productoId
                    }

                    val inventarioBarrancas = inventarios.firstOrNull {
                        it.presentacionId == presentacion.id &&
                                it.sede == "Barrancas"
                    }

                    val inventarioValledupar = inventarios.firstOrNull {
                        it.presentacionId == presentacion.id &&
                                it.sede == "Valledupar"
                    }

                    val stockBarrancas =
                        inventarioBarrancas?.cantidadDisponible ?: 0

                    val reservadoBarrancas =
                        inventarioBarrancas?.cantidadReservada ?: 0

                    val stockValledupar =
                        inventarioValledupar?.cantidadDisponible ?: 0

                    val reservadoValledupar =
                        inventarioValledupar?.cantidadReservada ?: 0

                    val disponibleTotal =
                        stockBarrancas + stockValledupar

                    val reservadoTotal =
                        reservadoBarrancas + reservadoValledupar

                    val existenciasTotales =
                        disponibleTotal + reservadoTotal

                    Card(
                        modifier = Modifier
                            .fillMaxWidth()
                            .padding(bottom = 14.dp),
                        colors = CardDefaults.cardColors(
                            containerColor = CardBlue
                        ),
                        shape = RoundedCornerShape(16.dp)
                    ) {

                        Column(
                            modifier = Modifier
                                .fillMaxWidth()
                                .padding(16.dp)
                        ) {

                            Text(
                                producto?.nombre ?: "Producto",
                                color = Color.White,
                                fontWeight = FontWeight.Bold,
                                style = MaterialTheme.typography.titleMedium
                            )

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

                            Text(
                                "Aroma: ${aroma?.nombre ?: "Sin aroma"}",
                                color = SoftBlue
                            )

                            Text(
                                "${presentacion.nombre} • ${presentacion.contenidoMl} ml",
                                color = SoftBlue
                            )

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

                            HorizontalDivider(
                                color = SoftBlue.copy(alpha = 0.25f)
                            )

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

                            // BARRANCAS

                            Text(
                                "Barrancas",
                                color = Color.White,
                                fontWeight = FontWeight.Bold
                            )

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

                            Row(
                                modifier = Modifier.fillMaxWidth(),
                                horizontalArrangement = Arrangement.SpaceBetween
                            ) {
                                Text("Disponibles", color = SoftBlue)

                                Text(
                                    "$stockBarrancas unidades",
                                    color = GreenStock,
                                    fontWeight = FontWeight.Bold
                                )
                            }

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

                            Row(
                                modifier = Modifier.fillMaxWidth(),
                                horizontalArrangement = Arrangement.SpaceBetween
                            ) {
                                Text("Reservadas", color = SoftBlue)

                                Text(
                                    "$reservadoBarrancas unidades",
                                    color = OrangeReserved,
                                    fontWeight = FontWeight.Bold
                                )
                            }

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

                            // VALLEDUPAR

                            Text(
                                "Valledupar",
                                color = Color.White,
                                fontWeight = FontWeight.Bold
                            )

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

                            Row(
                                modifier = Modifier.fillMaxWidth(),
                                horizontalArrangement = Arrangement.SpaceBetween
                            ) {
                                Text("Disponibles", color = SoftBlue)

                                Text(
                                    "$stockValledupar unidades",
                                    color = GreenStock,
                                    fontWeight = FontWeight.Bold
                                )
                            }

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

                            Row(
                                modifier = Modifier.fillMaxWidth(),
                                horizontalArrangement = Arrangement.SpaceBetween
                            ) {
                                Text("Reservadas", color = SoftBlue)

                                Text(
                                    "$reservadoValledupar unidades",
                                    color = OrangeReserved,
                                    fontWeight = FontWeight.Bold
                                )
                            }

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

                            HorizontalDivider(
                                color = SoftBlue.copy(alpha = 0.25f)
                            )

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

                            Row(
                                modifier = Modifier.fillMaxWidth(),
                                horizontalArrangement = Arrangement.SpaceBetween
                            ) {
                                Text(
                                    "Total disponible",
                                    color = SoftBlue,
                                    fontWeight = FontWeight.Medium
                                )

                                Text(
                                    "$disponibleTotal unidades",
                                    color = GreenStock,
                                    fontWeight = FontWeight.Bold
                                )
                            }

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

                            Row(
                                modifier = Modifier.fillMaxWidth(),
                                horizontalArrangement = Arrangement.SpaceBetween
                            ) {
                                Text(
                                    "Total reservado",
                                    color = SoftBlue,
                                    fontWeight = FontWeight.Medium
                                )

                                Text(
                                    "$reservadoTotal unidades",
                                    color = OrangeReserved,
                                    fontWeight = FontWeight.Bold
                                )
                            }

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

                            Row(
                                modifier = Modifier.fillMaxWidth(),
                                horizontalArrangement = Arrangement.SpaceBetween
                            ) {
                                Text(
                                    "Existencias totales",
                                    color = Color.White,
                                    fontWeight = FontWeight.Bold
                                )

                                Text(
                                    "$existenciasTotales unidades",
                                    color = AccentBlue,
                                    fontWeight = FontWeight.Bold
                                )
                            }
                        }
                    }
                }
        }

        Spacer(modifier = Modifier.height(20.dp))
    }
}



package com.negocio.desinfectantes

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
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.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.negocio.desinfectantes.ui.theme.DesinfectantesAppTheme
import com.negocio.desinfectantes.ui.productos.ProductosScreen
import com.negocio.desinfectantes.ui.productos.AgregarProductoScreen
import com.negocio.desinfectantes.ui.productos.AromasScreen
import com.negocio.desinfectantes.ui.inactivos.RegistrosInactivosScreen
import androidx.compose.ui.platform.LocalContext
import com.negocio.desinfectantes.data.DatabaseProvider
import com.negocio.desinfectantes.data.ProductoEntity
import com.negocio.desinfectantes.data.AromaEntity
import com.negocio.desinfectantes.data.PresentacionEntity
import kotlinx.coroutines.launch
import java.util.UUID
import androidx.compose.runtime.collectAsState
import com.negocio.desinfectantes.ui.productos.AgregarAromaScreen
import com.negocio.desinfectantes.ui.productos.PresentacionesScreen
import com.negocio.desinfectantes.ui.productos.AgregarPresentacionScreen
import com.negocio.desinfectantes.ui.productos.EditarPresentacionScreen
import com.negocio.desinfectantes.ui.produccion.ProduccionScreen
import com.negocio.desinfectantes.ui.inventario.InventarioScreen
import com.negocio.desinfectantes.data.ProduccionEntity
import com.negocio.desinfectantes.ui.clientes.ClienteScreen
import com.negocio.desinfectantes.data.ClienteEntity
import com.negocio.desinfectantes.data.DistribucionProduccionEntity
import com.negocio.desinfectantes.data.InventarioEntity
import com.negocio.desinfectantes.data.MovimientoInventarioEntity
import com.negocio.desinfectantes.ui.ventas.VentaScreen
import com.negocio.desinfectantes.ui.ventas.HistorialVentasScreen
import com.negocio.desinfectantes.ui.reportes.ReportesScreen
import java.util.Calendar
import java.util.Locale
import java.text.NumberFormat
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.res.painterResource
import androidx.compose.foundation.Image
import androidx.compose.ui.graphics.ColorFilter
private val Navy = Color(0xFF101D35)
private val CardBlue = Color(0xFF1B2D4A)
private val AccentBlue = Color(0xFF2585F5)
private val SoftBlue = Color(0xFFA9BEDB)
private val White = Color(0xFFFFFFFF)

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()

        setContent {
            DesinfectantesAppTheme {
                PrestigeCleanApp()
            }
        }
    }
}

@Composable
fun PrestigeCleanApp() {
    var selectedTab by remember { mutableStateOf("Inicio") }
    var ventaInicialId by remember {
        mutableStateOf<String?>(null)
    }
    var mostrarFormularioProducto by remember { mutableStateOf(false) }
    var mostrarRegistrosInactivos by remember {
        mutableStateOf(false)
    }
    var productoSeleccionado by remember {
        mutableStateOf<ProductoEntity?>(null)
    }
    var mostrarFormularioAroma by remember {
        mutableStateOf(false)
    }
    var aromaSeleccionado by remember {
        mutableStateOf<AromaEntity?>(null)
    }
    var mostrarFormularioPresentacion by remember {
        mutableStateOf(false)
    }
    var mensajeAroma by remember {
        mutableStateOf<String?>(null)
    }
    var presentacionSeleccionada by remember {
        mutableStateOf<PresentacionEntity?>(null)
    }
    val context = LocalContext.current

    val scope = rememberCoroutineScope()

    val productoDao = remember {
        DatabaseProvider.obtenerBaseDatos(context).productoDao()
    }
    val productos by productoDao.obtenerProductos()
        .collectAsState(initial = emptyList())
    val productosInactivos by productoDao.obtenerProductosInactivos()
        .collectAsState(initial = emptyList())
    val aromasInactivos by productoDao.obtenerTodosAromasInactivos()
        .collectAsState(initial = emptyList())

    val presentacionesInactivas by productoDao.obtenerTodasPresentacionesInactivas()
        .collectAsState(initial = emptyList())
    val todosProductos by productoDao.obtenerTodosProductos()
        .collectAsState(initial = emptyList())

    val todosAromas by productoDao.obtenerTodosAromas()
        .collectAsState(initial = emptyList())
    val aromasFlow = remember(productoSeleccionado?.id) {
        productoSeleccionado?.let {
            productoDao.obtenerAromas(it.id)
        } ?: kotlinx.coroutines.flow.flowOf(emptyList())
    }

    val aromas by aromasFlow.collectAsState(initial = emptyList())
    val presentacionesFlow = remember(aromaSeleccionado?.id) {
        aromaSeleccionado?.let {
            productoDao.obtenerPresentaciones(it.id)
        } ?: kotlinx.coroutines.flow.flowOf(emptyList())
    }

    val presentaciones by presentacionesFlow.collectAsState(initial = emptyList())

    val todasPresentacionesActivas by productoDao
        .obtenerTodasPresentacionesActivas()
        .collectAsState(initial = emptyList())
    val inventarios by productoDao
        .obtenerTodoInventario()
        .collectAsState(initial = emptyList())
    val clientes by productoDao.obtenerClientes()
        .collectAsState(initial = emptyList())
    val ventas by productoDao.obtenerVentas()
        .collectAsState(initial = emptyList())
    val todosLosPagos by productoDao.obtenerTodosLosPagos()
        .collectAsState(initial = emptyList())

    // FECHAS DEL DIA ACTUAL
    var inicioDia by remember {
        mutableStateOf(
            Calendar.getInstance().apply {
                set(Calendar.HOUR_OF_DAY, 0)
                set(Calendar.MINUTE, 0)
                set(Calendar.SECOND, 0)
                set(Calendar.MILLISECOND, 0)
            }.timeInMillis
        )
    }

    val finDia = remember(inicioDia) {
        Calendar.getInstance().apply {
            timeInMillis = inicioDia
            add(Calendar.DAY_OF_MONTH, 1)
        }.timeInMillis
    }

// ACTUALIZAR AUTOMATICAMENTE AL LLEGAR LA MEDIANOCHE
    LaunchedEffect(Unit) {
        while (true) {
            val ahora = Calendar.getInstance()

            val proximaMedianoche = (ahora.clone() as Calendar).apply {
                set(Calendar.HOUR_OF_DAY, 0)
                set(Calendar.MINUTE, 0)
                set(Calendar.SECOND, 0)
                set(Calendar.MILLISECOND, 0)
                add(Calendar.DAY_OF_MONTH, 1)
            }.timeInMillis

            val tiempoEspera = proximaMedianoche - System.currentTimeMillis()

            kotlinx.coroutines.delay(tiempoEspera.coerceAtLeast(1L))

            inicioDia = Calendar.getInstance().apply {
                set(Calendar.HOUR_OF_DAY, 0)
                set(Calendar.MINUTE, 0)
                set(Calendar.SECOND, 0)
                set(Calendar.MILLISECOND, 0)
            }.timeInMillis
        }
    }

// ESTADISTICAS DE ROOM

    val ventasDelDia by productoDao
        .obtenerVentasDelDia(inicioDia, finDia)
        .collectAsState(initial = 0.0)

    val dineroRecibidoHoy by productoDao
        .obtenerDineroRecibidoDelDia(inicioDia, finDia)
        .collectAsState(initial = 0.0)

    val totalPorCobrar by productoDao
        .obtenerTotalPorCobrar()
        .collectAsState(initial = 0.0)

    val inventarioDisponible by productoDao
        .obtenerInventarioDisponible()
        .collectAsState(initial = 0)

// FORMATO DE PESOS COLOMBIANOS

    val formatoPesos = remember {
        NumberFormat.getCurrencyInstance(Locale("es", "CO")).apply {
            maximumFractionDigits = 0
            minimumFractionDigits = 0
        }
    }

    Scaffold(
        containerColor = Navy,
        bottomBar = {
            NavigationBar(
                containerColor = CardBlue,
                contentColor = White
            ) {
                NavigationBarItem(
                    selected = selectedTab == "Inicio",
                    onClick = { selectedTab = "Inicio" },
                    icon = { Text("⌂", fontSize = 22.sp) },
                    label = { Text("Inicio") },
                    colors = navColors()
                )

                NavigationBarItem(
                    selected = selectedTab == "Ventas",
                    onClick = { selectedTab = "Ventas" },
                    icon = { Text("$", fontSize = 22.sp) },
                    label = { Text("Ventas") },
                    colors = navColors()
                )

                NavigationBarItem(
                    selected = selectedTab == "Productos",
                    onClick = { selectedTab = "Productos" },
                    icon = {
                        Icon(
                            painter = painterResource(id = R.drawable.ic_bottle),
                            contentDescription = "Productos",
                            tint = navColors().unselectedIconColor
                        )
                    },
                    label = { Text("Productos") },
                    colors = navColors()
                )

                NavigationBarItem(
                    selected = selectedTab == "Clientes",
                    onClick = { selectedTab = "Clientes" },
                    icon = { Text("♙", fontSize = 22.sp) },
                    label = { Text("Clientes") },
                    colors = navColors()
                )

                NavigationBarItem(
                    selected = selectedTab == "Reportes",
                    onClick = { selectedTab = "Reportes" },
                    icon = { Text("▤", fontSize = 22.sp) },
                    label = { Text("Reportes") },
                    colors = navColors()
                )
            }
        }
    ) { innerPadding ->

        when (selectedTab) {
            "Inicio" -> DashboardScreen(
                modifier = Modifier.padding(innerPadding),
                onNavigate = { selectedTab = it },
                ventasHoy = formatoPesos.format(ventasDelDia),
                dineroRecibido = formatoPesos.format(dineroRecibidoHoy),
                porCobrar = formatoPesos.format(totalPorCobrar),
                inventario = inventarioDisponible.toString()
            )

            "Ventas" -> VentaScreen(
                modifier = Modifier.padding(innerPadding),
                clientes = clientes,
                productos = productos,
                aromas = todosAromas.filter { it.activo },
                presentaciones = todasPresentacionesActivas,
                productoDao = productoDao,
                onVolver = { selectedTab = "Inicio" }
            )


            "Produccion" -> ProduccionScreen(
                modifier = Modifier.padding(innerPadding),
                productos = productos,
                aromas = todosAromas.filter { it.activo },
                presentaciones = todasPresentacionesActivas,
                onVolver = {
                    selectedTab = "Inicio"
                },
                onGuardar = { lote, detalles, gastos, inventariosLote ->
                    scope.launch {
                        try {
                            productoDao.registrarLoteCompleto(
                                lote = lote,
                                detalles = detalles,
                                gastos = gastos,
                                inventariosLote = inventariosLote
                            )

                            selectedTab = "Inicio"
                        } catch (e: Exception) {
                            mensajeAroma = e.message ?: "No se pudo guardar el lote."
                        }
                    }
                }
            )



            "Clientes" -> ClienteScreen(
                modifier = Modifier.padding(innerPadding),
                clientes = clientes,
                onGuardar = { cliente ->
                    scope.launch {
                        productoDao.guardarCliente(cliente)
                    }
                },
                onDesactivar = { clienteId ->
                    scope.launch {
                        productoDao.desactivarCliente(clienteId)
                    }
                },
                onVolver = {
                    selectedTab = "Inicio"
                }
            )
            "Historial" -> HistorialVentasScreen(
                modifier = Modifier.padding(innerPadding),
                ventas = ventas,
                clientes = clientes,
                productos = todosProductos,
                aromas = todosAromas,
                presentaciones = todasPresentacionesActivas + presentacionesInactivas,
                productoDao = productoDao,
                onVolver = {
                    ventaInicialId = null
                    selectedTab = "Inicio"
                },
                ventaInicialId = ventaInicialId
            )

            "Reportes" -> ReportesScreen(
                modifier = Modifier.padding(innerPadding),
                ventas = ventas,
                clientes = clientes,
                pagos = todosLosPagos,
                onAbrirVenta = { ventaId ->
                    ventaInicialId = ventaId
                    selectedTab = "Historial"
                }
            )
        }
    }

    if (mensajeAroma != null) {
        AlertDialog(
            onDismissRequest = {
                mensajeAroma = null
            },
            title = {
                Text("No se puede eliminar")
            },
            text = {
                Text(mensajeAroma!!)
            },
            confirmButton = {
                TextButton(
                    onClick = {
                        mensajeAroma = null
                    }
                ) {
                    Text("Entendido")
                }
            }
        )
    }
}

@Composable
fun navColors() = NavigationBarItemDefaults.colors(
    selectedIconColor = AccentBlue,
    selectedTextColor = AccentBlue,
    indicatorColor = Color(0xFF263F62),
    unselectedIconColor = SoftBlue,
    unselectedTextColor = SoftBlue
)

@Composable
fun DashboardScreen(
    modifier: Modifier = Modifier,
    onNavigate: (String) -> Unit,
    ventasHoy: String,
    dineroRecibido: String,
    porCobrar: String,
    inventario: String
) {
    Column(
        modifier = modifier
            .fillMaxSize()
            .background(Navy)
            .verticalScroll(rememberScrollState())
            .padding(20.dp),
        verticalArrangement = Arrangement.spacedBy(20.dp)
    ) {

        Row(
            verticalAlignment = Alignment.CenterVertically,
            horizontalArrangement = Arrangement.spacedBy(12.dp)
        ) {
            Box(
                modifier = Modifier
                    .size(48.dp)
                    .background(AccentBlue, RoundedCornerShape(14.dp)),
                contentAlignment = Alignment.Center
            ) {
                Text(
                    "PC",
                    color = White,
                    fontSize = 20.sp,
                    fontWeight = FontWeight.Bold
                )
            }

            Column(modifier = Modifier.weight(1f)) {
                Text(
                    "PRESTIGE CLEAN",
                    color = White,
                    fontSize = 17.sp,
                    fontWeight = FontWeight.Bold
                )
                Text(
                    "Panel de administración",
                    color = SoftBlue,
                    fontSize = 12.sp
                )
            }

            Text("●", color = Color(0xFF4ADE80), fontSize = 13.sp)
        }

        Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
            Text(
                "¡Bienvenido!",
                color = White,
                fontSize = 25.sp,
                fontWeight = FontWeight.Bold
            )
            Text(
                "Este es el resumen de tu negocio.",
                color = SoftBlue,
                fontSize = 14.sp
            )
        }

        Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
            Text(
                "Resumen del día",
                color = White,
                fontSize = 18.sp,
                fontWeight = FontWeight.Bold
            )

            Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) {
                MetricCard(
                    "Ventas de hoy",
                    ventasHoy,
                    "Operaciones registradas",
                    Modifier.weight(1f)
                )
                MetricCard(
                    "Dinero recibido",
                    dineroRecibido,
                    "Pagos recibidos",
                    Modifier.weight(1f)
                )
            }

            Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) {
                MetricCard(
                    "Por cobrar",
                    porCobrar,
                    "Saldos pendientes",
                    Modifier.weight(1f)
                )
                MetricCard(
                    "Inventario",
                    inventario,
                    "Unidades disponibles",
                    Modifier.weight(1f)
                )
            }
        }

        Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
            Text(
                "Accesos rápidos",
                color = White,
                fontSize = 18.sp,
                fontWeight = FontWeight.Bold
            )

            Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) {
                ActionCard(
                    "+",
                    "Nueva venta",
                    Modifier.weight(1f)
                ) { onNavigate("Ventas") }

                ActionCard(
                    symbol = "",
                    title = "Productos",
                    modifier = Modifier.weight(1f),
                    iconRes = R.drawable.ic_bottle
                ) {
                    onNavigate("Productos")
                }
            }

            Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) {
                ActionCard(
                    "♙",
                    "Clientes",
                    Modifier.weight(1f)
                ) { onNavigate("Clientes") }

                ActionCard(
                    "◷",
                    "Historial",
                    Modifier.weight(1f)
                ) { onNavigate("Historial") }
            }
            Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) {

                ActionCard(
                    "⚙",
                    "Producción",
                    Modifier.weight(1f)
                ) { onNavigate("Produccion") }

                ActionCard(
                    "▤",
                    "Inventario",
                    Modifier.weight(1f)
                ) { onNavigate("Inventario") }
            }
        }

        Text(
            "Prestige Clean  •  Gestión inteligente de tu negocio",
            color = SoftBlue,
            fontSize = 11.sp,
            modifier = Modifier
                .fillMaxWidth()
                .padding(top = 4.dp),
        )
    }
}

@Composable
fun MetricCard(
    title: String,
    value: String,
    description: String,
    modifier: Modifier = Modifier
) {
    Card(
        modifier = modifier,
        shape = RoundedCornerShape(18.dp),
        colors = CardDefaults.cardColors(
            containerColor = CardBlue
        )
    ) {
        Column(
            modifier = Modifier.padding(14.dp),
            verticalArrangement = Arrangement.spacedBy(7.dp)
        ) {
            Text(
                title,
                color = SoftBlue,
                fontSize = 12.sp
            )

            Text(
                value,
                color = White,
                fontSize = 23.sp,
                fontWeight = FontWeight.Bold
            )

            Text(
                description,
                color = SoftBlue,
                fontSize = 10.sp
            )
        }
    }
}


@Composable
fun ActionCard(
    symbol: String,
    title: String,
    modifier: Modifier = Modifier,
    iconRes: Int? = null,
    onClick: () -> Unit
) {
    Card(
        modifier = modifier.clickable { onClick() },
        shape = RoundedCornerShape(18.dp),
        colors = CardDefaults.cardColors(
            containerColor = CardBlue
        )
    ) {
        Column(
            modifier = Modifier
                .fillMaxWidth()
                .padding(16.dp),
            verticalArrangement = Arrangement.spacedBy(12.dp)
        ) {
            if (iconRes != null) {
                Image(
                    painter = painterResource(id = iconRes),
                    contentDescription = title,
                    modifier = Modifier.size(27.dp),
                    colorFilter = ColorFilter.tint(AccentBlue)
                )
            } else {
                Text(
                    symbol,
                    color = AccentBlue,
                    fontSize = 27.sp,
                    fontWeight = FontWeight.Bold
                )
            }

            Text(
                title,
                color = White,
                fontSize = 14.sp,
                fontWeight = FontWeight.SemiBold
            )
        }
    }
}


@Composable
fun SectionScreen(
    title: String,
    description: String,
    symbol: String,
    modifier: Modifier = Modifier
) {
    Column(
        modifier = modifier
            .fillMaxSize()
            .background(Navy)
            .padding(24.dp),
        verticalArrangement = Arrangement.spacedBy(16.dp)
    ) {
        Text(
            title,
            color = White,
            fontSize = 26.sp,
            fontWeight = FontWeight.Bold
        )

        Box(
            modifier = Modifier
                .size(70.dp)
                .background(CardBlue, RoundedCornerShape(20.dp)),
            contentAlignment = Alignment.Center
        ) {
            Text(
                symbol,
                color = AccentBlue,
                fontSize = 32.sp
            )
        }

        Text(
            description,
            color = SoftBlue,
            fontSize = 15.sp
        )

        Text(
            "Estamos preparando esta sección.",
            color = White,
            fontSize = 13.sp
        )
    }
}

41,184 chars · codepastes.com