-
-
-
+
+
+
+
+
+ {groups.map((group) => (
+
+ ))}
+
);
@@ -45,34 +105,133 @@ function IssuesPage() {
return null;
}
+type IssueGroupData = {
+ id: string;
+ title: string;
+ icon: ComponentType<{ size?: number; strokeWidth?: number }>;
+ issues: MyIssuesResult[keyof MyIssuesResult];
+};
+
+const ISSUE_GROUP_STICKY_TOP = -32;
+
+function IssueMetricCard({
+ href,
+ icon: Icon,
+ label,
+ value,
+}: {
+ href: string;
+ icon: ComponentType<{ size?: number; strokeWidth?: number }>;
+ label: string;
+ value: number;
+}) {
+ const content = (
+ <>
+
+
{value}
+ >
+ );
+
+ if (value === 0) {
+ return (
+
+ {content}
+
+ );
+ }
+
+ return (
+
+ {content}
+
+ );
+}
+
function IssueGroup({
+ id,
title,
+ icon: Icon,
issues,
+ scrollContainerRef,
}: {
+ id: string;
title: string;
+ icon: ComponentType<{ size?: number; strokeWidth?: number }>;
issues: IssueSummary[];
+ scrollContainerRef: RefObject
;
}) {
+ const sectionRef = useRef(null);
+ const headerRef = useRef(null);
+ const [isStickyActive, setIsStickyActive] = useState(false);
+
+ useEffect(() => {
+ const scrollContainer = scrollContainerRef.current;
+ const section = sectionRef.current;
+ const header = headerRef.current;
+
+ if (!scrollContainer || !section || !header) {
+ return;
+ }
+
+ const updateStickyState = () => {
+ const scrollContainerRect = scrollContainer.getBoundingClientRect();
+ const sectionRect = section.getBoundingClientRect();
+ const stickyTop = scrollContainerRect.top + ISSUE_GROUP_STICKY_TOP;
+ const headerHeight = header.offsetHeight;
+ const isStuck =
+ sectionRect.top <= stickyTop &&
+ sectionRect.bottom > stickyTop + headerHeight;
+
+ setIsStickyActive((current) => (current === isStuck ? current : isStuck));
+ };
+
+ updateStickyState();
+ scrollContainer.addEventListener("scroll", updateStickyState, {
+ passive: true,
+ });
+ window.addEventListener("resize", updateStickyState);
+
+ return () => {
+ scrollContainer.removeEventListener("scroll", updateStickyState);
+ window.removeEventListener("resize", updateStickyState);
+ };
+ }, [scrollContainerRef]);
+
return (
-
-
-
{title}
-
{issues.length}
+
+
- {issues.length === 0 ? (
-
- No issues in this slice.
-
- ) : (
-
+ {issues.length > 0 && (
+
{issues.map((issue) => (
-
-
- #{issue.number} {issue.title}
-
-
- {issue.repository.fullName}
-
-
+
))}
)}