From 6aca58ece7b5cfa192eb1dd66edd119fbef7f878 Mon Sep 17 00:00:00 2001 From: swve Date: Sun, 25 May 2025 21:32:39 +0200 Subject: [PATCH] feat: improve readability of the activity indicators --- .../activity/[activityid]/activity.tsx | 1 + .../Pages/Courses/ActivityIndicators.tsx | 152 ++++++++++++------ 2 files changed, 105 insertions(+), 48 deletions(-) diff --git a/apps/web/app/orgs/[orgslug]/(withmenu)/course/[courseuuid]/activity/[activityid]/activity.tsx b/apps/web/app/orgs/[orgslug]/(withmenu)/course/[courseuuid]/activity/[activityid]/activity.tsx index 4e37823c..505b9e82 100644 --- a/apps/web/app/orgs/[orgslug]/(withmenu)/course/[courseuuid]/activity/[activityid]/activity.tsx +++ b/apps/web/app/orgs/[orgslug]/(withmenu)/course/[courseuuid]/activity/[activityid]/activity.tsx @@ -532,6 +532,7 @@ function ActivityClient(props: ActivityClientProps) { current_activity={activityid} orgslug={orgslug} course={course} + enableNavigation={true} />
diff --git a/apps/web/components/Pages/Courses/ActivityIndicators.tsx b/apps/web/components/Pages/Courses/ActivityIndicators.tsx index bfe3be7d..2837f230 100644 --- a/apps/web/components/Pages/Courses/ActivityIndicators.tsx +++ b/apps/web/components/Pages/Courses/ActivityIndicators.tsx @@ -1,6 +1,6 @@ 'use client' -import { BookOpenCheck, Check, FileText, Layers, Video } from 'lucide-react' -import React, { useMemo, memo } from 'react' +import { BookOpenCheck, Check, FileText, Layers, Video, ChevronLeft, ChevronRight } from 'lucide-react' +import React, { useMemo, memo, useState } from 'react' import ToolTip from '@components/Objects/StyledElements/Tooltip/Tooltip' import { getUriWithOrg } from '@services/config/config' import Link from 'next/link' @@ -10,6 +10,7 @@ interface Props { orgslug: string course_uuid: string current_activity?: string + enableNavigation?: boolean } // Helper functions @@ -98,6 +99,9 @@ function ActivityIndicators(props: Props) { const course = props.course const orgslug = props.orgslug const courseid = props.course_uuid.replace('course_', '') + const enableNavigation = props.enableNavigation || false + + const [currentIndex, setCurrentIndex] = useState(0) const done_activity_style = 'bg-teal-600 hover:bg-teal-700' const black_activity_style = 'bg-zinc-300 hover:bg-zinc-400' @@ -105,6 +109,24 @@ function ActivityIndicators(props: Props) { const trail = props.course.trail + // Flatten all activities for navigation and rendering + const allActivities = useMemo(() => { + return course.chapters.flatMap((chapter: any) => + chapter.activities.map((activity: any) => ({ + ...activity, + chapterId: chapter.id + })) + ) + }, [course.chapters]) + + // Find current activity index + const currentActivityIndex = useMemo(() => { + if (!props.current_activity) return -1 + return allActivities.findIndex((activity: any) => + activity.activity_uuid.replace('activity_', '') === props.current_activity + ) + }, [allActivities, props.current_activity]) + // Memoize activity status checks const isActivityDone = useMemo(() => (activity: any) => { let run = props.course.trail?.runs.find( @@ -125,58 +147,92 @@ function ActivityIndicators(props: Props) { }, [props.current_activity]); const getActivityClass = useMemo(() => (activity: any) => { + const isCurrent = isActivityCurrent(activity) if (isActivityDone(activity)) { - return done_activity_style + return `${done_activity_style}` } - if (isActivityCurrent(activity)) { - return current_activity_style + if (isCurrent) { + return `${current_activity_style} border-2 border-gray-800 animate-pulse` } - return black_activity_style + return `${black_activity_style}` }, [isActivityDone, isActivityCurrent]); + const navigateToPrevious = () => { + if (currentActivityIndex > 0) { + const prevActivity = allActivities[currentActivityIndex - 1] + const activityId = prevActivity.activity_uuid.replace('activity_', '') + window.location.href = getUriWithOrg(orgslug, '') + `/course/${courseid}/activity/${activityId}` + } + } + + const navigateToNext = () => { + if (currentActivityIndex < allActivities.length - 1) { + const nextActivity = allActivities[currentActivityIndex + 1] + const activityId = nextActivity.activity_uuid.replace('activity_', '') + window.location.href = getUriWithOrg(orgslug, '') + `/course/${courseid}/activity/${activityId}` + } + } + return ( -
- {course.chapters.map((chapter: any) => { - return ( - -
- {chapter.activities.map((activity: any) => { - const isDone = isActivityDone(activity) - const isCurrent = isActivityCurrent(activity) - return ( - - } - key={activity.activity_uuid} - > - -
- -
- ) - })} -
-
- ) - })} +
+ {enableNavigation && ( + + )} + +
+ {allActivities.map((activity: any) => { + const isDone = isActivityDone(activity) + const isCurrent = isActivityCurrent(activity) + return ( + + } + key={activity.activity_uuid} + > + +
+ +
+ ) + })} +
+ + {enableNavigation && ( + + )}
) }