62 lines · 2.4 KB
import { issueStateTone } from "~/ui/tones";
import { useHovercards } from "~/hooks/use-hovercards";
import type { HovercardProfile } from "~/hooks/use-hovercards";
import { Avatar } from "~/ui/Avatar";
import { Badge } from "~/ui/Badge";
import { panelClass } from "~/ui/Panel";

const JOINED_FORMAT = new Intl.DateTimeFormat(undefined, { month: "short", year: "numeric" });

function ProfileStats({ profile }: { profile: HovercardProfile }) {
  const stats = [
    { label: profile.followers === 1 ? "follower" : "followers", value: profile.followers },
    { label: profile.repos === 1 ? "repository" : "repositories", value: profile.repos },
  ];
  return (
    <div className="flex flex-wrap gap-x-3 gap-y-1 text-xs text-gray-500">
      {stats.map((stat) => (
        <span key={stat.label}>
          <span className="font-medium text-gray-300">{stat.value}</span> {stat.label}
        </span>
      ))}
      <span>Joined {JOINED_FORMAT.format(profile.joinedAt)}</span>
    </div>
  );
}

/** Floating preview for issue, user, team and commit references; mount once near the app root. */
export function HovercardLayer() {
  const state = useHovercards();
  if (!state) return null;
  const { card } = state;
  return (
    <div
      role="tooltip"
      data-hovercard-popup
      style={{ top: state.top, left: state.left }}
      className={panelClass(
        "animate-rise absolute z-50 w-80 space-y-1.5 bg-gray-950 p-3 text-sm shadow-2xl shadow-black/60",
      )}
    >