chore: merged conflicts

This commit is contained in:
Jannat Patel
2025-11-07 15:45:21 +05:30
80 changed files with 6099 additions and 3891 deletions

View File

@@ -62,7 +62,7 @@
<Tooltip :text="__('Enrolled Students')">
<span class="flex items-center">
<Users class="h-4 w-4 stroke-1.5 mr-1" />
{{ course.enrollments }}
{{ formatAmount(course.enrollments) }}
</span>
</Tooltip>
</div>
@@ -116,27 +116,30 @@
<CourseInstructors :instructors="course.instructors" />
</div>
<div v-if="course.paid_course" class="font-semibold">
{{ course.price }}
</div>
<div class="flex items-center space-x-2">
<div v-if="course.paid_course" class="font-semibold">
{{ course.price }}
</div>
<Tooltip
v-if="course.paid_certificate || course.enable_certification"
:text="__('Get Certified')"
>
<GraduationCap class="size-5 stroke-1.5 text-ink-gray-7" />
</Tooltip>
<Tooltip
v-if="course.paid_certificate || course.enable_certification"
:text="__('Get Certified')"
>
<GraduationCap class="size-5 stroke-1.5 text-ink-gray-7" />
</Tooltip>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { Award, BookOpen, GraduationCap, Star, Users } from 'lucide-vue-next'
import UserAvatar from '@/components/UserAvatar.vue'
import { sessionStore } from '@/stores/session'
import { Tooltip } from 'frappe-ui'
import { theme } from '@/utils/theme'
import { formatAmount } from '@/utils'
import CourseInstructors from '@/components/CourseInstructors.vue'
import UserAvatar from '@/components/UserAvatar.vue'
import ProgressBar from '@/components/ProgressBar.vue'
const { user } = sessionStore()

View File

@@ -1,11 +1,12 @@
<template>
<div class="">
<div class="text-ink-gray-7">
<span v-if="instructors?.length == 1">
<router-link
:to="{
name: 'Profile',
params: { username: instructors[0].username },
}"
class="text-ink-gray-7 hover:text-ink-gray-9"
>
{{ instructors[0].full_name }}
</router-link>
@@ -16,6 +17,7 @@
name: 'Profile',
params: { username: instructors[0].username },
}"
class="text-ink-gray-7 hover:text-ink-gray-9"
>
{{ instructors[0].first_name }}
</router-link>
@@ -25,6 +27,7 @@
name: 'Profile',
params: { username: instructors[1].username },
}"
class="text-ink-gray-7 hover:text-ink-gray-9"
>
{{ instructors[1].first_name }}
</router-link>
@@ -35,6 +38,7 @@
name: 'Profile',
params: { username: instructors[0].username },
}"
class="text-ink-gray-7 hover:text-ink-gray-9"
>
{{ instructors[0].first_name }}
</router-link>

View File

@@ -20,10 +20,10 @@
</template>
</Dialog>
<Popover :show="iosInstallMessage" placement="top">
<Popover :show="iosInstallMessage" placement="top-start">
<template #body>
<div
class="fixed bottom-[4rem] left-1/2 -translate-x-1/2 z-20 w-[90%] flex flex-col gap-3 rounded bg-blue-100 py-5 drop-shadow-xl"
class="fixed top-[20rem] translate-x-1/3 z-20 flex flex-col gap-3 rounded bg-surface-white py-5 drop-shadow-xl"
>
<div
class="mb-1 flex flex-row items-center justify-between px-3 text-center"
@@ -41,7 +41,7 @@
</div>
<div class="px-3 text-xs text-gray-800">
<span class="flex flex-col gap-2">
<span>
<span class="leading-5">
{{
__(
'Get the app on your iPhone for easy access & a better experience'

View File

@@ -3,7 +3,7 @@
class="flex flex-col border rounded-md p-3 h-full hover:border-outline-gray-3"
>
<div class="flex space-x-4 mb-4">
<div class="flex flex-col space-y-2 flex-1">
<div class="flex flex-col space-y-2 flex-1 break-all">
<div class="text-lg font-semibold text-ink-gray-9">
{{ job.company_name }}
</div>

View File

@@ -165,6 +165,14 @@ const addAssignments = () => {
})
}
const addProgrammingExercises = () => {
otherLinks.value.push({
label: 'Programming Exercises',
icon: 'Code',
to: 'ProgrammingExercises',
})
}
const addPrograms = async () => {
let canAddProgram = await checkIfCanAddProgram()
if (!canAddProgram) return

View File

@@ -113,6 +113,14 @@ watch(
{ flush: 'post' }
)
watch(show, (newVal) => {
if (newVal && props.assignmentID === 'new') {
assignment.title = ''
assignment.type = ''
assignment.question = ''
}
})
const saveAssignment = () => {
if (props.assignmentID == 'new') {
assignments.value.insert.submit(

View File

@@ -11,7 +11,7 @@
<Avatar :image="student.user_image" size="3xl" />
<div class="space-y-1">
<div class="flex items-center space-x-2">
<div class="text-xl font-semibold">
<div class="text-xl font-semibold text-ink-gray-9">
{{ student.full_name }}
</div>
<Badge
@@ -36,7 +36,9 @@
v-if="Object.keys(student.assessments).length"
class="space-y-2 text-sm"
>
<div class="flex items-center border-b pb-1 font-medium">
<div
class="flex items-center border-b pb-1 font-medium text-ink-gray-9"
>
<span class="flex-1">
{{ __('Assessment') }}
</span>
@@ -86,7 +88,9 @@
v-if="Object.keys(student.courses).length"
class="space-y-2 text-sm"
>
<div class="flex items-center border-b pb-1 font-medium">
<div
class="flex items-center border-b pb-1 font-medium text-ink-gray-9"
>
<span class="flex-1">
{{ __('Courses') }}
</span>

View File

@@ -50,7 +50,7 @@
<FileText class="h-5 w-5 stroke-1.5 text-ink-gray-7" />
</div>
<div class="flex flex-col">
<span>
<span class="text-ink-gray-9">
{{ chapter.scorm_package.file_name }}
</span>
<span class="text-sm text-ink-gray-4 mt-1">

View File

@@ -66,7 +66,11 @@
</template>
{{ __('View Certificate') }}
</Button>
<Button v-else @click="openCallLink(event.venue)" class="w-full">
<Button
v-else-if="userIsEvaluator()"
@click="openCallLink(event.venue)"
class="w-full"
>
<template #prefix>
<Video class="h-4 w-4 stroke-1.5" />
</template>
@@ -83,21 +87,31 @@
class="flex flex-col space-y-4 p-5"
>
<div class="flex items-center justify-between">
<Rating v-model="evaluation.rating" :label="__('Rating')" />
<Rating
v-model="evaluation.rating"
:label="__('Rating')"
:disabled="!userIsEvaluator()"
/>
<FormControl
type="select"
:options="statusOptions"
v-model="evaluation.status"
:label="__('Status')"
class="w-1/2"
:disabled="!userIsEvaluator()"
/>
</div>
<Textarea
v-model="evaluation.summary"
:label="__('Summary')"
:rows="7"
:disabled="!userIsEvaluator()"
/>
<Button variant="solid" @click="saveEvaluation()">
<Button
v-if="userIsEvaluator()"
variant="solid"
@click="saveEvaluation()"
>
{{ __('Save') }}
</Button>
</div>
@@ -106,11 +120,13 @@
type="checkbox"
v-model="certificate.published"
:label="__('Published')"
:disabled="!userIsEvaluator()"
/>
<Link
v-model="certificate.template"
:label="__('Template')"
doctype="Print Format"
:disabled="!userIsEvaluator()"
:filters="{
doc_type: 'LMS Certificate',
}"
@@ -118,14 +134,20 @@
<FormControl
type="date"
v-model="certificate.issue_date"
:disabled="!userIsEvaluator()"
:label="__('Issue Date')"
/>
<FormControl
type="date"
v-model="certificate.expiry_date"
:disabled="!userIsEvaluator()"
:label="__('Expiry Date')"
/>
<Button variant="solid" @click="saveCertificate()">
<Button
v-if="userIsEvaluator()"
variant="solid"
@click="saveCertificate()"
>
{{ __('Save') }}
</Button>
</div>
@@ -163,6 +185,7 @@ import Rating from '@/components/Controls/Rating.vue'
import Link from '@/components/Controls/Link.vue'
const show = defineModel()
const user = inject('$user')
const dayjs = inject('$dayjs')
const tabIndex = ref(0)
const showCertification = ref(false)
@@ -175,9 +198,18 @@ const props = defineProps({
})
const evaluation = reactive({})
const certificate = reactive({})
watch(user, () => {
if (userIsEvaluator()) {
defaultTemplate.reload()
}
})
const userIsEvaluator = () => {
return user.data && user.data.name == props.event.evaluator
}
const defaultTemplate = createResource({
url: 'frappe.client.get_value',
makeParams(values) {
@@ -190,7 +222,6 @@ const defaultTemplate = createResource({
},
}
},
auto: true,
onSuccess(data) {
certificate.template = data.value
},

View File

@@ -18,7 +18,7 @@
>
<template #body-content>
<div class="flex flex-col gap-4">
<p>
<p class="text-ink-gray-9">
{{
__(
'Submit your resume to proceed with your application for this position. Upon submission, it will be shared with the job poster.'
@@ -29,6 +29,7 @@
<FileUploader
:fileTypes="['.pdf']"
:validateFile="validateFile"
:uploadArgs="{ private: 1 }"
@success="
(file) => {
resume = file
@@ -51,7 +52,7 @@
<FileText class="h-5 w-5 stroke-1.5 text-ink-gray-7" />
</div>
<div class="flex flex-col">
<span>
<span class="text-ink-gray-9">
{{ resume.file_name }}
</span>
<span class="text-sm text-ink-gray-4 mt-1">
@@ -95,7 +96,7 @@ const jobApplication = createResource({
doc: {
doctype: 'LMS Job Application',
user: user.data?.name,
resume: resume.value?.file_name,
resume: resume.value?.file_url,
job: props.job,
},
}

View File

@@ -126,7 +126,7 @@ import {
Button,
toast,
} from 'frappe-ui'
import { computed, watch, reactive, ref, inject } from 'vue'
import { watch, reactive, ref, inject } from 'vue'
import Link from '@/components/Controls/Link.vue'
import { useOnboarding } from 'frappe-ui/frappe'
@@ -141,6 +141,7 @@ const existingQuestion = reactive({
question: '',
marks: 1,
})
const question = reactive({
question: '',
type: 'Choices',

View File

@@ -1,13 +1,13 @@
<template>
<div class="border rounded-md w-1/3 mx-auto my-32">
<div class="border-b px-5 py-3 font-medium">
<div class="border-b px-5 py-3 font-medium text-ink-gray-9">
<span
class="inline-flex items-center before:bg-surface-red-5 before:w-2 before:h-2 before:rounded-md before:mr-2"
></span>
{{ __('Not Permitted') }}
</div>
<div v-if="user.data" class="px-5 py-3">
<div>
<div class="text-ink-gray-7">
{{ __('You do not have permission to access this page.') }}
</div>
<router-link
@@ -21,7 +21,7 @@
</router-link>
</div>
<div class="px-5 py-3">
<div>
<div class="text-ink-gray-7">
{{ __('Please login to access this page.') }}
</div>
<Button @click="redirectToLogin()" class="mt-4">

View File

@@ -1,13 +1,13 @@
<template>
<div class="text-base border rounded-md w-1/3 mx-auto my-32">
<div class="border-b px-5 py-3 font-medium">
<div class="border-b px-5 py-3 font-medium text-ink-gray-9">
<span
class="inline-flex items-center before:bg-surface-red-5 before:w-2 before:h-2 before:rounded-md before:mr-2"
></span>
{{ __(title) }}
</div>
<div class="px-5 py-3">
<div class="mb-4 leading-6">
<div class="mb-4 leading-6 text-ink-gray-7">
{{ __(text) }}
</div>
<Button variant="solid" class="w-full" @click="redirect()">

View File

@@ -1,5 +1,5 @@
<template>
<div class="text-lg font-semibold mb-4">
<div class="text-lg font-semibold mb-4 text-ink-gray-9">
{{ __('My Notes') }}
</div>
<TextEditor

View File

@@ -55,8 +55,8 @@
<div v-if="quiz.data.duration" class="flex flex-col space-x-1 my-4">
<div class="mb-2">
<span class=""> {{ __('Time') }}: </span>
<span class="font-semibold">
<span class="text-ink-gray-9"> {{ __('Time') }}: </span>
<span class="font-semibold text-ink-gray-9">
{{ formatTimer(timer) }}
</span>
</div>
@@ -165,14 +165,14 @@
</div>
</div>
<span
class="ml-2"
class="ml-2 text-ink-gray-9"
v-html="questionDetails.data[`option_${index}`]"
>
</span>
</label>
<div
v-if="questionDetails.data[`explanation_${index}`]"
class="mt-2 text-xs"
class="mt-2 text-xs text-ink-gray-7"
v-show="showAnswers.length"
>
{{ questionDetails.data[`explanation_${index}`] }}
@@ -260,7 +260,7 @@
)
}}
</div>
<div v-else>
<div v-else class="text-ink-gray-7">
{{
__(
'You got {0}% correct answers with a score of {1} out of {2}'

View File

@@ -69,9 +69,12 @@ const update = () => {
let imageFields = ['favicon', 'banner_image']
props.fields.forEach((f) => {
if (imageFields.includes(f.name)) {
fieldsToSave[f.name] = f.value ? f.value.file_url : null
fieldsToSave[f.name] =
branding.data[f.name] && branding.data[f.name].file_url
? branding.data[f.name].file_url
: null
} else {
fieldsToSave[f.name] = f.value
fieldsToSave[f.name] = branding.data[f.name]
}
})

View File

@@ -2,7 +2,9 @@
<Dialog v-model="show" :options="{ size: '5xl' }">
<template #body>
<div class="flex h-[calc(100vh_-_8rem)]">
<div class="flex w-52 shrink-0 flex-col bg-surface-gray-2 p-2">
<div
class="flex w-52 shrink-0 flex-col bg-surface-gray-2 p-2 overflow-y-auto"
>
<h1 class="mb-3 px-2 pt-2 text-lg font-semibold text-ink-gray-9">
{{ __('Settings') }}
</h1>

View File

@@ -1,6 +1,6 @@
<template>
<div v-if="heatmap.data">
<div class="text-lg font-semibold mb-2">
<div class="text-lg font-semibold mb-2 text-ink-gray-9">
{{ heatmap.data.total_activities }}
{{
heatmap.data.total_activities > 1 ? __('activities') : __('activity')