diff --git a/src/components/charts/CombinedContributionChart.js b/src/components/charts/CombinedContributionChart.js index 1ef3c36..114c52b 100644 --- a/src/components/charts/CombinedContributionChart.js +++ b/src/components/charts/CombinedContributionChart.js @@ -1,31 +1,116 @@ import React, { useState, useCallback, useEffect } from 'react'; import { useFetchGithubCommits } from '@/hooks/githubQueries/useFetchGithubCommits'; import { Tooltip } from 'primereact/tooltip'; +import { formatDateTime } from "@/utils/time"; -const GithubContributionChart = ({ username }) => { +const CombinedContributionChart = ({ username, session }) => { const [contributionData, setContributionData] = useState({}); - const [totalCommits, setTotalCommits] = useState(0); + const [totalContributions, setTotalContributions] = useState(0); + + const prepareProgressData = useCallback(() => { + if (!session?.user?.userCourses) return {}; + + const activityData = {}; + const allActivities = []; // Array to store all activities for logging + + // Process course activities + session.user.userCourses.forEach(courseProgress => { + if (courseProgress.started) { + const startDate = new Date(courseProgress.startedAt); + startDate.setFullYear(new Date().getFullYear()); + const date = startDate.toISOString().split('T')[0]; + activityData[date] = (activityData[date] || 0) + 1; + allActivities.push({ + type: 'course_started', + name: courseProgress.course?.name, + date: date + }); + } + if (courseProgress.completed) { + const completeDate = new Date(courseProgress.completedAt); + completeDate.setFullYear(new Date().getFullYear()); + const date = completeDate.toISOString().split('T')[0]; + activityData[date] = (activityData[date] || 0) + 1; + allActivities.push({ + type: 'course_completed', + name: courseProgress.course?.name, + date: date + }); + } + }); + + // Process lesson activities + session.user.userLessons?.forEach(lessonProgress => { + if (lessonProgress.opened) { + const openDate = new Date(lessonProgress.openedAt); + openDate.setFullYear(new Date().getFullYear()); + const date = openDate.toISOString().split('T')[0]; + activityData[date] = (activityData[date] || 0) + 1; + allActivities.push({ + type: 'lesson_started', + name: lessonProgress.lesson?.name, + date: date + }); + } + if (lessonProgress.completed) { + const completeDate = new Date(lessonProgress.completedAt); + completeDate.setFullYear(new Date().getFullYear()); + const date = completeDate.toISOString().split('T')[0]; + activityData[date] = (activityData[date] || 0) + 1; + allActivities.push({ + type: 'lesson_completed', + name: lessonProgress.lesson?.name, + date: date + }); + } + }); + + console.log('All Learning Activities:', allActivities); + console.log('Activities by Date:', activityData); + + return activityData; + }, [session]); const handleNewCommit = useCallback(({ contributionData, totalCommits }) => { - setContributionData(contributionData); - setTotalCommits(totalCommits); - }, []); + const activityData = prepareProgressData(); + console.log("GitHub Contribution Data:", contributionData); + + // Create a new object with GitHub commits + const combinedData = { ...contributionData }; + + // Add activities to the combined data + Object.entries(activityData).forEach(([date, count]) => { + combinedData[date] = (combinedData[date] || 0) + count; + }); + + console.log("Combined Data:", combinedData); + setContributionData(combinedData); + setTotalContributions(totalCommits + Object.values(activityData).reduce((a, b) => a + b, 0)); + }, [prepareProgressData]); const { data, isLoading, isFetching } = useFetchGithubCommits(username, handleNewCommit); // Initialize from cached data if available useEffect(() => { if (data && !isLoading) { - setContributionData(data.contributionData); - setTotalCommits(data.totalCommits); + const activityData = prepareProgressData(); + const combinedData = { ...data.contributionData }; + + // Add activities to the combined data + Object.entries(activityData).forEach(([date, count]) => { + combinedData[date] = (combinedData[date] || 0) + count; + }); + + setContributionData(combinedData); + setTotalContributions(data.totalCommits + Object.values(activityData).reduce((a, b) => a + b, 0)); } - }, [data, isLoading]); + }, [data, isLoading, prepareProgressData]); const getColor = useCallback((count) => { if (count === 0) return 'bg-gray-100'; - if (count < 5) return 'bg-green-300'; - if (count < 10) return 'bg-green-400'; - if (count < 20) return 'bg-green-600'; + if (count < 3) return 'bg-green-300'; + if (count < 6) return 'bg-green-400'; + if (count < 12) return 'bg-green-600'; return 'bg-green-700'; }, []); @@ -42,13 +127,19 @@ const GithubContributionChart = ({ username }) => { // Fill in the dates for (let d = new Date(oneYearAgo); d <= today; d.setDate(d.getDate() + 1)) { const dateString = d.toISOString().split('T')[0]; - const count = contributionData[dateString] || 0; - const dayOfWeek = d.getDay(); - calendar[dayOfWeek].push({ date: new Date(d), count }); + const githubCount = data?.contributionData[dateString] || 0; + const activityCount = (contributionData[dateString] || 0) - (data?.contributionData[dateString] || 0); + const totalCount = githubCount + activityCount; + calendar[d.getDay()].push({ + date: new Date(d), + count: totalCount, + githubCount, + activityCount + }); } return calendar; - }, [contributionData]); + }, [contributionData, data?.contributionData]); const calendar = generateCalendar(); const weekDays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; @@ -76,14 +167,14 @@ const GithubContributionChart = ({ username }) => { return (
- {(isLoading || isFetching) &&

Loading contribution data... ({totalCommits} commits fetched)

} + {(isLoading || isFetching) &&

Loading contribution data... ({totalContributions} total contributions / activities fetched)

} {!isLoading && !isFetching &&

- {totalCommits} contributions in the last year + {totalContributions} total contributions / activities in the last year

+ data-pr-tooltip="Combined total of GitHub commits and learning activities (starting/completing courses and lessons)" />
} @@ -91,7 +182,7 @@ const GithubContributionChart = ({ username }) => { {/* Days of week labels */}
{weekDays.map((day, index) => ( -
+
{index % 2 === 0 && day}
))} @@ -105,8 +196,13 @@ const GithubContributionChart = ({ username }) => { row[weekIndex] && (
0 ? `${row[weekIndex].githubCount} contribution${row[weekIndex].githubCount !== 1 ? 's' : ''}` : '', + row[weekIndex].activityCount > 0 ? `${row[weekIndex].activityCount} activit${row[weekIndex].activityCount !== 1 ? 'ies' : 'y'}` : '' + ].filter(Boolean).join(' & ') || 'No contributions or activities' + }`} >
) ))} @@ -130,11 +226,11 @@ const GithubContributionChart = ({ username }) => {
Less
-
-
-
-
-
+
+
+
+
+
More
@@ -142,4 +238,4 @@ const GithubContributionChart = ({ username }) => { ); }; -export default GithubContributionChart; +export default CombinedContributionChart; diff --git a/src/components/profile/UserProfile.js b/src/components/profile/UserProfile.js index a83e410..70ed3c1 100644 --- a/src/components/profile/UserProfile.js +++ b/src/components/profile/UserProfile.js @@ -1,24 +1,19 @@ import React, { useRef, useState, useEffect } from "react"; -import { DataTable } from "primereact/datatable"; import { Menu } from "primereact/menu"; -import { Column } from "primereact/column"; import { useImageProxy } from "@/hooks/useImageProxy"; import { useSession } from 'next-auth/react'; -import { ProgressSpinner } from "primereact/progressspinner"; -import ProgressListItem from "@/components/content/lists/ProgressListItem"; -import PurchasedListItem from "@/components/content/lists/PurchasedListItem"; import { useNDKContext } from "@/context/NDKContext"; import { formatDateTime } from "@/utils/time"; import { Tooltip } from "primereact/tooltip"; import { nip19 } from "nostr-tools"; import Image from "next/image"; +import CombinedContributionChart from "@/components/charts/CombinedContributionChart"; import GithubContributionChart from "@/components/charts/GithubContributionChart"; import GithubContributionChartDisabled from "@/components/charts/GithubContributionChartDisabled"; import useCheckCourseProgress from "@/hooks/tracking/useCheckCourseProgress"; import useWindowWidth from "@/hooks/useWindowWidth"; import { useToast } from "@/hooks/useToast"; import UserProgress from "@/components/profile/progress/UserProgress"; -import { classNames } from "primereact/utils"; import UserProgressTable from '@/components/profile/DataTables/UserProgressTable'; import UserPurchaseTable from '@/components/profile/DataTables/UserPurchaseTable'; @@ -138,7 +133,7 @@ const UserProfile = () => { )} {account && account?.provider === "github" ? ( - + ) : ( )}