Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions src/app/api/metrics/contributions/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ interface ContributionResponse {
data: Record<string, number>;
}

function toLocalDateStr(d: Date): string {
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
}

function mergeContributionDays(
a: Record<string, number>,
b: Record<string, number>
Expand All @@ -39,7 +35,7 @@ async function fetchContributionsForAccount(
): Promise<ContributionResponse> {
const since = new Date();
since.setDate(since.getDate() - days);
const sinceStr = toLocalDateStr(since);
const sinceStr = since.toISOString().slice(0, 10);

const searchRes = await fetch(
`${GITHUB_API}/search/commits?q=author:${githubLogin}+author-date:>=${sinceStr}&per_page=100&sort=author-date&order=desc`,
Expand Down
4 changes: 2 additions & 2 deletions src/app/api/metrics/prs/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ async function fetchPRMetrics(token: string): Promise<PRMetricsBase> {

const data = (await searchRes.json()) as {
total_count: number;
items: Array<{ state: string; created_at: string; closed_at: string | null }>;
items: Array<{ state: string; created_at: string; closed_at: string | null; pull_request?: { merged_at: string | null } }>;
};

const open = data.items.filter((pr) => pr.state === "open").length;
const merged = data.items.filter((pr) => pr.state === "closed").length;
const merged = data.items.filter((pr) => pr.pull_request?.merged_at != null).length;

const closedPRs = data.items.filter((pr) => pr.closed_at);
const avgReviewMs =
Expand Down
36 changes: 36 additions & 0 deletions src/app/api/metrics/repos/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,42 @@ async function fetchReposForAccount(
repoMap[name] = (repoMap[name] ?? 0) + 1;
}

const linkHeader = searchRes.headers.get("link");
const pagePattern = /<[^>]*[?&]page=(\d+)[^>]*>;\s*rel="last"/;
const lastPageMatch = linkHeader?.match(pagePattern);
if (lastPageMatch) {
const lastPage = parseInt(lastPageMatch[1], 10);
const pagePromises: Promise<Response>[] = [];
for (let page = 2; page <= Math.min(lastPage, 5); page++) {
pagePromises.push(
fetch(
`${GITHUB_API}/search/commits?q=author:${githubLogin}+author-date:>=${sinceStr}&per_page=100&page=${page}&sort=author-date&order=desc`,
{
headers: {
Authorization: `Bearer ${token}`,
Accept: "application/vnd.github+json",
},
cache: "no-store",
}
)
);
}
const pageResults = await Promise.allSettled(pagePromises);
for (const res of pageResults) {
if (res.status !== "fulfilled" || !res.value.ok) continue;
const pageData = (await res.value.json()) as {
items: Array<{
repository: { full_name: string; html_url: string };
commit: { author: { date: string } };
}>;
};
for (const item of pageData.items) {
const name = item.repository.full_name;
repoMap[name] = (repoMap[name] ?? 0) + 1;
}
}
}

const repos = Object.entries(repoMap)
.map(([name, commits]) => ({ name, commits }))
.sort((a, b) => b.commits - a.commits)
Expand Down
32 changes: 32 additions & 0 deletions src/app/api/metrics/streak/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,38 @@ async function fetchActiveDates(
activeDates.add(item.commit.author.date.slice(0, 10));
}

const linkHeader = searchRes.headers.get("link");
const pagePattern = /<[^>]*[?&]page=(\d+)[^>]*>;\s*rel="last"/;
const lastPageMatch = linkHeader?.match(pagePattern);
if (lastPageMatch) {
const lastPage = parseInt(lastPageMatch[1], 10);
const pagePromises: Promise<Response>[] = [];
for (let page = 2; page <= Math.min(lastPage, 5); page++) {
pagePromises.push(
fetch(
`${GITHUB_API}/search/commits?q=author:${githubLogin}+author-date:>=${sinceStr}&per_page=100&page=${page}&sort=author-date&order=desc`,
{
headers: {
Authorization: `Bearer ${token}`,
Accept: "application/vnd.github+json",
},
cache: "no-store",
}
)
);
}
const pageResults = await Promise.allSettled(pagePromises);
for (const res of pageResults) {
if (res.status !== "fulfilled" || !res.value.ok) continue;
const pageData = (await res.value.json()) as {
items: Array<{ commit: { author: { date: string } } }>;
};
for (const item of pageData.items) {
activeDates.add(item.commit.author.date.slice(0, 10));
}
}
}

return activeDates;
}

Expand Down
8 changes: 4 additions & 4 deletions src/components/StreakTracker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -394,8 +394,8 @@ interface StreakCalendarProps {
onMonthChange: (date: Date) => void;
}

function toLocalDateStr(d: Date): string {
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
function toUtcDateStr(d: Date): string {
return d.toISOString().slice(0, 10);
}

function StreakCalendar({ contributions, currentMonth, onMonthChange }: StreakCalendarProps) {
Expand Down Expand Up @@ -463,10 +463,10 @@ function StreakCalendar({ contributions, currentMonth, onMonthChange }: StreakCa
return <div key={`empty-${idx}`} className="aspect-square" />;
}

const dateStr = toLocalDateStr(dayData.date);
const dateStr = toUtcDateStr(dayData.date);
const commitCount = contributions[dateStr] ?? 0;
const isFuture = dayData.date > today;
const isToday = dayData.date.toDateString() === today.toDateString();
const isToday = toUtcDateStr(dayData.date) === toUtcDateStr(today);

let bgColor = "bg-white dark:bg-transparent";
let borderColor = "border border-[var(--border)]";
Expand Down
Loading