2026-01-28 10:44:49 +00:00
|
|
|
"use client";
|
|
|
|
|
|
|
|
|
|
import Link from 'next/link';
|
|
|
|
|
import { Calendar, DollarSign, TrendingUp } from 'lucide-react';
|
|
|
|
|
import { Avatar, AvatarFallback } from '@/components/ui/avatar';
|
2026-01-31 12:56:51 +00:00
|
|
|
import { ProjectStatusBadge } from '@/components/ui/project-status-badge';
|
|
|
|
|
import { Project } from '@/types/project';
|
2026-01-28 10:44:49 +00:00
|
|
|
|
|
|
|
|
interface ProjectListItemProps {
|
|
|
|
|
project: Project;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Función para generar iniciales
|
|
|
|
|
function getInitials(name: string): string {
|
|
|
|
|
return name
|
|
|
|
|
.split(' ')
|
|
|
|
|
.map(word => word[0])
|
|
|
|
|
.join('')
|
|
|
|
|
.toUpperCase()
|
|
|
|
|
.slice(0, 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Componente de fila de proyecto para vista de lista
|
|
|
|
|
* Diseño horizontal y compacto
|
|
|
|
|
*/
|
|
|
|
|
export default function ProjectListItem({ project }: ProjectListItemProps) {
|
|
|
|
|
const initials = getInitials(project.name);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Link href={`/proyectos/${project.id}`}>
|
2026-01-31 12:56:51 +00:00
|
|
|
<div className="bg-card border rounded-lg p-4 hover:shadow-md transition-all duration-300 cursor-pointer">
|
2026-01-28 10:44:49 +00:00
|
|
|
<div className="flex items-center gap-4">
|
|
|
|
|
{/* Avatar */}
|
|
|
|
|
<Avatar className="w-12 h-12 flex-shrink-0">
|
|
|
|
|
<AvatarFallback className="bg-gradient-to-br from-blue-500 to-purple-600 text-white font-semibold">
|
|
|
|
|
{initials}
|
|
|
|
|
</AvatarFallback>
|
|
|
|
|
</Avatar>
|
|
|
|
|
|
|
|
|
|
{/* Info Principal */}
|
|
|
|
|
<div className="flex-1 min-w-0">
|
|
|
|
|
<div className="flex items-start justify-between gap-4">
|
|
|
|
|
<div className="flex-1">
|
|
|
|
|
<div className="flex items-center gap-2 mb-1">
|
2026-01-31 12:56:51 +00:00
|
|
|
<h3 className="text-base font-semibold truncate">
|
2026-01-28 10:44:49 +00:00
|
|
|
{project.name}
|
|
|
|
|
</h3>
|
2026-01-31 12:56:51 +00:00
|
|
|
<span className="text-xs text-muted-foreground flex-shrink-0">{project.ref}</span>
|
2026-01-28 10:44:49 +00:00
|
|
|
</div>
|
|
|
|
|
{project.client !== 'Sin cliente' && (
|
2026-01-31 12:56:51 +00:00
|
|
|
<p className="text-sm text-muted-foreground truncate">{project.client}</p>
|
2026-01-28 10:44:49 +00:00
|
|
|
)}
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Estado */}
|
2026-01-31 12:56:51 +00:00
|
|
|
<ProjectStatusBadge status={project.status} />
|
2026-01-28 10:44:49 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Progreso */}
|
|
|
|
|
<div className="hidden md:flex items-center gap-2 flex-shrink-0 w-32">
|
2026-01-31 12:56:51 +00:00
|
|
|
<TrendingUp className="w-4 h-4 text-muted-foreground" />
|
2026-01-28 10:44:49 +00:00
|
|
|
<div className="flex-1">
|
|
|
|
|
<div className="flex items-center justify-between mb-1">
|
2026-01-31 12:56:51 +00:00
|
|
|
<span className="text-xs text-muted-foreground">Progreso</span>
|
|
|
|
|
<span className="text-xs font-semibold">{project.progress}%</span>
|
2026-01-28 10:44:49 +00:00
|
|
|
</div>
|
2026-01-31 12:56:51 +00:00
|
|
|
<div className="w-full bg-muted rounded-full h-1.5">
|
2026-01-28 10:44:49 +00:00
|
|
|
<div
|
|
|
|
|
className="bg-gradient-to-r from-blue-500 to-purple-600 h-1.5 rounded-full transition-all duration-500"
|
|
|
|
|
style={{ width: `${project.progress}%` }}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Presupuesto */}
|
|
|
|
|
<div className="hidden lg:flex items-center gap-2 flex-shrink-0">
|
|
|
|
|
<DollarSign className="w-4 h-4 text-green-500" />
|
|
|
|
|
<div className="text-right">
|
2026-01-31 12:56:51 +00:00
|
|
|
<div className="text-sm font-semibold">
|
2026-01-28 10:44:49 +00:00
|
|
|
€{project.budget.toLocaleString('es-ES', { minimumFractionDigits: 0, maximumFractionDigits: 0 })}
|
|
|
|
|
</div>
|
2026-01-31 12:56:51 +00:00
|
|
|
<div className="text-xs text-muted-foreground">Presupuesto</div>
|
2026-01-28 10:44:49 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Fechas */}
|
|
|
|
|
<div className="hidden xl:flex items-center gap-2 flex-shrink-0">
|
2026-01-31 12:56:51 +00:00
|
|
|
<Calendar className="w-4 h-4 text-muted-foreground" />
|
2026-01-28 10:44:49 +00:00
|
|
|
<div className="text-right">
|
2026-01-31 12:56:51 +00:00
|
|
|
<div className="text-sm">
|
2026-01-28 10:44:49 +00:00
|
|
|
{new Date(project.startDate).toLocaleDateString('es-ES', { day: '2-digit', month: 'short' })}
|
|
|
|
|
</div>
|
2026-01-31 12:56:51 +00:00
|
|
|
<div className="text-xs text-muted-foreground">Inicio</div>
|
2026-01-28 10:44:49 +00:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</Link>
|
|
|
|
|
);
|
|
|
|
|
}
|