Merge pull request #6066 from christianbeeznest/fixes-updates64

Internal: Improve course/sessions loading page, placeholders & overlay
pull/6058/merge
christianbeeznest 7 months ago committed by GitHub
commit 50051fdd6f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 9
      assets/css/app.scss
  2. 9
      assets/vue/components/Loading.vue
  3. 67
      assets/vue/views/user/courses/List.vue
  4. 31
      assets/vue/views/user/sessions/SessionsCurrent.vue

@ -803,6 +803,15 @@ form .field {
}
}
/* Loader */
.loader {
@apply w-10 h-10 border-4 border-gray-20 border-l-primary rounded-full animate-spin;
}
.loader-overlay {
@apply absolute inset-0 flex items-center justify-center bg-white bg-opacity-40 backdrop-blur-sm;
}
//@import "~jquery-ui-timepicker-addon/dist/jquery-ui-timepicker-addon.css";
@import "~@fancyapps/fancybox/dist/jquery.fancybox.css";
@import "~timepicker/jquery.timepicker.min.css";

@ -1,13 +1,10 @@
<template>
<div
v-if="visible"
class="w-full h-full fixed block top-0 left-0 bg-white opacity-60 text-center"
style="z-index: 9999"
class="absolute inset-0 flex items-center justify-center bg-white bg-opacity-50 backdrop-blur-md"
style="z-index: 10"
>
<div
class="spinner-border text-success opacity-75 top-1/2 my-0 mx-auto block relative w-0 h-0"
role="status"
>
<div class="loader" role="status">
<span class="sr-only">Loading</span>
</div>
</div>

@ -3,38 +3,41 @@
<hr />
<div
v-if="isLoading && courses.length === 0"
class="grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"
>
<Skeleton height="16rem" />
<Skeleton
class="hidden md:block"
height="16rem"
<div class="relative min-h-[300px]">
<Loading :visible="!isFullyLoaded" />
<div
v-if="isLoading && courses.length === 0"
class="grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"
>
<Skeleton height="16rem" />
<Skeleton
class="hidden md:block"
height="16rem"
/>
<Skeleton
class="hidden lg:block"
height="16rem"
/>
<Skeleton
class="hidden xl:block"
height="16rem"
/>
</div>
<div
v-if="courses.length > 0"
class="grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"
>
<CourseCardList :courses="courses" />
<div ref="lastCourseRef"></div>
</div>
<EmptyState
v-else-if="!isLoading && courses.length === 0"
:detail="t('Go to Explore to find a topic of interest, or wait for someone to subscribe you')"
:summary="t('You don\'t have any course yet.')"
icon="courses"
/>
<Skeleton
class="hidden lg:block"
height="16rem"
/>
<Skeleton
class="hidden xl:block"
height="16rem"
/>
</div>
<div
v-if="courses.length > 0"
class="grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"
>
<CourseCardList :courses="courses" />
<div ref="lastCourseRef"></div>
</div>
<EmptyState
v-else-if="!isLoading && 0 === courses.length"
:detail="t('Go to Explore to find a topic of interest, or wait for someone to subscribe you')"
:summary="t('You don\'t have any course yet.')"
icon="courses"
/>
</template>
<script setup>
@ -47,12 +50,14 @@ import StickyCourses from "../../../views/user/courses/StickyCourses.vue"
import CourseCardList from "../../../components/course/CourseCardList.vue"
import EmptyState from "../../../components/EmptyState"
import { useSecurityStore } from "../../../store/securityStore"
import Loading from "../../../components/Loading.vue"
const securityStore = useSecurityStore()
const { t } = useI18n()
const courses = ref([])
const isLoading = ref(false)
const isFullyLoaded = ref(false)
const endCursor = ref(null)
const hasMore = ref(true)
const lastCourseRef = ref(null)
@ -82,6 +87,7 @@ watch(result, (newResult) => {
})
}
isLoading.value = false
isFullyLoaded.value = true
})
const loadMoreCourses = () => {
@ -134,6 +140,7 @@ onMounted(() => {
endCursor.value = null
hasMore.value = true
isLoading.value = false
isFullyLoaded.value = false
if (observer) observer.disconnect()
observer = new IntersectionObserver(

@ -1,25 +1,38 @@
<template>
<StickyCourses />
<SessionTabs class="mb-4" />
<SessionsLoading :is-loading="isLoading" />
<!-- All sessions -->
<!-- <SessionListWrapper :sessions="sessionList"/>-->
<div class="relative min-h-[300px]">
<Loading :visible="!isFullyLoaded" />
<SessionCategoryView
v-if="!isLoading"
:categories="categories"
:categories-with-sessions="categoriesWithSessions"
:uncategorized-sessions="uncategorizedSessions"
/>
<SessionsLoading :is-loading="isLoading" />
<SessionCategoryView
v-if="!isLoading"
:categories="categories"
:categories-with-sessions="categoriesWithSessions"
:uncategorized-sessions="uncategorizedSessions"
/>
</div>
</template>
<script setup>
import { ref, watch, nextTick } from "vue"
import SessionTabs from "../../../components/session/SessionTabs.vue"
import StickyCourses from "../../../views/user/courses/StickyCourses.vue"
import SessionCategoryView from "../../../components/session/SessionCategoryView"
import { useSession } from "./session"
import SessionsLoading from "./SessionsLoading.vue"
import Loading from "../../../components/Loading.vue"
const { isLoading, uncategorizedSessions, categories, categoriesWithSessions } = useSession("current")
const isFullyLoaded = ref(false)
watch(isLoading, async (newVal) => {
if (!newVal) {
await new Promise((resolve) => setTimeout(resolve, 500))
await nextTick()
isFullyLoaded.value = true
}
})
</script>

Loading…
Cancel
Save