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 "~jquery-ui-timepicker-addon/dist/jquery-ui-timepicker-addon.css";
@import "~@fancyapps/fancybox/dist/jquery.fancybox.css"; @import "~@fancyapps/fancybox/dist/jquery.fancybox.css";
@import "~timepicker/jquery.timepicker.min.css"; @import "~timepicker/jquery.timepicker.min.css";

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

@ -3,38 +3,41 @@
<hr /> <hr />
<div <div class="relative min-h-[300px]">
v-if="isLoading && courses.length === 0" <Loading :visible="!isFullyLoaded" />
class="grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4" <div
> v-if="isLoading && courses.length === 0"
<Skeleton height="16rem" /> class="grid gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"
<Skeleton >
class="hidden md:block" <Skeleton height="16rem" />
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> </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> </template>
<script setup> <script setup>
@ -47,12 +50,14 @@ import StickyCourses from "../../../views/user/courses/StickyCourses.vue"
import CourseCardList from "../../../components/course/CourseCardList.vue" import CourseCardList from "../../../components/course/CourseCardList.vue"
import EmptyState from "../../../components/EmptyState" import EmptyState from "../../../components/EmptyState"
import { useSecurityStore } from "../../../store/securityStore" import { useSecurityStore } from "../../../store/securityStore"
import Loading from "../../../components/Loading.vue"
const securityStore = useSecurityStore() const securityStore = useSecurityStore()
const { t } = useI18n() const { t } = useI18n()
const courses = ref([]) const courses = ref([])
const isLoading = ref(false) const isLoading = ref(false)
const isFullyLoaded = ref(false)
const endCursor = ref(null) const endCursor = ref(null)
const hasMore = ref(true) const hasMore = ref(true)
const lastCourseRef = ref(null) const lastCourseRef = ref(null)
@ -82,6 +87,7 @@ watch(result, (newResult) => {
}) })
} }
isLoading.value = false isLoading.value = false
isFullyLoaded.value = true
}) })
const loadMoreCourses = () => { const loadMoreCourses = () => {
@ -134,6 +140,7 @@ onMounted(() => {
endCursor.value = null endCursor.value = null
hasMore.value = true hasMore.value = true
isLoading.value = false isLoading.value = false
isFullyLoaded.value = false
if (observer) observer.disconnect() if (observer) observer.disconnect()
observer = new IntersectionObserver( observer = new IntersectionObserver(

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

Loading…
Cancel
Save