mirror of
https://github.com/frappe/lms.git
synced 2026-05-02 13:39:31 +03:00
Merge pull request #2246 from frappe/misc/fixes
fix: misc issues in batch
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
:fileTypes="[fileType]"
|
||||
:validateFile="(file: File) => validateFile(file, true, type)"
|
||||
@success="(file: File) => saveFile(file)"
|
||||
@failure="onUploadFailure"
|
||||
>
|
||||
<template v-slot="{ file, progress, uploading, openFileSelector }">
|
||||
<div class="flex items-center">
|
||||
@@ -19,8 +20,8 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
<Button @click="openFileSelector">
|
||||
{{ __('Upload') }}
|
||||
<Button @click="openFileSelector" :loading="uploading">
|
||||
{{ uploading ? `${__('Uploading')} ${progress}%` : __('Upload') }}
|
||||
</Button>
|
||||
<div class="mt-1 text-ink-gray-5 text-sm leading-5">
|
||||
{{ __(description) }}
|
||||
@@ -62,7 +63,7 @@
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { validateFile } from '@/utils'
|
||||
import { Button, FileUploader } from 'frappe-ui'
|
||||
import { Button, FileUploader, toast } from 'frappe-ui'
|
||||
import { Image, Video } from 'lucide-vue-next'
|
||||
import { computed } from 'vue'
|
||||
|
||||
@@ -100,4 +101,14 @@ const saveFile = (file: any) => {
|
||||
const removeImage = () => {
|
||||
emit('update:modelValue', '')
|
||||
}
|
||||
|
||||
const onUploadFailure = (error: any) => {
|
||||
let message = __('Error Uploading File')
|
||||
if (error?._server_messages) {
|
||||
message = JSON.parse(JSON.parse(error._server_messages)[0]).message
|
||||
} else if (error?.exc) {
|
||||
message = JSON.parse(error.exc)[0].split('\n').slice(-2, -1)[0]
|
||||
}
|
||||
toast.error(message)
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,100 +1,108 @@
|
||||
<template>
|
||||
<div v-if="batch.data" class="border-2 rounded-md p-5 lg:w-72">
|
||||
<Badge
|
||||
v-if="batch.data.seat_count && batch.data.seats_left > 0"
|
||||
variant="subtle"
|
||||
theme="green"
|
||||
size="md"
|
||||
:class="
|
||||
batch.data.amount || batch.data.courses.length
|
||||
? 'float-right'
|
||||
: 'w-fit mb-4'
|
||||
"
|
||||
:label="
|
||||
batch.data.seats_left +
|
||||
' ' +
|
||||
(batch.data.seats_left > 1 ? __('Seats Left') : __('Seat Left'))
|
||||
"
|
||||
<div v-if="batch.data" class="border-2 rounded-md lg:w-72">
|
||||
<video
|
||||
v-if="batch.data.video_link"
|
||||
:src="batch.data.video_link"
|
||||
controls
|
||||
class="rounded-t-md w-full"
|
||||
/>
|
||||
<Badge
|
||||
v-else-if="batch.data.seat_count && batch.data.seats_left <= 0"
|
||||
variant="subtle"
|
||||
theme="red"
|
||||
size="md"
|
||||
class="float-right"
|
||||
:label="__('Sold Out')"
|
||||
/>
|
||||
<div
|
||||
v-if="batch.data.amount"
|
||||
class="text-lg font-semibold mb-5 text-ink-gray-9"
|
||||
>
|
||||
{{ formatNumberIntoCurrency(batch.data.amount, batch.data.currency) }}
|
||||
</div>
|
||||
<div
|
||||
v-if="batch.data.courses.length"
|
||||
class="flex items-center mb-3 text-ink-gray-7"
|
||||
>
|
||||
<BookOpen class="h-4 w-4 stroke-1.5 mr-2" />
|
||||
<span> {{ batch.data.courses.length }} {{ __('Courses') }} </span>
|
||||
</div>
|
||||
<DateRange
|
||||
:startDate="batch.data.start_date"
|
||||
:endDate="batch.data.end_date"
|
||||
class="mb-3"
|
||||
/>
|
||||
<div class="flex items-center mb-3 text-ink-gray-7">
|
||||
<Clock class="h-4 w-4 stroke-1.5 mr-2" />
|
||||
<span>
|
||||
{{ formatTime(batch.data.start_time) }} -
|
||||
{{ formatTime(batch.data.end_time) }}
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="batch.data.timezone" class="flex items-center text-ink-gray-7">
|
||||
<Globe class="h-4 w-4 stroke-1.5 mr-2" />
|
||||
<span>
|
||||
{{ batch.data.timezone }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="p-5">
|
||||
<Badge
|
||||
v-if="batch.data.seat_count && batch.data.seats_left > 0"
|
||||
variant="subtle"
|
||||
theme="green"
|
||||
size="md"
|
||||
:class="
|
||||
batch.data.amount || batch.data.courses.length
|
||||
? 'float-right'
|
||||
: 'w-fit mb-4'
|
||||
"
|
||||
:label="
|
||||
batch.data.seats_left +
|
||||
' ' +
|
||||
(batch.data.seats_left > 1 ? __('Seats Left') : __('Seat Left'))
|
||||
"
|
||||
/>
|
||||
<Badge
|
||||
v-else-if="batch.data.seat_count && batch.data.seats_left <= 0"
|
||||
variant="subtle"
|
||||
theme="red"
|
||||
size="md"
|
||||
class="float-right"
|
||||
:label="__('Sold Out')"
|
||||
/>
|
||||
<div
|
||||
v-if="batch.data.amount"
|
||||
class="text-lg font-semibold mb-5 text-ink-gray-9"
|
||||
>
|
||||
{{ formatNumberIntoCurrency(batch.data.amount, batch.data.currency) }}
|
||||
</div>
|
||||
<div
|
||||
v-if="batch.data.courses.length"
|
||||
class="flex items-center mb-3 text-ink-gray-7"
|
||||
>
|
||||
<BookOpen class="h-4 w-4 stroke-1.5 mr-2" />
|
||||
<span> {{ batch.data.courses.length }} {{ __('Courses') }} </span>
|
||||
</div>
|
||||
<DateRange
|
||||
:startDate="batch.data.start_date"
|
||||
:endDate="batch.data.end_date"
|
||||
class="mb-3"
|
||||
/>
|
||||
<div class="flex items-center mb-3 text-ink-gray-7">
|
||||
<Clock class="h-4 w-4 stroke-1.5 mr-2" />
|
||||
<span>
|
||||
{{ formatTime(batch.data.start_time) }} -
|
||||
{{ formatTime(batch.data.end_time) }}
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="batch.data.timezone" class="flex items-center text-ink-gray-7">
|
||||
<Globe class="h-4 w-4 stroke-1.5 mr-2" />
|
||||
<span>
|
||||
{{ batch.data.timezone }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div v-if="!readOnlyMode && !canAccessBatch">
|
||||
<router-link
|
||||
:to="{
|
||||
name: 'Billing',
|
||||
params: {
|
||||
type: 'batch',
|
||||
name: batch.data.name,
|
||||
},
|
||||
}"
|
||||
v-if="
|
||||
batch.data.paid_batch &&
|
||||
batch.data.seats_left > 0 &&
|
||||
batch.data.accept_enrollments
|
||||
"
|
||||
>
|
||||
<Button class="w-full mt-4" variant="solid">
|
||||
<div v-if="!readOnlyMode && !canAccessBatch">
|
||||
<router-link
|
||||
:to="{
|
||||
name: 'Billing',
|
||||
params: {
|
||||
type: 'batch',
|
||||
name: batch.data.name,
|
||||
},
|
||||
}"
|
||||
v-if="
|
||||
batch.data.paid_batch &&
|
||||
batch.data.seats_left > 0 &&
|
||||
batch.data.accept_enrollments
|
||||
"
|
||||
>
|
||||
<Button class="w-full mt-4" variant="solid">
|
||||
<template #prefix>
|
||||
<CreditCard class="size-4 stroke-1.5" />
|
||||
</template>
|
||||
<span>
|
||||
{{ __('Register Now') }}
|
||||
</span>
|
||||
</Button>
|
||||
</router-link>
|
||||
<Button
|
||||
variant="solid"
|
||||
class="w-full mt-2"
|
||||
v-else-if="
|
||||
batch.data.allow_self_enrollment &&
|
||||
batch.data.seats_left &&
|
||||
batch.data.accept_enrollments
|
||||
"
|
||||
@click="enrollInBatch()"
|
||||
>
|
||||
<template #prefix>
|
||||
<CreditCard class="size-4 stroke-1.5" />
|
||||
<GraduationCap class="size-4 stroke-1.5" />
|
||||
</template>
|
||||
<span>
|
||||
{{ __('Register Now') }}
|
||||
</span>
|
||||
{{ __('Enroll Now') }}
|
||||
</Button>
|
||||
</router-link>
|
||||
<Button
|
||||
variant="solid"
|
||||
class="w-full mt-2"
|
||||
v-else-if="
|
||||
batch.data.allow_self_enrollment &&
|
||||
batch.data.seats_left &&
|
||||
batch.data.accept_enrollments
|
||||
"
|
||||
@click="enrollInBatch()"
|
||||
>
|
||||
<template #prefix>
|
||||
<GraduationCap class="size-4 stroke-1.5" />
|
||||
</template>
|
||||
{{ __('Enroll Now') }}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
+2
-1
@@ -1087,7 +1087,7 @@ def get_neighbour_lesson(course: str, chapter: int, lesson: int) -> dict:
|
||||
}
|
||||
|
||||
|
||||
@frappe.whitelist(allow_guest=True)
|
||||
@frappe.whitelist(allow_guest=True) # nosemgrep: frappe-semgrep-rules.rules.security.guest-whitelisted-method
|
||||
@rate_limit(limit=500, seconds=60 * 60)
|
||||
def get_batch_details(batch: str):
|
||||
if not guest_access_allowed():
|
||||
@@ -1129,6 +1129,7 @@ def get_batch_details(batch: str):
|
||||
"zoom_account",
|
||||
"conferencing_provider",
|
||||
"google_meet_account",
|
||||
"video_link",
|
||||
],
|
||||
as_dict=True,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user