66 lines
4.3 KiB
TypeScript
Executable File
66 lines
4.3 KiB
TypeScript
Executable File
|
||
import React from 'react';
|
||
import { MOCK_CANDIDATES } from '../../constants';
|
||
import { Search, UserPlus, Phone, FileText, ChevronRight, MoreHorizontal } from 'lucide-react';
|
||
|
||
const STAGES = [
|
||
{ id: 'new', label: 'Новые', color: 'bg-slate-100 text-slate-500', border: 'border-slate-200' },
|
||
{ id: 'interview', label: 'Собеседование', color: 'bg-primary-50 text-primary-600', border: 'border-primary-200' },
|
||
{ id: 'offer', label: 'Оффер', color: 'bg-emerald-50 text-emerald-600', border: 'border-emerald-200' },
|
||
];
|
||
|
||
export const HiringPipeline: React.FC = () => {
|
||
return (
|
||
<div className="space-y-6 animate-fade-in">
|
||
{/* Stage Stats */}
|
||
<div className="flex justify-between items-center bg-white p-6 rounded-[2rem] border border-slate-200 shadow-sm overflow-hidden relative">
|
||
<div className="absolute top-0 right-0 p-8 opacity-5"><UserPlus className="w-24 h-24"/></div>
|
||
{STAGES.map((stage, idx) => {
|
||
const count = MOCK_CANDIDATES.filter(c => c.stage === stage.id).length;
|
||
return (
|
||
<React.Fragment key={stage.id}>
|
||
<div className="text-center px-4">
|
||
<p className="text-2xl font-black text-slate-800 leading-none">{count}</p>
|
||
<p className={`text-[9px] font-black uppercase mt-1.5 ${stage.color.split(' ')[1]}`}>{stage.label}</p>
|
||
</div>
|
||
{idx < STAGES.length - 1 && <div className="h-8 w-px bg-slate-100"/>}
|
||
</React.Fragment>
|
||
);
|
||
})}
|
||
</div>
|
||
|
||
{/* Candidate Cards */}
|
||
<div className="space-y-4">
|
||
<h3 className="font-black text-slate-500 text-[10px] uppercase tracking-[0.2em] px-1">Активные соискатели</h3>
|
||
{MOCK_CANDIDATES.map(cand => (
|
||
<div key={cand.id} className="bg-white p-5 rounded-[2rem] border border-slate-200 shadow-sm group hover:border-primary-300 transition-all flex flex-col md:flex-row justify-between gap-6">
|
||
<div className="flex items-center gap-4">
|
||
<div className={`p-4 rounded-2xl ${STAGES.find(s => s.id === cand.stage)?.color.split(' ')[0]}`}>
|
||
<UserPlus className={`w-7 h-7 ${STAGES.find(s => s.id === cand.stage)?.color.split(' ')[1]}`}/>
|
||
</div>
|
||
<div>
|
||
<div className="flex items-center gap-2 mb-0.5">
|
||
<h4 className="font-black text-slate-800 text-base leading-tight">{cand.name}</h4>
|
||
<span className={`text-[8px] font-black px-1.5 py-0.5 rounded-full uppercase ${STAGES.find(s => s.id === cand.stage)?.color}`}>
|
||
{STAGES.find(s => s.id === cand.stage)?.label}
|
||
</span>
|
||
</div>
|
||
<p className="text-[10px] text-slate-400 font-bold uppercase">{cand.position} • Тел: {cand.phone}</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="flex items-center justify-between md:justify-end gap-3 border-t md:border-t-0 border-slate-100 pt-4 md:pt-0">
|
||
<button className="p-2.5 bg-slate-50 text-slate-500 rounded-xl hover:bg-slate-100 transition-colors"><FileText className="w-5 h-5"/></button>
|
||
<button className="p-2.5 bg-slate-50 text-slate-500 rounded-xl hover:bg-slate-100 transition-colors"><Phone className="w-5 h-5"/></button>
|
||
<div className="h-10 w-px bg-slate-100 mx-1 hidden md:block" />
|
||
<button className="bg-slate-900 text-white px-5 py-2.5 rounded-xl text-[10px] font-black uppercase tracking-widest shadow-lg active:scale-95 transition-all">
|
||
{cand.stage === 'new' ? 'На собеседование' : cand.stage === 'interview' ? 'Сделать оффер' : 'Принять в штат'}
|
||
</button>
|
||
</div>
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
);
|
||
};
|