From 25902ee11087abd5bc38e2c0c19e1bd3af4bb87f Mon Sep 17 00:00:00 2001 From: planetazuzu Date: Sat, 20 Dec 2025 23:47:58 +0100 Subject: [PATCH] =?UTF-8?q?feat:=20implementar=20b=C3=BAsqueda=20avanzada?= =?UTF-8?q?=20con=20filtros=20por=20categor=C3=ADa?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Añadir filtros por tipo (Todos, Protocolos, Fármacos) - Añadir filtros por categoría (dinámicos según tipo seleccionado) - Mejorar visualización de resultados con badges de prioridad y edad - Aumentar límite de resultados de 8 a 12 - Resetear filtros al cerrar el modal - Añadir 'oxigenoterapia' a DrugCategory type - UI responsive con botones de filtro --- src/components/layout/SearchModal.tsx | 242 +++++++++++++++++++++++--- src/data/drugs.ts | 2 +- 2 files changed, 221 insertions(+), 23 deletions(-) diff --git a/src/components/layout/SearchModal.tsx b/src/components/layout/SearchModal.tsx index ae64333f..5264bed0 100644 --- a/src/components/layout/SearchModal.tsx +++ b/src/components/layout/SearchModal.tsx @@ -1,9 +1,10 @@ import { useState, useEffect, useRef } from 'react'; -import { Search, X, FileText, Pill, ArrowRight } from 'lucide-react'; +import { Search, X, FileText, Pill, ArrowRight, Filter } from 'lucide-react'; import { useNavigate } from 'react-router-dom'; -import { searchProcedures, Procedure } from '@/data/procedures'; -import { searchDrugs, Drug } from '@/data/drugs'; +import { searchProcedures, Procedure, Category, Priority, AgeGroup } from '@/data/procedures'; +import { searchDrugs, Drug, DrugCategory } from '@/data/drugs'; import { useSearchHistory } from '@/hooks/useSearchHistory'; +import { Button } from '@/components/ui/button'; interface SearchModalProps { isOpen: boolean; @@ -15,11 +16,29 @@ type SearchResult = { id: string; title: string; subtitle?: string; + category?: string; + priority?: Priority; + ageGroup?: AgeGroup; +}; + +type FilterType = 'all' | 'procedure' | 'drug'; +type CategoryFilter = Category | DrugCategory | 'all'; + +// Función helper para verificar si una categoría es de procedimientos +const isProcedureCategory = (cat: string): cat is Category => { + return ['soporte_vital', 'patologias', 'escena'].includes(cat); +}; + +// Función helper para verificar si una categoría es de fármacos +const isDrugCategory = (cat: string): cat is DrugCategory => { + return ['cardiovascular', 'respiratorio', 'neurologico', 'analgesia', 'oxigenoterapia', 'otros'].includes(cat); }; const SearchModal = ({ isOpen, onClose }: SearchModalProps) => { const [query, setQuery] = useState(''); const [results, setResults] = useState([]); + const [typeFilter, setTypeFilter] = useState('all'); + const [categoryFilter, setCategoryFilter] = useState('all'); const inputRef = useRef(null); const navigate = useNavigate(); const { addToHistory } = useSearchHistory(); @@ -36,22 +55,53 @@ const SearchModal = ({ isOpen, onClose }: SearchModalProps) => { return; } - const procedures = searchProcedures(query).map((p): SearchResult => ({ - type: 'procedure', - id: p.id, - title: p.shortTitle, - subtitle: p.category.replace('_', ' '), - })); + let procedures: SearchResult[] = []; + let drugs: SearchResult[] = []; - const drugs = searchDrugs(query).map((d): SearchResult => ({ - type: 'drug', - id: d.id, - title: d.genericName, - subtitle: d.tradeName, - })); + // Buscar procedimientos si el filtro lo permite + if (typeFilter === 'all' || typeFilter === 'procedure') { + const procedureResults = searchProcedures(query); + procedures = procedureResults + .filter((p) => { + // Filtrar por categoría si está seleccionada y es una categoría de procedimientos + if (categoryFilter !== 'all' && isProcedureCategory(categoryFilter)) { + return categoryFilter === p.category; + } + return true; + }) + .map((p): SearchResult => ({ + type: 'procedure', + id: p.id, + title: p.shortTitle, + subtitle: p.category.replace('_', ' '), + category: p.category, + priority: p.priority, + ageGroup: p.ageGroup, + })); + } - setResults([...procedures, ...drugs].slice(0, 8)); - }, [query]); + // Buscar fármacos si el filtro lo permite + if (typeFilter === 'all' || typeFilter === 'drug') { + const drugResults = searchDrugs(query); + drugs = drugResults + .filter((d) => { + // Filtrar por categoría si está seleccionada y es una categoría de fármacos + if (categoryFilter !== 'all' && isDrugCategory(categoryFilter)) { + return categoryFilter === d.category; + } + return true; + }) + .map((d): SearchResult => ({ + type: 'drug', + id: d.id, + title: d.genericName, + subtitle: d.tradeName, + category: d.category, + })); + } + + setResults([...procedures, ...drugs].slice(0, 12)); + }, [query, typeFilter, categoryFilter]); const handleResultClick = (result: SearchResult) => { // Añadir al historial @@ -99,6 +149,137 @@ const SearchModal = ({ isOpen, onClose }: SearchModalProps) => { + {/* Filtros */} +
+ {/* Filtro por tipo */} +
+ + Tipo: +
+ + + +
+
+ + {/* Filtro por categoría - mostrar según tipo seleccionado */} + {typeFilter === 'all' && ( +
+ Categoría: + + {procedureCategories.map((cat) => ( + + ))} + {drugCategories.map((cat) => ( + + ))} +
+ )} + + {typeFilter === 'procedure' && ( +
+ Categoría: + + {procedureCategories.map((cat) => ( + + ))} +
+ )} + + {typeFilter === 'drug' && ( +
+ Categoría: + + {drugCategories.map((cat) => ( + + ))} +
+ )} +
+
{results.length > 0 ? (
@@ -117,11 +298,28 @@ const SearchModal = ({ isOpen, onClose }: SearchModalProps) => {

{result.title}

- {result.subtitle && ( -

- {result.subtitle} -

- )} +
+ {result.subtitle && ( +

+ {result.subtitle} +

+ )} + {result.priority && ( + + {result.priority} + + )} + {result.ageGroup && result.ageGroup !== 'todos' && ( + + {result.ageGroup} + + )} +
diff --git a/src/data/drugs.ts b/src/data/drugs.ts index 3e70e5dd..1364cd5a 100644 --- a/src/data/drugs.ts +++ b/src/data/drugs.ts @@ -1,4 +1,4 @@ -export type DrugCategory = 'cardiovascular' | 'respiratorio' | 'neurologico' | 'analgesia' | 'otros'; +export type DrugCategory = 'cardiovascular' | 'respiratorio' | 'neurologico' | 'analgesia' | 'oxigenoterapia' | 'otros'; export type AdministrationRoute = 'IV' | 'IM' | 'SC' | 'IO' | 'Nebulizado' | 'SL' | 'Rectal' | 'Nasal'; export interface Drug {