first commit

This commit is contained in:
Inshal
2024-05-29 22:34:28 +05:00
commit e63fc41a20
1470 changed files with 174828 additions and 0 deletions

View File

@@ -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>

View 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>

View File

@@ -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>

View 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>

View 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>

View 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>

View 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>