fix: cleanup ui

This commit is contained in:
Jannat Patel
2024-02-05 17:35:46 +05:30
parent 4b9d3bd996
commit af48ccfb57
10 changed files with 185 additions and 2559 deletions

View File

@@ -15,13 +15,13 @@
"markdown-it": "^14.0.0", "markdown-it": "^14.0.0",
"pinia": "^2.0.33", "pinia": "^2.0.33",
"socket.io-client": "^4.7.2", "socket.io-client": "^4.7.2",
"tailwindcss": "^3.2.7", "tailwindcss": "^3.3.3",
"vue": "^3.2.25", "vue": "^3.2.25",
"vue-chartjs": "^5.0.0", "vue-chartjs": "^5.0.0",
"vue-router": "^4.0.12" "vue-router": "^4.0.12"
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-vue": "^2.0.0", "@vitejs/plugin-vue": "^5.0.3",
"autoprefixer": "^10.4.2", "autoprefixer": "^10.4.2",
"postcss": "^8.4.5", "postcss": "^8.4.5",
"vite": "^5.0.11" "vite": "^5.0.11"

View File

@@ -153,8 +153,8 @@ const props = defineProps({
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
background-color: theme('colors.gray.200'); background-color: theme('colors.orange.100');
color: theme('colors.gray.700'); color: theme('colors.orange.600');
} }
.avatar-group { .avatar-group {

View File

@@ -1,5 +1,5 @@
<template> <template>
<div class="border border-gray-200 rounded-md min-w-80"> <div class="shadow rounded-md min-w-80">
<iframe <iframe
v-if="course.data.video_link" v-if="course.data.video_link"
:src="video_link" :src="video_link"
@@ -70,13 +70,13 @@
<div class="mt-8 mb-4 font-medium"> <div class="mt-8 mb-4 font-medium">
{{ __('This course has:') }} {{ __('This course has:') }}
</div> </div>
<div class="flex items-center mb-4"> <div class="flex items-center mb-3">
<BookOpen class="h-5 w-5 stroke-1.5 text-gray-600" /> <BookOpen class="h-5 w-5 stroke-1.5 text-gray-600" />
<span class="ml-2"> <span class="ml-2">
{{ course.data.lesson_count }} {{ __('Lessons') }} {{ course.data.lesson_count }} {{ __('Lessons') }}
</span> </span>
</div> </div>
<div class="flex items-center mb-4"> <div class="flex items-center mb-3">
<Users class="h-5 w-5 stroke-1.5 text-gray-600" /> <Users class="h-5 w-5 stroke-1.5 text-gray-600" />
<span class="ml-2"> <span class="ml-2">
{{ course.data.enrollment_count_formatted }} {{ course.data.enrollment_count_formatted }}

View File

@@ -52,10 +52,12 @@
<script setup> <script setup>
import { Star } from 'lucide-vue-next' import { Star } from 'lucide-vue-next'
import { createResource, Button } from 'frappe-ui' import { createResource, Button } from 'frappe-ui'
import { computed, ref } from 'vue' import { computed, ref, inject } from 'vue'
import UserAvatar from '@/components/UserAvatar.vue' import UserAvatar from '@/components/UserAvatar.vue'
import ReviewModal from '@/components/Modals/ReviewModal.vue' import ReviewModal from '@/components/Modals/ReviewModal.vue'
const user = inject('$user')
const props = defineProps({ const props = defineProps({
courseName: { courseName: {
type: String, type: String,
@@ -81,12 +83,9 @@ const hasReviewed = createResource({
owner: props.membership?.member, owner: props.membership?.member,
}, },
}, },
auto: true, auto: user.data?.name ? true : false,
}) })
const reversedRange = (count) =>
Array.from({ length: count }, (_, index) => count - index)
const reviews = createResource({ const reviews = createResource({
url: 'lms.lms.utils.get_reviews', url: 'lms.lms.utils.get_reviews',
cache: ['course_reviews', props.courseName], cache: ['course_reviews', props.courseName],
@@ -96,26 +95,6 @@ const reviews = createResource({
auto: true, auto: true,
}) })
const rating_percent = computed(() => {
let rating_count = {}
let rating_percent = {}
for (const key of [1, 2, 3, 4, 5]) {
rating_count[key] = 0
}
for (const review of reviews?.data) {
rating_count[review.rating] += 1
}
;[1, 2, 3, 4, 5].forEach((key) => {
rating_percent[key] = (
(rating_count[key] / reviews.data.length) *
100
).toFixed(2)
})
return rating_percent
})
const showReviewModal = ref(false) const showReviewModal = ref(false)
function openReviewModal() { function openReviewModal() {

View File

@@ -1,34 +1,69 @@
<template> <template>
<div class="flex border rounded-md p-2 mb-4 h-full"> <div class="flex shadow rounded-md p-4 h-full">
<div class="mr-4"> <img
<img :src="job.company_logo"
:src="job.company_logo" class="w-12 h-12 rounded-lg object-contain mr-4"
class="w-11 h-11 rounded-lg object-contain" />
/>
</div>
<div> <div>
<div class="text-lg font-semibold mb-2"> <div class="text-xl font-semibold mb-2">
{{ job.job_title }} {{ job.job_title }}
</div> </div>
<div class="flex items-center mb-2 text-gray-700"> <div>
<div class="mr-5"> {{ __('posted by') }}
<span class="font-medium">
{{ job.company_name }} {{ job.company_name }}
</div> </span>
<div class="flex items-center">
<MapPin class="h-4 w-4 mr-1 stroke-1.5" />
<span class="text-gray-700">
{{ job.location }}
</span>
</div>
</div> </div>
<div class="flex items-center"> <div class="flex items-center my-4">
<Badge :label="job.type" theme="green" /> <Badge :label="job.type" theme="green" size="lg" class="mr-4" />
<div class="ml-5"> <Badge :label="job.location" theme="gray" size="lg">
<template #prefix>
<MapPin class="h-4 w-4 stroke-1.5" />
</template>
</Badge>
</div>
<div>
{{ __('posted on') }}
<span class="font-medium">
{{ dayjs(job.creation).format('DD MMM YYYY') }} {{ dayjs(job.creation).format('DD MMM YYYY') }}
</div> </span>
</div> </div>
</div> </div>
</div> </div>
<!-- <div class="flex flex-col shadow rounded-md p-4 h-full">
<div class="flex justify-between">
<div>
<div class="text-xl font-semibold mb-2">
{{ job.job_title }}
</div>
<div>
{{ __("posted by") }}
<span class="font-medium">
{{ job.company_name }}
</span>
</div>
</div>
<img
:src="job.company_logo"
class="w-12 h-12 rounded-lg object-contain"
/>
</div>
<div class="flex justify-between mt-8">
<div class="flex items-center">
<Badge :label="job.type" theme="green" size="lg" class="mr-4"/>
<Badge :label="job.location" theme="gray" size="lg">
<template #prefix>
<MapPin class="h-4 w-4 stroke-1.5" />
</template>
</Badge>
</div>
<div>
<span class="font-medium">
{{ dayjs(job.creation).format('DD MMM YYYY') }}
</span>
</div>
</div>
</div> -->
</template> </template>
<script setup> <script setup>
import { MapPin } from 'lucide-vue-next' import { MapPin } from 'lucide-vue-next'

View File

@@ -1,33 +1,45 @@
<template> <template>
<Dropdown :options="userDropdownOptions"> <Dropdown :options="userDropdownOptions">
<template v-slot="{ open }"> <template v-slot="{ open }">
<button class="flex h-12 py-2 items-center rounded-md duration-300 ease-in-out" :class="isCollapsed <button
? 'px-0 w-auto' class="flex h-12 py-2 items-center rounded-md duration-300 ease-in-out"
: open :class="
? 'bg-white shadow-sm px-2 w-52' isCollapsed
: 'hover:bg-gray-200 px-2 w-52' ? 'px-0 w-auto'
"> : open
<LMSLogo class="w-8 h-8 rounded flex-shrink-0" /> ? 'bg-white shadow-sm px-2 w-52'
<div class="flex flex-1 flex-col text-left duration-300 ease-in-out" :class="isCollapsed : 'hover:bg-gray-200 px-2 w-52'
? 'opacity-0 ml-0 w-0 overflow-hidden' "
: 'opacity-100 ml-2 w-auto' >
"> <LMSLogo class="w-8 h-8 rounded flex-shrink-0" />
<div class="text-base font-medium text-gray-900 leading-none"> <div
LMS class="flex flex-1 flex-col text-left duration-300 ease-in-out"
</div> :class="
<div v-if="user" class="mt-1 text-sm text-gray-700 leading-none"> isCollapsed
{{ convertToTitleCase(user.split('@')[0]) }} ? 'opacity-0 ml-0 w-0 overflow-hidden'
</div> : 'opacity-100 ml-2 w-auto'
</div> "
<div class="duration-300 ease-in-out" :class="isCollapsed >
? 'opacity-0 ml-0 w-0 overflow-hidden' <div class="text-base font-medium text-gray-900 leading-none">
: 'opacity-100 ml-2 w-auto' Learning
"> </div>
<ChevronDown class="h-4 w-4 text-gray-700" /> <div v-if="user" class="mt-1 text-sm text-gray-700 leading-none">
</div> {{ convertToTitleCase(user.split('@')[0]) }}
</button> </div>
</template> </div>
</Dropdown> <div
class="duration-300 ease-in-out"
:class="
isCollapsed
? 'opacity-0 ml-0 w-0 overflow-hidden'
: 'opacity-100 ml-2 w-auto'
"
>
<ChevronDown class="h-4 w-4 text-gray-700" />
</div>
</button>
</template>
</Dropdown>
</template> </template>
<script setup> <script setup>
@@ -37,47 +49,51 @@ import { Dropdown } from 'frappe-ui'
import { ChevronDown } from 'lucide-vue-next' import { ChevronDown } from 'lucide-vue-next'
const props = defineProps({ const props = defineProps({
isCollapsed: { isCollapsed: {
type: Boolean, type: Boolean,
default: false, default: false,
}, },
}) })
const { logout, user } = sessionStore() const { logout, user } = sessionStore()
let { isLoggedIn } = sessionStore(); let { isLoggedIn } = sessionStore()
const userDropdownOptions = [ const userDropdownOptions = [
{ {
icon: 'log-out', icon: 'log-out',
label: 'Log out', label: 'Log out',
onClick: () => { onClick: () => {
logout.submit().then(() => { logout.submit().then(() => {
isLoggedIn = false; isLoggedIn = false
}); })
}, },
condition: () => { condition: () => {
return isLoggedIn return isLoggedIn
} },
}, },
{ {
icon: 'log-in', icon: 'log-in',
label: 'Log in', label: 'Log in',
onClick: () => { onClick: () => {
window.location.href = '/login' window.location.href = '/login'
}, },
condition: () => { condition: () => {
return !isLoggedIn return !isLoggedIn
} },
} },
]; ]
function convertToTitleCase(str) { function convertToTitleCase(str) {
if (!str) { if (!str) {
return "" return ''
} }
return str.toLowerCase().split(' ').map(function (word) { return str
return word.charAt(0).toUpperCase().concat(word.substr(1)); .toLowerCase()
}).join(' '); .split(' ')
.map(function (word) {
return word.charAt(0).toUpperCase().concat(word.substr(1))
})
.join(' ')
} }
</script> </script>

View File

@@ -1,27 +1,48 @@
<template> <template>
<header <div class="text-base h-screen">
class="sticky top-0 z-10 flex items-center justify-between border-b bg-white px-3 py-2.5 sm:px-5" <header
> class="sticky top-0 z-10 flex items-center justify-between border-b bg-white px-3 py-2.5 sm:px-5"
<Breadcrumbs >
class="h-7" <Breadcrumbs
:items="[{ label: __('Jobs'), route: { name: 'Jobs' } }]" class="h-7"
/> :items="[{ label: __('Jobs'), route: { name: 'Jobs' } }]"
<div class="flex"> />
<Button v-if="user.data?.name" variant="solid"> <div class="flex">
<template #prefix> <Button v-if="user.data?.name" variant="solid">
<Plus class="h-4 w-4" /> <template #prefix>
</template> <Plus class="h-4 w-4" />
{{ __('New Job') }} </template>
</Button> {{ __('New Job') }}
</div> </Button>
</header> </div>
<div></div> </header>
<div></div>
</div>
</template> </template>
<script setup> <script setup>
import {
createDocumentResource,
Button,
Breadcrumbs,
createResource,
} from 'frappe-ui'
import { inject } from 'vue'
import { Plus } from 'lucide-vue-next'
const user = inject('$user')
const props = defineProps({ const props = defineProps({
job: { job: {
type: String, type: String,
required: true, required: true,
}, },
}) })
const job = createResource({
url: 'lms.lms.api.get_job_details',
params: {
job: props.job,
},
cache: ['job'],
auto: true,
})
</script> </script>

View File

@@ -41,7 +41,7 @@ import JobCard from '@/components/JobCard.vue'
const user = inject('$user') const user = inject('$user')
const jobs = createResource({ const jobs = createResource({
url: 'lms.lms.utils.get_job_opportunities', url: 'lms.lms.api.get_job_opportunities',
cache: ['jobs'], cache: ['jobs'],
auto: true, auto: true,
}) })

View File

@@ -361,12 +361,6 @@ const hideLesson = () => {
transition: margin 0.1s ease-in-out; transition: margin 0.1s ease-in-out;
} }
iframe {
border: 1px solid #ddd;
border-radius: 0.5rem;
margin-bottom: 1rem;
}
.lesson-content p { .lesson-content p {
margin-bottom: 1rem; margin-bottom: 1rem;
line-height: 1.7; line-height: 1.7;

File diff suppressed because it is too large Load Diff