first commit
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
<script setup>
|
||||
const assignmentData = [
|
||||
{
|
||||
title: 'User Experience Design',
|
||||
tasks: 120,
|
||||
progress: 72,
|
||||
color: 'primary',
|
||||
},
|
||||
{
|
||||
title: 'Basic fundamentals',
|
||||
tasks: 32,
|
||||
progress: 48,
|
||||
color: 'success',
|
||||
},
|
||||
{
|
||||
title: 'React Native components',
|
||||
tasks: 182,
|
||||
progress: 15,
|
||||
color: 'error',
|
||||
},
|
||||
{
|
||||
title: 'Basic of music theory',
|
||||
tasks: 56,
|
||||
progress: 24,
|
||||
color: 'info',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem title="Assignment progress">
|
||||
<template #append>
|
||||
<MoreBtn />
|
||||
</template>
|
||||
</VCardItem>
|
||||
<VCardText>
|
||||
<VList class="card-list">
|
||||
<VListItem
|
||||
v-for="assignment in assignmentData"
|
||||
:key="assignment.title"
|
||||
>
|
||||
<template #prepend>
|
||||
<VProgressCircular
|
||||
v-model="assignment.progress"
|
||||
:size="54"
|
||||
class="me-4"
|
||||
:color="assignment.color"
|
||||
>
|
||||
<h6 class="text-h6">
|
||||
{{ assignment.progress }}%
|
||||
</h6>
|
||||
</VProgressCircular>
|
||||
</template>
|
||||
<template #title>
|
||||
<div class="text-h6 me-4 mb-2 text-truncate">
|
||||
{{ assignment.title }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<VListItemSubtitle>{{ assignment.tasks }} Tasks</VListItemSubtitle>
|
||||
<template #append>
|
||||
<VBtn
|
||||
variant="tonal"
|
||||
color="secondary"
|
||||
class="rounded"
|
||||
size="34"
|
||||
>
|
||||
<VIcon
|
||||
icon="ri-arrow-right-s-line"
|
||||
size="20"
|
||||
class="flip-in-rtl"
|
||||
/>
|
||||
</VBtn>
|
||||
</template>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-list {
|
||||
--v-card-list-gap: 1.5rem;
|
||||
}
|
||||
</style>
|
238
resources/js/views/apps/academy/AcademyCardInterestedTopics.vue
Normal file
238
resources/js/views/apps/academy/AcademyCardInterestedTopics.vue
Normal file
@@ -0,0 +1,238 @@
|
||||
<script setup>
|
||||
const borderColor = 'rgba(var(--v-border-color), var(--v-border-opacity))'
|
||||
|
||||
// Topics Charts config
|
||||
const topicsChartConfig = {
|
||||
chart: {
|
||||
height: 270,
|
||||
type: 'bar',
|
||||
toolbar: { show: false },
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
horizontal: true,
|
||||
barHeight: '70%',
|
||||
distributed: true,
|
||||
borderRadius: 7,
|
||||
borderRadiusApplication: 'end',
|
||||
},
|
||||
},
|
||||
colors: [
|
||||
'rgba(var(--v-theme-primary),1)',
|
||||
'#16B1FF',
|
||||
'#56CA00',
|
||||
'#8A8D93',
|
||||
'#FF4C51',
|
||||
'#FFB400',
|
||||
],
|
||||
grid: {
|
||||
borderColor,
|
||||
strokeDashArray: 10,
|
||||
xaxis: { lines: { show: true } },
|
||||
yaxis: { lines: { show: false } },
|
||||
padding: {
|
||||
top: -35,
|
||||
bottom: -12,
|
||||
},
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
style: {
|
||||
colors: ['#fff'],
|
||||
fontWeight: 200,
|
||||
fontSize: '13px',
|
||||
},
|
||||
offsetX: 0,
|
||||
dropShadow: { enabled: false },
|
||||
formatter(val, opt) {
|
||||
return topicsChartConfig.labels[opt.dataPointIndex]
|
||||
},
|
||||
},
|
||||
labels: [
|
||||
'UI Design',
|
||||
'UX Design',
|
||||
'Music',
|
||||
'Animation',
|
||||
'Vue',
|
||||
'SEO',
|
||||
],
|
||||
xaxis: {
|
||||
categories: [
|
||||
'6',
|
||||
'5',
|
||||
'4',
|
||||
'3',
|
||||
'2',
|
||||
'1',
|
||||
],
|
||||
axisBorder: { show: false },
|
||||
axisTicks: { show: false },
|
||||
labels: {
|
||||
style: {
|
||||
colors: 'rgba(var(--v-theme-on-background), var(--v-disabled-opacity))',
|
||||
fontSize: '13px',
|
||||
},
|
||||
formatter(val) {
|
||||
return `${ val }%`
|
||||
},
|
||||
},
|
||||
},
|
||||
yaxis: {
|
||||
max: 35,
|
||||
labels: {
|
||||
style: {
|
||||
colors: 'rgba(var(--v-theme-on-background), var(--v-disabled-opacity))',
|
||||
fontSize: '13px',
|
||||
},
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
enabled: true,
|
||||
style: { fontSize: '12px' },
|
||||
onDatasetHover: { highlightDataSeries: false },
|
||||
},
|
||||
legend: { show: false },
|
||||
}
|
||||
|
||||
const topicsChartSeries = [{
|
||||
data: [
|
||||
35,
|
||||
20,
|
||||
14,
|
||||
12,
|
||||
10,
|
||||
9,
|
||||
],
|
||||
}]
|
||||
|
||||
const topicsData = [
|
||||
{
|
||||
title: 'UI Design',
|
||||
value: 35,
|
||||
color: 'primary',
|
||||
},
|
||||
{
|
||||
title: 'UX Design',
|
||||
value: 20,
|
||||
color: 'info',
|
||||
},
|
||||
{
|
||||
title: 'Music',
|
||||
value: 14,
|
||||
color: 'success',
|
||||
},
|
||||
]
|
||||
|
||||
const moreTopics = [
|
||||
{
|
||||
title: 'Animation',
|
||||
value: 12,
|
||||
color: 'secondary',
|
||||
},
|
||||
{
|
||||
title: 'Vue',
|
||||
value: 10,
|
||||
color: 'error',
|
||||
},
|
||||
{
|
||||
title: 'SEO',
|
||||
value: 9,
|
||||
color: 'warning',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard class="topicCard">
|
||||
<VCardItem title="Topic you are interested in">
|
||||
<template #append>
|
||||
<MoreBtn />
|
||||
</template>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
<VRow>
|
||||
<VCol
|
||||
cols="12"
|
||||
sm="6"
|
||||
>
|
||||
<VueApexCharts
|
||||
type="bar"
|
||||
height="300"
|
||||
:options="topicsChartConfig"
|
||||
:series="topicsChartSeries"
|
||||
class="mb-md-0 mb-6"
|
||||
/>
|
||||
</VCol>
|
||||
|
||||
<VCol class="d-flex justify-space-around align-center">
|
||||
<div class="d-flex flex-column gap-y-12">
|
||||
<div
|
||||
v-for="topic in topicsData"
|
||||
:key="topic.title"
|
||||
class="d-flex gap-x-2"
|
||||
>
|
||||
<VBadge
|
||||
inline
|
||||
dot
|
||||
:color="topic.color"
|
||||
class="mt-1"
|
||||
/>
|
||||
<div>
|
||||
<div
|
||||
class="text-body-1"
|
||||
style="min-inline-size: 90px;"
|
||||
>
|
||||
{{ topic.title }}
|
||||
</div>
|
||||
<h5 class="text-h5">
|
||||
{{ topic.value }}%
|
||||
</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-column gap-y-12">
|
||||
<div
|
||||
v-for="topic in moreTopics"
|
||||
:key="topic.title"
|
||||
class="d-flex gap-x-2"
|
||||
>
|
||||
<VBadge
|
||||
inline
|
||||
dot
|
||||
:color="topic.color"
|
||||
class="mt-1"
|
||||
/>
|
||||
<div>
|
||||
<div
|
||||
class="text-body-1"
|
||||
style="min-inline-size: 90px;"
|
||||
>
|
||||
{{ topic.title }}
|
||||
</div>
|
||||
<h5 class="text-h5">
|
||||
{{ topic.value }}%
|
||||
</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</VCol>
|
||||
</VRow>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@use "@core-scss/template/libs/apex-chart.scss";
|
||||
|
||||
.topicCard{
|
||||
.v-badge.v-badge--dot{
|
||||
.v-badge__badge{
|
||||
border-radius: 6px;
|
||||
block-size: 12px;
|
||||
inline-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -0,0 +1,61 @@
|
||||
<script setup>
|
||||
import avatar1 from '@images/avatars/avatar-1.png'
|
||||
import avatar2 from '@images/avatars/avatar-2.png'
|
||||
import avatar3 from '@images/avatars/avatar-3.png'
|
||||
import avatar4 from '@images/avatars/avatar-4.png'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem title="Popular Instructors">
|
||||
<template #append>
|
||||
<MoreBtn />
|
||||
</template>
|
||||
</VCardItem>
|
||||
<VDivider />
|
||||
<div class="text-overline d-flex justify-space-between px-5 py-4">
|
||||
<div>instructors</div>
|
||||
<div>Courses</div>
|
||||
</div>
|
||||
<VDivider />
|
||||
<VCardText>
|
||||
<VList class="card-list">
|
||||
<VListItem
|
||||
v-for="instructor in [
|
||||
{ name: 'Jordan Stevenson', profession: 'Business Intelligence', totalCourses: 33, avatar: avatar1 },
|
||||
{ name: 'Bentlee Emblin', profession: 'Digital Marketing', totalCourses: 52, avatar: avatar2 },
|
||||
{ name: 'Benedetto Rossiter', profession: 'UI/UX Design', totalCourses: 12, avatar: avatar3 },
|
||||
{ name: 'Beverlie Krabbe', profession: 'Vue', totalCourses: 8, avatar: avatar4 },
|
||||
]"
|
||||
:key="instructor.name"
|
||||
>
|
||||
<template #prepend>
|
||||
<VAvatar
|
||||
size="34"
|
||||
:image="instructor.avatar"
|
||||
/>
|
||||
</template>
|
||||
<h6 class="text-h6">
|
||||
{{ instructor.name }}
|
||||
</h6>
|
||||
<div class="text-caption text-medium-emphasis">
|
||||
{{ instructor.profession }}
|
||||
</div>
|
||||
|
||||
<template #append>
|
||||
<div class="text-body-1 text-high-emphasis">
|
||||
{{ instructor.totalCourses }}
|
||||
</div>
|
||||
</template>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card-list{
|
||||
--v-card-list-gap: 16px;
|
||||
|
||||
}
|
||||
</style>
|
82
resources/js/views/apps/academy/AcademyCardTopCourses.vue
Normal file
82
resources/js/views/apps/academy/AcademyCardTopCourses.vue
Normal file
@@ -0,0 +1,82 @@
|
||||
<script setup>
|
||||
const coursesData = [
|
||||
{
|
||||
title: 'Videography Basic Design Course',
|
||||
views: '1.2k',
|
||||
icon: 'ri-video-download-line',
|
||||
color: 'primary',
|
||||
},
|
||||
{
|
||||
title: 'Basic Front-end Development Course',
|
||||
views: '834',
|
||||
icon: 'ri-code-view',
|
||||
color: 'info',
|
||||
},
|
||||
{
|
||||
title: 'Basic Fundamentals of Photography',
|
||||
views: '3.7k',
|
||||
icon: 'ri-image-2-line',
|
||||
color: 'success',
|
||||
},
|
||||
{
|
||||
title: 'Advance Dribble Base Visual Design',
|
||||
views: '2.5k',
|
||||
icon: 'ri-palette-line',
|
||||
color: 'warning',
|
||||
},
|
||||
{
|
||||
title: 'Your First Singing Lesson',
|
||||
views: '948',
|
||||
icon: 'ri-music-2-line',
|
||||
color: 'error',
|
||||
},
|
||||
]
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardItem title="Top Courses">
|
||||
<template #append>
|
||||
<MoreBtn />
|
||||
</template>
|
||||
</VCardItem>
|
||||
|
||||
<VCardText>
|
||||
<VList class="card-list">
|
||||
<VListItem
|
||||
v-for="(course, index) in coursesData"
|
||||
:key="index"
|
||||
>
|
||||
<template #prepend>
|
||||
<VAvatar
|
||||
rounded
|
||||
variant="tonal"
|
||||
:color="course.color"
|
||||
>
|
||||
<VIcon
|
||||
:icon="course.icon"
|
||||
size="24"
|
||||
/>
|
||||
</VAvatar>
|
||||
</template>
|
||||
|
||||
<template #title>
|
||||
<div class="text-h6 clamp-text text-wrap me-4">
|
||||
{{ course.title }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #append>
|
||||
<VChip
|
||||
variant="tonal"
|
||||
color="secondary"
|
||||
size="small"
|
||||
>
|
||||
{{ course.views }} Views
|
||||
</VChip>
|
||||
</template>
|
||||
</VListItem>
|
||||
</VList>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
219
resources/js/views/apps/academy/AcademyCourseTable.vue
Normal file
219
resources/js/views/apps/academy/AcademyCourseTable.vue
Normal file
@@ -0,0 +1,219 @@
|
||||
<script setup>
|
||||
const searchQuery = ref('')
|
||||
|
||||
// Data table options
|
||||
const itemsPerPage = ref(5)
|
||||
const page = ref(1)
|
||||
const sortBy = ref()
|
||||
const orderBy = ref()
|
||||
|
||||
const updateOptions = options => {
|
||||
page.value = options.page
|
||||
sortBy.value = options.sortBy[0]?.key
|
||||
orderBy.value = options.sortBy[0]?.order
|
||||
}
|
||||
|
||||
const headers = [
|
||||
{
|
||||
title: 'Course Name',
|
||||
key: 'courseName',
|
||||
},
|
||||
{
|
||||
title: 'Time',
|
||||
key: 'time',
|
||||
sortable: false,
|
||||
},
|
||||
{
|
||||
title: 'Progress',
|
||||
key: 'progress',
|
||||
},
|
||||
{
|
||||
title: 'Status',
|
||||
key: 'status',
|
||||
sortable: false,
|
||||
},
|
||||
]
|
||||
|
||||
const { data: courseData } = await useApi(createUrl('/apps/academy/courses', {
|
||||
query: {
|
||||
q: searchQuery,
|
||||
itemsPerPage,
|
||||
page,
|
||||
sortBy,
|
||||
orderBy,
|
||||
},
|
||||
}))
|
||||
|
||||
const courses = computed(() => courseData.value.courses)
|
||||
const totalCourse = computed(() => courseData.value.total)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardText>
|
||||
<div class="d-flex flex-wrap justify-space-between align-center gap-4">
|
||||
<h5 class="text-h5">
|
||||
Courses you are taking
|
||||
</h5>
|
||||
<VTextField
|
||||
v-model="searchQuery"
|
||||
placeholder="Search Course"
|
||||
density="compact"
|
||||
style="max-inline-size: 300px; min-inline-size: 200px;"
|
||||
/>
|
||||
</div>
|
||||
</VCardText>
|
||||
|
||||
<VDataTableServer
|
||||
v-model:items-per-page="itemsPerPage"
|
||||
:items-per-page-options="[
|
||||
{ value: 5, title: '5' },
|
||||
{ value: 10, title: '10' },
|
||||
{ value: 20, title: '20' },
|
||||
{ value: -1, title: '$vuetify.dataFooter.itemsPerPageAll' },
|
||||
]"
|
||||
:headers="headers"
|
||||
:items="courses"
|
||||
item-value="id"
|
||||
:items-length="totalCourse"
|
||||
show-select
|
||||
class="text-no-wrap"
|
||||
@update:options="updateOptions"
|
||||
>
|
||||
<template #item.courseName="{ item }">
|
||||
<div class="d-flex align-center gap-x-4 py-2">
|
||||
<VAvatar
|
||||
variant="tonal"
|
||||
rounded
|
||||
:color="item.color"
|
||||
>
|
||||
<VIcon
|
||||
:icon="item.logo"
|
||||
size="28"
|
||||
/>
|
||||
</VAvatar>
|
||||
<div>
|
||||
<RouterLink
|
||||
:to="{ name: 'apps-academy-course-details' }"
|
||||
class="d-inline-block text-h6 mb-1"
|
||||
>
|
||||
{{ item.courseTitle }}
|
||||
</RouterLink>
|
||||
<div class="d-flex align-center">
|
||||
<VAvatar
|
||||
size="22"
|
||||
:image="item.image"
|
||||
class="me-2"
|
||||
/>
|
||||
<div class="text-body-2 text-high-emphasis">
|
||||
{{ item.user }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #item.time="{ item }">
|
||||
<h6 class="text-h6">
|
||||
{{ item.time }}
|
||||
</h6>
|
||||
</template>
|
||||
|
||||
<template #item.progress="{ item }">
|
||||
<div
|
||||
class="d-flex align-center gap-x-4 mb-2"
|
||||
style="inline-size: 15.625rem;"
|
||||
>
|
||||
<div class="text-no-wrap text-h6">
|
||||
{{ Math.floor((item.completedTasks / item.totalTasks) * 100) }}%
|
||||
</div>
|
||||
<div class="w-100">
|
||||
<VProgressLinear
|
||||
color="primary"
|
||||
height="8"
|
||||
:model-value="Math.floor((item.completedTasks / item.totalTasks) * 100)"
|
||||
rounded
|
||||
/>
|
||||
</div>
|
||||
<div class="text-body-2">
|
||||
{{ item.completedTasks }}/{{ item.totalTasks }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #item.status="{ item }">
|
||||
<div class="d-flex justify-space-between gap-x-4">
|
||||
<div class="d-flex gap-x-2 align-center">
|
||||
<VIcon
|
||||
icon="ri-group-line"
|
||||
color="primary"
|
||||
size="24"
|
||||
/>
|
||||
<span class="text-body-1">
|
||||
{{ item.userCount }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="d-flex gap-x-2 align-center">
|
||||
<VIcon
|
||||
icon="ri-computer-line"
|
||||
color="info"
|
||||
size="24"
|
||||
/>
|
||||
<span class="text-body-1">{{ item.note }}</span>
|
||||
</div>
|
||||
<div class="d-flex gap-x-2 align-center">
|
||||
<VIcon
|
||||
icon="ri-video-upload-line"
|
||||
color="error"
|
||||
size="24"
|
||||
/>
|
||||
<span class="text-body-1">{{ item.view }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Pagination -->
|
||||
<template #bottom>
|
||||
<VDivider />
|
||||
|
||||
<div class="d-flex justify-end flex-wrap gap-x-6 px-2 py-1">
|
||||
<div class="d-flex align-center gap-x-2 text-medium-emphasis text-base">
|
||||
Rows Per Page:
|
||||
<VSelect
|
||||
v-model="itemsPerPage"
|
||||
class="per-page-select"
|
||||
variant="plain"
|
||||
:items="[10, 20, 25, 50, 100]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<p class="d-flex align-center text-base text-high-emphasis me-2 mb-0">
|
||||
{{ paginationMeta({ page, itemsPerPage }, totalCourse) }}
|
||||
</p>
|
||||
|
||||
<div class="d-flex gap-x-2 align-center me-2">
|
||||
<VBtn
|
||||
class="flip-in-rtl text-high-emphasis"
|
||||
icon="ri-arrow-left-s-line"
|
||||
variant="text"
|
||||
density="comfortable"
|
||||
color="high-emphasis"
|
||||
:disabled="page <= 1"
|
||||
@click="page <= 1 ? page = 1 : page--"
|
||||
/>
|
||||
|
||||
<VBtn
|
||||
class="flip-in-rtl text-high-emphasis"
|
||||
icon="ri-arrow-right-s-line"
|
||||
density="comfortable"
|
||||
variant="text"
|
||||
color="high-emphasis"
|
||||
:disabled="page >= Math.ceil(totalCourse / itemsPerPage)"
|
||||
@click="page >= Math.ceil(totalCourse / itemsPerPage) ? page = Math.ceil(totalCourse / itemsPerPage) : page++ "
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</VDataTableServer>
|
||||
</VCard>
|
||||
</template>
|
234
resources/js/views/apps/academy/AcademyMyCourses.vue
Normal file
234
resources/js/views/apps/academy/AcademyMyCourses.vue
Normal file
@@ -0,0 +1,234 @@
|
||||
<script setup>
|
||||
const props = defineProps({
|
||||
searchQuery: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
})
|
||||
|
||||
const itemsPerPage = ref(6)
|
||||
const page = ref(1)
|
||||
const sortBy = ref()
|
||||
const orderBy = ref()
|
||||
const hideCompleted = ref(true)
|
||||
const label = ref('All Courses')
|
||||
|
||||
const { data: coursesData } = await useApi(createUrl('/apps/academy/courses', {
|
||||
query: {
|
||||
q: () => props.searchQuery,
|
||||
hideCompleted,
|
||||
label,
|
||||
itemsPerPage,
|
||||
page,
|
||||
sortBy,
|
||||
orderBy,
|
||||
},
|
||||
}))
|
||||
|
||||
const courses = computed(() => coursesData.value.courses)
|
||||
const totalCourse = computed(() => coursesData.value.total)
|
||||
|
||||
watch([
|
||||
hideCompleted,
|
||||
label,
|
||||
() => props.searchQuery,
|
||||
], () => {
|
||||
page.value = 1
|
||||
})
|
||||
|
||||
const resolveChipColor = tags => {
|
||||
if (tags === 'Web')
|
||||
return 'primary'
|
||||
if (tags === 'Art')
|
||||
return 'success'
|
||||
if (tags === 'UI/UX')
|
||||
return 'error'
|
||||
if (tags === 'Psychology')
|
||||
return 'warning'
|
||||
if (tags === 'Design')
|
||||
return 'info'
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard class="mb-6">
|
||||
<VCardText>
|
||||
<!-- 👉 Header -->
|
||||
<div class="d-flex justify-space-between align-center flex-wrap gap-4 mb-6">
|
||||
<div>
|
||||
<h5 class="text-h5">
|
||||
My Courses
|
||||
</h5>
|
||||
<div class="text-body-1">
|
||||
Total 6 course you have purchased
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex flex-wrap align-center gap-y-4 gap-x-6">
|
||||
<VSelect
|
||||
v-model="label"
|
||||
density="compact"
|
||||
:items="[
|
||||
{ title: 'Web', value: 'web' },
|
||||
{ title: 'Art', value: 'art' },
|
||||
{ title: 'UI/UX', value: 'ui/ux' },
|
||||
{ title: 'Psychology', value: 'psychology' },
|
||||
{ title: 'Design', value: 'design' },
|
||||
{ title: 'All Courses', value: 'All Courses' },
|
||||
]"
|
||||
style="min-inline-size: 250px;"
|
||||
/>
|
||||
<VSwitch
|
||||
v-model="hideCompleted"
|
||||
label="Hide Completed"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 👉 Course List -->
|
||||
<div class="mb-6">
|
||||
<VRow class="match-height">
|
||||
<template
|
||||
v-for="course in courses"
|
||||
:key="course.id"
|
||||
>
|
||||
<VCol
|
||||
cols="12"
|
||||
md="4"
|
||||
sm="6"
|
||||
>
|
||||
<VCard
|
||||
flat
|
||||
border
|
||||
>
|
||||
<div class="pa-2">
|
||||
<VImg
|
||||
:src="course.tutorImg"
|
||||
class="cursor-pointer"
|
||||
@click="() => $router.push({ name: 'apps-academy-course-details' })"
|
||||
/>
|
||||
</div>
|
||||
<VCardText class="pt-3">
|
||||
<div class="d-flex justify-space-between align-center mb-4">
|
||||
<VChip
|
||||
variant="tonal"
|
||||
:color="resolveChipColor(course.tags)"
|
||||
size="small"
|
||||
>
|
||||
{{ course.tags }}
|
||||
</VChip>
|
||||
<div class="d-flex">
|
||||
<h6 class="text-h6 text-medium-emphasis me-1">
|
||||
{{ course.rating }}
|
||||
</h6>
|
||||
<VIcon
|
||||
icon="ri-star-fill"
|
||||
color="warning"
|
||||
class="me-2"
|
||||
/>
|
||||
<div class="text-body-1">
|
||||
({{ course.ratingCount }})
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h5 class="text-h5 mb-1">
|
||||
<RouterLink
|
||||
:to="{ name: 'apps-academy-course-details' }"
|
||||
class="course-title"
|
||||
>
|
||||
{{ course.courseTitle }}
|
||||
</RouterLink>
|
||||
</h5>
|
||||
<p>
|
||||
{{ course.desc }}
|
||||
</p>
|
||||
|
||||
<div
|
||||
v-if="course.completedTasks !== course.totalTasks"
|
||||
class="d-flex align-center mb-1"
|
||||
>
|
||||
<VIcon
|
||||
icon="ri-time-line"
|
||||
size="20"
|
||||
class="me-1"
|
||||
/>
|
||||
<div class="text-body-1 my-auto">
|
||||
{{ course.time }}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="mb-2"
|
||||
>
|
||||
<VIcon
|
||||
icon="ri-check-line"
|
||||
color="success"
|
||||
class="me-1"
|
||||
/>
|
||||
<span class="text-success text-body-1">Completed</span>
|
||||
</div>
|
||||
|
||||
<VProgressLinear
|
||||
:model-value="(course.completedTasks / course.totalTasks) * 100"
|
||||
rounded
|
||||
rounded-bar
|
||||
color="primary"
|
||||
height="8"
|
||||
class="mb-4"
|
||||
/>
|
||||
|
||||
<div class="d-flex flex-wrap gap-4">
|
||||
<VBtn
|
||||
variant="outlined"
|
||||
color="secondary"
|
||||
class="flex-grow-1"
|
||||
:to="{ name: 'apps-academy-course-details' }"
|
||||
>
|
||||
<template #prepend>
|
||||
<VIcon
|
||||
icon="ri-refresh-line"
|
||||
class="flip-in-rtl"
|
||||
/>
|
||||
</template>
|
||||
Start Over
|
||||
</VBtn>
|
||||
<VBtn
|
||||
v-if="course.completedTasks !== course.totalTasks"
|
||||
variant="outlined"
|
||||
class="flex-grow-1"
|
||||
:to="{ name: 'apps-academy-course-details' }"
|
||||
>
|
||||
<template #append>
|
||||
<VIcon
|
||||
icon="ri-arrow-right-line"
|
||||
class="flip-in-rtl"
|
||||
/>
|
||||
</template>
|
||||
Continue
|
||||
</VBtn>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</VCol>
|
||||
</template>
|
||||
</VRow>
|
||||
</div>
|
||||
|
||||
<VPagination
|
||||
v-model="page"
|
||||
rounded
|
||||
color="primary"
|
||||
:length="Math.ceil(totalCourse / itemsPerPage)"
|
||||
/>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.course-title{
|
||||
&:not(:hover){
|
||||
color: rgba(var(--v-theme-on-surface), var(--v-text-high-emphasis))
|
||||
}
|
||||
}
|
||||
</style>
|
51
resources/js/views/apps/academy/AcademyUpcomingWebinar.vue
Normal file
51
resources/js/views/apps/academy/AcademyUpcomingWebinar.vue
Normal file
@@ -0,0 +1,51 @@
|
||||
<script setup>
|
||||
import girlWithLaptop from '@images/pages/pose-fs-9.png'
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VCard>
|
||||
<VCardText>
|
||||
<div class="d-flex justify-center align-start pb-0 px-3 pt-3 mb-6 bg-light-primary rounded">
|
||||
<VImg
|
||||
:src="girlWithLaptop"
|
||||
width="145"
|
||||
height="140"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<h5 class="text-h5 mb-1">
|
||||
Upcoming Webinar
|
||||
</h5>
|
||||
<div class="text-body-1">
|
||||
Next Generation Frontend Architecture Using Layout Engine And Vue.
|
||||
</div>
|
||||
<div class="d-flex justify-space-between my-6 gap-4 flex-wrap">
|
||||
<div
|
||||
v-for="{ icon, title, value } in [{ icon: 'ri-calendar-line', title: '17 Nov 23', value: 'Date' }, { icon: 'ri-time-line', title: '32 Minutes', value: 'Duration' }]"
|
||||
:key="title"
|
||||
class="d-flex gap-x-4 align-center"
|
||||
>
|
||||
<VAvatar
|
||||
color="primary"
|
||||
variant="tonal"
|
||||
rounded
|
||||
>
|
||||
<VIcon :icon="icon" />
|
||||
</VAvatar>
|
||||
<div>
|
||||
<div class="text-body-1 text-high-emphasis">
|
||||
{{ title }}
|
||||
</div>
|
||||
<div class="text-caption text-medium-emphasis">
|
||||
{{ value }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<VBtn block>
|
||||
Join the event
|
||||
</VBtn>
|
||||
</div>
|
||||
</VCardText>
|
||||
</VCard>
|
||||
</template>
|
Reference in New Issue
Block a user