feat(planning): ship holiday-aware planning and assistant upgrades
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
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;
|
||||
@@ -12,34 +12,20 @@ interface ResourceHoverCardProps {
|
||||
}
|
||||
|
||||
export function ResourceHoverCard({ resourceId, anchorEl, onClose }: ResourceHoverCardProps) {
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const [pos, setPos] = useState({ left: 0, top: 0 });
|
||||
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 },
|
||||
);
|
||||
|
||||
// Position relative to anchor element
|
||||
useEffect(() => {
|
||||
const rect = anchorEl.getBoundingClientRect();
|
||||
setPos({
|
||||
left: rect.right + 8,
|
||||
top: Math.min(rect.top, window.innerHeight - 320),
|
||||
});
|
||||
}, [anchorEl]);
|
||||
|
||||
// Close on outside click
|
||||
useEffect(() => {
|
||||
function handleClick(e: MouseEvent) {
|
||||
if (ref.current && !ref.current.contains(e.target as Node) && !anchorEl.contains(e.target as Node)) {
|
||||
onClose();
|
||||
}
|
||||
}
|
||||
document.addEventListener("mousedown", handleClick);
|
||||
return () => document.removeEventListener("mousedown", handleClick);
|
||||
}, [onClose, anchorEl]);
|
||||
|
||||
const skills = (data?.skills ?? []) as unknown as SkillEntry[];
|
||||
const mainSkills = skills.filter((s) => s.isMainSkill);
|
||||
const topSkills = skills
|
||||
@@ -47,19 +33,11 @@ export function ResourceHoverCard({ resourceId, anchorEl, onClose }: ResourceHov
|
||||
.sort((a, b) => b.proficiency - a.proficiency)
|
||||
.slice(0, 6);
|
||||
|
||||
const popoverStyle: React.CSSProperties = {
|
||||
position: "fixed",
|
||||
left: Math.min(pos.left, window.innerWidth - 300),
|
||||
top: pos.top,
|
||||
zIndex: 50,
|
||||
width: 280,
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
data-resource-hover-card="true"
|
||||
style={popoverStyle}
|
||||
style={style}
|
||||
className="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-600 rounded-xl shadow-xl overflow-hidden"
|
||||
onMouseLeave={onClose}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user