fix: course creation form validations
This commit is contained in:
@@ -55,7 +55,7 @@
|
||||
{{ resume.file_name }}
|
||||
</span>
|
||||
<span class="text-sm text-gray-500 mt-1">
|
||||
{{ getFileSize() }}
|
||||
{{ getFileSize(resume.file_size) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -67,7 +67,7 @@
|
||||
import { Dialog, FileUploader, Button, createResource } from 'frappe-ui'
|
||||
import { FileText } from 'lucide-vue-next'
|
||||
import { ref, inject, defineModel } from 'vue'
|
||||
import { createToast } from '@/utils/'
|
||||
import { createToast, getFileSize } from '@/utils/'
|
||||
|
||||
const resume = ref(null)
|
||||
const show = defineModel()
|
||||
@@ -87,16 +87,6 @@ const validateFile = (file) => {
|
||||
}
|
||||
}
|
||||
|
||||
const getFileSize = () => {
|
||||
let value = parseInt(resume.value.file_size)
|
||||
if (value > 1048576) {
|
||||
return (value / 1048576).toFixed(2) + 'M'
|
||||
} else if (value > 1024) {
|
||||
return (value / 1024).toFixed(2) + 'K'
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
const jobApplication = createResource({
|
||||
url: 'frappe.client.insert',
|
||||
makeParams(values) {
|
||||
|
||||
@@ -48,6 +48,7 @@ import { sessionStore } from '@/stores/session'
|
||||
import { Dropdown } from 'frappe-ui'
|
||||
import { ChevronDown, LogIn, LogOut, User } from 'lucide-vue-next'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { convertToTitleCase } from '../utils'
|
||||
|
||||
const router = useRouter()
|
||||
const props = defineProps({
|
||||
@@ -94,18 +95,4 @@ const userDropdownOptions = [
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
function convertToTitleCase(str) {
|
||||
if (!str) {
|
||||
return ''
|
||||
}
|
||||
|
||||
return str
|
||||
.toLowerCase()
|
||||
.split(' ')
|
||||
.map(function (word) {
|
||||
return word.charAt(0).toUpperCase().concat(word.substr(1))
|
||||
})
|
||||
.join(' ')
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -25,11 +25,15 @@
|
||||
</Button>
|
||||
</header>
|
||||
<div class="container mt-5">
|
||||
<Input v-model="course.title" :label="__('Title')" class="mb-2" />
|
||||
<Input
|
||||
<FormControl
|
||||
v-model="course.title"
|
||||
:label="__('Title')"
|
||||
class="mb-4"
|
||||
/>
|
||||
<FormControl
|
||||
v-model="course.short_introduction"
|
||||
:label="__('Short Introduction')"
|
||||
class="mb-2"
|
||||
class="mb-4"
|
||||
/>
|
||||
<div class="mb-4">
|
||||
<div class="mb-1.5 text-sm text-gray-700">
|
||||
@@ -37,35 +41,81 @@
|
||||
</div>
|
||||
<TextEditor
|
||||
:content="course.description"
|
||||
@change="(val) => (topic.reply = val)"
|
||||
@change="(val) => (course.description = val)"
|
||||
:editable="true"
|
||||
:fixedMenu="true"
|
||||
editorClass="prose-sm max-w-none border-b border-x bg-gray-100 rounded-b-md py-1 px-2 min-h-[7rem]"
|
||||
/>
|
||||
</div>
|
||||
<Input
|
||||
<FormControl
|
||||
v-model="course.video_link"
|
||||
:label="__('Preview Video')"
|
||||
class="mb-2"
|
||||
class="mb-4"
|
||||
/>
|
||||
<Input v-model="course.tags" :label="__('Tags')" class="mb-2" />
|
||||
<FileUploader
|
||||
v-if="!course.image"
|
||||
:fileTypes="['image/*']"
|
||||
:validateFile="validateFile"
|
||||
@success="
|
||||
(file) => {
|
||||
console.log(file)
|
||||
course.image = file
|
||||
console.log(course.image)
|
||||
}
|
||||
"
|
||||
>
|
||||
<template v-slot="{ file, progress, uploading, openFileSelector }">
|
||||
<div class="mb-4">
|
||||
<Button @click="openFileSelector" :loading="uploading">
|
||||
{{ uploading ? `Uploading ${progress}%` : 'Upload an image' }}
|
||||
</Button>
|
||||
</div>
|
||||
</template>
|
||||
</FileUploader>
|
||||
<div v-else class="flex items-center">
|
||||
<div class="border rounded-md p-2 mr-2">
|
||||
<FileText class="h-5 w-5 stroke-1.5 text-gray-700" />
|
||||
</div>
|
||||
<div class="flex flex-col">
|
||||
<span>
|
||||
{{ course.image }}
|
||||
</span>
|
||||
<span class="text-sm text-gray-500 mt-1">
|
||||
{{ getFileSize(course.image) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<FormControl v-model="course.tags" :label="__('Tags')" class="mb-4" />
|
||||
<div class="flex items-center mb-4">
|
||||
<Checkbox v-model="course.published" :label="__('Published')" />
|
||||
<Checkbox
|
||||
<FormControl
|
||||
type="checkbox"
|
||||
v-model="course.published"
|
||||
:label="__('Published')"
|
||||
/>
|
||||
<FormControl
|
||||
type="checkbox"
|
||||
v-model="course.upcoming"
|
||||
:label="__('Upcoming')"
|
||||
class="ml-20"
|
||||
/>
|
||||
</div>
|
||||
<Checkbox
|
||||
v-model="course.paid_course"
|
||||
:label="__('Paid Course')"
|
||||
class="mb-2"
|
||||
/>
|
||||
<Input
|
||||
<div class="mb-4">
|
||||
<FormControl
|
||||
type="checkbox"
|
||||
v-model="course.paid_course"
|
||||
:label="__('Paid Course')"
|
||||
/>
|
||||
</div>
|
||||
<FormControl
|
||||
v-model="course.course_price"
|
||||
:label="__('Course Price')"
|
||||
class="mb-2"
|
||||
class="mb-4"
|
||||
/>
|
||||
<Link
|
||||
doctype="Currency"
|
||||
v-model="course.currency"
|
||||
:filters="{ enabled: 1 }"
|
||||
:label="__('Currency')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -76,14 +126,16 @@
|
||||
<script setup>
|
||||
import {
|
||||
Breadcrumbs,
|
||||
Input,
|
||||
TextEditor,
|
||||
Checkbox,
|
||||
Button,
|
||||
createDocumentResource,
|
||||
createResource,
|
||||
FormControl,
|
||||
FileUploader,
|
||||
} from 'frappe-ui'
|
||||
import { reactive, inject, onMounted } from 'vue'
|
||||
import { convertToTitleCase, createToast, getFileSize } from '../utils'
|
||||
import Link from '@/components/Controls/Link.vue'
|
||||
import { FileText } from 'lucide-vue-next'
|
||||
|
||||
const user = inject('$user')
|
||||
|
||||
@@ -103,7 +155,7 @@ const course = reactive({
|
||||
upcoming: false,
|
||||
image: null,
|
||||
paid_course: false,
|
||||
course_price: 0,
|
||||
course_price: null,
|
||||
currency: '',
|
||||
})
|
||||
|
||||
@@ -118,14 +170,48 @@ const courseResource = createResource({
|
||||
}
|
||||
},
|
||||
})
|
||||
console.log(courseResource)
|
||||
|
||||
const submitCourse = () => {
|
||||
courseResource.submit(
|
||||
{},
|
||||
{
|
||||
validate() {},
|
||||
validate() {
|
||||
const mandatory_fields = [
|
||||
'title',
|
||||
'short_introduction',
|
||||
'description',
|
||||
'video_link',
|
||||
'image',
|
||||
]
|
||||
for (const field of mandatory_fields) {
|
||||
if (!course[field]) {
|
||||
let fieldLabel = convertToTitleCase(field.split('_').join(' '))
|
||||
return `${fieldLabel} is mandatory`
|
||||
}
|
||||
}
|
||||
if (course.paid_course && (!course.course_price || !course.currency)) {
|
||||
return 'Course price and currency are mandatory for paid courses'
|
||||
}
|
||||
},
|
||||
onError(err) {
|
||||
createToast({
|
||||
title: 'Error',
|
||||
text: err.messages?.[0] || err,
|
||||
icon: 'x',
|
||||
iconClasses: 'bg-red-600 text-white rounded-md p-px',
|
||||
position: 'top-center',
|
||||
timeout: 10,
|
||||
})
|
||||
},
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
const validateFile = (file) => {
|
||||
console.log(file)
|
||||
let extension = file.name.split('.').pop().toLowerCase()
|
||||
if (!['jpg', 'jpeg', 'png'].includes(extension)) {
|
||||
return 'Only image file is allowed.'
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -41,6 +41,29 @@ export function formatNumberIntoCurrency(number, currency) {
|
||||
return ''
|
||||
}
|
||||
|
||||
export function convertToTitleCase(str) {
|
||||
if (!str) {
|
||||
return ''
|
||||
}
|
||||
|
||||
return str
|
||||
.toLowerCase()
|
||||
.split(' ')
|
||||
.map(function (word) {
|
||||
return word.charAt(0).toUpperCase().concat(word.substr(1))
|
||||
})
|
||||
.join(' ')
|
||||
}
|
||||
export function getFileSize(file_size) {
|
||||
let value = parseInt(file_size)
|
||||
if (value > 1048576) {
|
||||
return (value / 1048576).toFixed(2) + 'M'
|
||||
} else if (value > 1024) {
|
||||
return (value / 1024).toFixed(2) + 'K'
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
export function getTimezones() {
|
||||
return [
|
||||
'Pacific/Midway',
|
||||
|
||||
@@ -75,7 +75,8 @@
|
||||
{
|
||||
"fieldname": "video_link",
|
||||
"fieldtype": "Data",
|
||||
"label": "Video Embed Link"
|
||||
"label": "Video Embed Link",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "short_introduction",
|
||||
@@ -92,7 +93,8 @@
|
||||
{
|
||||
"fieldname": "image",
|
||||
"fieldtype": "Attach Image",
|
||||
"label": "Preview Image"
|
||||
"label": "Preview Image",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "tags",
|
||||
@@ -266,7 +268,7 @@
|
||||
}
|
||||
],
|
||||
"make_attachments_public": 1,
|
||||
"modified": "2023-12-21 12:27:32.559901",
|
||||
"modified": "2024-02-28 11:20:47.700649",
|
||||
"modified_by": "Administrator",
|
||||
"module": "LMS",
|
||||
"name": "LMS Course",
|
||||
|
||||
Reference in New Issue
Block a user