fix: legends
This commit is contained in:
@@ -1,5 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="">
|
<div class="">
|
||||||
|
<div class="w-full flex items-center justify-between border-b pb-4">
|
||||||
|
<div class="font-medium text-gray-600">
|
||||||
|
{{ __('Statistics') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="grid grid-cols-3 gap-5 mb-8">
|
<div class="grid grid-cols-3 gap-5 mb-8">
|
||||||
<div class="flex items-center shadow py-2 px-3 rounded-md">
|
<div class="flex items-center shadow py-2 px-3 rounded-md">
|
||||||
<div class="p-2 rounded-md bg-gray-100 mr-3">
|
<div class="p-2 rounded-md bg-gray-100 mr-3">
|
||||||
@@ -44,7 +49,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mb-8">
|
<div class="mb-8">
|
||||||
<div class="text-lg font-semibold">
|
<div class="text-gray-600 font-medium">
|
||||||
{{ __('Progress') }}
|
{{ __('Progress') }}
|
||||||
</div>
|
</div>
|
||||||
<ApexChart
|
<ApexChart
|
||||||
@@ -54,9 +59,28 @@
|
|||||||
type="bar"
|
type="bar"
|
||||||
height="350"
|
height="350"
|
||||||
/>
|
/>
|
||||||
|
<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: #0289f7"></div>
|
||||||
|
<div>
|
||||||
|
{{ __('Courses') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center space-x-2">
|
||||||
|
<div class="w-3 h-3" style="background-color: #e03636"></div>
|
||||||
|
<div>
|
||||||
|
{{ __('Assessments') }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
<div class="flex items-center justify-between mb-4">
|
<div class="flex items-center justify-between mb-4">
|
||||||
<div class="text-lg font-semibold">
|
<div class="text-gray-600 font-medium">
|
||||||
{{ __('Students') }}
|
{{ __('Students') }}
|
||||||
</div>
|
</div>
|
||||||
<Button @click="openStudentModal()">
|
<Button @click="openStudentModal()">
|
||||||
@@ -66,80 +90,82 @@
|
|||||||
{{ __('Add') }}
|
{{ __('Add') }}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div v-if="students.data?.length">
|
<div v-if="students.data?.length">
|
||||||
<ListView
|
<ListView
|
||||||
:columns="getStudentColumns()"
|
:columns="getStudentColumns()"
|
||||||
:rows="students.data"
|
:rows="students.data"
|
||||||
row-key="name"
|
row-key="name"
|
||||||
:options="{
|
:options="{
|
||||||
showTooltip: false,
|
showTooltip: false,
|
||||||
onRowClick: (row) => {
|
onRowClick: (row) => {
|
||||||
openStudentProgressModal(row)
|
openStudentProgressModal(row)
|
||||||
},
|
},
|
||||||
}"
|
}"
|
||||||
>
|
|
||||||
<ListHeader
|
|
||||||
class="mb-2 grid items-center space-x-4 rounded bg-gray-100 p-2"
|
|
||||||
>
|
>
|
||||||
<ListHeaderItem
|
<ListHeader
|
||||||
:item="item"
|
class="mb-2 grid items-center space-x-4 rounded bg-gray-100 p-2"
|
||||||
v-for="item in getStudentColumns()"
|
|
||||||
:title="item.label"
|
|
||||||
>
|
>
|
||||||
<template #prefix="{ item }">
|
<ListHeaderItem
|
||||||
<FeatherIcon
|
:item="item"
|
||||||
v-if="item.icon"
|
v-for="item in getStudentColumns()"
|
||||||
:name="item.icon"
|
:title="item.label"
|
||||||
class="h-4 w-4 stroke-1.5"
|
>
|
||||||
/>
|
<template #prefix="{ item }">
|
||||||
</template>
|
<FeatherIcon
|
||||||
</ListHeaderItem>
|
v-if="item.icon"
|
||||||
</ListHeader>
|
:name="item.icon"
|
||||||
<ListRows>
|
class="h-4 w-4 stroke-1.5"
|
||||||
<ListRow :row="row" v-for="row in students.data">
|
/>
|
||||||
<template #default="{ column, item }">
|
</template>
|
||||||
<ListRowItem :item="row[column.key]" :align="column.align">
|
</ListHeaderItem>
|
||||||
<template #prefix>
|
</ListHeader>
|
||||||
<div v-if="column.key == 'full_name'">
|
<ListRows>
|
||||||
<Avatar
|
<ListRow :row="row" v-for="row in students.data">
|
||||||
class="flex items-center"
|
<template #default="{ column, item }">
|
||||||
:image="row['user_image']"
|
<ListRowItem :item="row[column.key]" :align="column.align">
|
||||||
:label="item"
|
<template #prefix>
|
||||||
size="sm"
|
<div v-if="column.key == 'full_name'">
|
||||||
/>
|
<Avatar
|
||||||
|
class="flex items-center"
|
||||||
|
:image="row['user_image']"
|
||||||
|
:label="item"
|
||||||
|
size="sm"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div
|
||||||
|
v-if="column.key == 'progress'"
|
||||||
|
class="flex items-center space-x-4 w-full"
|
||||||
|
>
|
||||||
|
<ProgressBar :progress="row[column.key]" size="sm" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
<div v-else>
|
||||||
<div
|
{{ row[column.key] }}
|
||||||
v-if="column.key == 'progress'"
|
</div>
|
||||||
class="flex items-center space-x-4 w-full"
|
</ListRowItem>
|
||||||
|
</template>
|
||||||
|
</ListRow>
|
||||||
|
</ListRows>
|
||||||
|
<ListSelectBanner>
|
||||||
|
<template #actions="{ unselectAll, selections }">
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
@click="removeStudents(selections, unselectAll)"
|
||||||
>
|
>
|
||||||
<ProgressBar :progress="row[column.key]" size="sm" />
|
<Trash2 class="h-4 w-4 stroke-1.5" />
|
||||||
</div>
|
</Button>
|
||||||
<div v-else>
|
</div>
|
||||||
{{ row[column.key] }}
|
|
||||||
</div>
|
|
||||||
</ListRowItem>
|
|
||||||
</template>
|
</template>
|
||||||
</ListRow>
|
</ListSelectBanner>
|
||||||
</ListRows>
|
</ListView>
|
||||||
<ListSelectBanner>
|
</div>
|
||||||
<template #actions="{ unselectAll, selections }">
|
<div v-else class="text-sm italic text-gray-600">
|
||||||
<div class="flex gap-2">
|
{{ __('There are no students in this batch.') }}
|
||||||
<Button
|
</div>
|
||||||
variant="ghost"
|
|
||||||
@click="removeStudents(selections, unselectAll)"
|
|
||||||
>
|
|
||||||
<Trash2 class="h-4 w-4 stroke-1.5" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</ListSelectBanner>
|
|
||||||
</ListView>
|
|
||||||
</div>
|
|
||||||
<div v-else class="text-sm italic text-gray-600">
|
|
||||||
{{ __('There are no students in this batch.') }}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<StudentModal
|
<StudentModal
|
||||||
:batch="props.batch.name"
|
:batch="props.batch.name"
|
||||||
v-model="showStudentModal"
|
v-model="showStudentModal"
|
||||||
@@ -267,6 +293,7 @@ const getChartData = () => {
|
|||||||
categories[course] = {
|
categories[course] = {
|
||||||
value: 0,
|
value: 0,
|
||||||
type: 'course',
|
type: 'course',
|
||||||
|
label: course,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -274,6 +301,7 @@ const getChartData = () => {
|
|||||||
categories[assessment] = {
|
categories[assessment] = {
|
||||||
value: 0,
|
value: 0,
|
||||||
type: 'assessment',
|
type: 'assessment',
|
||||||
|
label: assessment,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -294,15 +322,15 @@ const getChartData = () => {
|
|||||||
chartOptions.value = getChartOptions(categories)
|
chartOptions.value = getChartOptions(categories)
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
name: __('Student Progress'),
|
name: __('Completed by Students'),
|
||||||
data: Object.values(categories).map((item) => item.value),
|
data: Object.values(categories).map((item) => item.value),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
const getChartOptions = (categories) => {
|
const getChartOptions = (categories) => {
|
||||||
const courseColor = '#318AD8'
|
const courseColor = '#0289F7'
|
||||||
const assessmentColor = '#F683AE'
|
const assessmentColor = '#E03636'
|
||||||
const maxY = Math.ceil(students.data?.length / 10) * 10
|
const maxY = Math.ceil(students.data?.length / 10) * 10
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -325,21 +353,17 @@ const getChartOptions = (categories) => {
|
|||||||
item.type === 'course' ? courseColor : assessmentColor
|
item.type === 'course' ? courseColor : assessmentColor
|
||||||
),
|
),
|
||||||
legends: {
|
legends: {
|
||||||
show: true,
|
show: false,
|
||||||
markers: {
|
|
||||||
fillColors: [courseColor, assessmentColor],
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
xaxis: {
|
xaxis: {
|
||||||
categories: ['Courses', 'Assessments'],
|
categories: Object.values(categories).map((item) => item.label),
|
||||||
overwriteCategories: Object.keys(categories),
|
|
||||||
labels: {
|
labels: {
|
||||||
style: {
|
style: {
|
||||||
fontSize: '10px',
|
fontSize: '10px',
|
||||||
},
|
},
|
||||||
rotate: 0,
|
rotate: 0,
|
||||||
formatter: function (value) {
|
formatter: function (value) {
|
||||||
return value.length > 25 ? `${value.substring(0, 25)}...` : value // Trim long labels
|
return value.length > 22 ? `${value.substring(0, 22)}...` : value // Trim long labels
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -358,3 +382,8 @@ watch(students, () => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
<style>
|
||||||
|
.apexcharts-legend {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -59,15 +59,17 @@
|
|||||||
<div v-if="tab.label == 'Courses'">
|
<div v-if="tab.label == 'Courses'">
|
||||||
<BatchCourses :batch="batch.data.name" />
|
<BatchCourses :batch="batch.data.name" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="tab.label == 'Dashboard'">
|
<div v-else-if="tab.label == 'Dashboard' && isStudent">
|
||||||
<BatchDashboard :batch="batch" :isStudent="isStudent" />
|
<BatchDashboard :batch="batch" :isStudent="isStudent" />
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
v-else-if="tab.label == 'Dashboard' && user.data?.is_moderator"
|
||||||
|
>
|
||||||
|
<BatchStudents :batch="batch.data" />
|
||||||
|
</div>
|
||||||
<div v-else-if="tab.label == 'Live Class'">
|
<div v-else-if="tab.label == 'Live Class'">
|
||||||
<LiveClass :batch="batch.data.name" />
|
<LiveClass :batch="batch.data.name" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="tab.label == 'Students'">
|
|
||||||
<BatchStudents :batch="batch.data" />
|
|
||||||
</div>
|
|
||||||
<div v-else-if="tab.label == 'Assessments'">
|
<div v-else-if="tab.label == 'Assessments'">
|
||||||
<Assessments :batch="batch.data.name" />
|
<Assessments :batch="batch.data.name" />
|
||||||
</div>
|
</div>
|
||||||
@@ -259,34 +261,33 @@ const isStudent = computed(() => {
|
|||||||
const tabIndex = ref(0)
|
const tabIndex = ref(0)
|
||||||
const tabs = computed(() => {
|
const tabs = computed(() => {
|
||||||
let batchTabs = []
|
let batchTabs = []
|
||||||
if (isStudent.value) {
|
batchTabs.push({
|
||||||
batchTabs.push({
|
label: 'Dashboard',
|
||||||
label: 'Dashboard',
|
icon: LayoutDashboard,
|
||||||
icon: LayoutDashboard,
|
})
|
||||||
})
|
|
||||||
}
|
batchTabs.push({
|
||||||
|
label: 'Courses',
|
||||||
|
icon: BookOpen,
|
||||||
|
})
|
||||||
|
|
||||||
|
batchTabs.push({
|
||||||
|
label: 'Live Class',
|
||||||
|
icon: Laptop,
|
||||||
|
})
|
||||||
|
|
||||||
if (user.data?.is_moderator) {
|
if (user.data?.is_moderator) {
|
||||||
batchTabs.push({
|
|
||||||
label: 'Students',
|
|
||||||
icon: Contact2,
|
|
||||||
})
|
|
||||||
batchTabs.push({
|
batchTabs.push({
|
||||||
label: 'Assessments',
|
label: 'Assessments',
|
||||||
icon: BookOpenCheck,
|
icon: BookOpenCheck,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
batchTabs.push({
|
|
||||||
label: 'Live Class',
|
|
||||||
icon: Laptop,
|
|
||||||
})
|
|
||||||
batchTabs.push({
|
|
||||||
label: 'Courses',
|
|
||||||
icon: BookOpen,
|
|
||||||
})
|
|
||||||
batchTabs.push({
|
batchTabs.push({
|
||||||
label: 'Announcements',
|
label: 'Announcements',
|
||||||
icon: Mail,
|
icon: Mail,
|
||||||
})
|
})
|
||||||
|
|
||||||
batchTabs.push({
|
batchTabs.push({
|
||||||
label: 'Discussions',
|
label: 'Discussions',
|
||||||
icon: MessageCircle,
|
icon: MessageCircle,
|
||||||
|
|||||||
Reference in New Issue
Block a user