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 b899fab3..8c8546d4 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
@@ -5,7 +5,7 @@ import { BookOpenCheck, Check, CheckCircle, ChevronDown, ChevronLeft, ChevronRig
import { markActivityAsComplete, unmarkActivityAsComplete } from '@services/courses/activity'
import { usePathname, useRouter } from 'next/navigation'
import AuthenticatedClientElement from '@components/Security/AuthenticatedClientElement'
-import { getCourseThumbnailMediaDirectory } from '@services/media/media'
+import { getCourseThumbnailMediaDirectory, getUserAvatarMediaDirectory } from '@services/media/media'
import { useOrg } from '@components/Contexts/OrgContext'
import { CourseProvider } from '@components/Contexts/CourseContext'
import { useLHSession } from '@components/Contexts/LHSessionContext'
@@ -31,6 +31,7 @@ import MiniInfoTooltip from '@components/Objects/MiniInfoTooltip'
import GeneralWrapperStyled from '@components/Objects/StyledElements/Wrappers/GeneralWrapper'
import ActivityIndicators from '@components/Pages/Courses/ActivityIndicators'
import { revalidateTags } from '@services/utils/ts/requests'
+import UserAvatar from '@components/Objects/UserAvatar'
// Lazy load heavy components
const Canva = lazy(() => import('@components/Objects/Activities/DynamicCanva/DynamicCanva'))
@@ -132,6 +133,26 @@ function ActivityActions({ activity, activityid, course, orgslug, assignment, sh
);
}
+function getRelativeTime(date: Date): string {
+ const now = new Date();
+ const diff = now.getTime() - date.getTime();
+ const seconds = Math.floor(diff / 1000);
+ const minutes = Math.floor(seconds / 60);
+ const hours = Math.floor(minutes / 60);
+ const days = Math.floor(hours / 24);
+ const weeks = Math.floor(days / 7);
+ const months = Math.floor(days / 30);
+ const years = Math.floor(days / 365);
+
+ if (years > 0) return `${years} year${years > 1 ? 's' : ''} ago`;
+ if (months > 0) return `${months} month${months > 1 ? 's' : ''} ago`;
+ if (weeks > 0) return `${weeks} week${weeks > 1 ? 's' : ''} ago`;
+ if (days > 0) return `${days} day${days > 1 ? 's' : ''} ago`;
+ if (hours > 0) return `${hours} hour${hours > 1 ? 's' : ''} ago`;
+ if (minutes > 0) return `${minutes} minute${minutes > 1 ? 's' : ''} ago`;
+ return 'just now';
+}
+
function ActivityClient(props: ActivityClientProps) {
const activityid = props.activityid
const courseuuid = props.courseuuid
@@ -508,7 +529,7 @@ function ActivityClient(props: ActivityClientProps) {
@@ -550,6 +571,80 @@ function ActivityClient(props: ActivityClientProps) {
{activity.name}
+ {/* Authors and Dates Section */}
+
+ {/* Avatars */}
+ {course.authors && course.authors.length > 0 && (
+
+ {course.authors.filter((a: any) => a.authorship_status === 'ACTIVE').slice(0, 3).map((author: any, idx: number) => (
+
+
+
+ ))}
+ {course.authors.filter((a: any) => a.authorship_status === 'ACTIVE').length > 3 && (
+
+ +{course.authors.filter((a: any) => a.authorship_status === 'ACTIVE').length - 3}
+
+ )}
+
+ )}
+ {/* Author names */}
+ {course.authors && course.authors.length > 0 && (
+
+ {course.authors.filter((a: any) => a.authorship_status === 'ACTIVE').length > 1 && (
+
Co-created by
+ )}
+ {course.authors.filter((a: any) => a.authorship_status === 'ACTIVE').slice(0, 2).map((author: any, idx: number, arr: any[]) => (
+
+ {author.user.first_name && author.user.last_name
+ ? `${author.user.first_name} ${author.user.last_name}`
+ : `@${author.user.username}`}
+ {idx === 0 && arr.length > 1 ? ' & ' : ''}
+
+ ))}
+ {course.authors.filter((a: any) => a.authorship_status === 'ACTIVE').length > 2 && (
+
+ {course.authors
+ .filter((a: any) => a.authorship_status === 'ACTIVE')
+ .slice(2)
+ .map((author: any) => (
+
+ {author.user.first_name && author.user.last_name
+ ? `${author.user.first_name} ${author.user.last_name}`
+ : `@${author.user.username}`}
+
+ ))}
+
+ }
+ >
+
+ +{course.authors.filter((a: any) => a.authorship_status === 'ACTIVE').length - 2}
+
+
+ )}
+
+ )}
+ {/* Dates */}
+
+
+ Created on {new Date(course.creation_date).toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' })}
+
+ •
+
+ Last updated {getRelativeTime(new Date(course.updated_at || course.last_updated || course.creation_date))}
+
+
+
@@ -598,7 +693,7 @@ function ActivityClient(props: ActivityClientProps) {