"use client"; import { useState, useCallback } from "react"; import { trpc } from "~/lib/trpc/client.js"; import { SuccessToast } from "~/components/ui/SuccessToast.js"; import { StaffingSearchForm } from "./StaffingSearchForm.js"; import { ScoringExplanation } from "./ScoringExplanation.js"; import { StaffingResultsList } from "./StaffingResultsList.js"; export function StaffingPanel() { const [requiredSkills, setRequiredSkills] = useState(["TypeScript", "React"]); const [startDate, setStartDate] = useState(() => { const d = new Date(); return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`; }); const [endDate, setEndDate] = useState(() => { const d = new Date(Date.now() + 90 * 24 * 60 * 60 * 1000); return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`; }); const [hoursPerDay, setHoursPerDay] = useState(8); const [submitted, setSubmitted] = useState(false); const [assignedIds, setAssignedIds] = useState>(new Set()); const [toast, setToast] = useState<{ show: boolean; message: string; variant: "success" | "warning" }>({ show: false, message: "", variant: "success", }); const clearToast = useCallback(() => setToast((t) => ({ ...t, show: false })), []); const { data: suggestions, isLoading } = trpc.staffing.getSuggestions.useQuery( { requiredSkills, startDate: new Date(startDate), endDate: new Date(endDate), hoursPerDay, }, { enabled: submitted }, ); const handleAssigned = useCallback((resourceId: string, resourceName: string) => { setAssignedIds((prev) => new Set(prev).add(resourceId)); setToast({ show: true, message: `${resourceName} assigned successfully`, variant: "success" }); }, []); const searchCriteria = { startDate, endDate, hoursPerDay }; return (
Staffing

Staffing Suggestions

Match open work with the strongest available people based on skills, availability, utilization, and cost.

How scoring works

CapaKraken blends skill fit, free capacity, cost, and current utilization. Add the must-have skills first, then narrow the date window to get cleaner results.

setSubmitted(true)} />
setToast({ show: true, message: msg, variant: "warning" })} />
); }