From cf76456e86012589e4ced136d9fa5c96599f84f4 Mon Sep 17 00:00:00 2001 From: madjin <32600939+madjin@users.noreply.github.com> Date: Sat, 7 Jun 2025 23:16:53 -0400 Subject: [PATCH 1/4] update summary page --- .../[[...date]]/components/LeftSidebar.tsx | 204 ++++++++++++++++++ .../[[...date]]/components/MainContent.tsx | 144 +++++++++++++ .../[[...date]]/components/RightSidebar.tsx | 157 ++++++++++++++ .../[[...date]]/components/SummaryContent.tsx | 2 +- src/app/[interval]/[[...date]]/page.tsx | 62 ++++-- src/app/[interval]/[[...date]]/queries.ts | 1 + src/lib/pipelines/export/queries.ts | 13 ++ 7 files changed, 559 insertions(+), 24 deletions(-) create mode 100644 src/app/[interval]/[[...date]]/components/LeftSidebar.tsx create mode 100644 src/app/[interval]/[[...date]]/components/MainContent.tsx create mode 100644 src/app/[interval]/[[...date]]/components/RightSidebar.tsx diff --git a/src/app/[interval]/[[...date]]/components/LeftSidebar.tsx b/src/app/[interval]/[[...date]]/components/LeftSidebar.tsx new file mode 100644 index 00000000..c1157866 --- /dev/null +++ b/src/app/[interval]/[[...date]]/components/LeftSidebar.tsx @@ -0,0 +1,204 @@ +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +import { Badge } from "@/components/ui/badge"; +import type { IntervalMetrics } from "@/app/[interval]/[[...date]]/queries"; +import { Users, Star, TrendingUp } from "lucide-react"; +import Link from "next/link"; + +interface LeftSidebarProps { + metrics: IntervalMetrics; +} + +interface Contributor { + username: string; + totalScore: number; +} + +export function LeftSidebar({ metrics }: LeftSidebarProps) { + return ( + <> + {/* Top Contributors Card */} + + + + + Top Contributors + + + +
+ {metrics.topContributors + .slice(0, 5) + .map((contributor: Contributor, index) => ( + +
+ + + + {contributor.username[0].toUpperCase()} + + +
+

+ {contributor.username} +

+
+ + + {contributor.totalScore.toFixed(1)} pts + +
+
+
+ + #{index + 1} + + + ))} + {metrics.topContributors.length > 5 && ( +
+ +{metrics.topContributors.length - 5} more contributors +
+ )} +
+
+
+ + {/* Pull Requests Card */} + + + + + + + + + + Recent Pull Requests + + {metrics.pullRequests.total} + + + + +
+ {metrics.topPullRequests.slice(0, 10).map((pr, index) => ( +
+
+
+
+
+
+

+ #{pr.number} {pr.title} +

+
+ + by {pr.author} + + + {pr.mergedAt ? "merged" : "open"} + +
+
+
+
+ ))} + {metrics.topPullRequests.length > 10 && ( +
+ +{metrics.topPullRequests.length - 10} more pull requests +
+ )} +
+
+
+ + {/* Issues Card */} + + + + + + + + + Recent Issues + + {metrics.issues.total} + + + + +
+ {metrics.topIssues.slice(0, 10).map((issue, index) => ( +
+
+
+
+
+
+

+ #{issue.number} {issue.title} +

+
+ + by {issue.author} + + + {issue.state} + +
+
+
+
+ ))} + {metrics.topIssues.length > 10 && ( +
+ +{metrics.topIssues.length - 10} more issues +
+ )} +
+
+
+ + ); +} diff --git a/src/app/[interval]/[[...date]]/components/MainContent.tsx b/src/app/[interval]/[[...date]]/components/MainContent.tsx new file mode 100644 index 00000000..6d7cddf8 --- /dev/null +++ b/src/app/[interval]/[[...date]]/components/MainContent.tsx @@ -0,0 +1,144 @@ +import { StatCard } from "@/components/stat-card"; +import { CounterWithIcon } from "@/components/counter-with-icon"; +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +import type { IntervalMetrics } from "@/app/[interval]/[[...date]]/queries"; +import { + Users, + GitPullRequest, + MessageCircleWarning, + CircleDot, + GitMerge, + CheckCircle, +} from "lucide-react"; +import { formatTimeframeTitle } from "@/lib/date-utils"; +import { SummaryContent } from "./SummaryContent"; +import ContributorsListModalContent from "./ContributorsListModalContent"; +import PullRequestsListModalContent from "./PullRequestsListModalContent"; +import IssuesListModalContent from "./IssuesListModalContent"; + +interface MainContentProps { + metrics: IntervalMetrics; + summaryContent: string | null; +} + +interface Contributor { + username: string; + totalScore: number; +} + +export function MainContent({ metrics, summaryContent }: MainContentProps) { + const timeframeTitle = formatTimeframeTitle( + metrics.interval.intervalStart, + metrics.interval.intervalType, + ); + + return ( +
+ {/* Main Statistics Cards */} +
+ + } + > +
+
+ {metrics.activeContributors} +
+
+ {metrics.topContributors + .slice(0, 3) + .map((contributor: Contributor) => ( + + + + {contributor.username[0].toUpperCase()} + + + ))} + {metrics.topContributors.length > 3 && ( +
+ +{metrics.topContributors.length - 3} +
+ )} +
+
+
+ + + } + > +
+
+ {metrics.pullRequests.total} +
+
+ + +
+
+
+ + } + > +
+
{metrics.issues.total}
+
+ + +
+
+
+
+ + +
+ ); +} diff --git a/src/app/[interval]/[[...date]]/components/RightSidebar.tsx b/src/app/[interval]/[[...date]]/components/RightSidebar.tsx new file mode 100644 index 00000000..0956eb0c --- /dev/null +++ b/src/app/[interval]/[[...date]]/components/RightSidebar.tsx @@ -0,0 +1,157 @@ +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; +import { Badge } from "@/components/ui/badge"; +import type { IntervalMetrics } from "@/app/[interval]/[[...date]]/queries"; +import { + GitCommitVertical, + FileCode, + ArrowUp, + ArrowDown, + Folder, + Target, +} from "lucide-react"; + +interface RightSidebarProps { + metrics: IntervalMetrics; +} + +export function RightSidebar({ metrics }: RightSidebarProps) { + const { codeChanges, focusAreas } = metrics; + + // Calculate percentage for the commit activity bar + const totalChanges = codeChanges.additions + codeChanges.deletions; + const additionPercentage = + totalChanges > 0 ? (codeChanges.additions / totalChanges) * 100 : 50; + + return ( + <> + + + + + Code Activity + + + + {/* Commit Volume Visualization */} +
+
+ Volume + + {codeChanges.commitCount} commits + +
+
+
+
+
+ +{codeChanges.additions.toLocaleString()} + -{codeChanges.deletions.toLocaleString()} +
+
+ + {/* Code Stats */} +
+
+
+ +
+
+
+ +{codeChanges.additions.toLocaleString()} +
+
Added
+
+
+
+
+ +
+
+
+ -{codeChanges.deletions.toLocaleString()} +
+
Deleted
+
+
+
+ +
+ + + {codeChanges.files} files changed + +
+ + {/* Top Files Changed - Compact */} + {metrics.topFilesChanged && metrics.topFilesChanged.length > 0 && ( +
+ {metrics.topFilesChanged.slice(0, 6).map((file, index) => ( +
+ + {file.path.split("/").pop() || file.path} + +
+ + +{file.additions} + + + -{file.deletions} + +
+
+ ))} +
+ )} + + + + {/* Focus Areas */} + {focusAreas && focusAreas.length > 0 && ( + + + + + Focus Areas + + + +
+ {focusAreas.slice(0, 8).map((focusArea, index) => ( +
+
+ + + {focusArea.area} + +
+ + {focusArea.count} + +
+ ))} + {focusAreas.length > 8 && ( +
+ +{focusAreas.length - 8} more areas +
+ )} +
+
+
+ )} + + ); +} diff --git a/src/app/[interval]/[[...date]]/components/SummaryContent.tsx b/src/app/[interval]/[[...date]]/components/SummaryContent.tsx index aa87d569..97cc21f3 100644 --- a/src/app/[interval]/[[...date]]/components/SummaryContent.tsx +++ b/src/app/[interval]/[[...date]]/components/SummaryContent.tsx @@ -29,7 +29,7 @@ const remarkRemoveFirstH1 = () => { // Custom H2 component to apply primary color const CustomH2 = (props: HTMLProps) => { - return

; + return

; }; interface SummaryContentProps { diff --git a/src/app/[interval]/[[...date]]/page.tsx b/src/app/[interval]/[[...date]]/page.tsx index ae51a81a..48872dd9 100644 --- a/src/app/[interval]/[[...date]]/page.tsx +++ b/src/app/[interval]/[[...date]]/page.tsx @@ -16,11 +16,11 @@ import { import { UTCDate } from "@date-fns/utc"; import { addDays } from "date-fns"; import { DateNavigation } from "./components/DateNavigation"; -import { SummaryContent } from "./components/SummaryContent"; -import { StatCardsDisplay } from "./components/StatCardsDisplay"; -import { CodeChangesDisplay } from "./components/CodeChangesDisplay"; import { LlmCopyButton } from "@/components/ui/llm-copy-button"; import { IntervalSelector } from "./components/IntervalSelector"; +import { LeftSidebar } from "./components/LeftSidebar"; +import { MainContent } from "./components/MainContent"; +import { RightSidebar } from "./components/RightSidebar"; interface PageProps { params: Promise<{ @@ -124,27 +124,43 @@ export default async function IntervalSummaryPage({ params }: PageProps) { ); return ( -
-
-
- - - +
+
+
+
+ + + +
+ + +
+ {/* LEFT SIDEBAR */} +
+ +
+ + {/* MAIN CONTENT */} +
+ +
+ + {/* RIGHT SIDEBAR */} +
+ +
+
- - -
- - -
-
); diff --git a/src/app/[interval]/[[...date]]/queries.ts b/src/app/[interval]/[[...date]]/queries.ts index 58e1d2bc..ac7a47f5 100644 --- a/src/app/[interval]/[[...date]]/queries.ts +++ b/src/app/[interval]/[[...date]]/queries.ts @@ -180,6 +180,7 @@ export async function getMetricsForInterval( codeChanges: repoMetrics.codeChanges, topContributors: repoMetrics.topContributors, focusAreas: repoMetrics.focusAreas, + topFilesChanged: repoMetrics.topFilesChanged, topIssues, topPullRequests, detailedContributorSummaries, // Add the new field here diff --git a/src/lib/pipelines/export/queries.ts b/src/lib/pipelines/export/queries.ts index 478d1931..38199fc1 100644 --- a/src/lib/pipelines/export/queries.ts +++ b/src/lib/pipelines/export/queries.ts @@ -283,6 +283,18 @@ export async function getProjectMetrics(params: QueryParams = {}) { .sort((a, b) => b.count - a.count) .slice(0, 10); + // Get top files changed (by total changes: additions + deletions) + const topFilesChanged = prFiles + .map((file) => ({ + path: file.path, + additions: file.additions || 0, + deletions: file.deletions || 0, + totalChanges: (file.additions || 0) + (file.deletions || 0), + })) + .filter((file) => file.totalChanges > 0) + .sort((a, b) => b.totalChanges - a.totalChanges) + .slice(0, 10); + // Get completed items (PRs merged in this period) const completedItems = mergedPRsThisPeriod.map((pr) => ({ title: pr.title, @@ -299,6 +311,7 @@ export async function getProjectMetrics(params: QueryParams = {}) { topContributors, codeChanges, focusAreas, + topFilesChanged, completedItems, }; } From 217ce3d098db4cf764515f0e1574e9a83f2cc040 Mon Sep 17 00:00:00 2001 From: madjin <32600939+madjin@users.noreply.github.com> Date: Sun, 8 Jun 2025 00:31:25 -0400 Subject: [PATCH 2/4] update daily summary page --- .../[[...date]]/components/LeftSidebar.tsx | 397 ++++++++++-------- .../[[...date]]/components/MainContent.tsx | 2 + .../[[...date]]/components/RightSidebar.tsx | 58 +-- .../components/SummaryContent.skeleton.tsx | 2 +- .../[[...date]]/components/SummaryContent.tsx | 2 +- src/app/[interval]/[[...date]]/page.tsx | 19 +- 6 files changed, 278 insertions(+), 202 deletions(-) diff --git a/src/app/[interval]/[[...date]]/components/LeftSidebar.tsx b/src/app/[interval]/[[...date]]/components/LeftSidebar.tsx index c1157866..157c6072 100644 --- a/src/app/[interval]/[[...date]]/components/LeftSidebar.tsx +++ b/src/app/[interval]/[[...date]]/components/LeftSidebar.tsx @@ -1,9 +1,23 @@ +"use client"; + import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Badge } from "@/components/ui/badge"; +import { ScrollArea } from "@/components/ui/scroll-area"; +import { + Dialog, + DialogContent, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; import type { IntervalMetrics } from "@/app/[interval]/[[...date]]/queries"; import { Users, Star, TrendingUp } from "lucide-react"; import Link from "next/link"; +import PullRequestsListModalContent from "./PullRequestsListModalContent"; +import IssuesListModalContent from "./IssuesListModalContent"; +import ContributorsListModalContent from "./ContributorsListModalContent"; +import { formatTimeframeTitle } from "@/lib/date-utils"; interface LeftSidebarProps { metrics: IntervalMetrics; @@ -15,190 +29,237 @@ interface Contributor { } export function LeftSidebar({ metrics }: LeftSidebarProps) { + const timeframeTitle = formatTimeframeTitle( + metrics.interval.intervalStart, + metrics.interval.intervalType, + ); + return ( <> {/* Top Contributors Card */} - - - - - Top Contributors - - - -
- {metrics.topContributors - .slice(0, 5) - .map((contributor: Contributor, index) => ( - -
- - - - {contributor.username[0].toUpperCase()} - - -
-

- {contributor.username} -

-
- - - {contributor.totalScore.toFixed(1)} pts - + + + + + + + Top Contributors + + + +
+ {metrics.topContributors + .slice(0, 5) + .map((contributor: Contributor, index) => ( + e.stopPropagation()} + > +
+ + + + {contributor.username[0].toUpperCase()} + + +
+

+ {contributor.username} +

+
+ + + {contributor.totalScore.toFixed(1)} pts + +
+
-
+ + #{index + 1} + + + ))} + {metrics.topContributors.length > 5 && ( +
+ +{metrics.topContributors.length - 5} more contributors
- - #{index + 1} - - - ))} - {metrics.topContributors.length > 5 && ( -
- +{metrics.topContributors.length - 5} more contributors + )}
- )} -
- - + + + + + + Contributors + + + + {/* Pull Requests Card */} - - - - - - - - - - Recent Pull Requests - - {metrics.pullRequests.total} - - - - -
- {metrics.topPullRequests.slice(0, 10).map((pr, index) => ( -
-
-
+ + + + + + + + + + + + Recent Pull Requests + + {metrics.pullRequests.total} + + + + + +
+ {metrics.topPullRequests.slice(0, 10).map((pr, index) => (
-
-
-

- #{pr.number} {pr.title} -

-
- - by {pr.author} - - - {pr.mergedAt ? "merged" : "open"} - + key={pr.id} + className="group rounded-lg border border-border/50 p-2 transition-colors hover:bg-muted/50" + > +
+
+
+
+
+

+ #{pr.number} {pr.title} +

+
+ + by {pr.author} + + + {pr.mergedAt ? "merged" : "open"} + +
+
+
-
+ ))} + {metrics.topPullRequests.length > 10 && ( +
+ +{metrics.topPullRequests.length - 10} more pull requests +
+ )}
-
- ))} - {metrics.topPullRequests.length > 10 && ( -
- +{metrics.topPullRequests.length - 10} more pull requests -
- )} -
- - + + + + + + + Pull Requests + + + + {/* Issues Card */} - - - - - - - - - Recent Issues - - {metrics.issues.total} - - - - -
- {metrics.topIssues.slice(0, 10).map((issue, index) => ( -
-
-
+ + + + + + + + + + + Recent Issues + + {metrics.issues.total} + + + + + +
+ {metrics.topIssues.slice(0, 10).map((issue, index) => (
-
-
-

- #{issue.number} {issue.title} -

-
- - by {issue.author} - - - {issue.state} - + key={issue.id} + className="group rounded-lg border border-border/50 p-2 transition-colors hover:bg-muted/50" + > +
+
+
+
+
+

+ #{issue.number} {issue.title} +

+
+ + by {issue.author} + + + {issue.state} + +
+
+
-
+ ))} + {metrics.topIssues.length > 10 && ( +
+ +{metrics.topIssues.length - 10} more issues +
+ )}
-
- ))} - {metrics.topIssues.length > 10 && ( -
- +{metrics.topIssues.length - 10} more issues -
- )} -
- - + + + + + + + Issues + + + + ); } diff --git a/src/app/[interval]/[[...date]]/components/MainContent.tsx b/src/app/[interval]/[[...date]]/components/MainContent.tsx index 6d7cddf8..9283f9fb 100644 --- a/src/app/[interval]/[[...date]]/components/MainContent.tsx +++ b/src/app/[interval]/[[...date]]/components/MainContent.tsx @@ -1,3 +1,5 @@ +"use client"; + import { StatCard } from "@/components/stat-card"; import { CounterWithIcon } from "@/components/counter-with-icon"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; diff --git a/src/app/[interval]/[[...date]]/components/RightSidebar.tsx b/src/app/[interval]/[[...date]]/components/RightSidebar.tsx index 0956eb0c..61bf370b 100644 --- a/src/app/[interval]/[[...date]]/components/RightSidebar.tsx +++ b/src/app/[interval]/[[...date]]/components/RightSidebar.tsx @@ -1,5 +1,7 @@ import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Badge } from "@/components/ui/badge"; +import { ScrollArea } from "@/components/ui/scroll-area"; +import { Progress } from "@/components/ui/progress"; import type { IntervalMetrics } from "@/app/[interval]/[[...date]]/queries"; import { GitCommitVertical, @@ -40,12 +42,14 @@ export function RightSidebar({ metrics }: RightSidebarProps) { {codeChanges.commitCount} commits
-
+
+
@@ -87,31 +91,33 @@ export function RightSidebar({ metrics }: RightSidebarProps) {
- {/* Top Files Changed - Compact */} + {/* Top Files Changed - Scrollable */} {metrics.topFilesChanged && metrics.topFilesChanged.length > 0 && ( -
- {metrics.topFilesChanged.slice(0, 6).map((file, index) => ( -
- +
+ {metrics.topFilesChanged.slice(0, 15).map((file, index) => ( +
- {file.path.split("/").pop() || file.path} - -
- - +{file.additions} - - - -{file.deletions} + + {file.path.split("/").pop() || file.path} +
+ + +{file.additions} + + + -{file.deletions} + +
-
- ))} -
+ ))} +
+ )} diff --git a/src/app/[interval]/[[...date]]/components/SummaryContent.skeleton.tsx b/src/app/[interval]/[[...date]]/components/SummaryContent.skeleton.tsx index 85d79695..9b421697 100644 --- a/src/app/[interval]/[[...date]]/components/SummaryContent.skeleton.tsx +++ b/src/app/[interval]/[[...date]]/components/SummaryContent.skeleton.tsx @@ -5,7 +5,7 @@ export function SummaryContentSkeleton({ className }: { className?: string }) { return (
diff --git a/src/app/[interval]/[[...date]]/components/SummaryContent.tsx b/src/app/[interval]/[[...date]]/components/SummaryContent.tsx index 97cc21f3..3673ecc2 100644 --- a/src/app/[interval]/[[...date]]/components/SummaryContent.tsx +++ b/src/app/[interval]/[[...date]]/components/SummaryContent.tsx @@ -48,7 +48,7 @@ export function SummaryContent({ return (
diff --git a/src/app/[interval]/[[...date]]/page.tsx b/src/app/[interval]/[[...date]]/page.tsx index 48872dd9..34ab14f6 100644 --- a/src/app/[interval]/[[...date]]/page.tsx +++ b/src/app/[interval]/[[...date]]/page.tsx @@ -125,9 +125,9 @@ export default async function IntervalSummaryPage({ params }: PageProps) { return (
-
+
-
+
-
+
{/* LEFT SIDEBAR */} -
+
{/* MAIN CONTENT */} -
+
- {/* RIGHT SIDEBAR */} + {/* RIGHT SIDEBAR - Hidden on md, shown on lg+ */} +
+ +
+
+ + {/* RIGHT SIDEBAR CONTENT FOR TABLET (md) - Shown below main content */} +
From b997c55453a913ec13511d2199ef09610941c596 Mon Sep 17 00:00:00 2001 From: madjin <32600939+madjin@users.noreply.github.com> Date: Sun, 8 Jun 2025 00:59:29 -0400 Subject: [PATCH 3/4] update interval page --- .../components/IssuesListModalContent.tsx | 1 + .../[[...date]]/components/LeftSidebar.tsx | 279 +++++++++--------- .../[[...date]]/components/MainContent.tsx | 2 - .../PullRequestsListModalContent.tsx | 1 + src/components/activity-item.tsx | 11 +- 5 files changed, 159 insertions(+), 135 deletions(-) diff --git a/src/app/[interval]/[[...date]]/components/IssuesListModalContent.tsx b/src/app/[interval]/[[...date]]/components/IssuesListModalContent.tsx index 0b448a35..937a851a 100644 --- a/src/app/[interval]/[[...date]]/components/IssuesListModalContent.tsx +++ b/src/app/[interval]/[[...date]]/components/IssuesListModalContent.tsx @@ -22,6 +22,7 @@ export default function IssuesListModalContent({ author={issue.author} number={issue.number} href={`https://github.com/${issue.repository}/issues/${issue.number}`} + allowTitleWrap={true} icon={ issue.state === "closed" || issue.closedAt ? ( diff --git a/src/app/[interval]/[[...date]]/components/LeftSidebar.tsx b/src/app/[interval]/[[...date]]/components/LeftSidebar.tsx index 157c6072..5c3c4f7d 100644 --- a/src/app/[interval]/[[...date]]/components/LeftSidebar.tsx +++ b/src/app/[interval]/[[...date]]/components/LeftSidebar.tsx @@ -12,7 +12,15 @@ import { DialogTrigger, } from "@/components/ui/dialog"; import type { IntervalMetrics } from "@/app/[interval]/[[...date]]/queries"; -import { Users, Star, TrendingUp } from "lucide-react"; +import { + Users, + Star, + TrendingUp, + CircleDot, + GitMerge, + CheckCircle, +} from "lucide-react"; +import { CounterWithIcon } from "@/components/counter-with-icon"; import Link from "next/link"; import PullRequestsListModalContent from "./PullRequestsListModalContent"; import IssuesListModalContent from "./IssuesListModalContent"; @@ -26,6 +34,7 @@ interface LeftSidebarProps { interface Contributor { username: string; totalScore: number; + summary?: string | null; } export function LeftSidebar({ metrics }: LeftSidebarProps) { @@ -43,56 +52,68 @@ export function LeftSidebar({ metrics }: LeftSidebarProps) { - Top Contributors + Contributors ({metrics.activeContributors}) - -
- {metrics.topContributors - .slice(0, 5) - .map((contributor: Contributor, index) => ( - e.stopPropagation()} - > -
- - - - {contributor.username[0].toUpperCase()} - - -
-

- {contributor.username} -

-
- - - {contributor.totalScore.toFixed(1)} pts - + + +
+ {metrics.topContributors + .slice(0, 10) + .map((contributor: Contributor, index) => ( + e.stopPropagation()} + > +
+ + + + {contributor.username[0].toUpperCase()} + + +
+
+

+ {contributor.username} +

+ + #{index + 1} + +
+
+ + + {contributor.totalScore.toFixed(1)} pts + +
+ {contributor.summary && ( +

+ {contributor.summary.replace( + `${contributor.username}: `, + "", + )} +

+ )}
-
- - #{index + 1} - - - ))} - {metrics.topContributors.length > 5 && ( -
- +{metrics.topContributors.length - 5} more contributors -
- )} -
+ + ))} + {metrics.topContributors.length > 10 && ( +
+ +{metrics.topContributors.length - 10} more contributors +
+ )} +
+ @@ -111,28 +132,41 @@ export function LeftSidebar({ metrics }: LeftSidebarProps) { - - - - - - - - Recent Pull Requests - - {metrics.pullRequests.total} - + +
+ + + + + + + Pull Requests ({metrics.pullRequests.new}) +
+
+
+ + + {metrics.pullRequests.new} + +
+
+ + + {metrics.pullRequests.merged} + +
+
@@ -141,28 +175,14 @@ export function LeftSidebar({ metrics }: LeftSidebarProps) { {metrics.topPullRequests.slice(0, 10).map((pr, index) => (
-
-
-
-
-
-

- #{pr.number} {pr.title} -

-
- - by {pr.author} - - - {pr.mergedAt ? "merged" : "open"} - -
-
-
+
+

+ #{pr.number} {pr.title} +

))} {metrics.topPullRequests.length > 10 && ( @@ -190,27 +210,36 @@ export function LeftSidebar({ metrics }: LeftSidebarProps) { - - - - - - - Recent Issues - - {metrics.issues.total} - + +
+ + + + + + Issues ({metrics.issues.new}) +
+
+
+ + {metrics.issues.new} +
+
+ + {metrics.issues.closed} +
+
@@ -219,28 +248,14 @@ export function LeftSidebar({ metrics }: LeftSidebarProps) { {metrics.topIssues.slice(0, 10).map((issue, index) => (
-
-
-
-
-
-

- #{issue.number} {issue.title} -

-
- - by {issue.author} - - - {issue.state} - -
-
-
+
+

+ #{issue.number} {issue.title} +

))} {metrics.topIssues.length > 10 && ( diff --git a/src/app/[interval]/[[...date]]/components/MainContent.tsx b/src/app/[interval]/[[...date]]/components/MainContent.tsx index 9283f9fb..6d7cddf8 100644 --- a/src/app/[interval]/[[...date]]/components/MainContent.tsx +++ b/src/app/[interval]/[[...date]]/components/MainContent.tsx @@ -1,5 +1,3 @@ -"use client"; - import { StatCard } from "@/components/stat-card"; import { CounterWithIcon } from "@/components/counter-with-icon"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; diff --git a/src/app/[interval]/[[...date]]/components/PullRequestsListModalContent.tsx b/src/app/[interval]/[[...date]]/components/PullRequestsListModalContent.tsx index 9f3902b8..76dd51e4 100644 --- a/src/app/[interval]/[[...date]]/components/PullRequestsListModalContent.tsx +++ b/src/app/[interval]/[[...date]]/components/PullRequestsListModalContent.tsx @@ -22,6 +22,7 @@ export default function PullRequestsListModalContent({ className="px-4" number={pr.number} href={`https://github.com/${pr.repository}/pull/${pr.number}`} + allowTitleWrap={true} icon={ pr.mergedAt ? ( diff --git a/src/components/activity-item.tsx b/src/components/activity-item.tsx index 846b0788..1d9d1ca0 100644 --- a/src/components/activity-item.tsx +++ b/src/components/activity-item.tsx @@ -12,6 +12,7 @@ interface ActivityItemProps { icon: React.ReactNode; metadata?: React.ReactNode; className?: string; + allowTitleWrap?: boolean; } export function ActivityItem({ @@ -23,6 +24,7 @@ export function ActivityItem({ icon, metadata, className, + allowTitleWrap = false, }: ActivityItemProps) { return (
-

{title}

+

+ {title} +

From 3fbe77d922d6f7722642867baac0548b0dcad0c7 Mon Sep 17 00:00:00 2001 From: madjin <32600939+madjin@users.noreply.github.com> Date: Sun, 8 Jun 2025 16:45:34 -0400 Subject: [PATCH 4/4] fix sidebars --- .../[[...date]]/components/LeftSidebar.tsx | 4 +- .../[[...date]]/components/RightSidebar.tsx | 164 +++++++++--------- src/lib/pipelines/export/queries.ts | 5 +- 3 files changed, 82 insertions(+), 91 deletions(-) diff --git a/src/app/[interval]/[[...date]]/components/LeftSidebar.tsx b/src/app/[interval]/[[...date]]/components/LeftSidebar.tsx index 5c3c4f7d..745dd781 100644 --- a/src/app/[interval]/[[...date]]/components/LeftSidebar.tsx +++ b/src/app/[interval]/[[...date]]/components/LeftSidebar.tsx @@ -170,7 +170,7 @@ export function LeftSidebar({ metrics }: LeftSidebarProps) { - +
{metrics.topPullRequests.slice(0, 10).map((pr, index) => (
- +
{metrics.topIssues.slice(0, 10).map((issue, index) => (
- {/* Code Stats */} -
-
-
- -
-
-
- +{codeChanges.additions.toLocaleString()} + + +
+
+ + + {codeChanges.files} files changed +
-
Added
-
-
-
- -
-
-
- -{codeChanges.deletions.toLocaleString()} -
-
Deleted
-
-
-
- -
- - - {codeChanges.files} files changed - -
- - {/* Top Files Changed - Scrollable */} - {metrics.topFilesChanged && metrics.topFilesChanged.length > 0 && ( - -
- {metrics.topFilesChanged.slice(0, 15).map((file, index) => ( -
- - {file.path.split("/").pop() || file.path} - -
- - +{file.additions} - - - -{file.deletions} - -
+ + + + + Files Changed ({metrics.topFilesChanged?.length || 0} of{" "} + {codeChanges.files}) + +

+ Sorted by most changes (additions + deletions) +

+
+ {metrics.topFilesChanged && metrics.topFilesChanged.length > 0 ? ( + +
+ {metrics.topFilesChanged.map((file, index) => ( +
+ + {file.path} + +
+ + +{file.additions} + + + -{file.deletions} + +
+
+ ))}
- ))} -
- - )} + + ) : ( +

+ No file changes to display. +

+ )} + + @@ -132,27 +127,24 @@ export function RightSidebar({ metrics }: RightSidebarProps) { -
- {focusAreas.slice(0, 8).map((focusArea, index) => ( -
-
- - - {focusArea.area} - -
- - {focusArea.count} - -
+
+ {focusAreas.slice(0, 10).map((focusArea, index) => ( + + {focusArea.area} + ))} - {focusAreas.length > 8 && ( -
- +{focusAreas.length - 8} more areas -
+ {focusAreas.length > 10 && ( + + +{focusAreas.length - 10} more + )}
diff --git a/src/lib/pipelines/export/queries.ts b/src/lib/pipelines/export/queries.ts index 38199fc1..4701300a 100644 --- a/src/lib/pipelines/export/queries.ts +++ b/src/lib/pipelines/export/queries.ts @@ -283,7 +283,7 @@ export async function getProjectMetrics(params: QueryParams = {}) { .sort((a, b) => b.count - a.count) .slice(0, 10); - // Get top files changed (by total changes: additions + deletions) + // Get all files changed (sorted by total changes: additions + deletions) const topFilesChanged = prFiles .map((file) => ({ path: file.path, @@ -292,8 +292,7 @@ export async function getProjectMetrics(params: QueryParams = {}) { totalChanges: (file.additions || 0) + (file.deletions || 0), })) .filter((file) => file.totalChanges > 0) - .sort((a, b) => b.totalChanges - a.totalChanges) - .slice(0, 10); + .sort((a, b) => b.totalChanges - a.totalChanges); // Get completed items (PRs merged in this period) const completedItems = mergedPRsThisPeriod.map((pr) => ({