Files
2026-06-12 16:08:49 -04:00

761 lines
35 KiB
TypeScript

"use client"
import { useState } from "react"
import { mockCandidates, mockRequisitions, mockUsers, pipelineStages } from "@/lib/mock-data"
import type { Candidate, PipelineStage } from "@/lib/types"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Badge } from "@/components/ui/badge"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
import { Label } from "@/components/ui/label"
import { Textarea } from "@/components/ui/textarea"
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuSeparator, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import {
Search,
Filter,
Plus,
MoreVertical,
Mail,
Phone,
Calendar,
Star,
ChevronRight,
FileText,
MessageSquare,
Clock,
CheckCircle2,
XCircle,
ArrowRight,
GripVertical,
User,
Briefcase,
MapPin,
DollarSign,
ThumbsUp,
ThumbsDown,
Eye,
Download,
Send,
Video,
Linkedin
} from "lucide-react"
import { cn } from "@/lib/utils"
export function RecruitmentPipelinePage() {
const [candidates, setCandidates] = useState<Candidate[]>(mockCandidates)
const [selectedRequisition, setSelectedRequisition] = useState<string>("all")
const [searchQuery, setSearchQuery] = useState("")
const [selectedCandidate, setSelectedCandidate] = useState<Candidate | null>(null)
const [isDetailOpen, setIsDetailOpen] = useState(false)
const [isAddCandidateOpen, setIsAddCandidateOpen] = useState(false)
const [draggedCandidate, setDraggedCandidate] = useState<Candidate | null>(null)
const [viewMode, setViewMode] = useState<"kanban" | "list">("kanban")
const activeRequisitions = mockRequisitions.filter(r => r.status === "approved" || r.status === "published")
const filteredCandidates = candidates.filter(candidate => {
const matchesRequisition = selectedRequisition === "all" || candidate.requisitionId === selectedRequisition
const matchesSearch = candidate.name.toLowerCase().includes(searchQuery.toLowerCase()) ||
candidate.email.toLowerCase().includes(searchQuery.toLowerCase()) ||
candidate.currentPosition?.toLowerCase().includes(searchQuery.toLowerCase())
return matchesRequisition && matchesSearch
})
const getCandidatesByStage = (stageId: string) => {
return filteredCandidates.filter(c => c.currentStage === stageId)
}
const handleDragStart = (candidate: Candidate) => {
setDraggedCandidate(candidate)
}
const handleDragOver = (e: React.DragEvent) => {
e.preventDefault()
}
const handleDrop = (stageId: string) => {
if (draggedCandidate) {
setCandidates(prev => prev.map(c =>
c.id === draggedCandidate.id
? { ...c, currentStage: stageId as PipelineStage }
: c
))
setDraggedCandidate(null)
}
}
const getStageColor = (stageId: string) => {
const colors: Record<string, string> = {
applied: "border-slate-300",
screening: "border-[var(--color-chart-1)]",
interview_rrhh: "border-[var(--color-chart-2)]",
interview_technical: "border-[var(--color-chart-3)]",
interview_manager: "border-[var(--color-chart-4)]",
offer: "border-[var(--color-status-recruiting)]",
hired: "border-[var(--color-status-closed)]",
rejected: "border-[var(--color-status-cancelled)]"
}
return colors[stageId] || "border-muted-foreground"
}
const getRatingStars = (rating: number) => {
return Array.from({ length: 5 }, (_, i) => (
<Star
key={i}
className={cn(
"h-3 w-3",
i < rating ? "fill-yellow-400 text-yellow-400" : "text-muted-foreground/30"
)}
/>
))
}
const getSourceBadge = (source: string) => {
const sourceConfig: Record<string, { label: string; className: string }> = {
linkedin: { label: "LinkedIn", className: "bg-[var(--color-chart-2)] text-white" },
referral: { label: "Referido", className: "bg-accent text-accent-foreground" },
job_board: { label: "Portal Empleo", className: "bg-primary text-primary-foreground" },
website: { label: "Web", className: "bg-secondary text-secondary-foreground" },
agency: { label: "Agencia", className: "bg-[var(--color-chart-1)] text-white" }
}
const config = sourceConfig[source] || { label: source, className: "bg-muted text-muted-foreground" }
return <Badge className={config.className}>{config.label}</Badge>
}
const openCandidateDetail = (candidate: Candidate) => {
setSelectedCandidate(candidate)
setIsDetailOpen(true)
}
const getRequisitionTitle = (requisitionId: string) => {
const requisition = mockRequisitions.find(r => r.id === requisitionId)
return requisition?.position || "Sin asignar"
}
return (
<div className="space-y-6">
{/* Header */}
<div className="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
<div>
<h1 className="text-3xl font-bold tracking-tight">Pipeline de Reclutamiento</h1>
<p className="text-muted-foreground">
Gestiona candidatos y su progreso en el proceso de seleccion
</p>
</div>
<Dialog open={isAddCandidateOpen} onOpenChange={setIsAddCandidateOpen}>
<DialogTrigger asChild>
<Button className="bg-accent hover:bg-accent/90 text-accent-foreground">
<Plus className="mr-2 h-4 w-4" />
Agregar Candidato
</Button>
</DialogTrigger>
<DialogContent className="max-w-2xl">
<DialogHeader>
<DialogTitle>Agregar Nuevo Candidato</DialogTitle>
<DialogDescription>
Ingresa la informacion del candidato para agregarlo al pipeline
</DialogDescription>
</DialogHeader>
<div className="grid gap-4 py-4">
<div className="grid grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="name">Nombre Completo</Label>
<Input id="name" placeholder="Juan Perez" />
</div>
<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<Input id="email" type="email" placeholder="juan@email.com" />
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="phone">Telefono</Label>
<Input id="phone" placeholder="+52 55 1234 5678" />
</div>
<div className="space-y-2">
<Label htmlFor="linkedin">LinkedIn</Label>
<Input id="linkedin" placeholder="linkedin.com/in/usuario" />
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="position">Posicion Actual</Label>
<Input id="position" placeholder="Ingeniero de Software" />
</div>
<div className="space-y-2">
<Label htmlFor="company">Empresa Actual</Label>
<Input id="company" placeholder="Empresa ABC" />
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="requisition">Vacante</Label>
<Select>
<SelectTrigger>
<SelectValue placeholder="Seleccionar vacante" />
</SelectTrigger>
<SelectContent>
{activeRequisitions.map(req => (
<SelectItem key={req.id} value={req.id}>
{req.position} - {req.department}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="space-y-2">
<Label htmlFor="source">Fuente</Label>
<Select>
<SelectTrigger>
<SelectValue placeholder="Seleccionar fuente" />
</SelectTrigger>
<SelectContent>
<SelectItem value="linkedin">LinkedIn</SelectItem>
<SelectItem value="referral">Referido</SelectItem>
<SelectItem value="job_board">Portal de Empleo</SelectItem>
<SelectItem value="website">Sitio Web</SelectItem>
<SelectItem value="agency">Agencia</SelectItem>
</SelectContent>
</Select>
</div>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="space-y-2">
<Label htmlFor="salary">Expectativa Salarial</Label>
<Input id="salary" placeholder="$50,000 MXN" />
</div>
<div className="space-y-2">
<Label htmlFor="availability">Disponibilidad</Label>
<Select>
<SelectTrigger>
<SelectValue placeholder="Seleccionar" />
</SelectTrigger>
<SelectContent>
<SelectItem value="immediate">Inmediata</SelectItem>
<SelectItem value="2_weeks">2 Semanas</SelectItem>
<SelectItem value="1_month">1 Mes</SelectItem>
<SelectItem value="negotiable">Negociable</SelectItem>
</SelectContent>
</Select>
</div>
</div>
<div className="space-y-2">
<Label htmlFor="notes">Notas</Label>
<Textarea id="notes" placeholder="Notas adicionales sobre el candidato..." />
</div>
<div className="space-y-2">
<Label htmlFor="cv">CV / Resume</Label>
<Input id="cv" type="file" accept=".pdf,.doc,.docx" />
</div>
</div>
<DialogFooter>
<Button variant="outline" onClick={() => setIsAddCandidateOpen(false)}>
Cancelar
</Button>
<Button className="bg-accent hover:bg-accent/90" onClick={() => setIsAddCandidateOpen(false)}>
Agregar Candidato
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</div>
{/* Filters */}
<Card>
<CardContent className="p-4">
<div className="flex flex-col gap-4 md:flex-row md:items-center">
<div className="relative flex-1">
<Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
<Input
placeholder="Buscar candidatos por nombre, email o posicion..."
className="pl-10"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
/>
</div>
<Select value={selectedRequisition} onValueChange={setSelectedRequisition}>
<SelectTrigger className="w-full md:w-[280px]">
<SelectValue placeholder="Filtrar por vacante" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all">Todas las vacantes</SelectItem>
{activeRequisitions.map(req => (
<SelectItem key={req.id} value={req.id}>
{req.position} - {req.department}
</SelectItem>
))}
</SelectContent>
</Select>
<div className="flex gap-2">
<Button
variant={viewMode === "kanban" ? "default" : "outline"}
size="sm"
onClick={() => setViewMode("kanban")}
>
Kanban
</Button>
<Button
variant={viewMode === "list" ? "default" : "outline"}
size="sm"
onClick={() => setViewMode("list")}
>
Lista
</Button>
</div>
</div>
</CardContent>
</Card>
{/* Pipeline Stats */}
<div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-8 gap-3">
{pipelineStages.map(stage => {
const count = getCandidatesByStage(stage.id).length
return (
<div
key={stage.id}
className={`p-4 rounded-xl border bg-white ${getStageColor(stage.id)} border-t-4 shadow-sm flex flex-col justify-center`}
>
<div className="text-2xl font-bold mb-1 text-card-foreground">{count}</div>
<div className="text-sm font-medium text-muted-foreground">{stage.name}</div>
</div>
)
})}
</div>
{/* Kanban Board */}
{viewMode === "kanban" ? (
<div className="flex gap-4 overflow-x-auto pb-4">
{pipelineStages.filter(s => s.id !== "rejected").map(stage => {
const columnCandidates = getCandidatesByStage(stage.id)
return (
<div
key={stage.id}
className="flex-shrink-0 w-[300px]"
onDragOver={handleDragOver}
onDrop={() => handleDrop(stage.id)}
>
<div className={`flex flex-col h-full min-h-[500px] rounded-lg border bg-white ${getStageColor(stage.id)} border-t-4`}>
<div className="flex items-center justify-between p-3 border-b border-border/50">
<h3 className="font-semibold text-sm text-card-foreground">
{stage.name}
</h3>
<Badge variant="secondary" className="bg-muted text-muted-foreground">{columnCandidates.length}</Badge>
</div>
<div className="space-y-3 p-3 max-h-[600px] overflow-y-auto">
{columnCandidates.map(candidate => (
<Card
key={candidate.id}
className="cursor-pointer hover:shadow-md transition-shadow"
draggable
onDragStart={() => handleDragStart(candidate)}
onClick={() => openCandidateDetail(candidate)}
>
<CardContent className="p-3">
<div className="flex items-start gap-3">
<Avatar className="h-10 w-10">
<AvatarImage src={candidate.avatar} />
<AvatarFallback className="bg-primary/10 text-primary">
{candidate.name.split(" ").map(n => n[0]).join("")}
</AvatarFallback>
</Avatar>
<div className="flex-1 min-w-0">
<div className="flex items-center gap-2">
<h4 className="font-medium text-sm truncate">{candidate.name}</h4>
<GripVertical className="h-3 w-3 text-muted-foreground/50" />
</div>
<p className="text-xs text-muted-foreground truncate">
{candidate.currentPosition}
</p>
<div className="flex items-center gap-1 mt-1">
{getRatingStars(candidate.rating || 0)}
</div>
</div>
</div>
<div className="flex items-center justify-between mt-3">
{getSourceBadge(candidate.source)}
<span className="text-xs text-muted-foreground">
{new Date(candidate.appliedDate).toLocaleDateString("es-MX", {
day: "numeric",
month: "short"
})}
</span>
</div>
</CardContent>
</Card>
))}
{columnCandidates.length === 0 && (
<div className="text-center py-8 text-muted-foreground text-sm">
Sin candidatos
</div>
)}
</div>
</div>
</div>
)})}
</div>
) : (
/* List View */
<Card>
<CardContent className="p-0">
<div className="overflow-x-auto">
<table className="w-full">
<thead>
<tr className="border-b bg-muted/50">
<th className="text-left p-4 font-medium">Candidato</th>
<th className="text-left p-4 font-medium">Vacante</th>
<th className="text-left p-4 font-medium">Etapa</th>
<th className="text-left p-4 font-medium">Fuente</th>
<th className="text-left p-4 font-medium">Rating</th>
<th className="text-left p-4 font-medium">Fecha</th>
<th className="text-right p-4 font-medium">Acciones</th>
</tr>
</thead>
<tbody>
{filteredCandidates.map(candidate => {
const stage = pipelineStages.find(s => s.id === candidate.currentStage)
return (
<tr
key={candidate.id}
className="border-b hover:bg-muted/30 cursor-pointer"
onClick={() => openCandidateDetail(candidate)}
>
<td className="p-4">
<div className="flex items-center gap-3">
<Avatar className="h-9 w-9">
<AvatarImage src={candidate.avatar} />
<AvatarFallback className="bg-primary/10 text-primary text-xs">
{candidate.name.split(" ").map(n => n[0]).join("")}
</AvatarFallback>
</Avatar>
<div>
<div className="font-medium">{candidate.name}</div>
<div className="text-sm text-muted-foreground">{candidate.email}</div>
</div>
</div>
</td>
<td className="p-4">
<span className="text-sm">{getRequisitionTitle(candidate.requisitionId)}</span>
</td>
<td className="p-4">
<Badge variant="outline" className={cn("border", getStageColor(candidate.currentStage))}>
{stage?.name}
</Badge>
</td>
<td className="p-4">
{getSourceBadge(candidate.source)}
</td>
<td className="p-4">
<div className="flex items-center gap-1">
{getRatingStars(candidate.rating || 0)}
</div>
</td>
<td className="p-4">
<span className="text-sm text-muted-foreground">
{new Date(candidate.appliedDate).toLocaleDateString("es-MX")}
</span>
</td>
<td className="p-4 text-right">
<DropdownMenu>
<DropdownMenuTrigger asChild onClick={(e) => e.stopPropagation()}>
<Button variant="ghost" size="icon">
<MoreVertical className="h-4 w-4" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem>
<Eye className="mr-2 h-4 w-4" />
Ver Perfil
</DropdownMenuItem>
<DropdownMenuItem>
<Mail className="mr-2 h-4 w-4" />
Enviar Email
</DropdownMenuItem>
<DropdownMenuItem>
<Calendar className="mr-2 h-4 w-4" />
Agendar Entrevista
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem>
<ArrowRight className="mr-2 h-4 w-4" />
Mover a siguiente etapa
</DropdownMenuItem>
<DropdownMenuItem className="text-destructive">
<XCircle className="mr-2 h-4 w-4" />
Rechazar
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</td>
</tr>
)
})}
</tbody>
</table>
</div>
</CardContent>
</Card>
)}
{/* Candidate Detail Dialog */}
<Dialog open={isDetailOpen} onOpenChange={setIsDetailOpen}>
<DialogContent className="max-w-4xl max-h-[90vh] overflow-y-auto">
{selectedCandidate && (
<>
<DialogHeader>
<div className="flex items-start gap-4">
<Avatar className="h-16 w-16">
<AvatarImage src={selectedCandidate.avatar} />
<AvatarFallback className="bg-primary/10 text-primary text-xl">
{selectedCandidate.name.split(" ").map(n => n[0]).join("")}
</AvatarFallback>
</Avatar>
<div className="flex-1">
<DialogTitle className="text-xl">{selectedCandidate.name}</DialogTitle>
<DialogDescription className="mt-1">
{selectedCandidate.currentPosition} en {selectedCandidate.currentCompany}
</DialogDescription>
<div className="flex items-center gap-3 mt-2">
{getSourceBadge(selectedCandidate.source)}
<Badge variant="outline">
{pipelineStages.find(s => s.id === selectedCandidate.currentStage)?.name}
</Badge>
<div className="flex items-center gap-1">
{getRatingStars(selectedCandidate.rating || 0)}
</div>
</div>
</div>
<div className="flex gap-2">
<Button variant="outline" size="icon">
<Linkedin className="h-4 w-4" />
</Button>
<Button variant="outline" size="icon">
<Mail className="h-4 w-4" />
</Button>
<Button variant="outline" size="icon">
<Phone className="h-4 w-4" />
</Button>
</div>
</div>
</DialogHeader>
<Tabs defaultValue="info" className="mt-4">
<TabsList className="grid w-full grid-cols-4">
<TabsTrigger value="info">Informacion</TabsTrigger>
<TabsTrigger value="timeline">Timeline</TabsTrigger>
<TabsTrigger value="evaluations">Evaluaciones</TabsTrigger>
<TabsTrigger value="documents">Documentos</TabsTrigger>
</TabsList>
<TabsContent value="info" className="space-y-4 mt-4">
<div className="grid grid-cols-2 gap-4">
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-sm">Contacto</CardTitle>
</CardHeader>
<CardContent className="space-y-2">
<div className="flex items-center gap-2 text-sm">
<Mail className="h-4 w-4 text-muted-foreground" />
{selectedCandidate.email}
</div>
<div className="flex items-center gap-2 text-sm">
<Phone className="h-4 w-4 text-muted-foreground" />
{selectedCandidate.phone}
</div>
{selectedCandidate.linkedin && (
<div className="flex items-center gap-2 text-sm">
<Linkedin className="h-4 w-4 text-muted-foreground" />
<a href={selectedCandidate.linkedin} className="text-primary hover:underline">
Ver perfil
</a>
</div>
)}
</CardContent>
</Card>
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-sm">Expectativas</CardTitle>
</CardHeader>
<CardContent className="space-y-2">
<div className="flex items-center gap-2 text-sm">
<DollarSign className="h-4 w-4 text-muted-foreground" />
{selectedCandidate.salaryExpectation || "No especificado"}
</div>
<div className="flex items-center gap-2 text-sm">
<Clock className="h-4 w-4 text-muted-foreground" />
Disponibilidad: {selectedCandidate.availability || "No especificada"}
</div>
</CardContent>
</Card>
</div>
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-sm">Vacante Aplicada</CardTitle>
</CardHeader>
<CardContent>
<div className="flex items-center justify-between">
<div>
<div className="font-medium">{getRequisitionTitle(selectedCandidate.requisitionId)}</div>
<div className="text-sm text-muted-foreground">
Aplicado el {new Date(selectedCandidate.appliedDate).toLocaleDateString("es-MX", {
day: "numeric",
month: "long",
year: "numeric"
})}
</div>
</div>
<Button variant="outline" size="sm">
Ver Requisicion
</Button>
</div>
</CardContent>
</Card>
{selectedCandidate.notes && (
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-sm">Notas</CardTitle>
</CardHeader>
<CardContent>
<p className="text-sm text-muted-foreground">{selectedCandidate.notes}</p>
</CardContent>
</Card>
)}
</TabsContent>
<TabsContent value="timeline" className="mt-4">
<Card>
<CardContent className="p-4">
<div className="space-y-4">
{selectedCandidate.history?.map((event, index) => (
<div key={index} className="flex gap-4">
<div className="flex flex-col items-center">
<div className={cn(
"w-8 h-8 rounded-full flex items-center justify-center",
event.type === "stage_change" && "bg-primary/10 text-primary",
event.type === "note" && "bg-secondary/10 text-secondary",
event.type === "interview" && "bg-accent/10 text-accent",
event.type === "evaluation" && "bg-blue-500/10 text-blue-500"
)}>
{event.type === "stage_change" && <ArrowRight className="h-4 w-4" />}
{event.type === "note" && <MessageSquare className="h-4 w-4" />}
{event.type === "interview" && <Video className="h-4 w-4" />}
{event.type === "evaluation" && <Star className="h-4 w-4" />}
</div>
{index < (selectedCandidate.history?.length || 0) - 1 && (
<div className="w-px h-full bg-border mt-2" />
)}
</div>
<div className="flex-1 pb-4">
<div className="flex items-center justify-between">
<h4 className="font-medium text-sm">{event.title}</h4>
<span className="text-xs text-muted-foreground">
{new Date(event.date).toLocaleDateString("es-MX")}
</span>
</div>
<p className="text-sm text-muted-foreground mt-1">{event.description}</p>
{event.user && (
<p className="text-xs text-muted-foreground mt-1">Por: {event.user}</p>
)}
</div>
</div>
))}
</div>
</CardContent>
</Card>
</TabsContent>
<TabsContent value="evaluations" className="mt-4">
<Card>
<CardContent className="p-4">
<div className="space-y-4">
{selectedCandidate.evaluations?.map((evaluation, index) => (
<Card key={index}>
<CardContent className="p-4">
<div className="flex items-start justify-between">
<div>
<h4 className="font-medium">{evaluation.stage}</h4>
<p className="text-sm text-muted-foreground">
Evaluado por {evaluation.evaluator} - {new Date(evaluation.date).toLocaleDateString("es-MX")}
</p>
</div>
<div className="flex items-center gap-2">
<Badge variant={evaluation.recommendation === "hire" ? "default" : evaluation.recommendation === "reject" ? "destructive" : "secondary"}>
{evaluation.recommendation === "hire" ? "Contratar" : evaluation.recommendation === "reject" ? "Rechazar" : "Continuar"}
</Badge>
<div className="flex items-center gap-1">
{getRatingStars(evaluation.score)}
</div>
</div>
</div>
<p className="text-sm mt-3">{evaluation.comments}</p>
</CardContent>
</Card>
)) || (
<div className="text-center py-8 text-muted-foreground">
No hay evaluaciones registradas
</div>
)}
</div>
</CardContent>
</Card>
</TabsContent>
<TabsContent value="documents" className="mt-4">
<Card>
<CardContent className="p-4">
<div className="space-y-3">
{selectedCandidate.documents?.map((doc, index) => (
<div key={index} className="flex items-center justify-between p-3 border rounded-lg">
<div className="flex items-center gap-3">
<div className="w-10 h-10 bg-primary/10 rounded-lg flex items-center justify-center">
<FileText className="h-5 w-5 text-primary" />
</div>
<div>
<div className="font-medium text-sm">{doc.name}</div>
<div className="text-xs text-muted-foreground">
Subido el {new Date(doc.uploadedAt).toLocaleDateString("es-MX")}
</div>
</div>
</div>
<Button variant="ghost" size="icon">
<Download className="h-4 w-4" />
</Button>
</div>
)) || (
<div className="text-center py-8 text-muted-foreground">
No hay documentos adjuntos
</div>
)}
</div>
</CardContent>
</Card>
</TabsContent>
</Tabs>
<DialogFooter className="gap-2 mt-4">
<Button variant="outline">
<XCircle className="mr-2 h-4 w-4" />
Rechazar
</Button>
<Button variant="outline">
<Calendar className="mr-2 h-4 w-4" />
Agendar Entrevista
</Button>
<Button className="bg-accent hover:bg-accent/90">
<ArrowRight className="mr-2 h-4 w-4" />
Siguiente Etapa
</Button>
</DialogFooter>
</>
)}
</DialogContent>
</Dialog>
</div>
)
}