fix: persistent favicon for all pages

This commit is contained in:
Jannat Patel
2025-04-08 10:57:02 +05:30
parent c70da08078
commit 5d1673bad8
35 changed files with 307 additions and 175 deletions

View File

@@ -142,6 +142,7 @@
</div>
</div>
<ChapterModal
v-if="user.data"
v-model="showChapterModal"
v-model:outline="outline"
:course="courseName"

View File

@@ -1,7 +1,7 @@
<template>
<div v-if="quiz.data">
<div
class="bg-surface-blue-2 space-y-1 py-2 px-2 mb-4 rounded-md text-sm text-ink-blue-2"
class="bg-surface-blue-2 space-y-1 py-2 px-2 mb-4 rounded-md text-sm text-ink-blue-3"
>
<div class="leading-5">
{{

View File

@@ -63,6 +63,7 @@ import {
createResource,
FormControl,
TextEditor,
usePageMeta,
} from 'frappe-ui'
import {
computed,
@@ -72,11 +73,13 @@ import {
reactive,
watch,
} from 'vue'
import { sessionStore } from '../stores/session'
import { showToast } from '@/utils'
import { useRouter } from 'vue-router'
const user = inject('$user')
const router = useRouter()
const { brand } = sessionStore()
const props = defineProps({
assignmentID: {
@@ -188,4 +191,11 @@ const assignmentOptions = computed(() => {
{ label: 'URL', value: 'URL' },
]
})
usePageMeta(() => {
return {
title: assignment.doc ? assignment.doc.title : __('New Assignment'),
icon: brand.favicon,
}
})
</script>

View File

@@ -14,12 +14,14 @@
</div>
</template>
<script setup>
import { Breadcrumbs, createResource } from 'frappe-ui'
import { computed, inject, onMounted, onBeforeUnmount, ref } from 'vue'
import { Breadcrumbs, createResource, usePageMeta } from 'frappe-ui'
import { computed, inject, onMounted, ref } from 'vue'
import { sessionStore } from '../stores/session'
import Assignment from '@/components/Assignment.vue'
const user = inject('$user')
const fromLesson = ref(false)
const { brand } = sessionStore()
const props = defineProps({
assignmentID: {
@@ -72,4 +74,11 @@ const breadcrumbs = computed(() => {
]
return crumbs
})
usePageMeta(() => {
return {
title: title.data?.title,
icon: brand.favicon,
}
})
</script>

View File

@@ -84,14 +84,17 @@ import {
ListRows,
ListRow,
ListRowItem,
usePageMeta,
} from 'frappe-ui'
import { computed, inject, onMounted, ref, watch } from 'vue'
import { useRouter } from 'vue-router'
import { Pencil } from 'lucide-vue-next'
import { sessionStore } from '../stores/session'
import Link from '@/components/Controls/Link.vue'
const user = inject('$user')
const dayjs = inject('$dayjs')
const { brand } = sessionStore()
const router = useRouter()
const assignmentID = ref('')
const member = ref('')
@@ -214,4 +217,11 @@ const breadcrumbs = computed(() => {
},
]
})
usePageMeta(() => {
return {
title: __('Assignment Submissions'),
icon: brand.favicon,
}
})
</script>

View File

@@ -80,15 +80,18 @@ import {
createListResource,
FormControl,
ListView,
usePageMeta,
} from 'frappe-ui'
import { computed, inject, onMounted, ref, watch } from 'vue'
import { Plus, Pencil } from 'lucide-vue-next'
import { useRouter } from 'vue-router'
import { sessionStore } from '../stores/session'
const user = inject('$user')
const dayjs = inject('$dayjs')
const titleFilter = ref('')
const typeFilter = ref('')
const { brand } = sessionStore()
const router = useRouter()
onMounted(() => {
@@ -184,4 +187,11 @@ const breadcrumbs = computed(() => [
route: { name: 'Assignments' },
},
])
usePageMeta(() => {
return {
title: __('Assignments'),
icon: brand.favicon,
}
})
</script>

View File

@@ -24,10 +24,12 @@
</div>
</template>
<script setup>
import { createDocumentResource, createResource } from 'frappe-ui'
import { createResource, usePageMeta } from 'frappe-ui'
import { computed, inject } from 'vue'
import { sessionStore } from '../stores/session'
const dayjs = inject('$dayjs')
const { brand } = sessionStore()
const props = defineProps({
badgeName: {
@@ -70,4 +72,11 @@ const breadcrumbs = computed(() => {
},
]
})
usePageMeta(() => {
return {
title: badge.data.badge,
icon: brand.favicon,
}
})
</script>

View File

@@ -199,9 +199,14 @@
<script setup>
import { computed, inject, ref, onMounted, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { Breadcrumbs, Button, createResource, Tabs, Badge } from 'frappe-ui'
import CourseInstructors from '@/components/CourseInstructors.vue'
import UserAvatar from '@/components/UserAvatar.vue'
import {
Breadcrumbs,
Button,
createResource,
Tabs,
Badge,
usePageMeta,
} from 'frappe-ui'
import {
Clock,
LayoutDashboard,
@@ -214,7 +219,10 @@ import {
Globe,
ClipboardPen,
} from 'lucide-vue-next'
import { formatTime, updateDocumentTitle } from '@/utils'
import { formatTime } from '@/utils'
import { sessionStore } from '@/stores/session'
import CourseInstructors from '@/components/CourseInstructors.vue'
import UserAvatar from '@/components/UserAvatar.vue'
import BatchDashboard from '@/components/BatchDashboard.vue'
import BatchCourses from '@/components/BatchCourses.vue'
import LiveClass from '@/components/LiveClass.vue'
@@ -232,6 +240,7 @@ const showAnnouncementModal = ref(false)
const openCertificateDialog = ref(false)
const route = useRoute()
const router = useRouter()
const { brand } = sessionStore()
const tabIndex = ref(0)
const tabs = computed(() => {
@@ -345,12 +354,10 @@ watch(tabIndex, () => {
}
})
const pageMeta = computed(() => {
usePageMeta(() => {
return {
title: batch.data?.title,
description: batch.data?.description,
title: batch?.data?.title,
icon: brand.favicon,
}
})
updateDocumentTitle(pageMeta)
</script>

View File

@@ -102,8 +102,9 @@
import { computed, inject } from 'vue'
import { useRouter } from 'vue-router'
import { BookOpen, Clock } from 'lucide-vue-next'
import { formatTime, updateDocumentTitle } from '@/utils'
import { Breadcrumbs, createResource } from 'frappe-ui'
import { formatTime } from '@/utils'
import { Breadcrumbs, createResource, usePageMeta } from 'frappe-ui'
import { sessionStore } from '@/stores/session'
import CourseCard from '@/components/CourseCard.vue'
import BatchOverlay from '@/components/BatchOverlay.vue'
import DateRange from '../components/Common/DateRange.vue'
@@ -112,6 +113,7 @@ import UserAvatar from '@/components/UserAvatar.vue'
const user = inject('$user')
const router = useRouter()
const { brand } = sessionStore()
const props = defineProps({
batchName: {
@@ -152,14 +154,12 @@ const breadcrumbs = computed(() => {
return items
})
const pageMeta = computed(() => {
usePageMeta(() => {
return {
title: batch.data?.title,
description: batch.data?.description,
title: batch?.data?.title,
icon: brand.favicon,
}
})
updateDocumentTitle(pageMeta)
</script>
<style>
.batch-description p {

View File

@@ -264,17 +264,20 @@ import {
Button,
TextEditor,
createResource,
usePageMeta,
} from 'frappe-ui'
import Link from '@/components/Controls/Link.vue'
import { useRouter } from 'vue-router'
import { showToast } from '@/utils'
import { Image } from 'lucide-vue-next'
import { capture } from '@/telemetry'
import MultiSelect from '@/components/Controls/MultiSelect.vue'
import { useOnboarding } from 'frappe-ui/frappe'
import { sessionStore } from '../stores/session'
import MultiSelect from '@/components/Controls/MultiSelect.vue'
import Link from '@/components/Controls/Link.vue'
const router = useRouter()
const user = inject('$user')
const { brand } = sessionStore()
const { updateOnboardingStep } = useOnboarding('learning')
const props = defineProps({
@@ -505,4 +508,11 @@ const breadcrumbs = computed(() => {
})
return crumbs
})
usePageMeta(() => {
return {
title: props.batchName == 'new' ? 'New Batch' : batchDetail.data?.title,
icon: brand.favicon,
}
})
</script>

View File

@@ -104,14 +104,16 @@ import {
FormControl,
Select,
TabButtons,
usePageMeta,
} from 'frappe-ui'
import { computed, inject, onMounted, ref, watch } from 'vue'
import { BookOpen, Plus } from 'lucide-vue-next'
import { updateDocumentTitle } from '@/utils'
import { sessionStore } from '@/stores/session'
import BatchCard from '@/components/BatchCard.vue'
const user = inject('$user')
const dayjs = inject('$dayjs')
const { brand } = sessionStore()
const start = ref(0)
const pageLength = ref(20)
const categories = ref([])
@@ -304,12 +306,10 @@ const breadcrumbs = computed(() => [
},
])
const pageMeta = computed(() => {
usePageMeta(() => {
return {
title: 'Batches',
description: 'All upcoming batches.',
title: __('Batches'),
icon: brand.favicon,
}
})
updateDocumentTitle(pageMeta)
</script>

View File

@@ -151,19 +151,20 @@
</template>
<script setup>
import {
Input,
Button,
createResource,
FormControl,
Breadcrumbs,
Tooltip,
usePageMeta,
} from 'frappe-ui'
import { reactive, inject, onMounted, computed } from 'vue'
import { showToast } from '@/utils/'
import { sessionStore } from '../stores/session'
import Link from '@/components/Controls/Link.vue'
import NotPermitted from '@/components/NotPermitted.vue'
import { showToast } from '@/utils/'
const user = inject('$user')
const { brand } = sessionStore()
onMounted(() => {
const script = document.createElement('script')
@@ -356,4 +357,11 @@ const redirectTo = computed(() => {
return `/lms/courses/${props.name}/certification`
}
})
usePageMeta(() => {
return {
title: __('Billing Details'),
icon: brand.favicon,
}
})
</script>

View File

@@ -102,14 +102,17 @@ import {
createListResource,
FormControl,
Select,
usePageMeta,
} from 'frappe-ui'
import { computed, onMounted, ref } from 'vue'
import { updateDocumentTitle } from '@/utils'
import { BookOpen, GraduationCap } from 'lucide-vue-next'
import { sessionStore } from '../stores/session'
const currentCategory = ref('')
const filters = ref({})
const nameFilter = ref('')
const { brand } = sessionStore()
onMounted(() => {
updateParticipants()
@@ -163,13 +166,12 @@ const breadcrumbs = computed(() => [
},
])
const pageMeta = computed(() => {
usePageMeta(() => {
return {
title: 'Certified Participants',
description: 'All participants that have been certified.',
title: __('Certified Participants'),
icon: brand.favicon,
}
})
updateDocumentTitle(pageMeta)
</script>
<style>
.headline {

View File

@@ -36,12 +36,14 @@
</template>
<script setup>
import { computed, inject, onMounted, ref } from 'vue'
import { Breadcrumbs, call, createResource } from 'frappe-ui'
import { Breadcrumbs, call, createResource, usePageMeta } from 'frappe-ui'
import { useRouter } from 'vue-router'
import { sessionStore } from '../stores/session'
import UpcomingEvaluations from '@/components/UpcomingEvaluations.vue'
const courseTitle = ref(null)
const evaluator = ref(null)
const { brand } = sessionStore()
const courses = ref([])
const user = inject('$user')
const dayjs = inject('$dayjs')
@@ -133,4 +135,11 @@ const breadcrumbs = computed(() => [
label: __('Certification'),
},
])
usePageMeta(() => {
return {
title: courseTitle.value,
icon: brand.favicon,
}
})
</script>

View File

@@ -92,16 +92,24 @@
</div>
</template>
<script setup>
import { createResource, Breadcrumbs, Badge, Tooltip } from 'frappe-ui'
import {
createResource,
Breadcrumbs,
Badge,
Tooltip,
usePageMeta,
} from 'frappe-ui'
import { computed } from 'vue'
import { Users, Star } from 'lucide-vue-next'
import { sessionStore } from '@/stores/session'
import CourseCardOverlay from '@/components/CourseCardOverlay.vue'
import CourseOutline from '@/components/CourseOutline.vue'
import CourseReviews from '@/components/CourseReviews.vue'
import UserAvatar from '@/components/UserAvatar.vue'
import { updateDocumentTitle } from '@/utils'
import CourseInstructors from '@/components/CourseInstructors.vue'
const { brand } = sessionStore()
const props = defineProps({
courseName: {
type: String,
@@ -127,14 +135,12 @@ const breadcrumbs = computed(() => {
return items
})
const pageMeta = computed(() => {
usePageMeta(() => {
return {
title: course?.data?.title,
description: course?.data?.short_introduction,
icon: brand.favicon,
}
})
updateDocumentTitle(pageMeta)
</script>
<style>
.avatar-group {

View File

@@ -253,6 +253,7 @@ import {
createResource,
FormControl,
FileUploader,
usePageMeta,
} from 'frappe-ui'
import {
inject,
@@ -265,17 +266,19 @@ import {
getCurrentInstance,
} from 'vue'
import { showToast, updateDocumentTitle } from '@/utils'
import Link from '@/components/Controls/Link.vue'
import { Image, Trash2, X } from 'lucide-vue-next'
import { useRouter } from 'vue-router'
import CourseOutline from '@/components/CourseOutline.vue'
import MultiSelect from '@/components/Controls/MultiSelect.vue'
import { capture } from '@/telemetry'
import { useOnboarding } from 'frappe-ui/frappe'
import { sessionStore } from '../stores/session'
import { useSettings } from '@/stores/settings'
import Link from '@/components/Controls/Link.vue'
import CourseOutline from '@/components/CourseOutline.vue'
import MultiSelect from '@/components/Controls/MultiSelect.vue'
const user = inject('$user')
const newTag = ref('')
const { brand } = sessionStore()
const router = useRouter()
const instructors = ref([])
const settingsStore = useSettings()
@@ -574,12 +577,10 @@ const breadcrumbs = computed(() => {
return crumbs
})
const pageMeta = computed(() => {
usePageMeta(() => {
return {
title: 'Create a Course',
description: 'Create or edit a course for your learning system.',
title: courseResource.data?.title || __('New Course'),
icon: brand.favicon,
}
})
updateDocumentTitle(pageMeta)
</script>

View File

@@ -100,10 +100,11 @@ import {
FormControl,
Select,
TabButtons,
usePageMeta,
} from 'frappe-ui'
import { computed, inject, onMounted, ref, watch } from 'vue'
import { BookOpen, Plus } from 'lucide-vue-next'
import { updateDocumentTitle } from '@/utils'
import { sessionStore } from '@/stores/session'
import CourseCard from '@/components/CourseCard.vue'
const user = inject('$user')
@@ -116,6 +117,7 @@ const title = ref('')
const certification = ref(false)
const filters = ref({})
const currentTab = ref('Live')
const { brand } = sessionStore()
onMounted(() => {
setFiltersFromQuery()
@@ -303,12 +305,10 @@ const breadcrumbs = computed(() => [
},
])
const pageMeta = computed(() => {
usePageMeta(() => {
return {
title: 'Courses',
description: 'All published courses.',
title: __('Courses'),
icon: brand.favicon,
}
})
updateDocumentTitle(pageMeta)
</script>

View File

@@ -1,39 +0,0 @@
<template>
<div class="max-w-3xl py-12 mx-auto">
<Button
icon-left="code"
@click="$resources.ping.fetch"
:loading="$resources.ping.loading"
>
Click to send 'ping' request
</Button>
<div>
{{ $resources.ping.data }}
</div>
<pre>{{ $resources.ping }}</pre>
<Button @click="showDialog = true">Open Dialog</Button>
<Dialog title="Title" v-model="showDialog"> Dialog content </Dialog>
</div>
</template>
<script>
import { Dialog } from 'frappe-ui'
export default {
name: 'Home',
data() {
return {
showDialog: false,
}
},
resources: {
ping: {
url: 'ping',
},
},
components: {
Dialog,
},
}
</script>

View File

@@ -139,14 +139,17 @@ import {
Button,
TextEditor,
FileUploader,
usePageMeta,
} from 'frappe-ui'
import { computed, onMounted, reactive, inject } from 'vue'
import { FileText, X } from 'lucide-vue-next'
import { sessionStore } from '@/stores/session'
import { useRouter } from 'vue-router'
import { getFileSize, showToast } from '../utils'
const user = inject('$user')
const router = useRouter()
const { brand } = sessionStore()
const props = defineProps({
jobName: {
@@ -319,4 +322,11 @@ const breadcrumbs = computed(() => {
]
return crumbs
})
usePageMeta(() => {
return {
title: props.jobName == 'new' ? 'New Job' : jobDetail.data?.title,
icon: brand.favicon,
}
})
</script>

View File

@@ -142,9 +142,9 @@
</div>
</template>
<script setup>
import { Button, Breadcrumbs, createResource } from 'frappe-ui'
import { inject, ref, computed } from 'vue'
import { updateDocumentTitle } from '@/utils'
import { Button, Breadcrumbs, createResource, usePageMeta } from 'frappe-ui'
import { inject, ref } from 'vue'
import { sessionStore } from '../stores/session'
import JobApplicationModal from '@/components/Modals/JobApplicationModal.vue'
import {
MapPin,
@@ -158,6 +158,7 @@ import {
const user = inject('$user')
const dayjs = inject('$dayjs')
const { brand } = sessionStore()
const showApplicationModal = ref(false)
const props = defineProps({
@@ -215,12 +216,10 @@ const redirectToLogin = (job) => {
window.location.href = `/login?redirect-to=/job-openings/${job}`
}
const pageMeta = computed(() => {
usePageMeta(() => {
return {
title: job.data?.job_title,
description: job.data?.description,
icon: brand.favicon,
}
})
updateDocumentTitle(pageMeta)
</script>

View File

@@ -81,14 +81,21 @@
</div>
</template>
<script setup>
import { Button, Breadcrumbs, createResource, FormControl } from 'frappe-ui'
import {
Button,
Breadcrumbs,
createResource,
FormControl,
usePageMeta,
} from 'frappe-ui'
import { Plus, Search } from 'lucide-vue-next'
import { sessionStore } from '../stores/session'
import { inject, computed, ref, onMounted } from 'vue'
import JobCard from '@/components/JobCard.vue'
import { updateDocumentTitle } from '@/utils'
const user = inject('$user')
const jobType = ref(null)
const { brand } = sessionStore()
const searchQuery = ref('')
const filters = ref({})
const orFilters = ref({})
@@ -147,12 +154,11 @@ const jobTypes = computed(() => {
{ label: __('Freelance'), value: 'Freelance' },
]
})
const pageMeta = computed(() => {
usePageMeta(() => {
return {
title: 'Jobs',
description: 'An open job board for the community',
title: __('Jobs'),
icon: brand.favicon,
}
})
updateDocumentTitle(pageMeta)
</script>

View File

@@ -193,14 +193,15 @@
</div>
</template>
<script setup>
import { createResource, Breadcrumbs, Button } from 'frappe-ui'
import { createResource, Breadcrumbs, Button, usePageMeta } from 'frappe-ui'
import { computed, watch, inject, ref, onMounted, onBeforeUnmount } from 'vue'
import CourseOutline from '@/components/CourseOutline.vue'
import UserAvatar from '@/components/UserAvatar.vue'
import { useRouter, useRoute } from 'vue-router'
import { ChevronLeft, ChevronRight, GraduationCap } from 'lucide-vue-next'
import Discussions from '@/components/Discussions.vue'
import { getEditorTools, updateDocumentTitle } from '../utils'
import { getEditorTools } from '../utils'
import { sessionStore } from '@/stores/session'
import EditorJS from '@editorjs/editorjs'
import LessonContent from '@/components/LessonContent.vue'
import CourseInstructors from '@/components/CourseInstructors.vue'
@@ -215,6 +216,7 @@ const editor = ref(null)
const instructorEditor = ref(null)
const lessonProgress = ref(0)
const timer = ref(0)
const { brand } = sessionStore()
let timerInterval
const props = defineProps({
@@ -419,14 +421,12 @@ const redirectToLogin = () => {
window.location.href = `/login?redirect-to=/lms/courses/${props.courseName}`
}
const pageMeta = computed(() => {
usePageMeta(() => {
return {
title: lesson.data?.title,
description: lesson.data?.course,
title: lesson?.data?.title,
icon: brand.favicon,
}
})
updateDocumentTitle(pageMeta)
</script>
<style>
.avatar-group {

View File

@@ -78,7 +78,13 @@
</div>
</template>
<script setup>
import { Breadcrumbs, Button, createResource, FormControl } from 'frappe-ui'
import {
Breadcrumbs,
Button,
createResource,
FormControl,
usePageMeta,
} from 'frappe-ui'
import {
computed,
reactive,
@@ -87,13 +93,15 @@ import {
ref,
onBeforeUnmount,
} from 'vue'
import { sessionStore } from '../stores/session'
import EditorJS from '@editorjs/editorjs'
import LessonHelp from '@/components/LessonHelp.vue'
import { ChevronRight } from 'lucide-vue-next'
import { updateDocumentTitle, createToast, getEditorTools } from '@/utils'
import { createToast, getEditorTools } from '@/utils'
import { capture } from '@/telemetry'
import { useOnboarding } from 'frappe-ui/frappe'
const { brand } = sessionStore()
const editor = ref(null)
const instructorEditor = ref(null)
const user = inject('$user')
@@ -492,14 +500,14 @@ const breadcrumbs = computed(() => {
return crumbs
})
const pageMeta = computed(() => {
usePageMeta(() => {
return {
title: 'Lesson Editor',
description: 'Create and edit lessons for your course',
title: lessonDetails?.data?.lesson
? lessonDetails.data.lesson.title
: 'New Lesson',
icon: brand.favicon,
}
})
updateDocumentTitle(pageMeta)
</script>
<style>
.embed-tool__caption,

View File

@@ -65,12 +65,14 @@ import {
TabButtons,
Button,
Tooltip,
usePageMeta,
} from 'frappe-ui'
import { sessionStore } from '../stores/session'
import { computed, inject, ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { X } from 'lucide-vue-next'
import { updateDocumentTitle } from '@/utils'
const { brand } = sessionStore()
const user = inject('$user')
const socket = inject('$socket')
const activeTab = ref('Unread')
@@ -145,14 +147,12 @@ const breadcrumbs = computed(() => {
return crumbs
})
const pageMeta = computed(() => {
usePageMeta(() => {
return {
title: 'Notifications',
description: 'All your notifications in one place.',
icon: brand.favicon,
}
})
updateDocumentTitle(pageMeta)
</script>
<style>
.notification strong {

View File

@@ -86,18 +86,24 @@
/>
</template>
<script setup>
import { Breadcrumbs, createResource, Button, TabButtons } from 'frappe-ui'
import {
Breadcrumbs,
createResource,
Button,
TabButtons,
usePageMeta,
} from 'frappe-ui'
import { computed, inject, watch, ref, onMounted, watchEffect } from 'vue'
import { sessionStore } from '@/stores/session'
import { Edit } from 'lucide-vue-next'
import { Edit, icons } from 'lucide-vue-next'
import UserAvatar from '@/components/UserAvatar.vue'
import { useRoute, useRouter } from 'vue-router'
import NoPermission from '@/components/NoPermission.vue'
import { convertToTitleCase, updateDocumentTitle } from '@/utils'
import { convertToTitleCase } from '@/utils'
import EditProfile from '@/components/Modals/EditProfile.vue'
import EditCoverImage from '@/components/Modals/EditCoverImage.vue'
const { user } = sessionStore()
const { user, brand } = sessionStore()
const $user = inject('$user')
const route = useRoute()
const router = useRouter()
@@ -215,12 +221,10 @@ const breadcrumbs = computed(() => {
return crumbs
})
const pageMeta = computed(() => {
usePageMeta(() => {
return {
title: profile.data?.full_name,
description: profile.data?.headline,
icon: brand.favicon,
}
})
updateDocumentTitle(pageMeta)
</script>

View File

@@ -186,14 +186,17 @@ import {
ListHeader,
ListHeaderItem,
ListSelectBanner,
usePageMeta,
} from 'frappe-ui'
import { computed, ref } from 'vue'
import { Plus, Trash2 } from 'lucide-vue-next'
import Link from '@/components/Controls/Link.vue'
import { showToast } from '@/utils/'
import Draggable from 'vuedraggable'
import { useRouter } from 'vue-router'
import { sessionStore } from '../stores/session'
import Draggable from 'vuedraggable'
import Link from '@/components/Controls/Link.vue'
const { brand } = sessionStore()
const showDialog = ref(false)
const currentForm = ref(null)
const course = ref(null)
@@ -364,4 +367,11 @@ const breadbrumbs = computed(() => {
},
]
})
usePageMeta(() => {
return {
title: program.doc?.title,
icon: brand.favicon,
}
})
</script>

View File

@@ -126,14 +126,17 @@ import {
createResource,
Dialog,
FormControl,
usePageMeta,
} from 'frappe-ui'
import { computed, inject, onMounted, ref } from 'vue'
import { BookOpen, Edit, Plus, LockKeyhole } from 'lucide-vue-next'
import CourseCard from '@/components/CourseCard.vue'
import { useRouter } from 'vue-router'
import { sessionStore } from '../stores/session'
import { showToast } from '@/utils'
import { useSettings } from '@/stores/settings'
const { brand } = sessionStore()
const user = inject('$user')
const showDialog = ref(false)
const router = useRouter()
@@ -210,4 +213,11 @@ const breadbrumbs = computed(() => [
label: 'Programs',
},
])
usePageMeta(() => {
return {
title: __('Programs'),
icon: brand.favicon,
}
})
</script>

View File

@@ -197,6 +197,7 @@ import {
ListRowItem,
ListSelectBanner,
Button,
usePageMeta,
} from 'frappe-ui'
import {
computed,
@@ -207,11 +208,13 @@ import {
onBeforeUnmount,
watch,
} from 'vue'
import { sessionStore } from '../stores/session'
import { Plus, Trash2 } from 'lucide-vue-next'
import Question from '@/components/Modals/Question.vue'
import { showToast, updateDocumentTitle } from '@/utils'
import { useRouter } from 'vue-router'
import Question from '@/components/Modals/Question.vue'
const { brand } = sessionStore()
const showQuestionModal = ref(false)
const currentQuestion = reactive({
question: '',
@@ -453,12 +456,10 @@ const breadcrumbs = computed(() => {
return crumbs
})
const pageMeta = computed(() => {
usePageMeta(() => {
return {
title: props.quizID == 'new' ? __('New Quiz') : quizDetails.data?.title,
description: __('Form to create and edit quizzes'),
icon: brand.favicon,
}
})
updateDocumentTitle(pageMeta)
</script>

View File

@@ -14,11 +14,12 @@
</template>
<script setup>
import Quiz from '@/components/Quiz.vue'
import { createResource, Breadcrumbs } from 'frappe-ui'
import { createResource, Breadcrumbs, usePageMeta } from 'frappe-ui'
import { computed, inject, onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import { updateDocumentTitle } from '@/utils'
import { sessionStore } from '../stores/session'
const { brand } = sessionStore()
const user = inject('$user')
const router = useRouter()
const fromLesson = ref(false)
@@ -56,12 +57,10 @@ const breadcrumbs = computed(() => {
return [{ label: __('Quiz Submission') }, { label: title.data?.title }]
})
const pageMeta = computed(() => {
usePageMeta(() => {
return {
title: title.data?.title,
description: __('Quiz Submission'),
title: `${title.data?.title}`,
icon: brand.favicon,
}
})
updateDocumentTitle(pageMeta)
</script>

View File

@@ -80,10 +80,12 @@ import {
Button,
Badge,
} from 'frappe-ui'
import { computed, onBeforeUnmount, onMounted, inject } from 'vue'
import { computed, onBeforeUnmount, onMounted, inject, usePageMeta } from 'vue'
import { useRouter } from 'vue-router'
import { showToast } from '@/utils'
import { sessionStore } from '@/stores/session'
const { brand } = sessionStore()
const router = useRouter()
const user = inject('$user')
@@ -149,4 +151,11 @@ const saveSubmission = () => {
}
)
}
usePageMeta(() => {
return {
title: `${submisisonDetails.doc.quiz_title}`,
icon: brand.favicon,
}
})
</script>

View File

@@ -40,6 +40,18 @@
</Button>
</div>
</div>
<div
v-else
class="text-center p-5 text-ink-gray-5 mt-52 w-3/4 md:w-1/2 mx-auto space-y-2"
>
<BookOpen class="size-10 mx-auto stroke-1 text-ink-gray-4" />
<div class="text-xl font-medium">
{{ __('No submissions') }}
</div>
<div class="leading-5">
{{ __('No quiz submissions found. Please check again later.') }}
</div>
</div>
</template>
<script setup>
import {
@@ -51,10 +63,14 @@ import {
ListRows,
ListHeader,
ListHeaderItem,
usePageMeta,
} from 'frappe-ui'
import { BookOpen } from 'lucide-vue-next'
import { computed, onMounted, inject } from 'vue'
import { sessionStore } from '../stores/session'
import { useRouter } from 'vue-router'
const { brand } = sessionStore()
const router = useRouter()
const user = inject('$user')
@@ -105,4 +121,11 @@ const quizColumns = computed(() => {
const breadcrumbs = computed(() => {
return [{ label: __('Quiz Submissions') }]
})
usePageMeta(() => {
return {
title: __('Quiz Submissions'),
icon: brand.favicon,
}
})
</script>

View File

@@ -79,12 +79,14 @@ import {
ListRow,
ListHeader,
ListHeaderItem,
usePageMeta,
} from 'frappe-ui'
import { useRouter } from 'vue-router'
import { computed, inject, onMounted } from 'vue'
import { BookOpen, Plus } from 'lucide-vue-next'
import { updateDocumentTitle } from '@/utils'
import { sessionStore } from '@/stores/session'
const { brand } = sessionStore()
const user = inject('$user')
const router = useRouter()
@@ -143,12 +145,10 @@ const breadcrumbs = computed(() => {
]
})
const pageMeta = computed(() => {
usePageMeta(() => {
return {
title: __('Quizzes'),
description: __('List of quizzes'),
icon: brand.favicon,
}
})
updateDocumentTitle(pageMeta)
</script>

View File

@@ -39,11 +39,13 @@ import {
createDocumentResource,
createListResource,
createResource,
usePageMeta,
} from 'frappe-ui'
import { computed, inject, onBeforeMount, ref } from 'vue'
import { useSidebar } from '@/stores/sidebar'
import { updateDocumentTitle } from '@/utils'
import { sessionStore } from '../stores/session'
const { brand } = sessionStore()
const sidebarStore = useSidebar()
const user = inject('$user')
const readyToRender = ref(false)
@@ -195,14 +197,10 @@ const breadcrumbs = computed(() => {
]
})
const pageMeta = computed(() => {
usePageMeta(() => {
return {
title: chapter?.doc?.title,
description: __('This is a chapter in the course {0}').format(
chapter?.doc?.course_title
),
title: chapter.doc?.title,
icon: brand.favicon,
}
})
updateDocumentTitle(pageMeta)
</script>

View File

@@ -117,9 +117,9 @@
</div>
</template>
<script setup>
import { createResource, Breadcrumbs } from 'frappe-ui'
import { computed, inject } from 'vue'
import { updateDocumentTitle } from '@/utils'
import { createResource, Breadcrumbs, usePageMeta } from 'frappe-ui'
import { computed } from 'vue'
import { sessionStore } from '../stores/session'
import { formatNumber } from '@/utils'
import { Line, Pie } from 'vue-chartjs'
import {
@@ -154,7 +154,7 @@ import {
BookOpenCheck,
} from 'lucide-vue-next'
const dayjs = inject('$dayjs')
const { brand } = sessionStore()
const breadcrumbs = computed(() => {
return [
@@ -317,12 +317,10 @@ const chartOptions = (isPie) => {
}
}
const pageMeta = computed(() => {
usePageMeta(() => {
return {
title: 'Statistics',
description: 'Statistics of the platform',
title: __('Statistics'),
icon: brand.favicon,
}
})
updateDocumentTitle(pageMeta)
</script>

View File

@@ -2,10 +2,11 @@ import { defineStore } from 'pinia'
import { createResource } from 'frappe-ui'
import { usersStore } from './user'
import router from '@/router'
import { ref, computed } from 'vue'
import { computed, reactive, ref } from 'vue'
export const sessionStore = defineStore('lms-session', () => {
let { userResource } = usersStore()
const brand = reactive({})
function sessionUser() {
let cookies = new URLSearchParams(document.cookie.split('; ').join('&'))
@@ -46,7 +47,9 @@ export const sessionStore = defineStore('lms-session', () => {
cache: 'brand',
auto: true,
onSuccess(data) {
document.querySelector("link[rel='icon']").href = data.favicon
brand.name = data.app_name
brand.logo = data.app_logo
brand.favicon = data.favicon.file_url
},
})
@@ -61,6 +64,7 @@ export const sessionStore = defineStore('lms-session', () => {
isLoggedIn,
login,
logout,
brand,
branding,
sidebarSettings,
}