diff --git a/src/components/Activity/ActivityCounters.tsx b/src/components/Activity/ActivityCounters.tsx index f647761ca..4024ae33e 100644 --- a/src/components/Activity/ActivityCounters.tsx +++ b/src/components/Activity/ActivityCounters.tsx @@ -47,7 +47,7 @@ export function ActivityCounters(props: ActivityCountersType) { /> diff --git a/src/components/Activity/ActivityPage.tsx b/src/components/Activity/ActivityPage.tsx index 72f0ff9cf..cfc9ac5ad 100644 --- a/src/components/Activity/ActivityPage.tsx +++ b/src/components/Activity/ActivityPage.tsx @@ -20,6 +20,7 @@ type ActivityResponse = { done: number; total: number; skipped: number; + updatedAt: string; }[]; bestPractices: { title: string; @@ -28,10 +29,13 @@ type ActivityResponse = { done: number; skipped: number; total: number; + updatedAt: string; }[]; }; streak: { count: number; + firstVisitAt: Date | null; + lastVisitAt: Date | null; }; activity: { type: 'done' | 'learning' | 'pending' | 'skipped'; @@ -52,7 +56,7 @@ export function ActivityPage() { async function loadActivity() { const { error, response } = await httpGet( - `${import.meta.env.PUBLIC_API_URL}/v1-get-user-activity` + `${import.meta.env.PUBLIC_API_URL}/v1-get-user-stats` ); if (!response || error) { @@ -105,6 +109,7 @@ export function ActivityPage() { skippedCount={roadmap.skipped || 0} resourceId={roadmap.id} resourceType={'roadmap'} + updatedAt={roadmap.updatedAt} title={roadmap.title} onCleared={() => { pageLoadingMessage.set('Updating activity'); @@ -124,6 +129,7 @@ export function ActivityPage() { skippedCount={bestPractice.skipped || 0} resourceType={'best-practice'} title={bestPractice.title} + updatedAt={bestPractice.updatedAt} onCleared={() => { pageLoadingMessage.set('Updating activity'); loadActivity().finally(() => { diff --git a/src/components/Activity/EmptyActivity.tsx b/src/components/Activity/EmptyActivity.tsx index 0fd9f33ee..a38fa7a15 100644 --- a/src/components/Activity/EmptyActivity.tsx +++ b/src/components/Activity/EmptyActivity.tsx @@ -7,10 +7,10 @@ export function EmptyActivity() { no roadmaps -

No Progress

-

+

No Progress

+

Progress will appear here as you start tracking your{' '} Roadmaps diff --git a/src/components/Activity/ResourceProgress.tsx b/src/components/Activity/ResourceProgress.tsx index 77729e8d8..f94a7451e 100644 --- a/src/components/Activity/ResourceProgress.tsx +++ b/src/components/Activity/ResourceProgress.tsx @@ -1,10 +1,12 @@ -import { useEffect, useState } from 'preact/hooks'; +import { useState } from 'preact/hooks'; import { httpPost } from '../../lib/http'; +import { getRelativeTimeString } from '../../lib/date'; type ResourceProgressType = { resourceType: 'roadmap' | 'best-practice'; resourceId: string; title: string; + updatedAt: string; totalCount: number; doneCount: number; learningCount: number; @@ -17,6 +19,7 @@ export function ResourceProgress(props: ResourceProgressType) { const [isConfirming, setIsConfirming] = useState(false); const { + updatedAt, resourceType, resourceId, title, @@ -71,16 +74,30 @@ export function ResourceProgress(props: ResourceProgressType) { width: `${progressPercentage}%`, }} > - {title} - - 5 hours ago + + {title} + + + {getRelativeTimeString(updatedAt)} -

- - {doneCount} done • - { learningCount > 0 && <>{learningCount} in progress • } - { skippedCount > 0 && <>{skippedCount} skipped • } +

+ + {doneCount > 0 && ( + <> + {doneCount} done • + + )} + {learningCount > 0 && ( + <> + {learningCount} in progress • + + )} + {skippedCount > 0 && ( + <> + {skippedCount} skipped • + + )} {totalCount} total {!isConfirming && ( @@ -101,10 +118,19 @@ export function ResourceProgress(props: ResourceProgressType) { {isConfirming && ( - Are you sure?{' '} - Sure?{' '} - {' '} - + Are you sure?{' '} + {' '} + )}

diff --git a/src/components/Navigation/Navigation.astro b/src/components/Navigation/Navigation.astro index 70415b268..1dd61f317 100644 --- a/src/components/Navigation/Navigation.astro +++ b/src/components/Navigation/Navigation.astro @@ -26,8 +26,8 @@ import AccountDropdown from './AccountDropdown.astro'; Videos
  • -
  • diff --git a/src/lib/date.ts b/src/lib/date.ts new file mode 100644 index 000000000..07a0b4d40 --- /dev/null +++ b/src/lib/date.ts @@ -0,0 +1,30 @@ +export function getRelativeTimeString(date: string): string { + if (!Intl?.RelativeTimeFormat) { + return date; + } + + const rtf = new Intl.RelativeTimeFormat('en', { + numeric: 'auto', + style: 'narrow', + }); + + const currentDate = new Date(); + const targetDate = new Date(date); + const diffInMilliseconds = currentDate.getTime() - targetDate.getTime(); + + const diffInMinutes = Math.round(diffInMilliseconds / (1000 * 60)); + const diffInHours = Math.round(diffInMilliseconds / (1000 * 60 * 60)); + const diffInDays = Math.round(diffInMilliseconds / (1000 * 60 * 60 * 24)); + + let relativeTime; + + if (diffInMinutes < 60) { + relativeTime = rtf.format(-diffInMinutes, 'minute'); + } else if (diffInHours < 24) { + relativeTime = rtf.format(-diffInHours, 'hour'); + } else { + relativeTime = rtf.format(-diffInDays, 'day'); + } + + return relativeTime; +}