Files
karibeo_backend_admin/src/pages/dashboard/politur/Reports.tsx
2025-10-11 15:47:12 +00:00

205 lines
6.6 KiB
TypeScript

import React, { useState } from 'react';
import { FileText, Search, Filter, Download, Eye } from 'lucide-react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Badge } from '@/components/ui/badge';
interface Report {
id: string;
reportNumber: string;
touristName: string;
type: string;
category: string;
date: string;
status: 'open' | 'under_review' | 'closed';
officer: string;
description: string;
}
const Reports = () => {
const [searchTerm, setSearchTerm] = useState('');
const [reports] = useState<Report[]>([
{
id: '1',
reportNumber: 'POL-2024-001',
touristName: 'John Smith',
type: 'Robo',
category: 'Seguridad',
date: '2024-01-15',
status: 'closed',
officer: 'Oficial Rodriguez',
description: 'Robo de cartera en Zona Colonial'
},
{
id: '2',
reportNumber: 'POL-2024-002',
touristName: 'Maria Garcia',
type: 'Accidente',
category: 'Tránsito',
date: '2024-01-16',
status: 'under_review',
officer: 'Oficial Martinez',
description: 'Accidente de tránsito menor en el Malecón'
},
{
id: '3',
reportNumber: 'POL-2024-003',
touristName: 'Robert Johnson',
type: 'Pérdida',
category: 'Documentos',
date: '2024-01-17',
status: 'open',
officer: 'Oficial Fernandez',
description: 'Pérdida de pasaporte en área hotelera'
}
]);
const getStatusBadge = (status: string) => {
switch (status) {
case 'open':
return <Badge variant="default">Abierto</Badge>;
case 'under_review':
return <Badge variant="secondary">En Revisión</Badge>;
case 'closed':
return <Badge variant="outline">Cerrado</Badge>;
default:
return null;
}
};
const filteredReports = reports.filter(report =>
report.touristName.toLowerCase().includes(searchTerm.toLowerCase()) ||
report.reportNumber.toLowerCase().includes(searchTerm.toLowerCase()) ||
report.type.toLowerCase().includes(searchTerm.toLowerCase())
);
return (
<div className="space-y-6">
<div className="flex items-center justify-between">
<h2 className="text-2xl font-bold text-gray-900">Reportes y Denuncias</h2>
<Button>
<FileText className="w-4 h-4 mr-2" />
Nuevo Reporte
</Button>
</div>
{/* Stats */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<Card>
<CardHeader className="pb-3">
<CardTitle className="text-sm font-medium text-gray-600">
Reportes Abiertos
</CardTitle>
</CardHeader>
<CardContent>
<div className="text-3xl font-bold text-blue-600">
{reports.filter(r => r.status === 'open').length}
</div>
</CardContent>
</Card>
<Card>
<CardHeader className="pb-3">
<CardTitle className="text-sm font-medium text-gray-600">
En Revisión
</CardTitle>
</CardHeader>
<CardContent>
<div className="text-3xl font-bold text-orange-600">
{reports.filter(r => r.status === 'under_review').length}
</div>
</CardContent>
</Card>
<Card>
<CardHeader className="pb-3">
<CardTitle className="text-sm font-medium text-gray-600">
Cerrados
</CardTitle>
</CardHeader>
<CardContent>
<div className="text-3xl font-bold text-green-600">
{reports.filter(r => r.status === 'closed').length}
</div>
</CardContent>
</Card>
</div>
{/* Search and Filters */}
<Card>
<CardHeader>
<div className="flex flex-col md:flex-row gap-4">
<div className="flex-1">
<div className="relative">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 w-4 h-4" />
<Input
placeholder="Buscar por nombre, número o tipo..."
className="pl-10"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
</div>
</div>
<Button variant="outline">
<Filter className="w-4 h-4 mr-2" />
Filtros
</Button>
<Button variant="outline">
<Download className="w-4 h-4 mr-2" />
Exportar
</Button>
</div>
</CardHeader>
<CardContent>
<div className="space-y-3">
{filteredReports.map((report) => (
<div
key={report.id}
className="border rounded-lg p-4 hover:bg-gray-50 transition-colors"
>
<div className="flex items-start justify-between mb-2">
<div>
<div className="flex items-center gap-2 mb-1">
<h3 className="font-semibold">{report.reportNumber}</h3>
{getStatusBadge(report.status)}
</div>
<p className="text-sm text-gray-600">{report.touristName}</p>
</div>
<Button size="sm" variant="outline">
<Eye className="w-4 h-4 mr-1" />
Ver
</Button>
</div>
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 text-sm mb-2">
<div>
<span className="text-gray-500">Tipo:</span>
<p className="font-medium">{report.type}</p>
</div>
<div>
<span className="text-gray-500">Categoría:</span>
<p className="font-medium">{report.category}</p>
</div>
<div>
<span className="text-gray-500">Fecha:</span>
<p className="font-medium">{new Date(report.date).toLocaleDateString('es-ES')}</p>
</div>
<div>
<span className="text-gray-500">Oficial:</span>
<p className="font-medium">{report.officer}</p>
</div>
</div>
<p className="text-sm text-gray-700">{report.description}</p>
</div>
))}
</div>
</CardContent>
</Card>
</div>
);
};
export default Reports;