Merge pull request #884 from pateljannat/issues-21
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>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import Paragraph from '@editorjs/paragraph'
|
|||||||
import { CodeBox } from '@/utils/code'
|
import { CodeBox } from '@/utils/code'
|
||||||
import NestedList from '@editorjs/nested-list'
|
import NestedList from '@editorjs/nested-list'
|
||||||
import InlineCode from '@editorjs/inline-code'
|
import InlineCode from '@editorjs/inline-code'
|
||||||
import { watch, createApp } from 'vue'
|
import { watch } from 'vue'
|
||||||
import dayjs from '@/utils/dayjs'
|
import dayjs from '@/utils/dayjs'
|
||||||
import Embed from '@editorjs/embed'
|
import Embed from '@editorjs/embed'
|
||||||
|
|
||||||
@@ -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>",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -31,14 +31,16 @@ 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(
|
this.wrapper.innerHTML = `<img class="mb-4" src=${encodeURI(
|
||||||
file.file_url
|
file.file_url
|
||||||
)} width='100%'>`
|
)} width='100%'>`
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,50 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"condition": "{\n \"parent\": \"CLS-03050\"\n}",
|
|
||||||
"description": "You have successfully completed the VueJs + Frappe UI training.",
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "LMS Badge",
|
|
||||||
"enabled": 0,
|
|
||||||
"event": "Auto Assign",
|
|
||||||
"field_to_check": null,
|
|
||||||
"grant_only_once": 1,
|
|
||||||
"image": "/files/images.jpeg",
|
|
||||||
"modified": "2024-05-14 12:56:05.031313",
|
|
||||||
"name": "Batch Completion",
|
|
||||||
"reference_doctype": "Batch Student",
|
|
||||||
"title": "Batch Completion",
|
|
||||||
"user_field": "student"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"condition": "doc.progress == float(\"100.0\")",
|
|
||||||
"description": "You have completed your first course 👏",
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "LMS Badge",
|
|
||||||
"enabled": 0,
|
|
||||||
"event": "Value Change",
|
|
||||||
"field_to_check": "progress",
|
|
||||||
"grant_only_once": 1,
|
|
||||||
"image": "/files/icon_badge-04.png",
|
|
||||||
"modified": "2024-05-14 12:56:15.469656",
|
|
||||||
"name": "Course Completion",
|
|
||||||
"reference_doctype": "LMS Enrollment",
|
|
||||||
"title": "Course Completion",
|
|
||||||
"user_field": "member"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"condition": "doc.percentage == 100",
|
|
||||||
"description": "Congratulations on getting a 100% score on a quiz.",
|
|
||||||
"docstatus": 0,
|
|
||||||
"doctype": "LMS Badge",
|
|
||||||
"enabled": 0,
|
|
||||||
"event": "New",
|
|
||||||
"field_to_check": null,
|
|
||||||
"grant_only_once": 1,
|
|
||||||
"image": "/files/curiosity-badge-removebg-preview.png",
|
|
||||||
"modified": "2024-05-14 12:56:22.907584",
|
|
||||||
"name": "Quiz Completion",
|
|
||||||
"reference_doctype": "LMS Quiz Submission",
|
|
||||||
"title": "Quiz Completion",
|
|
||||||
"user_field": "member"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -115,7 +115,7 @@ scheduler_events = {
|
|||||||
"daily": ["lms.job.doctype.job_opportunity.job_opportunity.update_job_openings"],
|
"daily": ["lms.job.doctype.job_opportunity.job_opportunity.update_job_openings"],
|
||||||
}
|
}
|
||||||
|
|
||||||
fixtures = ["Custom Field", "Function", "Industry", "LMS Badge"]
|
fixtures = ["Custom Field", "Function", "Industry"]
|
||||||
|
|
||||||
# Testing
|
# Testing
|
||||||
# -------
|
# -------
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -21,8 +21,7 @@
|
|||||||
"list_columns": [],
|
"list_columns": [],
|
||||||
"login_required": 1,
|
"login_required": 1,
|
||||||
"max_attachment_size": 0,
|
"max_attachment_size": 0,
|
||||||
"meta_image": "/files/og_image_web_form_evaluation_68ddf18e.png",
|
"modified": "2023-08-23 14:37:03.086305",
|
||||||
"modified": "2023-08-23 14:37:03.086304",
|
|
||||||
"modified_by": "Administrator",
|
"modified_by": "Administrator",
|
||||||
"module": "LMS",
|
"module": "LMS",
|
||||||
"name": "evaluation",
|
"name": "evaluation",
|
||||||
|
|||||||
Reference in New Issue
Block a user