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 2095ee8e..ffbe6899 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 @@ -35,6 +35,8 @@ import FixedActivitySecondaryBar from '@components/Pages/Activity/FixedActivityS import CourseEndView from '@components/Pages/Activity/CourseEndView' import { motion, AnimatePresence } from 'framer-motion' import ActivityBreadcrumbs from '@components/Pages/Activity/ActivityBreadcrumbs' +import MiniInfoTooltip from '@components/Objects/MiniInfoTooltip' + interface ActivityClientProps { activityid: string @@ -601,7 +603,12 @@ function ActivityClient(props: ActivityClientProps) { {/* Activity Actions below the content box */} {activity && activity.published == true && activity.content.paid_access != false && ( -
+
+ { + if (typeof window !== 'undefined') { + const markedTooltipCount = localStorage.getItem('activity_marked_tooltip_count'); + const unmarkedTooltipCount = localStorage.getItem('activity_unmarked_tooltip_count'); + + if (!markedTooltipCount || parseInt(markedTooltipCount) < 3) { + setShowMarkedTooltip(true); + } + if (!unmarkedTooltipCount || parseInt(unmarkedTooltipCount) < 3) { + setShowUnmarkedTooltip(true); + } + } + }, []); + + const handleMarkedTooltipClose = () => { + if (typeof window !== 'undefined') { + localStorage.setItem('activity_marked_tooltip_count', '3'); + setShowMarkedTooltip(false); + } + }; + + const handleUnmarkedTooltipClose = () => { + if (typeof window !== 'undefined') { + localStorage.setItem('activity_unmarked_tooltip_count', '3'); + setShowUnmarkedTooltip(false); + } + }; + + const infoIcon = ( + + + + + + ); const areAllActivitiesCompleted = () => { const run = props.course.trail.runs.find( @@ -654,7 +706,6 @@ export function MarkStatus(props: { let totalActivities = 0; let completedActivities = 0; - // Count all activities and completed activities props.course.chapters.forEach((chapter: any) => { chapter.activities.forEach((activity: any) => { totalActivities++; @@ -667,21 +718,12 @@ export function MarkStatus(props: { }); }); - console.log('Total activities:', totalActivities); - console.log('Completed activities:', completedActivities); - console.log('All completed?', completedActivities >= totalActivities - 1); - - // We check for totalActivities - 1 because the current activity completion - // hasn't been counted yet (it's in progress) return completedActivities >= totalActivities - 1; }; async function markActivityAsCompleteFront() { try { - // Check if this will be the last activity to complete const willCompleteAll = areAllActivitiesCompleted(); - console.log('Will complete all?', willCompleteAll); - setIsLoading(true); await markActivityAsComplete( props.orgslug, @@ -690,11 +732,9 @@ export function MarkStatus(props: { session.data?.tokens?.access_token ); - // Mutate the course data await mutate(`${getAPIUrl()}courses/${props.course.course_uuid}/meta`); if (willCompleteAll) { - console.log('Redirecting to end page...'); const cleanCourseUuid = props.course.course_uuid.replace('course_', ''); router.push(getUriWithOrg(props.orgslug, '') + `/course/${cleanCourseUuid}/activity/end`); } else { @@ -711,14 +751,13 @@ export function MarkStatus(props: { async function unmarkActivityAsCompleteFront() { try { setIsLoading(true); - const trail = await unmarkActivityAsComplete( + await unmarkActivityAsComplete( props.orgslug, props.course.course_uuid, props.activity.activity_uuid, session.data?.tokens?.access_token ); - // Mutate the course data to trigger re-render await mutate(`${getAPIUrl()}courses/${props.course.course_uuid}/meta`); router.refresh(); } catch (error) { @@ -743,24 +782,13 @@ export function MarkStatus(props: { <> {isActivityCompleted() ? (
-
- - - {' '} - Complete -
- +
+
{isLoading ? (
@@ -769,34 +797,78 @@ export function MarkStatus(props: {
) : ( - + + + + )} + Complete
} functionToExecute={unmarkActivityAsCompleteFront} status="warning" /> - + {showMarkedTooltip && ( + + )} +
) : (
-
- {isLoading ? ( -
- - - +
+
+ {isLoading ? ( +
+ + + + +
+ ) : ( + + -
- ) : ( - - - - )}{' '} - {!isMobile && {isLoading ? 'Marking...' : 'Mark as complete'}} + )} + {isLoading ? 'Marking...' : 'Mark as complete'} +
+ {showUnmarkedTooltip && ( + + )}
)} diff --git a/apps/web/components/Objects/MiniInfoTooltip.tsx b/apps/web/components/Objects/MiniInfoTooltip.tsx new file mode 100644 index 00000000..6e27890e --- /dev/null +++ b/apps/web/components/Objects/MiniInfoTooltip.tsx @@ -0,0 +1,47 @@ +import React from 'react'; +import { motion } from 'framer-motion'; + +interface MiniInfoTooltipProps { + icon?: React.ReactNode; + message: string; + onClose: () => void; + iconColor?: string; + iconSize?: number; + width?: string; +} + +export default function MiniInfoTooltip({ + icon, + message, + onClose, + iconColor = 'text-teal-600', + iconSize = 20, + width = 'w-48' +}: MiniInfoTooltipProps) { + return ( + +
+ {icon && ( +
+ {icon} +
+ )} +

{message}

+
+
+ +
+ ); +} \ No newline at end of file