11// resources/js/Components/ListaInventario.jsx
2- import React from 'react' ;
2+ import React , { useState } from 'react' ;
33
44const ListaInventario = ( {
55 productos,
@@ -14,11 +14,45 @@ const ListaInventario = ({
1414 onLimpiarFiltros,
1515 onEstanteriaClick
1616} ) => {
17+ const [ expandida , setExpandida ] = useState ( true ) ;
18+
19+ const toggleExpandida = ( ) => {
20+ setExpandida ( ! expandida ) ;
21+ } ;
22+
23+ // Si está contraída, mostrar solo un ícono pequeño
24+ if ( ! expandida ) {
25+ return (
26+ < div className = "w-16 bg-white/80 backdrop-blur-sm border border-white/30 shadow-2xl rounded-3xl p-4 flex flex-col items-center justify-center" >
27+ < button
28+ onClick = { toggleExpandida }
29+ className = "p-3 bg-blue-500 text-white rounded-full hover:bg-blue-600 transition-all duration-300 hover:scale-110"
30+ title = "Expandir lista de inventario"
31+ >
32+ < svg className = "w-6 h-6" fill = "none" stroke = "currentColor" viewBox = "0 0 24 24" >
33+ < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M9 5l7 7-7 7" />
34+ </ svg >
35+ </ button >
36+ < span className = "text-xs text-gray-600 mt-2 text-center" > Mostrar Lista</ span >
37+ </ div >
38+ ) ;
39+ }
40+
41+ // Si está expandida, mostrar la lista completa
1742 return (
18- < div className = "w-[ 450px] bg-white/80 backdrop-blur-sm border border-white/30 shadow-2xl rounded-3xl p-6 overflow-hidden flex flex-col" >
19- { /* Header */ }
43+ < div className = "w-full sm:w-[350px] md:w-[400px] lg:w-[ 450px] bg-white/80 backdrop-blur-sm border border-white/30 shadow-2xl rounded-3xl p-6 overflow-hidden flex flex-col transition-all duration-300 " >
44+ { /* Header con botón de cerrar */ }
2045 < div className = "flex justify-between items-center mb-4" >
2146 < h2 className = "text-2xl font-bold text-gray-800" > 📦 Inventario</ h2 >
47+ < button
48+ onClick = { toggleExpandida }
49+ className = "p-2 text-gray-500 hover:text-gray-700 hover:bg-gray-100 rounded-full transition-all duration-200"
50+ title = "Contraer lista"
51+ >
52+ < svg className = "w-5 h-5" fill = "none" stroke = "currentColor" viewBox = "0 0 24 24" >
53+ < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M15 19l-7-7 7-7" />
54+ </ svg >
55+ </ button >
2256 </ div >
2357
2458 { /* Filtros y búsqueda */ }
@@ -27,22 +61,22 @@ const ListaInventario = ({
2761 < input
2862 type = "text"
2963 placeholder = "Buscar producto, color, tipo o ubicación..."
30- className = "flex-1 border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
64+ className = "flex-1 border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm "
3165 value = { busqueda }
3266 onChange = { ( e ) => onBusquedaChange ( e . target . value ) }
3367 />
3468 < button
35- className = "bg-blue-500 text-white px-4 py-2 rounded-lg hover:bg-blue-600 transition"
69+ className = "bg-blue-500 text-white px-3 py-2 rounded-lg hover:bg-blue-600 transition text-sm whitespace-nowrap "
3670 onClick = { onLimpiarFiltros }
3771 >
3872 Limpiar
3973 </ button >
4074 </ div >
4175
4276 < div className = "flex items-center gap-2" >
43- < span className = "text-gray-700 font-medium" > Categoría:</ span >
77+ < span className = "text-gray-700 font-medium text-sm " > Categoría:</ span >
4478 < select
45- className = "border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
79+ className = "border border-gray-300 rounded-lg px-2 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 text-sm flex-1 "
4680 value = { categoriaFiltro }
4781 onChange = { ( e ) => onCategoriaChange ( e . target . value ) }
4882 >
@@ -56,11 +90,11 @@ const ListaInventario = ({
5690 { /* Información de filtros activos */ }
5791 { filtro && (
5892 < div className = "mb-4 p-3 bg-blue-50 border border-blue-200 rounded-lg flex justify-between items-center" >
59- < span className = "text-blue-700" >
93+ < span className = "text-blue-700 text-sm " >
6094 Filtrado por: < strong > { filtro } </ strong >
6195 </ span >
6296 < button
63- className = "text-blue-600 hover:text-blue-800 text-sm font-medium"
97+ className = "text-blue-600 hover:text-blue-800 text-xs font-medium"
6498 onClick = { ( ) => onFiltroChange ( null ) }
6599 >
66100 Quitar filtro
@@ -69,7 +103,7 @@ const ListaInventario = ({
69103 ) }
70104
71105 { /* Contador de resultados */ }
72- < div className = "mb-3 text-sm text-gray-600" >
106+ < div className = "mb-3 text-xs text-gray-600" >
73107 Mostrando { productosFiltrados . length } de { productos . length } productos
74108 { productosFiltrados . some ( p => ! p . tiene_ubicacion ) && (
75109 < span className = "text-red-500 ml-2" > ⚠️ Algunos sin ubicación</ span >
@@ -82,38 +116,51 @@ const ListaInventario = ({
82116 productosFiltrados . map ( ( p ) => (
83117 < div
84118 key = { p . id }
85- className = { `border-b border-gray-200 py-3 px-2 hover:bg-blue-50 rounded-lg transition cursor-pointer flex justify-between items-center ${
119+ className = { `border-b border-gray-200 py-2 px-2 hover:bg-blue-50 rounded-lg transition cursor-pointer flex justify-between items-center ${
86120 ! p . tiene_ubicacion ? 'bg-red-50 border-l-4 border-l-red-400' : ''
87121 } `}
88122 onClick = { ( ) => onEstanteriaClick ( p . estanteria ) }
89123 >
90124 < div className = "max-w-[60%]" >
91- < div className = "font-medium text-gray-800 text-base truncate" >
125+ < div className = "font-medium text-gray-800 text-sm truncate" >
92126 { p . descripcion || `${ p . tipo_producto } ${ p . color_nombre } ${ p . tamanio } ` }
93127 { ! p . tiene_ubicacion && (
94- < span className = "text-red-500 text-xs ml-2 " > ⚠️ Sin ubicación </ span >
128+ < span className = "text-red-500 text-xs ml-1 " > ⚠️</ span >
95129 ) }
96130 </ div >
97- < div className = "text-xs text-gray-500" >
131+ < div className = "text-xs text-gray-500 truncate " >
98132 { p . tipo_producto } • { p . color_nombre } • { p . tamanio }
99133 </ div >
100134 </ div >
101135 < div className = "text-right max-w-[40%]" >
102- < div className = { `text-sm font-medium truncate ${
136+ < div className = { `text-xs font-medium truncate ${
103137 ! p . tiene_ubicacion ? 'text-red-700' : 'text-gray-700'
104138 } `} >
105139 { p . estanteria }
106140 </ div >
107- < div className = "text-xs text-gray-500" > { p . stock_total } unidades </ div >
141+ < div className = "text-xs text-gray-500" > { p . stock_total } u </ div >
108142 </ div >
109143 </ div >
110144 ) )
111145 ) : (
112- < div className = "text-center py-8 text-gray-500" >
146+ < div className = "text-center py-8 text-gray-500 text-sm " >
113147 No se encontraron productos con los filtros aplicados
114148 </ div >
115149 ) }
116150 </ div >
151+
152+ { /* Botón flotante para contraer (alternativo) */ }
153+ < div className = "mt-4 pt-4 border-t border-gray-200" >
154+ < button
155+ onClick = { toggleExpandida }
156+ className = "w-full py-2 bg-gray-100 text-gray-600 rounded-lg hover:bg-gray-200 transition flex items-center justify-center gap-2 text-sm"
157+ >
158+ < svg className = "w-4 h-4" fill = "none" stroke = "currentColor" viewBox = "0 0 24 24" >
159+ < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M15 19l-7-7 7-7" />
160+ </ svg >
161+ Ocultar lista
162+ </ button >
163+ </ div >
117164 </ div >
118165 ) ;
119166} ;
0 commit comments