import React from 'react'; import { useNavigate } from 'react-router-dom'; import { motion } from 'framer-motion'; import { useJobPostings, useApplications, useStaff } from '@/lib/krowHooks'; import PipelineFunnel from '@/components/krow/PipelineFunnel'; import KROWCandidateLeaderboard from '@/components/krow/KROWCandidateLeaderboard'; import { Briefcase, Users, Brain, ClipboardCheck, UserCheck, BadgeCheck, Gauge, Plus, ChevronRight, Sparkles } from 'lucide-react'; import { AssistantTrigger } from '@/components/ai-assistant'; const METRICS = [ { icon: Briefcase, label: 'Open Positions', bg: 'bg-[#0A39DF]', glow: 'shadow-blue-600/20' }, { icon: Users, label: 'Applicants', bg: 'bg-[#333F48]', glow: 'shadow-slate-600/20' }, { icon: Brain, label: 'AI Screened', bg: 'bg-[#0A39DF]', glow: 'shadow-blue-600/20' }, { icon: ClipboardCheck, label: 'Shortlisted', bg: 'bg-[#F9E547]', glow: 'shadow-yellow-400/30' }, { icon: UserCheck, label: 'Hired', bg: 'bg-[#0A39DF]', glow: 'shadow-blue-600/20' }, { icon: BadgeCheck, label: 'Active Staff', bg: 'bg-[#333F48]', glow: 'shadow-slate-600/20' }, { icon: Gauge, label: 'Avg KROW Score', bg: 'bg-[#0A39DF]', glow: 'shadow-blue-600/20' }, { icon: Sparkles, label: 'AI Interviews', bg: 'bg-[#F9E547]', glow: 'shadow-yellow-400/30' }, ]; function MetricCard({ icon: Icon, value, label, bg, glow, index }) { const isYellow = bg === 'bg-[#F9E547]'; return (
{value}
{label}
); } export default function AdminDashboard() { const navigate = useNavigate(); const { data: postings = [] } = useJobPostings(); const { data: applications = [] } = useApplications(); const { data: staff = [] } = useStaff(); const openPositions = postings.filter(p => p.status === 'active'); const screened = applications.filter(a => ['ai_screened', 'shortlisted', 'interview', 'hired'].includes(a.status)); const shortlisted = applications.filter(a => ['shortlisted', 'interview', 'hired'].includes(a.status)); const hired = applications.filter(a => a.status === 'hired'); const activeStaff = staff.filter(s => s.status === 'active' || s.status === 'onboarding'); const scored = applications.filter(a => a.ai_score > 0); const avgScore = scored.length ? Math.round(scored.reduce((s, a) => s + a.ai_score, 0) / scored.length) : 0; const interviews = applications.filter(a => a.status === 'interview' || a.interview_id).length; const values = [ openPositions.length, applications.length, screened.length, shortlisted.length, hired.length, activeStaff.length, avgScore, interviews, ]; const statsForPosting = (id) => { const apps = applications.filter(a => a.job_posting_id === id); return { applied: apps.length, screened: apps.filter(a => a.status !== 'applied').length, hired: apps.filter(a => a.status === 'hired').length }; }; const recentStaff = [...activeStaff].sort((a, b) => new Date(b.hire_date || 0) - new Date(a.hire_date || 0)).slice(0, 6); return (
{/* Hero */}
Admin · Employer

Workforce Control Center

Full hiring pipeline, staffing & talent intelligence in one view

{/* Metrics */}
{METRICS.map((m, i) => ( ))}
{/* Pipeline funnel + Active positions */}

Active Positions

{openPositions.length === 0 && (

No active positions

)} {openPositions.slice(0, 6).map((p, idx) => { const s = statsForPosting(p.id); return ( navigate(`/positions/${p.id}`)} className="flex items-center gap-3 p-2.5 rounded-xl hover:bg-white/50 transition-colors cursor-pointer group">
{p.title}
{s.applied} applied · {s.screened} screened · {s.hired} hired
); })}
{/* Leaderboard + Active staff */}

Active Staff

{activeStaff.length} on roster
{recentStaff.length === 0 && (

No hired staff yet

)} {recentStaff.map((s, idx) => (
{s.name?.split(' ').map(w => w[0]).slice(0, 2).join('').toUpperCase()}
{s.name}
{s.role} · {s.profile_tier}
{s.status}
))}
); }