import { useState } from 'react' import { Briefcase, Clock, PauseCircle, Plus, UserCheck, UserPlus, Users } from 'lucide-react' import { Link, useSearchParams } from 'react-router-dom' import { ToolHeader } from '../../components/ToolHeader' import { Modal, Panel } from '../../components/ui' import { useAuth } from '../../lib/useAuth' import { recruitBrand } from './brand' import { useClients } from './clientQueries' import { useClaimRequisition, useCreateRequisition, useRequisitions } from './requisitionQueries' import { PRIORITY_LABEL, STATUS_LABEL, priorityColor, rateRange, statusColor, targetText } from './statusUi' const chip = (on: boolean) => `rounded-full px-3 py-1 text-xs font-semibold transition ${ on ? 'bg-recruit/25 text-recruit shadow-[inset_0_0_0_1px_var(--color-recruit)]' : 'bg-navy-900 text-faint hover:text-muted border border-line/60' }` const inputCls = 'w-full rounded-lg border border-line/70 bg-navy-900 px-3 py-2 text-sm text-ink outline-none focus:border-recruit' export function Requisitions() { const { principal } = useAuth() // The client screen links here with ?client=. Reading it is what makes that link filter rather // than quietly showing every order in the organization. const [params, setParams] = useSearchParams() const clientFilter = params.get('client') ?? '' const [status, setStatus] = useState('active') const [owner, setOwner] = useState('') const [q, setQ] = useState('') const [open, setOpen] = useState(false) const list = useRequisitions({ client_id: clientFilter, status, owner, q }) const clients = useClients({}) const create = useCreateRequisition() const claim = useClaimRequisition() const [title, setTitle] = useState('') const [clientId, setClientId] = useState('') const [openings, setOpenings] = useState('1') const [priority, setPriority] = useState('normal') const [target, setTarget] = useState('') const [billMin, setBillMin] = useState('') const [billMax, setBillMax] = useState('') const submit = () => { create.mutate( { title, client_id: clientId, openings: Number(openings) || 1, priority, target_fill_date: target, bill_rate_min: billMin, bill_rate_max: billMax, }, { onSuccess: () => { setTitle('') setClientId('') setOpenings('1') setPriority('normal') setTarget('') setBillMin('') setBillMax('') setOpen(false) }, }, ) } const rows = list.data?.requisitions ?? [] return (
{/* Active means open plus on hold. A recruiter asking for their live roles does not mean to exclude the paused ones, and quietly dropping them would understate the desk. */} setQ(e.target.value)} placeholder="Search title or labor category" className={`${inputCls} ml-auto max-w-xs`} />
{clientFilter && (
Showing one client only{rows[0]?.client_name ? `: ${rows[0].client_name}` : ''}
)} {list.isError ? (

Could not load job orders. {(list.error as Error)?.message}

) : list.isLoading ? (

Loading job orders…

) : rows.length === 0 ? (

{owner === 'me' ? 'You are not working any job orders in this view.' : status === 'active' ? 'No live job orders. Open one against a client to start filling roles.' : 'Nothing matches this filter.'}

) : (
    {rows.map((r) => { const mine = !!r.owner_user_id && r.owner_user_id === principal?.user_id const t = targetText(r) const rate = rateRange(r.bill_rate_min, r.bill_rate_max) return (
  • {r.title} {STATUS_LABEL[r.status] ?? r.status} {r.priority !== 'normal' && r.priority !== 'low' && ( {PRIORITY_LABEL[r.priority]} )}

    {r.client_name || 'No client'} {r.openings} opening{r.openings === 1 ? '' : 's'} {/* Working days, not wall clock. Time the client had the order frozen is not time this team took to fill it. */} {r.working_days.toFixed(1)}d worked {r.held_days > 0 && ( {r.held_days.toFixed(1)}d held )} {rate && {rate}} {t && ( {t.text} )}

    {r.owner_user_id ? ( {mine ? 'You' : r.owner_name} ) : ( )}
  • ) })}
)}
setOpen(false)} title="New job order">

You will own this job order. It opens immediately and the clock starts now.

{create.isError &&

{(create.error as Error).message}

}
) }