237 lines
6.4 KiB
Vue
237 lines
6.4 KiB
Vue
<script setup lang="ts">
|
||
import hadithaApi from "@haditha/apis/hadithaApi";
|
||
import headLinks from "@haditha/json/haditha/headLinks";
|
||
import headMetas from "@haditha/json/haditha/headMetas";
|
||
// import { useInfiniteScroll } from "@vueuse/core";
|
||
// const id_token = useCookie("id_token");
|
||
// const token = id_token.value ?? "GuestAccess";
|
||
|
||
// const config = useRuntimeConfig();
|
||
// const baseUrl =
|
||
// config.public.NUXT_PUBLIC_BASE_URL + config.public.NUXT_PUBLIC_API_NAME;
|
||
|
||
// this enable us to send cookies.
|
||
// const requestFetch = useRequestFetch();
|
||
|
||
definePageMeta({
|
||
layout: false,
|
||
name: "hadithaLibrary",
|
||
});
|
||
useHead({
|
||
title: `${import.meta.env.VITE_HADITH_PAGE_TITLE} | کتابخانه`,
|
||
meta: [
|
||
{ name: "description", content: "کاوش با هوش مصنوعی در احادیث اسلامی" },
|
||
...headMetas,
|
||
],
|
||
bodyAttrs: {
|
||
class: `${import.meta.env.VITE_HADITH_SYSTEM} library-page`,
|
||
},
|
||
link: headLinks,
|
||
});
|
||
|
||
// #region refs
|
||
const httpService = useNuxtApp()["$http"];
|
||
// const { $api } = useNuxtApp()
|
||
const offset = useState("offset", () => 0);
|
||
const total = useState("total", () => 0);
|
||
// const libraryList = useState("libraryList", () => []);
|
||
// const loading = useState("loading", () => false);
|
||
// const hasMore = useState("hasMore", () => true);
|
||
|
||
// const el = ref(null);
|
||
// #endregion refs
|
||
|
||
// #region reactive
|
||
const state = reactive({
|
||
pagination: {
|
||
limit: 15,
|
||
page: 1,
|
||
pages: 1,
|
||
},
|
||
});
|
||
|
||
// #region methods
|
||
|
||
const getLibraryList = async () => {
|
||
// let url = baseUrl + repoUrl() + hadithaApi.library.list;
|
||
let url = repoUrl() + hadithaApi.library.list;
|
||
url = url.replace("@field_collapsed", "normal");
|
||
url = url.replace("@offset", offset.value);
|
||
url = url.replace("@limit", state.pagination.limit);
|
||
url = url.replace("@q", "none");
|
||
|
||
// return requestFetch(url, {
|
||
// method: "POST",
|
||
// headers: {
|
||
// Authorization: token,
|
||
// },
|
||
// })
|
||
return httpService.postRequest(url).then((data) => {
|
||
total.value = data.hits?.total?.value ?? 0;
|
||
offset.value += state.pagination.limit;
|
||
return data.hits?.hits;
|
||
});
|
||
};
|
||
|
||
// Server-side initial load
|
||
// Wrapping with useAsyncDataavoid double data fetching when
|
||
// doing server-side rendering (server & client on hydration).
|
||
const { data: libraryList } = await useAsyncData("libraryList", () =>
|
||
getLibraryList()
|
||
);
|
||
|
||
// Client-side infinite scroll
|
||
const loadMore = async () => {
|
||
// const listElm = $event.target;
|
||
|
||
// if (status.value == "pending") return;
|
||
// // window.innerHeight + window.scrollY >= document.body.offsetHeight - 100
|
||
// if (listElm.scrollTop + listElm.clientHeight >= listElm.scrollHeight) {
|
||
// status.value = "pending";
|
||
// mainState.pagination.offset =
|
||
// mainState.pagination.offset + mainState.pagination.limit;
|
||
|
||
// if (total.value > mainState.pagination.offset) {
|
||
// window.clearTimeout(isScrolling.value);
|
||
// isScrolling.value = setTimeout(() => {
|
||
return await getLibraryList().then((res) => {
|
||
const hits = res ?? [];
|
||
// Use spread operator to create new array reference
|
||
libraryList.value = [...libraryList.value, ...hits];
|
||
// status.value = "success";
|
||
return res;
|
||
});
|
||
|
||
// }, 300);
|
||
// } else {
|
||
// toast.add({
|
||
// title: "کاربر محترم",
|
||
// description: "دیگر رکوردی جهت بارگزاری وجود ندارد.",
|
||
// color: "success",
|
||
// });
|
||
// status.value = "idle";
|
||
// }
|
||
// } else status.value = "idle";
|
||
};
|
||
// const { isFetching } = useInfiniteScroll(loadMore, "libraryInfiniteScroll");
|
||
|
||
const { isFetching } = useInfiniteScroll(async () => {
|
||
await loadMore();
|
||
});
|
||
// #endregion methods
|
||
|
||
// #region hooks
|
||
onUnmounted(() => {
|
||
offset.value = total.value = 0;
|
||
});
|
||
// #endregion hooks
|
||
|
||
// components declaration
|
||
const HadithaLayout = defineAsyncComponent(
|
||
() => import("@haditha/layouts/HadithaLayout.vue")
|
||
);
|
||
const NavigationMenu = defineAsyncComponent(
|
||
() => import("@haditha/components/haditha/NavigationMenu.vue")
|
||
);
|
||
const CardList = defineAsyncComponent(
|
||
() => import("@haditha/components/haditha/CardList.vue")
|
||
);
|
||
</script>
|
||
|
||
<template>
|
||
<HadithaLayout>
|
||
<div class="search-box-container h-fullsd flex flex-col justify-center">
|
||
<navigation-menu></navigation-menu>
|
||
|
||
<div class="library-list-contianer">
|
||
<div class="page-header flex items-center">
|
||
<span class="title">کتابخانه</span>
|
||
<img fit="auto" quality="80" src="/img/haditha/haditha-title.svg" />
|
||
</div>
|
||
|
||
<div
|
||
ref="libraryInfiniteScroll"
|
||
id="libraryInfiniteScroll"
|
||
class="library-list pl-4 firefox-scrollbar gap-x-15 gap-y-12 md:grid-cols-3 md:gap-x-28 md:gap-y-12 lg:grid-cols-5 lg:gap-x-28 lg:gap-y-12 mx-6"
|
||
:class="{ 'grid grid-cols-2': libraryList?.length }"
|
||
>
|
||
<!-- Client-side loaded content -->
|
||
<card-list
|
||
:list="libraryList"
|
||
no-data-text="به زودی لیست کتاب ها بروزرسانی خواهد شد."
|
||
no-data-icon=""
|
||
></card-list>
|
||
|
||
<no-data
|
||
class="h-full w-full flex flex-col justify-center items-center"
|
||
v-if="libraryList?.length == 0"
|
||
>
|
||
<p class="no-data-text">به زودی لیست کتاب ها بروزرسانی خواهد شد.</p>
|
||
</no-data>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</HadithaLayout>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.search-box-container {
|
||
padding-top: 8.3em;
|
||
|
||
.library-list-contianer {
|
||
height: 100%;
|
||
margin-top: 10em;
|
||
max-width: 1200px;
|
||
width: 100%;
|
||
margin: 0 1em;
|
||
margin-right: auto;
|
||
margin-left: auto;
|
||
|
||
.page-header {
|
||
margin-bottom: 2em;
|
||
.title {
|
||
margin-left: 0.4em;
|
||
font-family: var(--font);
|
||
font-weight: 300;
|
||
font-size: 24px;
|
||
line-height: 36px;
|
||
letter-spacing: 0%;
|
||
text-align: center;
|
||
|
||
color: var(--ui-color-two);
|
||
}
|
||
}
|
||
|
||
.library-list {
|
||
/* padding: 1em 1.3em; */
|
||
/* height: calc(100dvh - 13.5em); */
|
||
/* overflow-y: auto; */
|
||
/* scroll-behavior: smooth; */
|
||
}
|
||
.no-data-text {
|
||
font-family: var(--font);
|
||
font-weight: 300;
|
||
font-size: 16px;
|
||
line-height: 24px;
|
||
letter-spacing: 0%;
|
||
text-align: center;
|
||
}
|
||
}
|
||
}
|
||
|
||
@media screen and (max-width: 991.99px) {
|
||
.search-box-container {
|
||
padding-top: 0em;
|
||
}
|
||
.library-list {
|
||
height: calc(100dvh - 13em);
|
||
}
|
||
|
||
.page-header {
|
||
margin-top: 4em;
|
||
margin-right: 2em;
|
||
margin-bottom: 1em;
|
||
}
|
||
}
|
||
</style>
|