fix: job page layout
This commit is contained in:
@@ -6,9 +6,7 @@
|
|||||||
<audio @ended="handleAudioEnd" controlsList="nodownload" class="mb-4">
|
<audio @ended="handleAudioEnd" controlsList="nodownload" class="mb-4">
|
||||||
<source :src="encodeURI(file)" type="audio/mp3" />
|
<source :src="encodeURI(file)" type="audio/mp3" />
|
||||||
</audio>
|
</audio>
|
||||||
<div
|
<div class="flex items-center space-x-2 shadow rounded-lg p-1 w-1/2">
|
||||||
class="flex items-center space-x-2 shadow rounded-lg p-1 w-1/2 mx-auto"
|
|
||||||
>
|
|
||||||
<Button variant="ghost" @click="togglePlay">
|
<Button variant="ghost" @click="togglePlay">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<Play v-if="!isPlaying" class="w-4 h-4 text-gray-900" />
|
<Play v-if="!isPlaying" class="w-4 h-4 text-gray-900" />
|
||||||
|
|||||||
@@ -1,35 +1,29 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="flex shadow rounded-md p-4 h-full">
|
<div class="flex rounded px-2 py-2.5 hover:bg-gray-100">
|
||||||
<img
|
<div class="flex w-2/5">
|
||||||
:src="job.company_logo"
|
<img
|
||||||
class="w-12 h-12 rounded-lg object-contain mr-4"
|
:src="job.company_logo"
|
||||||
:alt="job.company_name"
|
class="w-12 h-12 rounded-lg object-contain mr-4"
|
||||||
/>
|
:alt="job.company_name"
|
||||||
<div>
|
/>
|
||||||
<div class="text-xl font-semibold mb-2">
|
|
||||||
{{ job.job_title }}
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
{{ __('posted by') }}
|
<div class="font-medium mb-1">
|
||||||
<span class="font-medium">
|
{{ job.job_title }}
|
||||||
|
</div>
|
||||||
|
<div class="text-gray-700">
|
||||||
{{ job.company_name }}
|
{{ job.company_name }}
|
||||||
</span>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="flex items-center my-4">
|
|
||||||
<Badge :label="job.type" theme="green" size="lg" class="mr-4" />
|
|
||||||
<Badge :label="job.location.split(' ')[0]" 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') }}
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex justify-end w-1/5 text-gray-700">
|
||||||
|
{{ job.location.replace(',', '').split(' ')[0] }}
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-end w-1/5 text-gray-700">
|
||||||
|
{{ job.type }}
|
||||||
|
</div>
|
||||||
|
<div class="flex justify-end w-1/5 text-sm text-gray-700 text-right">
|
||||||
|
{{ dayjs(job.creation).format('DD MMM YYYY') }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div class="flex flex-col shadow rounded-md p-4 h-full">
|
<!-- <div class="flex flex-col shadow rounded-md p-4 h-full">
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ const addFile = (data) => {
|
|||||||
|
|
||||||
const validateFile = (file) => {
|
const validateFile = (file) => {
|
||||||
let extension = file.name.split('.').pop().toLowerCase()
|
let extension = file.name.split('.').pop().toLowerCase()
|
||||||
if (!['jpg', 'jpeg', 'png', 'mp4', 'mov', 'mp3'].includes(extension)) {
|
if (!['jpg', 'jpeg', 'png', 'mp4', 'mov', 'mp3', 'pdf'].includes(extension)) {
|
||||||
return 'Only image and video files are allowed.'
|
return 'Only image and video files are allowed.'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,8 +50,8 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<div v-if="job.data">
|
<div v-if="job.data" class="w-3/4 mx-auto">
|
||||||
<div class="p-5 sm:p-5">
|
<div class="p-4">
|
||||||
<div class="flex mb-4">
|
<div class="flex mb-4">
|
||||||
<img
|
<img
|
||||||
:src="job.data.company_logo"
|
:src="job.data.company_logo"
|
||||||
@@ -114,8 +114,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Badge, Button, Breadcrumbs, createResource } from 'frappe-ui'
|
import { Button, Breadcrumbs, createResource } from 'frappe-ui'
|
||||||
import { inject, ref, onMounted } from 'vue'
|
import { inject, ref, computed } from 'vue'
|
||||||
|
import { updateDocumentTitle } from '@/utils'
|
||||||
|
import JobApplicationModal from '@/components/Modals/JobApplicationModal.vue'
|
||||||
import {
|
import {
|
||||||
MapPin,
|
MapPin,
|
||||||
SendHorizonal,
|
SendHorizonal,
|
||||||
@@ -125,7 +127,6 @@ import {
|
|||||||
ClipboardType,
|
ClipboardType,
|
||||||
SquareUserRound,
|
SquareUserRound,
|
||||||
} from 'lucide-vue-next'
|
} from 'lucide-vue-next'
|
||||||
import JobApplicationModal from '@/components/Modals/JobApplicationModal.vue'
|
|
||||||
|
|
||||||
const user = inject('$user')
|
const user = inject('$user')
|
||||||
const dayjs = inject('$dayjs')
|
const dayjs = inject('$dayjs')
|
||||||
@@ -185,4 +186,13 @@ const openApplicationModal = () => {
|
|||||||
const redirectToLogin = (job) => {
|
const redirectToLogin = (job) => {
|
||||||
window.location.href = `/login?redirect-to=/job-openings/${job}`
|
window.location.href = `/login?redirect-to=/job-openings/${job}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pageMeta = computed(() => {
|
||||||
|
return {
|
||||||
|
title: job.data?.job_title,
|
||||||
|
description: job.data?.description,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
updateDocumentTitle(pageMeta)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -26,9 +26,9 @@
|
|||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<div v-if="jobs.data">
|
<div v-if="jobs.data?.length">
|
||||||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-5 p-5">
|
<div class="divide-y w-3/4 mx-auto p-5">
|
||||||
<div v-if="jobs.data.length" v-for="job in jobs.data">
|
<div v-for="job in jobs.data">
|
||||||
<router-link
|
<router-link
|
||||||
:to="{
|
:to="{
|
||||||
name: 'JobDetail',
|
name: 'JobDetail',
|
||||||
@@ -41,13 +41,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else class="text-gray-700 italic p-5 w-fit mx-auto">
|
||||||
|
{{ __('No jobs posted') }}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Button, Breadcrumbs, createResource } from 'frappe-ui'
|
import { Button, Breadcrumbs, createResource } from 'frappe-ui'
|
||||||
import { Plus } from 'lucide-vue-next'
|
import { Plus } from 'lucide-vue-next'
|
||||||
import { inject } from 'vue'
|
import { inject, computed } from 'vue'
|
||||||
import JobCard from '@/components/JobCard.vue'
|
import JobCard from '@/components/JobCard.vue'
|
||||||
|
import { updateDocumentTitle } from '@/utils'
|
||||||
|
|
||||||
const user = inject('$user')
|
const user = inject('$user')
|
||||||
|
|
||||||
@@ -56,4 +60,13 @@ const jobs = createResource({
|
|||||||
cache: ['jobs'],
|
cache: ['jobs'],
|
||||||
auto: true,
|
auto: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const pageMeta = computed(() => {
|
||||||
|
return {
|
||||||
|
title: 'Jobs',
|
||||||
|
description: 'An open job board for the community',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
updateDocumentTitle(pageMeta)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
{{ formatNumber(chartDetails.data.courses) }}
|
{{ formatNumber(chartDetails.data.courses) }}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-gray-700">
|
<div class="text-gray-700">
|
||||||
{{ __('Published Courses') }}
|
{{ __('Courses') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
{{ formatNumber(chartDetails.data.users) }}
|
{{ formatNumber(chartDetails.data.users) }}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-gray-700">
|
<div class="text-gray-700">
|
||||||
{{ __('Total Signups') }}
|
{{ __('Signups') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
{{ formatNumber(chartDetails.data.enrollments) }}
|
{{ formatNumber(chartDetails.data.enrollments) }}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-gray-700">
|
<div class="text-gray-700">
|
||||||
{{ __('Enrolled Users') }}
|
{{ __('Enrollments') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
{{ formatNumber(chartDetails.data.completions) }}
|
{{ formatNumber(chartDetails.data.completions) }}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-gray-700">
|
<div class="text-gray-700">
|
||||||
{{ __('Courses Completed') }}
|
{{ __('Completions') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -68,7 +68,7 @@
|
|||||||
{{ formatNumber(chartDetails.data.lesson_completions) }}
|
{{ formatNumber(chartDetails.data.lesson_completions) }}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-gray-700">
|
<div class="text-gray-700">
|
||||||
{{ __('Lessons Completed') }}
|
{{ __('Milestones') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -109,6 +109,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { createResource, Breadcrumbs } from 'frappe-ui'
|
import { createResource, Breadcrumbs } from 'frappe-ui'
|
||||||
import { computed, inject } from 'vue'
|
import { computed, inject } from 'vue'
|
||||||
|
import { updateDocumentTitle } from '@/utils'
|
||||||
import { formatNumber } from '@/utils'
|
import { formatNumber } from '@/utils'
|
||||||
import { Line, Pie } from 'vue-chartjs'
|
import { Line, Pie } from 'vue-chartjs'
|
||||||
import {
|
import {
|
||||||
@@ -197,7 +198,7 @@ const courseCompletion = createResource({
|
|||||||
|
|
||||||
const signupChartOptions = () => {
|
const signupChartOptions = () => {
|
||||||
let options = chartOptions(false)
|
let options = chartOptions(false)
|
||||||
options.plugins.title.text = 'New Signups'
|
options.plugins.title.text = 'Signups'
|
||||||
options.borderColor = '#4563f0'
|
options.borderColor = '#4563f0'
|
||||||
options.backgroundColor = (ctx) => {
|
options.backgroundColor = (ctx) => {
|
||||||
const canvas = ctx.chart.ctx
|
const canvas = ctx.chart.ctx
|
||||||
@@ -213,7 +214,7 @@ const signupChartOptions = () => {
|
|||||||
|
|
||||||
const enrollmentChartOptions = () => {
|
const enrollmentChartOptions = () => {
|
||||||
let options = chartOptions(false)
|
let options = chartOptions(false)
|
||||||
options.plugins.title.text = 'Course Enrollments'
|
options.plugins.title.text = 'Enrollments'
|
||||||
options.borderColor = '#4563f0'
|
options.borderColor = '#4563f0'
|
||||||
options.backgroundColor = (ctx) => {
|
options.backgroundColor = (ctx) => {
|
||||||
const canvas = ctx.chart.ctx
|
const canvas = ctx.chart.ctx
|
||||||
@@ -229,7 +230,7 @@ const enrollmentChartOptions = () => {
|
|||||||
|
|
||||||
const lessonChartOptions = () => {
|
const lessonChartOptions = () => {
|
||||||
let options = chartOptions(false)
|
let options = chartOptions(false)
|
||||||
options.plugins.title.text = 'Lesson Completion'
|
options.plugins.title.text = 'Milestones'
|
||||||
options.borderColor = '#4563f0'
|
options.borderColor = '#4563f0'
|
||||||
options.backgroundColor = (ctx) => {
|
options.backgroundColor = (ctx) => {
|
||||||
const canvas = ctx.chart.ctx
|
const canvas = ctx.chart.ctx
|
||||||
@@ -245,7 +246,7 @@ const lessonChartOptions = () => {
|
|||||||
|
|
||||||
const courseChartOptions = () => {
|
const courseChartOptions = () => {
|
||||||
let options = chartOptions(true)
|
let options = chartOptions(true)
|
||||||
options.plugins.title.text = 'Course Completion'
|
options.plugins.title.text = 'Completions'
|
||||||
options.backgroundColor = ['#4563f0', '#f683ae']
|
options.backgroundColor = ['#4563f0', '#f683ae']
|
||||||
return options
|
return options
|
||||||
}
|
}
|
||||||
@@ -305,4 +306,13 @@ const chartOptions = (isPie) => {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pageMeta = computed(() => {
|
||||||
|
return {
|
||||||
|
title: 'Statistics',
|
||||||
|
description: 'Statistics of the platform',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
updateDocumentTitle(pageMeta)
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ export function getEditorTools() {
|
|||||||
regex: /https:\/\/docs\.google\.com\/presentation\/d\/e\/([A-Za-z0-9_-]+)\/pub/,
|
regex: /https:\/\/docs\.google\.com\/presentation\/d\/e\/([A-Za-z0-9_-]+)\/pub/,
|
||||||
embedUrl:
|
embedUrl:
|
||||||
'https://docs.google.com/presentation/d/e/<%= remote_id %>/embed',
|
'https://docs.google.com/presentation/d/e/<%= remote_id %>/embed',
|
||||||
html: "<iframe width='100%' height='300' frameborder='0' allowfullscreen='true'></iframe>",
|
html: "<iframe style='width: 100%; height: 28rem;' frameborder='0' allowfullscreen='true'></iframe>",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,12 +13,14 @@ export class Upload {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
console.log('render')
|
||||||
this.wrapper = document.createElement('div')
|
this.wrapper = document.createElement('div')
|
||||||
this.renderUpload(this.data)
|
this.renderUpload(this.data)
|
||||||
return this.wrapper
|
return this.wrapper
|
||||||
}
|
}
|
||||||
|
|
||||||
renderUpload(file) {
|
renderUpload(file) {
|
||||||
|
console.log(file.file_type)
|
||||||
if (this.isVideo(file.file_type)) {
|
if (this.isVideo(file.file_type)) {
|
||||||
const app = createApp(VideoBlock, {
|
const app = createApp(VideoBlock, {
|
||||||
file: file.file_url,
|
file: file.file_url,
|
||||||
@@ -31,14 +33,17 @@ export class Upload {
|
|||||||
})
|
})
|
||||||
app.mount(this.wrapper)
|
app.mount(this.wrapper)
|
||||||
return
|
return
|
||||||
} else if (file.file_type == 'pdf') {
|
} else if (file.file_type == 'PDF') {
|
||||||
return `<iframe src="${encodeURI(
|
this.wrapper.innerHTML = `<iframe src="${encodeURI(
|
||||||
file.file_url
|
file.file_url
|
||||||
)}#toolbar=0" width='100%' height='700px' class="mb-4"></iframe>`
|
)}#toolbar=0" width='100%' height='700px' class="mb-4"></iframe>`
|
||||||
|
return
|
||||||
} else {
|
} else {
|
||||||
return `<img class="mb-4" src=${encodeURI(
|
console.log('in else')
|
||||||
|
this.wrapper.innerHTML = `<img class="mb-4" src=${encodeURI(
|
||||||
file.file_url
|
file.file_url
|
||||||
)} width='100%'>`
|
)} width='100%'>`
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
],
|
],
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
|
"default": "Today",
|
||||||
"fieldname": "issue_date",
|
"fieldname": "issue_date",
|
||||||
"fieldtype": "Date",
|
"fieldtype": "Date",
|
||||||
"label": "Issue Date",
|
"label": "Issue Date",
|
||||||
@@ -88,7 +89,7 @@
|
|||||||
],
|
],
|
||||||
"index_web_pages_for_search": 1,
|
"index_web_pages_for_search": 1,
|
||||||
"links": [],
|
"links": [],
|
||||||
"modified": "2024-05-14 14:48:31.650107",
|
"modified": "2024-06-21 18:14:30.491841",
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "LMS Certificate",
|
"name": "LMS Certificate",
|
||||||
|
|||||||
Reference in New Issue
Block a user