feat: upcoming evals
This commit is contained in:
47
frontend/src/components/Assessments.vue
Normal file
47
frontend/src/components/Assessments.vue
Normal file
@@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="text-lg font-semibold mb-4">
|
||||
{{ __('Assessments') }}
|
||||
</div>
|
||||
<div v-if="assessments?.length">
|
||||
<ListView
|
||||
:columns="getAssessmentColumns()"
|
||||
:rows="attempts?.data"
|
||||
row-key="name"
|
||||
:options="{ selectable: false, showTooltip: false }"
|
||||
>
|
||||
</ListView>
|
||||
</div>
|
||||
<div v-else class="text-sm italic text-gray-600">
|
||||
{{ __('No Assessments') }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { ListView } from 'frappe-ui'
|
||||
|
||||
const props = defineProps({
|
||||
assessments: {
|
||||
type: Array,
|
||||
default: [],
|
||||
},
|
||||
})
|
||||
|
||||
const getSubmissionColumns = () => {
|
||||
return [
|
||||
{
|
||||
label: 'Assessment',
|
||||
key: 'title',
|
||||
},
|
||||
{
|
||||
label: 'Type',
|
||||
key: 'type',
|
||||
},
|
||||
{
|
||||
label: 'Status/Score',
|
||||
key: 'status',
|
||||
align: 'center',
|
||||
},
|
||||
]
|
||||
}
|
||||
</script>
|
||||
@@ -29,7 +29,7 @@
|
||||
</div>
|
||||
<div class="flex items-center mb-3">
|
||||
<BookOpen class="h-4 w-4 stroke-1.5 mr-2 text-gray-700" />
|
||||
<span> {{ batch.courses }} {{ __('Courses') }} </span>
|
||||
<span> {{ batch.courses.length }} {{ __('Courses') }} </span>
|
||||
</div>
|
||||
<div class="flex items-center mb-3">
|
||||
<Calendar class="h-4 w-4 stroke-1.5 mr-2 text-gray-700" />
|
||||
|
||||
17
frontend/src/components/BatchDashboard.vue
Normal file
17
frontend/src/components/BatchDashboard.vue
Normal file
@@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<div>
|
||||
<UpcomingEvaluations :upcoming_evals="batch.data.upcoming_evals" />
|
||||
<Assessments :assessments="batch.data.assessments" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import UpcomingEvaluations from './UpcomingEvaluations.vue'
|
||||
import Assessments from './Assessments.vue'
|
||||
|
||||
const props = defineProps({
|
||||
batch: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
@@ -1,38 +1,38 @@
|
||||
<template>
|
||||
<div class="shadow rounded-md p-5" style="width: 300px">
|
||||
<div v-if="batch.data" class="shadow rounded-md p-5" style="width: 300px">
|
||||
<Badge
|
||||
v-if="batch.doc.seat_count && seats_left > 0"
|
||||
v-if="batch.data.seat_count && seats_left > 0"
|
||||
theme="green"
|
||||
class="self-start mb-2 float-right"
|
||||
>
|
||||
{{ seats_left }} {{ __('Seat Left') }}
|
||||
</Badge>
|
||||
<Badge
|
||||
v-else-if="batch.doc.seat_count && seats_left <= 0"
|
||||
v-else-if="batch.data.seat_count && seats_left <= 0"
|
||||
theme="red"
|
||||
class="self-start mb-2 float-right"
|
||||
>
|
||||
{{ __('Sold Out') }}
|
||||
</Badge>
|
||||
<div v-if="batch.doc.amount" class="text-lg font-semibold mb-3">
|
||||
{{ formatNumberIntoCurrency(batch.doc.amount, batch.doc.currency) }}
|
||||
<div v-if="batch.data.amount" class="text-lg font-semibold mb-3">
|
||||
{{ formatNumberIntoCurrency(batch.data.amount, batch.data.currency) }}
|
||||
</div>
|
||||
<div class="flex items-center mb-3">
|
||||
<BookOpen class="h-4 w-4 stroke-1.5 mr-2 text-gray-700" />
|
||||
<span> {{ batch.doc.courses.length }} {{ __('Courses') }} </span>
|
||||
<span> {{ batch.data.courses.length }} {{ __('Courses') }} </span>
|
||||
</div>
|
||||
<div class="flex items-center mb-3">
|
||||
<Calendar class="h-4 w-4 stroke-1.5 mr-2 text-gray-700" />
|
||||
<span>
|
||||
{{ dayjs(batch.doc.start_date).format('DD MMM YYYY') }} -
|
||||
{{ dayjs(batch.doc.end_date).format('DD MMM YYYY') }}
|
||||
{{ dayjs(batch.data.start_date).format('DD MMM YYYY') }} -
|
||||
{{ dayjs(batch.data.end_date).format('DD MMM YYYY') }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<Clock class="h-4 w-4 stroke-1.5 mr-2 text-gray-700" />
|
||||
<span>
|
||||
{{ formatTime(batch.doc.start_time) }} -
|
||||
{{ formatTime(batch.doc.end_time) }}
|
||||
{{ formatTime(batch.data.start_time) }} -
|
||||
{{ formatTime(batch.data.end_time) }}
|
||||
</span>
|
||||
</div>
|
||||
<Button v-if="user?.data?.is_moderator" class="w-full mt-4">
|
||||
@@ -41,7 +41,7 @@
|
||||
</span>
|
||||
</Button>
|
||||
<Button
|
||||
v-else-if="batch.doc.paid_batch"
|
||||
v-else-if="batch.data.paid_batch"
|
||||
class="w-full mt-4"
|
||||
variant="solid"
|
||||
>
|
||||
@@ -73,8 +73,8 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
const seats_left = computed(() => {
|
||||
if (props.batch.doc.seat_count) {
|
||||
return props.batch.doc.seat_count - props.batch.doc.students.length
|
||||
if (props.batch.data?.seat_count) {
|
||||
return props.batch.data?.seat_count - props.batch.data?.students?.length
|
||||
}
|
||||
return null
|
||||
})
|
||||
|
||||
@@ -114,35 +114,13 @@ import { Badge, createResource } from 'frappe-ui'
|
||||
import { ref, watchEffect } from 'vue'
|
||||
|
||||
const { user } = sessionStore()
|
||||
let course = ref({})
|
||||
|
||||
const props = defineProps({
|
||||
course: {
|
||||
type: [Object, String],
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
})
|
||||
|
||||
const courseDetails = createResource({
|
||||
url: 'lms.lms.utils.get_course_details',
|
||||
cache: ['course', props.courseName],
|
||||
makeParams() {
|
||||
return {
|
||||
course: props.course,
|
||||
}
|
||||
},
|
||||
transform(data) {
|
||||
course.value = data
|
||||
},
|
||||
})
|
||||
|
||||
/* watchEffect(() => {
|
||||
if (props.course && typeof props.course === "object") {
|
||||
course.value = props.course;
|
||||
} else {
|
||||
courseDetails.reload();
|
||||
}
|
||||
}); */
|
||||
</script>
|
||||
<style>
|
||||
.course-image {
|
||||
|
||||
53
frontend/src/components/UpcomingEvaluations.vue
Normal file
53
frontend/src/components/UpcomingEvaluations.vue
Normal file
@@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<div class="mb-10">
|
||||
<div class="text-lg font-semibold mb-4">
|
||||
{{ __('Upcoming Evaluations') }}
|
||||
</div>
|
||||
<div v-if="upcoming_evals.length">
|
||||
<div class="grid grid-cols-2">
|
||||
<div v-for="evl in upcoming_evals">
|
||||
<div class="border rounded-md p-3">
|
||||
<div class="font-medium mb-3">
|
||||
{{ evl.course_title }}
|
||||
</div>
|
||||
<div class="flex items-center mb-2">
|
||||
<Calendar class="w-4 h-4 stroke-1.5" />
|
||||
<span class="ml-2">
|
||||
{{ dayjs(evl.date).format('DD MMMM YYYY') }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center mb-2">
|
||||
<Clock class="w-4 h-4 stroke-1.5" />
|
||||
<span class="ml-2">
|
||||
{{ formatTime(evl.start_time) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<UserCog2 class="w-4 h-4 stroke-1.5" />
|
||||
<span class="ml-2">
|
||||
{{ evl.evaluator_name }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="text-sm italic text-gray-600">
|
||||
{{ __('No upcoming evaluations.') }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { Calendar, Clock, UserCog2 } from 'lucide-vue-next'
|
||||
import { inject } from 'vue'
|
||||
import { formatTime } from '../utils'
|
||||
|
||||
const dayjs = inject('$dayjs')
|
||||
|
||||
const props = defineProps({
|
||||
upcoming_evals: {
|
||||
type: Array,
|
||||
default: [],
|
||||
},
|
||||
})
|
||||
</script>
|
||||
Reference in New Issue
Block a user