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 []; + } +}