Using react query with caching for github commits, added to profile

This commit is contained in:
austinkelsay 2024-09-21 14:45:45 -05:00
parent d6264ef4ac
commit f5748b4823
3 changed files with 47 additions and 31 deletions

View File

@ -1,12 +1,12 @@
import React, { useState, useEffect, useCallback } from 'react'; import React, { useState, useEffect, useCallback } from 'react';
import { getAllCommits } from '@/lib/github'; import { useFetchGithubCommits } from '@/hooks/githubQueries/useFetchGithubCommits';
import { Tooltip } from 'primereact/tooltip';
const GithubContributionChart = ({ username }) => { const GithubContributionChart = ({ username }) => {
const [contributionData, setContributionData] = useState({}); const [contributionData, setContributionData] = useState({});
const [loading, setLoading] = useState(true);
const [timeTaken, setTimeTaken] = useState(null);
const [totalCommits, setTotalCommits] = useState(0); const [totalCommits, setTotalCommits] = useState(0);
const { data: commits, isLoading, isFetching } = useFetchGithubCommits(username);
const getColor = useCallback((count) => { const getColor = useCallback((count) => {
if (count === 0) return 'bg-gray-100'; if (count === 0) return 'bg-gray-100';
if (count < 5) return 'bg-green-300'; if (count < 5) return 'bg-green-300';
@ -30,42 +30,35 @@ const GithubContributionChart = ({ username }) => {
}, [contributionData]); }, [contributionData]);
useEffect(() => { useEffect(() => {
const fetchData = async () => { if (commits) {
setLoading(true);
const startTime = Date.now();
const sixMonthsAgo = new Date();
sixMonthsAgo.setMonth(sixMonthsAgo.getMonth() - 6);
let commitCount = 0; let commitCount = 0;
for await (const commit of getAllCommits(username, sixMonthsAgo)) { const newContributionData = {};
commits.forEach(commit => {
const date = commit.commit.author.date.split('T')[0]; const date = commit.commit.author.date.split('T')[0];
setContributionData(prev => { newContributionData[date] = (newContributionData[date] || 0) + 1;
const newData = { ...prev };
newData[date] = (newData[date] || 0) + 1;
return newData;
});
commitCount++; commitCount++;
setTotalCommits(commitCount); });
}
setContributionData(newContributionData);
setTotalCommits(commitCount);
const endTime = Date.now();
setTimeTaken(((endTime - startTime) / 1000).toFixed(2));
setLoading(false);
console.log(`Total commits fetched: ${commitCount}`); console.log(`Total commits fetched: ${commitCount}`);
}; }
}, [commits]);
fetchData();
}, [username]);
const calendar = generateCalendar(); const calendar = generateCalendar();
return ( return (
<div className="p-4"> <div className="mx-auto py-2 px-4 max-w-[900px] bg-gray-900 rounded-lg">
<h2 className="text-xl font-bold mb-4">Github Contributions for {username}</h2> {(isLoading || isFetching) && <p>Loading contribution data... ({totalCommits} commits fetched)</p>}
{loading && <p>Loading contribution data... ({totalCommits} commits fetched)</p>} {!isLoading && !isFetching &&
{timeTaken && <p className="mb-2">Time taken to fetch data: {timeTaken} seconds</p>} <div className="flex justify-between items-center pr-1">
{!loading && <p className="mb-2">Total commits: {totalCommits}</p>} <p className="mb-2">Total commits: {totalCommits}</p>
<i className="pi pi-question-circle cursor-pointer" data-pr-tooltip="Total number of commits made to GitHub repositories over the last 6 months. (may not be 100% accurate)" />
<Tooltip target=".pi-question-circle" position="top"/>
</div>
}
<div className="flex flex-wrap gap-1"> <div className="flex flex-wrap gap-1">
{calendar.map((day, index) => ( {calendar.map((day, index) => (
<div <div

View File

@ -11,7 +11,7 @@ import { formatDateTime } from "@/utils/time";
import { Tooltip } from "primereact/tooltip"; import { Tooltip } from "primereact/tooltip";
import { nip19 } from "nostr-tools"; import { nip19 } from "nostr-tools";
import Image from "next/image"; import Image from "next/image";
import SubscribeModal from "@/components/profile/subscription/SubscribeModal"; import GithubContributionChart from "@/components/charts/GithubContributionChart";
import useWindowWidth from "@/hooks/useWindowWidth"; import useWindowWidth from "@/hooks/useWindowWidth";
import { useToast } from "@/hooks/useToast"; import { useToast } from "@/hooks/useToast";
import UserProgress from "@/components/profile/progress/UserProgress"; import UserProgress from "@/components/profile/progress/UserProgress";
@ -85,6 +85,7 @@ const UserProfile = () => {
<Tooltip target=".pubkey-tooltip" content={"this is your nostr npub"} /> <Tooltip target=".pubkey-tooltip" content={"this is your nostr npub"} />
{nip19.npubEncode(user.pubkey)} <i className="pi pi-question-circle text-xl pubkey-tooltip" /> {nip19.npubEncode(user.pubkey)} <i className="pi pi-question-circle text-xl pubkey-tooltip" />
</h2> </h2>
<GithubContributionChart username={"austinkelsay"} />
<UserProgress /> <UserProgress />
</div> </div>
{!session || !session?.user || !ndk ? ( {!session || !session?.user || !ndk ? (

View File

@ -0,0 +1,22 @@
import { useQuery } from '@tanstack/react-query';
import { getAllCommits } from '@/lib/github';
export function useFetchGithubCommits(username) {
const fetchCommits = async () => {
const sixMonthsAgo = new Date();
sixMonthsAgo.setMonth(sixMonthsAgo.getMonth() - 6);
const commits = [];
for await (const commit of getAllCommits(username, sixMonthsAgo)) {
commits.push(commit);
}
return commits;
};
return useQuery({
queryKey: ['githubCommits', username],
queryFn: fetchCommits,
staleTime: 1000 * 60 * 30, // 30 minutes
refetchInterval: 1000 * 60 * 30, // 30 minutes
});
}