"use client"; import { trpc } from "~/lib/trpc/client.js"; import { formatCents } from "~/lib/format.js"; import type { SkillEntry } from "@capakraken/shared"; import { useViewportPopover } from "~/hooks/useViewportPopover.js"; interface ResourceHoverCardProps { resourceId: string; anchorEl: HTMLElement; onClose: () => void; } export function ResourceHoverCard({ resourceId, anchorEl, onClose }: ResourceHoverCardProps) { const { ref, style } = useViewportPopover({ anchor: { kind: "element", element: anchorEl }, width: 280, estimatedHeight: 320, onClose, side: "right", ignoreElements: [anchorEl], }); const { data, isLoading } = trpc.resource.getHoverCard.useQuery( { id: resourceId }, { staleTime: 60_000 }, ); const skills = (data?.skills ?? []) as unknown as SkillEntry[]; const mainSkills = skills.filter((s) => s.isMainSkill); const topSkills = skills .filter((s) => !s.isMainSkill && s.proficiency >= 4) .sort((a, b) => b.proficiency - a.proficiency) .slice(0, 6); return (
{isLoading || !data ? (
Loading...
) : ( <> {/* Header */}
{data.displayName.slice(0, 2).toUpperCase()}
{data.displayName}
{data.eid}
{/* Role & Chapter */}
{data.areaRole && (
Role
{data.areaRole.color && ( )} {data.areaRole.name}
)} {data.chapter && (
Chapter
{data.chapter}
)} {data.country && (
Location
{data.country.name}
)} {data.managementLevel && (
Level
{data.managementLevel.name}
)}
{/* Rates */}
LCR
{formatCents(data.lcrCents)} {data.currency}/h
UCR
{formatCents(data.ucrCents)} {data.currency}/h
Chg%
{data.chargeabilityTarget}%
{/* Main Skills */} {mainSkills.length > 0 && (
Main Skills
{mainSkills.map((s) => ( {s.skill} ))}
)} {/* Top Skills */} {topSkills.length > 0 && (
Top Skills
{topSkills.map((s) => ( {s.skill} L{s.proficiency} ))}
)} {/* No skills */} {skills.length === 0 && (
No skills imported yet.
)}
)}
); }