@@ -29,17 +29,62 @@ export default function MarcadoPage({ orderCustomer, buttonUser, itemsPedidos })
2929 const [ search , setSearch ] = useState ( '' ) ;
3030 const [ estadoFiltro , setEstadoFiltro ] = useState ( "" ) ;
3131 const [ trabajadorFiltro , setTrabajadorFiltro ] = useState ( "" ) ;
32+ const [ fechaInicio , setFechaInicio ] = useState ( '' ) ;
33+ const [ fechaFin , setFechaFin ] = useState ( '' ) ;
34+
35+ const filtrarPorFecha = ( item , inicio , fin ) => {
36+ if ( ! inicio && ! fin ) return true ; // Si no hay filtros de fecha
37+
38+ const fechaItem = new Date ( item . updated_at ) ;
39+
40+ if ( inicio && fin ) {
41+ const start = new Date ( inicio ) ;
42+ const end = new Date ( fin ) ;
43+ end . setHours ( 23 , 59 , 59 ) ; // Incluir todo el día final
44+ return fechaItem >= start && fechaItem <= end ;
45+ }
46+
47+ if ( inicio ) {
48+ const start = new Date ( inicio ) ;
49+ return fechaItem >= start ;
50+ }
51+
52+ if ( fin ) {
53+ const end = new Date ( fin ) ;
54+ end . setHours ( 23 , 59 , 59 ) ;
55+ return fechaItem <= end ;
56+ }
57+
58+ return true ;
59+ } ;
3260 const itemsFiltrados = itemsPedidos . filter ( ( item ) => {
33- // Filtrar por estado (si aplica)
61+ // Filtrar por estado
3462 const coincideEstado = estadoFiltro === "" ? true : item . estado === estadoFiltro ;
35-
36- // Filtrar por trabajador (si aplica)
37- const coincideTrabajador = trabajadorFiltro === "" ? true : item . marcaciones ?. [ 0 ] ?. trabajador ?. id === parseInt ( trabajadorFiltro ) ;
38-
39- // El item debe cumplir con ambos filtros
40- return coincideEstado && coincideTrabajador ;
63+
64+ // Filtrar por trabajador
65+ const coincideTrabajador = trabajadorFiltro === "" ? true :
66+ item . marcaciones ?. [ 0 ] ?. trabajador ?. id === parseInt ( trabajadorFiltro ) ;
67+
68+ // Filtrar por fecha
69+ const coincideFecha = filtrarPorFecha ( item , fechaInicio , fechaFin ) ;
70+
71+ // El item debe cumplir con todos los filtros
72+ return coincideEstado && coincideTrabajador && coincideFecha ;
4173 } ) ;
4274
75+ // Función para filtrar por rango de fechas
76+
77+ console . log ( itemsFiltrados , fechaFin ) ;
78+
79+ // Limpiar filtros
80+ const limpiarFiltros = ( ) => {
81+ setEstadoFiltro ( '' ) ;
82+ setTrabajadorFiltro ( '' ) ;
83+ setFechaInicio ( '' ) ;
84+ setFechaFin ( '' ) ;
85+ setSearch ( '' ) ;
86+ } ;
87+
4388 const {
4489 marcados,
4590 seleccionados,
@@ -198,70 +243,125 @@ export default function MarcadoPage({ orderCustomer, buttonUser, itemsPedidos })
198243 ) }
199244 </ div >
200245
201- < div className = "" >
202- { /* Header de la tabla con buscador */ }
203- < div className = "flex flex-col sm:flex-row sm:items-center justify-between p-4 gap-3 bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700" >
204- < div className = "" >
246+ < div className = "bg-white dark:bg-gray-900 rounded-lg shadow " >
247+ { /* Header con filtros */ }
248+ < div className = "flex flex-col p-4 gap-4 bg-gray-50 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700" >
249+ < div className = "flex justify-between items-center " >
205250 < h2 className = "text-lg font-semibold text-gray-800 dark:text-gray-200" >
206251 Lista de items
207252 </ h2 >
253+ < button
254+ onClick = { limpiarFiltros }
255+ className = "px-3 py-1 text-sm text-gray-600 dark:text-gray-300 bg-gray-200 dark:bg-gray-700 rounded-md hover:bg-gray-300 dark:hover:bg-gray-600"
256+ >
257+ Limpiar filtros
258+ </ button >
259+ </ div >
260+
261+ < div className = "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4" >
262+ { /* Filtro por estado */ }
208263 < div >
209- < label className = "text-sm font-medium text-gray-700 dark:text-gray-300" >
210- Filtrar por estado :
264+ < label className = "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1 " >
265+ Estado :
211266 </ label >
212267 < select
213268 value = { estadoFiltro }
214269 onChange = { ( e ) => setEstadoFiltro ( e . target . value ) }
215- className = "border rounded-lg px-2 py-1 text-sm dark:bg-gray-800 dark:text-white"
270+ className = "w-full border rounded-lg px-3 py-2 text-sm dark:bg-gray-700 dark:text-white dark:border-gray-600 "
216271 >
217- < option value = "" > Todos</ option >
272+ < option value = "" > Todos los estados </ option >
218273 < option value = "pendiente" > Pendiente</ option >
219274 < option value = "en proceso" > En proceso</ option >
220275 < option value = "completado" > Completado</ option >
221276 </ select >
222277 </ div >
278+
279+ { /* Filtro por trabajador */ }
223280 < div >
224- < label className = "text-sm font-medium text-gray-700 dark:text-gray-300" >
225- Filtrar por trabajador :
281+ < label className = "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1 " >
282+ Trabajador :
226283 </ label >
227284 < select
228285 value = { trabajadorFiltro }
229286 onChange = { ( e ) => setTrabajadorFiltro ( e . target . value ) }
230- className = "border rounded-lg px-2 py-1 text-sm dark:bg-gray-800 dark:text-white"
287+ className = "w-full border rounded-lg px-3 py-2 text-sm dark:bg-gray-700 dark:text-white dark:border-gray-600 "
231288 >
232- < option value = "" > Seleccionar trabajador </ option >
289+ < option value = "" > Todos los trabajadores </ option >
233290 { buttonUser . map ( ( trabajador ) => (
234291 < option key = { trabajador . id } value = { trabajador . id } >
235292 { trabajador . name }
236293 </ option >
237294 ) ) }
238295 </ select >
239296 </ div >
297+
298+ { /* Filtro por fecha inicio */ }
299+ < div >
300+ < label className = "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" >
301+ Fecha inicio:
302+ </ label >
303+ < input
304+ type = "date"
305+ value = { fechaInicio }
306+ onChange = { ( e ) => setFechaInicio ( e . target . value ) }
307+ className = "w-full border rounded-lg px-3 py-2 text-sm dark:bg-gray-700 dark:text-white dark:border-gray-600"
308+ />
309+ </ div >
310+
311+ { /* Filtro por fecha fin */ }
312+ < div >
313+ < label className = "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1" >
314+ Fecha fin:
315+ </ label >
316+ < input
317+ type = "date"
318+ value = { fechaFin }
319+ onChange = { ( e ) => setFechaFin ( e . target . value ) }
320+ className = "w-full border rounded-lg px-3 py-2 text-sm dark:bg-gray-700 dark:text-white dark:border-gray-600"
321+ />
322+ </ div >
240323 </ div >
241- < div className = "relative w-full sm:w-72" >
242- < svg
243- className = "absolute left-3 top-2.5 w-4 h-4 text-gray-400"
244- xmlns = "http://www.w3.org/2000/svg"
245- fill = "none"
246- viewBox = "0 0 24 24"
247- stroke = "currentColor"
248- >
249- < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M21 21l-4.35-4.35M15.5 10.5a5 5 0 11-10 0 5 5 0 0110 0z" />
250- </ svg >
324+
325+ { /* Búsqueda general */ }
326+ < div className = "relative" >
327+ < div className = "absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none" >
328+ < svg
329+ className = "w-4 h-4 text-gray-400"
330+ xmlns = "http://www.w3.org/2000/svg"
331+ fill = "none"
332+ viewBox = "0 0 24 24"
333+ stroke = "currentColor"
334+ >
335+ < path strokeLinecap = "round" strokeLinejoin = "round" strokeWidth = { 2 } d = "M21 21l-4.35-4.35M15.5 10.5a5 5 0 11-10 0 5 5 0 0110 0z" />
336+ </ svg >
337+ </ div >
251338 < input
252339 type = "text"
253340 value = { search }
254341 onChange = { ( e ) => setSearch ( e . target . value ) }
255- className = "w-full pl-10 pr-4 py-2 text-sm text-gray-900 border border-gray-200 rounded-lg bg-white dark:bg-gray-900 dark:border-gray-700 dark:placeholder-gray-400 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-blue-500 shadow-sm"
256- placeholder = "Buscar producto ..."
342+ className = "w-full pl-10 pr-4 py-2 text-sm text-gray-900 border border-gray-200 rounded-lg bg-white dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-blue-500 shadow-sm"
343+ placeholder = "Buscar en todos los campos ..."
257344 />
258345 </ div >
259- </ div >
260346
347+ { /* Info de filtros aplicados */ }
348+ { ( estadoFiltro || trabajadorFiltro || fechaInicio || fechaFin ) && (
349+ < div className = "text-sm text-gray-600 dark:text-gray-400" >
350+ Filtros aplicados:
351+ { estadoFiltro && < span className = "ml-2 bg-blue-100 dark:bg-blue-900 px-2 py-1 rounded" > Estado: { estadoFiltro } </ span > }
352+ { trabajadorFiltro && < span className = "ml-2 bg-green-100 dark:bg-green-900 px-2 py-1 rounded" > Trabajador: { buttonUser . find ( t => t . id === parseInt ( trabajadorFiltro ) ) ?. name } </ span > }
353+ { fechaInicio && < span className = "ml-2 bg-yellow-100 dark:bg-yellow-900 px-2 py-1 rounded" > Desde: { new Date ( fechaInicio ) . toLocaleDateString ( ) } </ span > }
354+ { fechaFin && < span className = "ml-2 bg-purple-100 dark:bg-purple-900 px-2 py-1 rounded" > Hasta: { new Date ( fechaFin ) . toLocaleDateString ( ) } </ span > }
355+ </ div >
356+ ) }
357+ </ div >
261358
262- { /* Contenedor de la tabla */ }
359+ { /* Tabla con los datos filtrados */ }
263360 < div className = "overflow-x-auto" >
264- < TablaMarcacionBL itemsPedidos = { itemsFiltrados } search = { search } estadoFiltro = { estadoFiltro } />
361+ < TablaMarcacionBL
362+ itemsPedidos = { itemsFiltrados }
363+ search = { search }
364+ />
265365 </ div >
266366 </ div >
267367
0 commit comments