Work on library show page.
This commit is contained in:
parent
55f39c3721
commit
237b9b6da9
|
@ -30,20 +30,8 @@ const goToLibraryShow = (item) => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="library-list-contianer">
|
||||
<div class="page-header flex items-center">
|
||||
<span class="title">کتابخانه</span>
|
||||
<img
|
||||
fit="auto"
|
||||
quality="80"
|
||||
placeholder
|
||||
src="/img/haditha/haditha-title.svg"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="library-list grid grid-cols-5 gap-x-28 gap-y-12">
|
||||
<UCard
|
||||
v-if="props.list.length"
|
||||
v-if="props.list?.length"
|
||||
v-for="(item, index) in props.list"
|
||||
:key="index"
|
||||
variant="solid"
|
||||
|
@ -98,40 +86,10 @@ const goToLibraryShow = (item) => {
|
|||
<img fit="auto" quality="80" placeholder :src="props.noDataIcon" />
|
||||
<p class="no-data-text">{{ props.noDataText }}</p>
|
||||
</no-data>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.library-list-contianer {
|
||||
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: IRANSansX;
|
||||
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;
|
||||
|
||||
.library-list-item {
|
||||
.library-list-item {
|
||||
width: 140;
|
||||
height: 200;
|
||||
border-radius: 8px;
|
||||
|
@ -156,15 +114,5 @@ const goToLibraryShow = (item) => {
|
|||
text-align: right;
|
||||
color: #444444;
|
||||
}
|
||||
}
|
||||
}
|
||||
.no-data-text {
|
||||
font-family: IRANSansX;
|
||||
font-weight: 300;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
letter-spacing: 0%;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
<script setup>
|
||||
<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";
|
||||
|
||||
definePageMeta({
|
||||
layout: false,
|
||||
|
@ -10,153 +13,99 @@ useHead({
|
|||
title: `${import.meta.env.VITE_HADITH_PAGE_TITLE} | کتابخانه`,
|
||||
meta: [
|
||||
{ name: "description", content: "کاوش با هوش مصنوعی در احادیث اسلامی" },
|
||||
{
|
||||
name: "msapplication-TileImage",
|
||||
content: "/img/haditha/fav-icons/ms-icon-144x144.png",
|
||||
},
|
||||
{ name: "theme-color", content: "#ffffff" },
|
||||
...headMetas,
|
||||
],
|
||||
bodyAttrs: {
|
||||
class: import.meta.env.VITE_HADITH_SYSTEM,
|
||||
},
|
||||
link: [
|
||||
{
|
||||
rel: "icon",
|
||||
type: "image/x-icon",
|
||||
href: "/img/haditha/fav-icons/favicon.ico",
|
||||
},
|
||||
{ rel: "manifest", href: "/img/haditha/fav-icons/manifest.json" },
|
||||
// rel: icon
|
||||
{
|
||||
rel: "icon",
|
||||
type: "image/png",
|
||||
sizes: "16x16",
|
||||
href: "/img/haditha/fav-icons/favicon-16x16.png",
|
||||
},
|
||||
{
|
||||
rel: "icon",
|
||||
type: "image/png",
|
||||
sizes: "32x32",
|
||||
href: "/img/haditha/fav-icons/favicon-32x32.png",
|
||||
},
|
||||
{
|
||||
rel: "icon",
|
||||
type: "image/png",
|
||||
sizes: "96x96",
|
||||
href: "/img/haditha/fav-icons/favicon-96x96.png",
|
||||
},
|
||||
{
|
||||
rel: "icon",
|
||||
sizes: "192x192",
|
||||
type: "image/png",
|
||||
href: "/img/haditha/fav-icons/android-icon-192x192.png",
|
||||
},
|
||||
// rel: apple
|
||||
{
|
||||
rel: "apple-touch-icon",
|
||||
sizes: "57x57",
|
||||
href: "/img/haditha/fav-icons/apple-icon-57x57.png",
|
||||
},
|
||||
{
|
||||
rel: "apple-touch-icon",
|
||||
sizes: "60x60",
|
||||
href: "/img/haditha/fav-icons/android-icon-60x60.png",
|
||||
},
|
||||
{
|
||||
rel: "apple-touch-icon",
|
||||
sizes: "72x72",
|
||||
href: "/img/haditha/fav-icons/android-icon-72x72.png",
|
||||
},
|
||||
{
|
||||
rel: "apple-touch-icon",
|
||||
sizes: "76x76",
|
||||
href: "/img/haditha/fav-icons/android-icon-76x76.png",
|
||||
},
|
||||
{
|
||||
rel: "apple-touch-icon",
|
||||
sizes: "114x114",
|
||||
href: "/img/haditha/fav-icons/android-icon-114x114.png",
|
||||
},
|
||||
{
|
||||
rel: "apple-touch-icon",
|
||||
sizes: "120x120",
|
||||
href: "/img/haditha/fav-icons/android-icon-120x120.png",
|
||||
},
|
||||
{
|
||||
rel: "apple-touch-icon",
|
||||
sizes: "144x144",
|
||||
href: "/img/haditha/fav-icons/android-icon-144x144.png",
|
||||
},
|
||||
{
|
||||
rel: "apple-touch-icon",
|
||||
sizes: "152x152",
|
||||
href: "/img/haditha/fav-icons/android-icon-152x152.png",
|
||||
},
|
||||
{
|
||||
rel: "apple-touch-icon",
|
||||
sizes: "180x180",
|
||||
href: "/img/haditha/fav-icons/android-icon-180x180.png",
|
||||
},
|
||||
],
|
||||
link: headLinks,
|
||||
});
|
||||
|
||||
// #region refs
|
||||
const loading = ref(false);
|
||||
const el = useTemplateRef<HTMLElement>("el");
|
||||
const httpService = useNuxtApp()["$http"];
|
||||
|
||||
const route = useRoute();
|
||||
const page = ref(Number(route.query.page) || 1);
|
||||
// #endregion refs
|
||||
|
||||
// #region reactive
|
||||
const state = reactive({
|
||||
list: [],
|
||||
counts: [],
|
||||
totalCounts: [],
|
||||
libraryList: new Array(20).fill(0),
|
||||
pagination: {
|
||||
offset: 0,
|
||||
limit: 10,
|
||||
page: 1,
|
||||
pages: 1,
|
||||
},
|
||||
});
|
||||
// #endregion reactive
|
||||
|
||||
// #region methods
|
||||
|
||||
const getLibraryList = async (dataType = "bookmark") => {
|
||||
if (loading.value) return;
|
||||
|
||||
loading.value = true;
|
||||
|
||||
let url = repoUrl() + hadithaApi.library.list;
|
||||
url = url.replace("@field_collapsed", "normal");
|
||||
url = url.replace("@offset", 0);
|
||||
url = url.replace("@limit", 20);
|
||||
url = url.replace("@offset", state.pagination.offset);
|
||||
url = url.replace("@limit", state.pagination.limit);
|
||||
url = url.replace("@q", "none");
|
||||
|
||||
return await httpService
|
||||
.postRequest(url)
|
||||
.then((res) => {
|
||||
state.libraryList = res.hits.hits;
|
||||
console.info(state.libraryList)
|
||||
})
|
||||
.catch((err) => {
|
||||
console.info(err);
|
||||
loading.value = false;
|
||||
})
|
||||
.finally(() => (loading.value = false));
|
||||
return await httpService.postRequest(url);
|
||||
};
|
||||
// #endregion methods
|
||||
|
||||
// #region hooks
|
||||
onMounted(() => {
|
||||
getLibraryList();
|
||||
});
|
||||
// Server-side initial load
|
||||
const { data: initialItems } = await useAsyncData(
|
||||
"libraryList",
|
||||
() => getLibraryList(),
|
||||
{
|
||||
transform: (data) => data.hits.hits,
|
||||
getCachedData: (key) => {
|
||||
return useNuxtApp().payload.data[key] || useNuxtApp().static.data[key];
|
||||
},
|
||||
watch: [page],
|
||||
}
|
||||
);
|
||||
|
||||
// Client-side state
|
||||
const loadedItems = ref([]);
|
||||
const loading = ref(false);
|
||||
const hasMore = ref(true);
|
||||
const loader = ref(null);
|
||||
const totalPages = ref(10); // Set based on your API response
|
||||
|
||||
// Client-side infinite scroll
|
||||
useInfiniteScroll(
|
||||
el,
|
||||
async () => {
|
||||
if (!hasMore.value || loading.value) return;
|
||||
|
||||
loading.value = true;
|
||||
try {
|
||||
// const nextPage = page.value + 1;
|
||||
await getLibraryList().then((res) => {
|
||||
const hits = res.hits.hits;
|
||||
|
||||
if (hits.length) {
|
||||
loadedItems.value.push(...hits);
|
||||
state.pagination.offset += state.pagination.limit;
|
||||
} else {
|
||||
hasMore.value = false;
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
},
|
||||
{ distance: 100 }
|
||||
);
|
||||
// #endregion methods
|
||||
|
||||
// components declaration
|
||||
const HadithaLayout = defineAsyncComponent(() =>
|
||||
import("@haditha/layouts/HadithaLayout.vue")
|
||||
const HadithaLayout = defineAsyncComponent(
|
||||
() => import("@haditha/layouts/HadithaLayout.vue")
|
||||
);
|
||||
const NavigationMenu = defineAsyncComponent(() =>
|
||||
import("@haditha/components/haditha/NavigationMenu.vue")
|
||||
const NavigationMenu = defineAsyncComponent(
|
||||
() => import("@haditha/components/haditha/NavigationMenu.vue")
|
||||
);
|
||||
const CardList = defineAsyncComponent(() =>
|
||||
import("@haditha/components/haditha/CardList.vue")
|
||||
const CardList = defineAsyncComponent(
|
||||
() => import("@haditha/components/haditha/CardList.vue")
|
||||
);
|
||||
</script>
|
||||
|
||||
|
@ -165,11 +114,30 @@ const CardList = defineAsyncComponent(() =>
|
|||
<div class="search-box-container h-full 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="el" class="library-list grid grid-cols-5 gap-x-28 gap-y-12">
|
||||
<!-- Client-side loaded content -->
|
||||
<card-list
|
||||
v-if="loadedItems.length"
|
||||
no-data-text="هنوز چیزی ذخیره نکردهاید!"
|
||||
no-data-icon="/img/haditha/no-data.png"
|
||||
:list="state.libraryList"
|
||||
:list="loadedItems"
|
||||
></card-list>
|
||||
|
||||
<!-- Server-rendered initial content -->
|
||||
<card-list
|
||||
v-else
|
||||
no-data-text="هنوز چیزی ذخیره نکردهاید!"
|
||||
no-data-icon="/img/haditha/no-data.png"
|
||||
:list="initialItems"
|
||||
></card-list>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</HadithaLayout>
|
||||
</template>
|
||||
|
@ -178,5 +146,43 @@ const CardList = defineAsyncComponent(() =>
|
|||
.search-box-container {
|
||||
padding-top: 8.3em;
|
||||
background: #f7fffd;
|
||||
|
||||
.library-list-contianer {
|
||||
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: IRANSansX;
|
||||
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;
|
||||
}
|
||||
.no-data-text {
|
||||
font-family: IRANSansX;
|
||||
font-weight: 300;
|
||||
font-size: 16px;
|
||||
line-height: 24px;
|
||||
letter-spacing: 0%;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue
Block a user