diff --git a/src/components/charts/GithubContributionChart.js b/src/components/charts/GithubContributionChart.js index 1ef3c36..24c6df0 100644 --- a/src/components/charts/GithubContributionChart.js +++ b/src/components/charts/GithubContributionChart.js @@ -91,7 +91,7 @@ const GithubContributionChart = ({ username }) => { {/* Days of week labels */}
{weekDays.map((day, index) => ( -
+
{index % 2 === 0 && day}
))} @@ -105,7 +105,7 @@ const GithubContributionChart = ({ username }) => { row[weekIndex] && (
) @@ -130,11 +130,11 @@ const GithubContributionChart = ({ username }) => {
Less
-
-
-
-
-
+
+
+
+
+
More
diff --git a/src/components/profile/DataTables/UserProgressTable.js b/src/components/profile/DataTables/UserProgressTable.js index 431aa96..13cf250 100644 --- a/src/components/profile/DataTables/UserProgressTable.js +++ b/src/components/profile/DataTables/UserProgressTable.js @@ -13,16 +13,29 @@ const UserProgressTable = ({ session, ndk, windowWidth }) => { const progressData = []; session.user.userCourses.forEach(courseProgress => { - progressData.push({ - id: courseProgress.id, - type: 'course', - name: courseProgress.course?.name, - started: courseProgress.started, - startedAt: courseProgress.startedAt, - completed: courseProgress.completed, - completedAt: courseProgress.completedAt, - courseId: courseProgress.courseId - }); + // Add course start entry + if (courseProgress.started) { + progressData.push({ + id: `${courseProgress.id}-start`, + type: 'course', + name: courseProgress.course?.name, + eventType: 'started', + date: courseProgress.startedAt, + courseId: courseProgress.courseId + }); + } + + // Add course completion entry + if (courseProgress.completed) { + progressData.push({ + id: `${courseProgress.id}-complete`, + type: 'course', + name: courseProgress.course?.name, + eventType: 'completed', + date: courseProgress.completedAt, + courseId: courseProgress.courseId + }); + } // Add lesson entries const courseLessons = session.user.userLessons?.filter( @@ -30,22 +43,38 @@ const UserProgressTable = ({ session, ndk, windowWidth }) => { ) || []; courseLessons.forEach(lessonProgress => { - progressData.push({ - id: lessonProgress.id, - type: 'lesson', - name: lessonProgress.lesson?.name, - started: lessonProgress.opened, - startedAt: lessonProgress.openedAt, - completed: lessonProgress.completed, - completedAt: lessonProgress.completedAt, - courseId: courseProgress.courseId, - lessonId: lessonProgress.lessonId, - resourceId: lessonProgress.lesson?.resourceId - }); + // Add lesson start entry + if (lessonProgress.opened) { + progressData.push({ + id: `${lessonProgress.id}-start`, + type: 'lesson', + name: lessonProgress.lesson?.name, + eventType: 'started', + date: lessonProgress.openedAt, + courseId: courseProgress.courseId, + lessonId: lessonProgress.lessonId, + resourceId: lessonProgress.lesson?.resourceId + }); + } + + // Add lesson completion entry + if (lessonProgress.completed) { + progressData.push({ + id: `${lessonProgress.id}-complete`, + type: 'lesson', + name: lessonProgress.lesson?.name, + eventType: 'completed', + date: lessonProgress.completedAt, + courseId: courseProgress.courseId, + lessonId: lessonProgress.lessonId, + resourceId: lessonProgress.lesson?.resourceId + }); + } }); }); - return progressData; + // Sort by date, most recent first + return progressData.sort((a, b) => new Date(b.date) - new Date(a.date)); }; const header = ( @@ -54,6 +83,37 @@ const UserProgressTable = ({ session, ndk, windowWidth }) => {
); + const typeTemplate = (rowData) => ( +
+ + {rowData.type} +
+ ); + + const eventTemplate = (rowData) => ( +
+ + {rowData.eventType} +
+ ); + + const nameTemplate = (rowData) => ( +
+ {rowData.type === 'course' + ? + : + } +
+ ); + + const dateTemplate = (rowData) => ( +
+ + {formatDateTime(rowData.date)} +
+ ); + if (!session || !session?.user || !ndk) { return
; } @@ -63,60 +123,45 @@ const UserProgressTable = ({ session, ndk, windowWidth }) => { emptyMessage="No Courses or Milestones completed" value={prepareProgressData()} header={header} - style={{ maxWidth: windowWidth < 768 ? "100%" : "90%", margin: "0 auto", borderRadius: "10px" }} + style={{ maxWidth: windowWidth < 768 ? "100%" : "90%", margin: "0 auto" }} pt={{ wrapper: { - className: "rounded-lg rounded-t-none" + className: "rounded-b-lg shadow-md" }, header: { - className: "rounded-t-lg" + className: "rounded-t-lg border-b border-gray-700" + }, + th: { + className: "text-gray-300 font-semibold" + }, + bodyRow: { + className: "border-b border-gray-700" + }, + bodyCell: { + className: "text-gray-200 p-4" } }} + stripedRows > ( - {rowData.type} - )} + body={typeTemplate} > ( - - )} - > - ( - - )} + field="eventType" + header="Event" + body={eventTemplate} > ( - rowData.type === 'course' - ? - : - )} + body={nameTemplate} > { - if (rowData.completed) { - return formatDateTime(rowData.completedAt); - } - return formatDateTime(rowData.startedAt) || formatDateTime(rowData.createdAt); - }} - header="Last Activity" + field="date" + body={dateTemplate} + header="Date" > ); diff --git a/src/components/profile/DataTables/UserPurchaseTable.js b/src/components/profile/DataTables/UserPurchaseTable.js new file mode 100644 index 0000000..bdac7d8 --- /dev/null +++ b/src/components/profile/DataTables/UserPurchaseTable.js @@ -0,0 +1,95 @@ +import React from 'react'; +import { DataTable } from "primereact/datatable"; +import { Column } from "primereact/column"; +import PurchasedListItem from "@/components/content/lists/PurchasedListItem"; +import { formatDateTime } from "@/utils/time"; + +const UserPurchaseTable = ({ session, windowWidth }) => { + const purchasesHeader = ( +
+ Purchases +
+ ); + + const costTemplate = (rowData) => ( +
+ + {rowData.amountPaid} sats +
+ ); + + const nameTemplate = (rowData) => ( +
+ +
+ ); + + const categoryTemplate = (rowData) => ( +
+ + {rowData?.course ? 'course' : 'resource'} +
+ ); + + const dateTemplate = (rowData) => ( +
+ + {formatDateTime(rowData?.createdAt)} +
+ ); + + return ( + session && session?.user && ( + + + + + + + ) + ); +}; + +export default UserPurchaseTable; diff --git a/src/components/profile/UserProfile.js b/src/components/profile/UserProfile.js index c7251f8..a83e410 100644 --- a/src/components/profile/UserProfile.js +++ b/src/components/profile/UserProfile.js @@ -20,6 +20,7 @@ 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'; const UserProfile = () => { const windowWidth = useWindowWidth(); @@ -103,14 +104,14 @@ const UserProfile = () => { className="rounded-full my-4" />
- menu.current.toggle(e)} /> -
@@ -143,37 +144,15 @@ const UserProfile = () => { )}
- - {session && session?.user && ( - - - { - return - }} - header="Name" - > - item.courseId) ? "course" : "resource"} header="Category"> - formatDateTime(rowData?.createdAt)} header="Date"> - - )} + + ) ); diff --git a/src/hooks/tracking/useTrackVideoLesson.js b/src/hooks/tracking/useTrackVideoLesson.js index c2a5af2..9a77669 100644 --- a/src/hooks/tracking/useTrackVideoLesson.js +++ b/src/hooks/tracking/useTrackVideoLesson.js @@ -85,7 +85,7 @@ const useTrackVideoLesson = ({lessonId, videoDuration, courseId, videoPlayed, pa timerRef.current = setInterval(() => { setTimeSpent(prevTime => { const newTime = prevTime + 1; - // console.log(`⏱️ Time spent: ${newTime}s / ${videoDuration}s (${((newTime/videoDuration)*100).toFixed(1)}%)`); + console.log(`⏱️ Time spent: ${newTime}s / ${videoDuration}s (${((newTime/videoDuration)*100).toFixed(1)}%)`); return newTime; }); }, 1000);