Skip to content

Commit

Permalink
Merge pull request frappe#1234 from pateljannat/batch-dashboard-23
Browse files Browse the repository at this point in the history
feat: student activities display in a heatmap
  • Loading branch information
pateljannat authored Jan 7, 2025
2 parents c597f96 + fb40b62 commit 9dcfc34
Show file tree
Hide file tree
Showing 11 changed files with 347 additions and 87 deletions.
2 changes: 1 addition & 1 deletion frontend/src/components/Assessments.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
{{ __('Add') }}
</Button>
</div>
<div v-if="assessments.data?.length">
<div v-if="assessments.data?.length" class="text-sm">
<ListView
:columns="getAssessmentColumns()"
:rows="assessments.data"
Expand Down
5 changes: 3 additions & 2 deletions frontend/src/components/BatchDashboard.vue
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
<template>
<div>
<div class="space-y-10">
<UpcomingEvaluations
:batch="batch.data.name"
:endDate="batch.data.evaluation_end_date"
:courses="batch.data.courses"
:isStudent="isStudent"
/>
<Assessments :batch="batch.data.name" />
<StudentHeatmap />
</div>
</template>
<script setup>
import UpcomingEvaluations from '@/components/UpcomingEvaluations.vue'
import Assessments from '@/components/Assessments.vue'
import StudentHeatmap from '@/components/StudentHeatmap.vue'
const props = defineProps({
batch: {
Expand Down
66 changes: 27 additions & 39 deletions frontend/src/components/BatchStudents.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
<div class="grid grid-cols-3 gap-5 mb-8">
<div class="flex items-center shadow py-2 px-3 rounded-md">
<div class="p-2 rounded-md bg-gray-100 mr-3">
<User class="w-18 h-18 stroke-1.5 text-gray-700" />
<User class="w-5 h-5 stroke-1.5 text-gray-700" />
</div>
<div class="flex flex-col">
<span class="text-xl font-semibold mb-1">
<div class="flex items-center space-x-2">
<span class="font-semibold">
{{ students.data?.length }}
</span>
<span class="text-gray-700">
Expand All @@ -22,10 +22,10 @@

<div class="flex items-center shadow py-2 px-3 rounded-md">
<div class="p-2 rounded-md bg-gray-100 mr-3">
<BookOpen class="w-18 h-18 stroke-1.5 text-gray-700" />
<BookOpen class="w-5 h-5 stroke-1.5 text-gray-700" />
</div>
<div class="flex flex-col">
<span class="text-xl font-semibold mb-1">
<div class="flex items-center space-x-2">
<span class="font-semibold">
{{ batch.courses?.length }}
</span>
<span class="text-gray-700">
Expand All @@ -36,10 +36,10 @@

<div class="flex items-center shadow py-2 px-3 rounded-md">
<div class="p-2 rounded-md bg-gray-100 mr-3">
<ShieldCheck class="w-18 h-18 stroke-1.5 text-gray-700" />
<ShieldCheck class="w-5 h-5 stroke-1.5 text-gray-700" />
</div>
<div class="flex flex-col">
<span class="text-xl font-semibold mb-1">
<div class="flex items-center space-x-2">
<span class="font-semibold">
{{ assessmentCount }}
</span>
<span class="text-gray-700">
Expand All @@ -48,28 +48,33 @@
</div>
</div>
</div>
<div class="mb-8">
<div v-if="showProgressChart" class="mb-8">
<div class="text-gray-600 font-medium">
{{ __('Progress') }}
</div>
<ApexChart
v-if="showProgressChart"
:options="chartOptions"
:series="chartData"
type="bar"
height="350"
height="200"
/>
<div
class="flex items-center justify-center text-sm text-gray-700 space-x-4"
>
<div class="flex items-center space-x-2">
<div class="w-3 h-3" style="background-color: #0f736b"></div>
<div
class="w-3 h-3 rounded-sm"
:style="{ 'background-color': theme.colors.green[600] }"
></div>
<div>
{{ __('Courses') }}
</div>
</div>
<div class="flex items-center space-x-2">
<div class="w-3 h-3" style="background-color: #0070cc"></div>
<div
class="w-3 h-3 rounded-sm"
:style="{ 'background-color': theme.colors.blue[600] }"
></div>
<div>
{{ __('Assessments') }}
</div>
Expand Down Expand Up @@ -147,16 +152,6 @@
<ProgressBar :progress="row[column.key]" size="sm" />
<div class="text-xs">{{ row[column.key] }}%</div>
</div>
<div
v-else-if="column.key == 'copy'"
class="invisible group-hover:visible"
>
<Button variant="ghost" @click="copyEmail(row)">
<template #icon>
<Clipboard class="h-4 w-4 stroke-1.5" />
</template>
</Button>
</div>
<div v-else>
{{ row[column.key] }}
</div>
Expand Down Expand Up @@ -221,6 +216,7 @@ import { showToast } from '@/utils'
import ProgressBar from '@/components/ProgressBar.vue'
import BatchStudentProgress from '@/components/Modals/BatchStudentProgress.vue'
import ApexChart from 'vue3-apexcharts'
import { theme } from '@/utils/theme'
const showStudentModal = ref(false)
const showStudentProgressModal = ref(false)
Expand Down Expand Up @@ -271,10 +267,6 @@ const getStudentColumns = () => {
align: 'center',
icon: 'clock',
},
{
label: '',
key: 'copy',
},
]
return columns
Expand Down Expand Up @@ -357,8 +349,8 @@ const getChartData = () => {
}
const getChartOptions = (categories) => {
const courseColor = '#0F736B'
const assessmentColor = '#0070CC'
const courseColor = theme.colors.green[700]
const assessmentColor = theme.colors.blue[700]
const maxY =
students.data?.length % 5
? students.data?.length + (5 - (students.data?.length % 5))
Expand All @@ -367,17 +359,17 @@ const getChartOptions = (categories) => {
return {
chart: {
type: 'bar',
height: 50,
toolbar: {
show: false,
},
},
plotOptions: {
bar: {
distributed: true,
borderRadius: 0,
borderRadius: 3,
borderRadiusApplication: 'end',
horizontal: true,
barHeight: '30%',
barHeight: '40%',
},
},
colors: Object.values(categories).map((item) =>
Expand All @@ -391,7 +383,7 @@ const getChartOptions = (categories) => {
},
rotate: 0,
formatter: function (value) {
return value.length > 20 ? `${value.substring(0, 20)}...` : value // Trim long labels
return value.length > 30 ? `${value.substring(0, 30)}...` : value // Trim long labels
},
},
},
Expand All @@ -400,15 +392,11 @@ const getChartOptions = (categories) => {
min: 0,
stepSize: 10,
tickAmount: maxY / 5,
/* reversed: true */
},
}
}
const copyEmail = (row) => {
navigator.clipboard.writeText(row.email)
showToast(__('Success'), __('Email copied to clipboard'), 'check')
}
watch(students, () => {
if (students.data?.length) {
assessmentCount.value = Object.keys(students.data?.[0].assessments).length
Expand Down
48 changes: 23 additions & 25 deletions frontend/src/components/Modals/BatchStudentProgress.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
<template>
<Dialog v-model="show" :options="{}">
<Dialog
v-model="show"
:options="{
size: 'xl',
}"
>
<template #body>
<div class="p-5 space-y-8 text-base">
<div class="p-5 space-y-10 text-base">
<div class="flex items-center space-x-2">
<Avatar :image="student.user_image" size="3xl" />
<div class="space-y-1">
Expand All @@ -19,13 +24,11 @@
</div>
</div>

<!-- Assessments -->
<div>
<div>
<div
class="grid grid-cols-[70%,30%] border-b pl-2 pb-1 mb-2 text-xs text-gray-700 font-medium"
>
<span>
<div class="space-y-8">
<!-- Assessments -->
<div class="space-y-2 text-sm">
<div class="flex items-center border-b pb-1 font-medium">
<span class="flex-1">
{{ __('Assessment') }}
</span>
<span>
Expand All @@ -34,9 +37,9 @@
</div>
<div
v-for="assessment in Object.keys(student.assessments)"
class="grid grid-cols-[70%,30%] pl-2 mb-2 text-gray-700 font-medium"
class="flex items-center text-gray-700 font-medium"
>
<span>
<span class="flex-1">
{{ assessment }}
</span>
<span v-if="isAssignment(student.assessments[assessment])">
Expand All @@ -49,15 +52,11 @@
</span>
</div>
</div>
</div>

<!-- Courses -->
<div>
<div>
<div
class="grid grid-cols-[70%,30%] mb-2 text-xs text-gray-700 border-b pl-2 pb-1 font-medium"
>
<span>
<!-- Courses -->
<div class="space-y-2 text-sm">
<div class="flex items-center border-b pb-1 font-medium">
<span class="flex-1">
{{ __('Courses') }}
</span>
<span>
Expand All @@ -66,9 +65,9 @@
</div>
<div
v-for="course in Object.keys(student.courses)"
class="grid grid-cols-[70%,30%] pl-2 mb-2 text-gray-700 font-medium"
class="flex items-center text-gray-700 font-medium"
>
<span>
<span class="flex-1">
{{ course }}
</span>
<span>
Expand All @@ -78,16 +77,15 @@
</div>
</div>

<!-- <span class="mt-4">
{{ student }}
</span> -->
<!-- Heatmap -->
<StudentHeatmap :member="student.email" :base_days="120" />
</div>
</template>
</Dialog>
</template>
<script setup>
import { Avatar, Badge, Dialog } from 'frappe-ui'
import ProgressBar from '@/components/ProgressBar.vue'
import StudentHeatmap from '@/components/StudentHeatmap.vue'
const show = defineModel()
const props = defineProps({
Expand Down
Loading

0 comments on commit 9dcfc34

Please sign in to comment.