Implement Tourist Guide System
This commit is contained in:
204
src/pages/dashboard/politur/Reports.tsx
Normal file
204
src/pages/dashboard/politur/Reports.tsx
Normal file
@@ -0,0 +1,204 @@
|
||||
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;
|
||||
Reference in New Issue
Block a user