From 268e74be3eefaa4d20e3ec2d8b3ae92aa67fc61c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ai-chan-0411=20=28=E8=97=8D=29?= Date: Sun, 12 Apr 2026 10:06:58 +0900 Subject: [PATCH] feat: make pull request titles clickable links to GitHub PR Add `title` and `url` fields to the GitHub GraphQL pullRequests query, pass them through the type system and scoring logic, and wrap PR titles in the TopList component with anchor tags linking to the GitHub PR page. Also fixes a pre-existing bug where PR titles incorrectly displayed the repository name instead of the actual pull request title. Closes #61 Co-Authored-By: Claude Opus 4.6 --- components/top-list.tsx | 12 +++++++++++- lib/github.ts | 2 ++ lib/score.ts | 5 +++-- types/github.ts | 2 ++ types/user-result.ts | 1 + 5 files changed, 19 insertions(+), 3 deletions(-) diff --git a/components/top-list.tsx b/components/top-list.tsx index d0740d9..a7c0baf 100644 --- a/components/top-list.tsx +++ b/components/top-list.tsx @@ -27,6 +27,7 @@ type Props = { export function TopList({ userResults }: Props) { const cardDetails = (data: { title: string; + url?: string; subtitle?: string; score?: number; badges: { tooltip?: string; label?: any; icon: any }[]; @@ -37,7 +38,15 @@ export function TopList({ userResults }: Props) { key={data.key} >
-
{data.title}
+
+ {data.url ? ( + + {data.title} + + ) : ( + data.title + )} +
{data.subtitle}
@@ -125,6 +134,7 @@ export function TopList({ userResults }: Props) { cardDetails({ key: `pr-${i}`, title: pr.title || "Untitled Pull Request", + url: pr.url, subtitle: `in ${pr.repo}`, score: pr.score, badges: [ diff --git a/lib/github.ts b/lib/github.ts index 4023aac..f70ef5c 100644 --- a/lib/github.ts +++ b/lib/github.ts @@ -36,6 +36,8 @@ const QUERY = /* GraphQL */ ` orderBy: { field: CREATED_AT, direction: DESC } ) { nodes { + title + url merged additions deletions diff --git a/lib/score.ts b/lib/score.ts index d62908d..0d3e340 100644 --- a/lib/score.ts +++ b/lib/score.ts @@ -89,7 +89,7 @@ export function calculateUserScore( contributionScore: number; finalScore: number; topRepos: { name: string; stars: number; forks: number; score: number }[]; - topPullRequests: { repo: string; stars: number; score: number }[]; + topPullRequests: { repo: string; title: string; url: string; stars: number; score: number }[]; } { const repoScore = calculateRepoScore(data.repos); const prScore = calculatePRScore(data.pullRequests, username); @@ -114,7 +114,8 @@ export function calculateUserScore( })), topPullRequests: prScore.details.slice(0, 3).map((item) => ({ repo: item.pr.repository.nameWithOwner, - title: item.pr.repository.nameWithOwner, + title: item.pr.title, + url: item.pr.url, stars: item.pr.repository.stargazerCount, score: item.score, additions: item.pr.additions, diff --git a/types/github.ts b/types/github.ts index 0a7ff56..80c8fda 100644 --- a/types/github.ts +++ b/types/github.ts @@ -7,6 +7,8 @@ export type RepoNode = { }; export type PullRequestNode = { + title: string; + url: string; merged: boolean; additions: number; deletions: number; diff --git a/types/user-result.ts b/types/user-result.ts index d972cf2..0f79652 100644 --- a/types/user-result.ts +++ b/types/user-result.ts @@ -16,6 +16,7 @@ export type UserResult = { stars?: number; score?: number; title?: string; + url?: string; deletions?: number; additions?: number; }[];