feat: org and course student analytics page (#509)
* UI initialization * feat: structure API * feat: audience & people analytics * feat: quick changes * feat: add comments * redesign course student page * chore: make requests to db more efficient * clean up analytics page for course * feat: finish up audience analytics page * chore: minor UI tweaks * translate all * replace inserts of log in events to update * catch error if last_login isn't inserted --------- Co-authored-by: Rotimi Best <[email protected]>
This commit is contained in:
co-authored by
Rotimi Best
parent
381776f388
commit
f69bf920a9
@@ -0,0 +1,34 @@
|
||||
<script lang="ts">
|
||||
interface Activity {
|
||||
icon: any;
|
||||
title: string;
|
||||
percentage: number;
|
||||
description: string;
|
||||
hidePercentage?: boolean;
|
||||
}
|
||||
|
||||
export let activity: Activity;
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="flex flex-col items-center justify-center gap-5 rounded-xl border p-3 dark:border-neutral-600 md:flex-row md:p-5"
|
||||
>
|
||||
<div class="bg-primary-200 w-fit rounded-full p-4 text-black">
|
||||
<svelte:component this={activity.icon} size={24} />
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p class="text-center text-sm font-medium text-gray-600 dark:text-gray-200 md:text-left">
|
||||
{activity.title}
|
||||
</p>
|
||||
<p class="text-center text-2xl font-bold md:text-left">
|
||||
{activity.percentage}
|
||||
{#if !activity.hidePercentage}
|
||||
%
|
||||
{/if}
|
||||
</p>
|
||||
<p class="text-center text-xs text-gray-500 dark:text-gray-300 md:text-left md:text-sm">
|
||||
{activity.description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,36 @@
|
||||
<script lang="ts">
|
||||
import Avatar from '$lib/components/Avatar/index.svelte';
|
||||
import { calDateDiff } from '$lib/utils/functions/date';
|
||||
import { t } from '$lib/utils/functions/translations';
|
||||
import type { UserAnalytics } from '$lib/utils/types/analytics';
|
||||
import Alarm from 'carbon-icons-svelte/lib/Alarm.svelte';
|
||||
import Email from 'carbon-icons-svelte/lib/Email.svelte';
|
||||
|
||||
export let user: UserAnalytics['user'];
|
||||
</script>
|
||||
|
||||
<div class="rounded-md border p-5 dark:border-neutral-600">
|
||||
<div class="flex w-full flex-col items-center justify-start gap-4 text-start md:flex-row">
|
||||
<Avatar src={user.avatarUrl} name={user.fullName} width="w-16" height="h-16" />
|
||||
<div class="flex flex-col space-y-2">
|
||||
<p class="text-center text-2xl font-bold dark:text-white md:text-left">
|
||||
{user.fullName}
|
||||
</p>
|
||||
|
||||
<div class="flex flex-col items-center gap-1 md:flex-row md:gap-4">
|
||||
<p class="flex items-center gap-1 text-sm text-gray-500 dark:text-gray-300">
|
||||
<Email />
|
||||
{user.email}
|
||||
</p>
|
||||
|
||||
<p class="flex items-center gap-1 text-sm text-gray-500 dark:text-gray-300">
|
||||
<Alarm />
|
||||
{$t('analytics.last_seen')}:
|
||||
<span class="italic">
|
||||
{user.lastSeen ? calDateDiff(user.lastSeen) : $t('analytics.a_while_ago')}
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,12 @@
|
||||
<script>
|
||||
import { SkeletonPlaceholder } from 'carbon-components-svelte';
|
||||
</script>
|
||||
|
||||
<div class="mx-auto max-w-4xl pt-14">
|
||||
<SkeletonPlaceholder style="width: 100%; height: 10rem;" />
|
||||
<div class="mt-10 grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-3">
|
||||
<SkeletonPlaceholder style="width: 270px; height: 10rem;" />
|
||||
<SkeletonPlaceholder style="width: 270px; height: 10rem;" />
|
||||
<SkeletonPlaceholder style="width: 270px; height: 10rem;" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,3 @@
|
||||
export { default as ActivityCard } from './ActivityCard.svelte';
|
||||
export { default as HeroProfileCard } from './HeroProfileCard.svelte';
|
||||
export { default as LoadingPage } from './LoadingPage.svelte';
|
||||
Reference in New Issue
Block a user