agregar fiiltros de busqueda en el front
This commit is contained in:
@@ -1462,6 +1462,8 @@ function ChecklistsTab({ checklists, user, onChecklistCreated, onStartInspection
|
||||
const [creating, setCreating] = useState(false)
|
||||
const [updating, setUpdating] = useState(false)
|
||||
const [mechanics, setMechanics] = useState([])
|
||||
const [searchTerm, setSearchTerm] = useState('')
|
||||
const [aiModeFilter, setAiModeFilter] = useState('all') // all, off, optional, required
|
||||
const [formData, setFormData] = useState({
|
||||
name: '',
|
||||
description: '',
|
||||
@@ -1497,6 +1499,19 @@ function ChecklistsTab({ checklists, user, onChecklistCreated, onStartInspection
|
||||
}
|
||||
}
|
||||
|
||||
// Filtrar checklists
|
||||
const filteredChecklists = checklists.filter(checklist => {
|
||||
const matchesSearch =
|
||||
checklist.name?.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
checklist.description?.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
checklist.id?.toString().includes(searchTerm)
|
||||
|
||||
const matchesAiMode =
|
||||
aiModeFilter === 'all' || checklist.ai_mode === aiModeFilter
|
||||
|
||||
return matchesSearch && matchesAiMode
|
||||
})
|
||||
|
||||
const handleCreate = async (e) => {
|
||||
e.preventDefault()
|
||||
setCreating(true)
|
||||
@@ -1581,6 +1596,41 @@ function ChecklistsTab({ checklists, user, onChecklistCreated, onStartInspection
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Buscador y Filtros */}
|
||||
{checklists.length > 0 && (
|
||||
<div className="mb-6 space-y-4">
|
||||
<div className="flex gap-4 flex-wrap">
|
||||
{/* Buscador */}
|
||||
<div className="flex-1 min-w-[300px]">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Buscar por nombre, descripción o ID..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Filtro de Modo IA */}
|
||||
<select
|
||||
value={aiModeFilter}
|
||||
onChange={(e) => setAiModeFilter(e.target.value)}
|
||||
className="px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||
>
|
||||
<option value="all">Todos los modos IA</option>
|
||||
<option value="off">Sin IA</option>
|
||||
<option value="optional">IA Opcional</option>
|
||||
<option value="required">IA Requerida</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Contador de resultados */}
|
||||
<div className="text-sm text-gray-600">
|
||||
Mostrando {filteredChecklists.length} de {checklists.length} checklists
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{checklists.length === 0 ? (
|
||||
<div className="text-center py-12">
|
||||
{user.role === 'admin' ? (
|
||||
@@ -1603,8 +1653,21 @@ function ChecklistsTab({ checklists, user, onChecklistCreated, onStartInspection
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
) : filteredChecklists.length === 0 ? (
|
||||
<div className="text-center py-12">
|
||||
<p className="text-gray-500">No se encontraron checklists con los filtros aplicados</p>
|
||||
<button
|
||||
onClick={() => {
|
||||
setSearchTerm('')
|
||||
setAiModeFilter('all')
|
||||
}}
|
||||
className="mt-4 text-blue-600 hover:text-blue-700 underline"
|
||||
>
|
||||
Limpiar filtros
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
checklists.map((checklist) => (
|
||||
filteredChecklists.map((checklist) => (
|
||||
<div key={checklist.id} className="border border-gray-200 rounded-lg p-4 hover:shadow-md transition">
|
||||
<div className="flex justify-between items-start">
|
||||
<div className="flex-1">
|
||||
@@ -2670,6 +2733,26 @@ function InspectionDetailModal({ inspection, user, onClose, onUpdate }) {
|
||||
|
||||
function InspectionsTab({ inspections, user, onUpdate }) {
|
||||
const [selectedInspection, setSelectedInspection] = useState(null)
|
||||
const [searchTerm, setSearchTerm] = useState('')
|
||||
const [statusFilter, setStatusFilter] = useState('all') // all, completed, draft
|
||||
|
||||
// Filtrar inspecciones
|
||||
const filteredInspections = inspections.filter(inspection => {
|
||||
const matchesSearch =
|
||||
inspection.vehicle_plate?.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
inspection.vehicle_brand?.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
inspection.vehicle_model?.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
inspection.client_name?.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
inspection.or_number?.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
inspection.id?.toString().includes(searchTerm)
|
||||
|
||||
const matchesStatus =
|
||||
statusFilter === 'all' ||
|
||||
(statusFilter === 'completed' && inspection.status === 'completed') ||
|
||||
(statusFilter === 'draft' && inspection.status !== 'completed')
|
||||
|
||||
return matchesSearch && matchesStatus
|
||||
})
|
||||
|
||||
if (inspections.length === 0) {
|
||||
return (
|
||||
@@ -2682,8 +2765,55 @@ function InspectionsTab({ inspections, user, onUpdate }) {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="space-y-4">
|
||||
{inspections.map((inspection) => (
|
||||
{/* Buscador y Filtros */}
|
||||
<div className="mb-6 space-y-4">
|
||||
<div className="flex gap-4 flex-wrap">
|
||||
{/* Buscador */}
|
||||
<div className="flex-1 min-w-[300px]">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Buscar por placa, marca, modelo, cliente, OR o ID..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Filtro de Estado */}
|
||||
<select
|
||||
value={statusFilter}
|
||||
onChange={(e) => setStatusFilter(e.target.value)}
|
||||
className="px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||
>
|
||||
<option value="all">Todos los estados</option>
|
||||
<option value="completed">Completadas</option>
|
||||
<option value="draft">Borradores</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Contador de resultados */}
|
||||
<div className="text-sm text-gray-600">
|
||||
Mostrando {filteredInspections.length} de {inspections.length} inspecciones
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Lista de Inspecciones */}
|
||||
{filteredInspections.length === 0 ? (
|
||||
<div className="text-center py-12">
|
||||
<p className="text-gray-500">No se encontraron inspecciones con los filtros aplicados</p>
|
||||
<button
|
||||
onClick={() => {
|
||||
setSearchTerm('')
|
||||
setStatusFilter('all')
|
||||
}}
|
||||
className="mt-4 text-blue-600 hover:text-blue-700 underline"
|
||||
>
|
||||
Limpiar filtros
|
||||
</button>
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-4">
|
||||
{filteredInspections.map((inspection) => (
|
||||
<div key={inspection.id} className="border border-gray-200 rounded-lg p-4 hover:shadow-md transition">
|
||||
<div className="flex justify-between items-start">
|
||||
<div>
|
||||
@@ -2725,7 +2855,8 @@ function InspectionsTab({ inspections, user, onUpdate }) {
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Modal de Detalle */}
|
||||
{selectedInspection && (
|
||||
|
||||
Reference in New Issue
Block a user