diff --git a/app/segments/[id]/retention/page.tsx b/app/segments/[id]/retention/page.tsx
index 44dcb96..df22cf4 100644
--- a/app/segments/[id]/retention/page.tsx
+++ b/app/segments/[id]/retention/page.tsx
@@ -1,59 +1,25 @@
-"use client";
+import { useRouter } from "next/router";
+import { useEffect, useState } from "react";
+import { getRepositoryRetentionData } from "@/lib/services/repository-sublists-service";
+import { RepositoryActivityHeatmap } from "@/components/charts/repository-activity-heatmap";
-import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
-import { Skeleton } from "@/components/ui/skeleton";
-import { useSegment } from "@/lib/react-query/segments";
-import { use } from "react";
+const RetentionPage = () => {
+ const router = useRouter();
+ const { id } = router.query;
+ const [retentionData, setRetentionData] = useState([]);
-export default function RetentionPage({ params }: { params: Promise<{ id: string }> }) {
- const resolvedParams = use(params);
- const { data: segment, isLoading, error } = useSegment(resolvedParams.id);
+ useEffect(() => {
+ if (id) {
+ getRepositoryRetentionData(id).then((data) => setRetentionData(data));
+ }
+ }, [id]);
- if (isLoading) {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
-
- );
- }
+ return (
+
+
Repository Retention
+
+
+ );
+};
- if (error || !segment) {
- return (
-
-
- Error
- {error ? error.message : "Segment not found"}
-
-
- );
- }
-
- return (
-
-
- Retention Analysis
- Contributor retention metrics and analysis
-
-
- Retention analysis will be displayed here in a future update.
-
-
-
-
This feature is still under development
-
Retention analysis will show metrics about contributor engagement over time
-
-
-
-
- );
-}
+export default RetentionPage;
diff --git a/components/charts/repository-activity-heatmap.tsx b/components/charts/repository-activity-heatmap.tsx
new file mode 100644
index 0000000..d040f8c
--- /dev/null
+++ b/components/charts/repository-activity-heatmap.tsx
@@ -0,0 +1,30 @@
+import React from 'react';
+import { HeatMapGrid } from 'react-grid-heatmap';
+
+const RepositoryActivityHeatmap = ({ data }) => {
+ const months = [
+ 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
+ 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
+ ];
+
+ const repoNames = data.map((repo) => repo.repositoryName);
+ const heatmapData = data.map((repo) => repo.monthlyActivity);
+
+ return (
+
+
Repository Activity Heatmap
+ `${value} commits`}
+ cellStyle={(x, y, ratio) => ({
+ background: `rgba(0, 255, 0, ${ratio})`,
+ fontSize: '.8rem',
+ })}
+ />
+
+ );
+};
+
+export default RepositoryActivityHeatmap;
diff --git a/lib/services/repository-activity-service.ts b/lib/services/repository-activity-service.ts
new file mode 100644
index 0000000..10cd6b3
--- /dev/null
+++ b/lib/services/repository-activity-service.ts
@@ -0,0 +1,32 @@
+import { dbFactory } from "@/lib/drizzle";
+import { repositories } from "@/lib/drizzle/schema/repositories";
+import { sql } from "drizzle-orm";
+
+// Service to fetch repository activity data
+export async function getRepositoryActivityData() {
+ try {
+ const activityData = await dbFactory.getClient().execute(sql`
+ SELECT
+ r.name AS repository_name,
+ DATE_TRUNC('month', c.committed_at) AS month,
+ COUNT(c.id) AS commit_count
+ FROM
+ indexer_exp.github_commits c
+ JOIN
+ indexer_exp.github_repos r ON c.repo_id = r.id
+ GROUP BY
+ r.name, DATE_TRUNC('month', c.committed_at)
+ ORDER BY
+ r.name, DATE_TRUNC('month', c.committed_at)
+ `);
+
+ return activityData.map(row => ({
+ repositoryName: row.repository_name,
+ month: row.month,
+ commitCount: row.commit_count
+ }));
+ } catch (error) {
+ console.error("Error fetching repository activity data:", error);
+ return [];
+ }
+}