Update and refactor

This commit is contained in:
mustafa-rezae 2025-05-15 16:21:45 +03:30
parent b6a742d177
commit 1df5c5d356
16 changed files with 1255 additions and 535 deletions

View File

@ -0,0 +1,52 @@
<svg width="64" height="25" viewBox="0 0 64 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M36.0096 17.6483C37.4078 17.6483 38.5034 17.4396 39.2965 17.0223C40.1103 16.6049 40.6947 15.9788 41.0495 15.1441L39.2965 5.09567L40.5799 4.43829L42.3642 14.7371C42.5103 15.5301 42.9068 16.2188 43.5537 16.8031C44.2215 17.3666 45.0876 17.6483 46.1519 17.6483H47.4667C47.6545 17.6483 47.811 17.7318 47.9362 17.8988C48.0823 18.0657 48.1553 18.264 48.1553 18.4935C48.1553 18.7231 48.0823 18.9213 47.9362 19.0883C47.811 19.2552 47.6545 19.3387 47.4667 19.3387H46.4336C45.2441 19.3387 44.2424 19.0883 43.4285 18.5874C42.6146 18.0657 42.0512 17.3666 41.7381 16.4901C41.2999 17.3875 40.6112 18.0866 39.6721 18.5874C38.733 19.0883 37.5539 19.3387 36.1348 19.3387H33.114L32.9575 17.6483H36.0096Z" fill="url(#paint0_linear_344_2248)"/>
<path d="M47.4094 19.3387C47.2216 19.3387 47.0651 19.2552 46.9399 19.0883C46.7938 18.9213 46.7208 18.7231 46.7208 18.4935C46.7208 18.2431 46.7938 18.0448 46.9399 17.8988C47.0651 17.7318 47.2216 17.6483 47.4094 17.6483H59.8682L58.9917 11.1998C58.783 9.80161 58.3134 8.75816 57.583 8.06949C56.8735 7.35994 55.9448 7.00517 54.797 7.00517C54.5466 7.00517 54.1501 7.04691 53.6075 7.13039L49.7572 7.75645L49.9137 6.06607L53.5762 5.47131C54.0144 5.4087 54.4318 5.3774 54.8283 5.3774C56.3309 5.3774 57.5726 5.83651 58.5534 6.75475C59.5552 7.65211 60.1708 8.92512 60.4003 10.5738L61.3707 17.6483H64.0002L63.5307 19.3387H47.4094Z" fill="url(#paint1_linear_344_2248)"/>
<path d="M24.9984 17.6481C26.2506 17.6481 27.2627 17.4185 28.0348 16.9594C28.8279 16.5003 29.3705 15.8429 29.6626 14.9873L27.8783 5.97193L29.287 5.34586L30.8209 12.9526C30.9043 13.37 30.9461 13.8291 30.9461 14.3299C30.9461 15.8534 30.4243 17.0742 29.3809 17.9924C28.3583 18.8898 26.9184 19.3385 25.061 19.3385C21.3002 19.3385 21.1849 17.6481 24.9984 17.6481Z" fill="#1B2132"/>
<path d="M17.3823 17.0222C18.1962 16.6049 18.7805 15.9788 19.1353 15.144L17.5295 7.59986L18.813 6.94249L20.2686 13.2736L20.4501 14.7371C20.5961 15.5301 20.9927 16.2188 21.6396 16.8031C22.3074 17.3666 23.1735 17.6483 24.2378 17.6483H25.5525C25.7403 17.6483 25.8968 17.7318 26.0221 17.8987C26.1681 18.0657 26.2412 18.2639 26.2412 18.4935C26.2412 18.7231 26.1681 18.9213 26.0221 19.0883C25.8968 19.2552 25.7403 19.3387 25.5525 19.3387H24.5195C23.33 19.3387 22.3283 19.0883 21.5144 18.5874C20.7005 18.0657 20.137 17.3666 19.824 16.4901C19.3857 17.3875 18.6971 18.0866 17.758 18.5874L17.3823 17.0222Z" fill="#1B2132"/>
<path d="M25.4953 19.3387C25.3075 19.3387 25.1509 19.2552 25.0257 19.0883C24.8797 18.9213 24.8066 18.7231 24.8066 18.4935C24.8066 18.2431 24.8797 18.0448 25.0257 17.8987C25.1509 17.7318 25.3075 17.6483 25.4953 17.6483V19.3387Z" fill="#1B2132"/>
<path d="M7.2878 19.3381C5.70176 19.3381 4.44962 18.8998 3.53139 18.0233C2.61316 17.1469 2.15404 15.8843 2.15404 14.2356V3.29512L0.606445 3.78424V2.02342L3.50008 1.08821V13.7348C3.50008 16.3434 4.76266 17.6477 7.2878 17.6477H8.00778C8.1956 17.6477 8.35211 17.7312 8.47733 17.8981C8.62341 18.0651 8.69645 18.2633 8.69645 18.4929C8.69645 18.7225 8.62341 18.9207 8.47733 19.0877C8.35211 19.2546 8.1956 19.3381 8.00778 19.3381H7.2878Z" fill="url(#paint2_linear_344_2248)"/>
<path d="M7.96767 19.3381C7.77985 19.3381 7.62333 19.2546 7.49812 19.0877C7.35203 18.9207 7.27899 18.7225 7.27899 18.4929C7.27899 18.2633 7.35203 18.0651 7.49812 17.8981C7.62333 17.7312 7.77985 17.6477 7.96767 17.6477H11.8806C12.0684 17.6477 12.2249 17.7312 12.3501 17.8981C12.4962 18.0651 12.5693 18.2633 12.5693 18.4929C12.5693 18.7225 12.4962 18.9207 12.3501 19.0877C12.2249 19.2546 12.0684 19.3381 11.8806 19.3381H7.96767Z" fill="url(#paint3_linear_344_2248)"/>
<path d="M11.8493 19.3381C11.6615 19.3381 11.505 19.2546 11.3797 19.0877C11.2337 18.9207 11.1606 18.7225 11.1606 18.4929C11.1606 18.2425 11.2337 18.0442 11.3797 17.8981C11.505 17.7312 11.6615 17.6477 11.8493 17.6477H14.3849C15.637 17.6477 16.6491 17.4181 17.4213 16.959C18.2143 16.4999 18.7569 15.8425 19.0491 14.9869L17.4213 7.50149L18.83 6.87542L20.2073 12.9522C20.2908 13.3696 20.3325 13.8287 20.3325 14.3295C20.3325 15.853 19.8108 17.0738 18.7673 17.992C17.7448 18.8894 16.3048 19.3381 14.4475 19.3381H11.8493Z" fill="url(#paint4_linear_344_2248)"/>
<path d="M9.69727 3.04489H16.2397V4.76658H9.69727V3.04489Z" fill="url(#paint5_linear_344_2248)"/>
<path d="M11.7584 0.215851H13.9105V1.97667H11.7584V0.215851Z" fill="url(#paint6_linear_344_2248)"/>
<path d="M23.0732 22.9774H29.5844V24.6991H23.0732V22.9774Z" fill="#1B2132"/>
<defs>
<linearGradient id="paint0_linear_344_2248" x1="32.8895" y1="7.84648" x2="38.5865" y2="12.6934" gradientUnits="userSpaceOnUse">
<stop stop-color="#84FFC8"/>
<stop offset="0.419292" stop-color="#00E03C"/>
<stop offset="1" stop-color="#1B2132"/>
</linearGradient>
<linearGradient id="paint1_linear_344_2248" x1="32.8895" y1="7.84648" x2="38.5865" y2="12.6934" gradientUnits="userSpaceOnUse">
<stop stop-color="#84FFC8"/>
<stop offset="0.419292" stop-color="#00E03C"/>
<stop offset="1" stop-color="#1B2132"/>
</linearGradient>
<linearGradient id="paint2_linear_344_2248" x1="0.143793" y1="-2.0274" x2="11.5175" y2="-0.647003" gradientUnits="userSpaceOnUse">
<stop stop-color="#D284FF"/>
<stop offset="0.245187" stop-color="#4D00FF"/>
<stop offset="1" stop-color="#1B2132"/>
</linearGradient>
<linearGradient id="paint3_linear_344_2248" x1="0.143793" y1="-2.0274" x2="11.5175" y2="-0.647003" gradientUnits="userSpaceOnUse">
<stop stop-color="#D284FF"/>
<stop offset="0.245187" stop-color="#4D00FF"/>
<stop offset="1" stop-color="#1B2132"/>
</linearGradient>
<linearGradient id="paint4_linear_344_2248" x1="0.143793" y1="-2.0274" x2="11.5175" y2="-0.647003" gradientUnits="userSpaceOnUse">
<stop stop-color="#D284FF"/>
<stop offset="0.245187" stop-color="#4D00FF"/>
<stop offset="1" stop-color="#1B2132"/>
</linearGradient>
<linearGradient id="paint5_linear_344_2248" x1="9.54382" y1="-0.561046" x2="25.143" y2="2.76377" gradientUnits="userSpaceOnUse">
<stop stop-color="#D284FF"/>
<stop offset="0.245187" stop-color="#4D00FF"/>
<stop offset="0.410433"/>
<stop offset="1"/>
</linearGradient>
<linearGradient id="paint6_linear_344_2248" x1="9.54382" y1="-0.561046" x2="25.143" y2="2.76377" gradientUnits="userSpaceOnUse">
<stop stop-color="#D284FF"/>
<stop offset="0.245187" stop-color="#4D00FF"/>
<stop offset="0.410433"/>
<stop offset="1"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

View File

@ -66,6 +66,20 @@ html {
padding: 0 !important; padding: 0 !important;
margin: 0px !important; margin: 0px !important;
overflow: auto !important; overflow: auto !important;
&.favorites-page {
background: #f7fffd;
}
&.search-page {
background-color: #f7fffd;
}
&.library-page {
background-color: #f7fffd;
}
&.chat-bot-page {
background-color: #E5E0FF;
}
} }
} }
.haditha-system, .haditha-system,

View File

@ -835,7 +835,8 @@ onMounted(() => {
.search-filter { .search-filter {
.filter-item { .filter-item {
/* width: 81px; */ /* width: 81px; */
height: 40px; /* height: 40px; */
height: 56px;
border-radius: 12px; border-radius: 12px;
border-width: 0.3px; border-width: 0.3px;
padding-top: 8px; padding-top: 8px;

View File

@ -0,0 +1,45 @@
<script setup lang="ts"></script>
<template>
<footer class="haditha-footer fixedsd">
<UContainer
class="flex justify-between max-w-[var(--ui-container-two)] py-4 lg:px-4"
>
<p class="description">
© تمام حقوق اين وبسايت نیز برای مؤسسه هوش مصنوعی و تمدن اسلامی (همتا)
است.
</p>
<p class="description">طراحی شده توسط <span class="designer"> استودیو نیوا </span></p>
</UContainer>
</footer>
</template>
<style lang="scss" scoped>
.haditha-footer {
// position: fixed;
bottom: 0;
left: 0;
right: 0;
background-color: #1B2132;
.description {
font-weight: 300;
font-size: 14px;
line-height: 100%;
letter-spacing: 0%;
text-align: center;
color: #ffffff;
.designer {
font-weight: 300;
font-size: 14px;
line-height: 100%;
letter-spacing: 0%;
text-align: center;
color: #3fc8fa;
}
}
}
</style>

View File

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { useAuthStore } from "@stores/authStore"; import { useAuthStore } from "@stores/authStore";
const route = useRoute();
// { // {
// label: "چت بات", // label: "چت بات",
// icon: "haditha:chat-bot", // icon: "haditha:chat-bot",
@ -12,10 +12,12 @@ import { useAuthStore } from "@stores/authStore";
const items = ref([ const items = ref([
{ {
label: "خانه", label: "خانه",
icon: "haditha:home", icon: route.name == "haditha" ? "haditha:home" : "haditha:haditha-title",
to: "/haditha", to: "/haditha",
descrption: "صفحه اصلی", descrption: "صفحه اصلی",
class: "flex flex-col lg:flex-row justify-center items-center hide-label", class: `flex flex-col lg:flex-row justify-center items-center hide-label ${
route.name == "haditha" ? "icon-mode" : "title-mode"
}`,
}, },
{ {
label: "جستجو", label: "جستجو",
@ -193,7 +195,7 @@ onMounted(() => {
</script> </script>
<template> <template>
<div class="fixed bottom-2 lg:bottom-auto lg:top-2 right-0 left-0"> <div class="fixed bottom-2 main-navbar lg:bottom-auto lg:top-2 right-0 left-0 pt-2">
<UContainer class="flex my-navbar mx-3 lg:mx-auto"> <UContainer class="flex my-navbar mx-3 lg:mx-auto">
<!-- :disableHoverTrigge="isMobile" --> <!-- :disableHoverTrigge="isMobile" -->
<UNavigationMenu <UNavigationMenu
@ -266,7 +268,7 @@ onMounted(() => {
</template> </template>
<style lang="scss"> <style lang="scss">
.fixed { .main-navbar {
z-index: 999; z-index: 999;
.my-navbar { .my-navbar {
max-width: 75em; //1200px max-width: 75em; //1200px
@ -342,6 +344,11 @@ onMounted(() => {
} }
.hide-label { .hide-label {
&.title-mode {
.iconify {
width: 4.475em; /* 62px;*/
}
}
.truncate { .truncate {
display: none; display: none;
} }
@ -388,7 +395,7 @@ onMounted(() => {
} }
@media screen and (max-width: 991.99px) { @media screen and (max-width: 991.99px) {
.fixed { .main-navbar {
.my-navbar { .my-navbar {
height: 4.8em; // 76px; height: 4.8em; // 76px;

View File

@ -1,17 +0,0 @@
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="17"
viewBox="0 0 16 17"
fill="none"
>
<path d="M10.6668 1.83301H5.3335C2.66683 1.83301 1.3335 3.16634 1.3335 5.83301V14.4997C1.3335 14.8663 1.6335 15.1663 2.00016 15.1663H10.6668C13.3335 15.1663 14.6668 13.833 14.6668 11.1663V5.83301C14.6668 3.16634 13.3335 1.83301 10.6668 1.83301Z" stroke="#1B2132" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4.66748 6.83301H11.3341" stroke="url(#paint0_linear_67_3319)" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4.66748 10.166H9.33415" stroke="#1B2132" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<defs>
<linearGradient id="paint0_linear_67_3319" x1="11.378" y1="6.83301" x2="4.33954" y2="7.69806" gradientUnits="userSpaceOnUse">
<stop stop-color="#D284FF"/>
<stop offset="1" stop-color="#4D00FF"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 961 B

View File

@ -9,6 +9,11 @@ const props = defineProps({
}, },
}, },
}); });
const emit = defineEmits(["on-select-item"]);
const onSelectItem = (item) => {
emit("on-select-item", item.detail.value);
};
</script> </script>
<template> <template>
@ -18,6 +23,7 @@ const props = defineProps({
:items="items" :items="items"
:get-key="(item) => item.title" :get-key="(item) => item.title"
:default-expanded="['components']" :default-expanded="['components']"
dir="rtl"
> >
<!-- <h2 class="font-semibold text-sm text-stone-400 px-2 pt-1 pb-3"> <!-- <h2 class="font-semibold text-sm text-stone-400 px-2 pt-1 pb-3">
Directory Structure Directory Structure
@ -29,6 +35,7 @@ const props = defineProps({
:style="{ 'margin-right': `${item.level - 0.7}rem` }" :style="{ 'margin-right': `${item.level - 0.7}rem` }"
v-bind="item.bind" v-bind="item.bind"
class="tree-item flex items-center py-1.5 px-3 mb-4 rounded-lg border-[#29D985] outline-none bg-[#F0F1F4] focus:ring-grass8 focus:ring-[#29d985]" class="tree-item flex items-center py-1.5 px-3 mb-4 rounded-lg border-[#29D985] outline-none bg-[#F0F1F4] focus:ring-grass8 focus:ring-[#29d985]"
@select="onSelectItem"
> >
<template v-if="item.hasChildren"> <template v-if="item.hasChildren">
<Icon v-if="!isExpanded" icon="lucide:plus" class="h-6 w-6" /> <Icon v-if="!isExpanded" icon="lucide:plus" class="h-6 w-6" />

View File

@ -27,48 +27,46 @@ const emit = defineEmits(["on-bookmard-removed"]);
const router = useRouter(); const router = useRouter();
const route = useRoute(); const route = useRoute();
// const modal = useModal(); const modal = useModal();
// const isModalOpen = ref(false); const isModalOpen = ref(false);
let selectedItem = ref(undefined);
const hadithAddress = (item) => { const hadithAddress = (item) => {
return `${item?._source?.address?.vol_title}، صفحه return `${item?._source?.address?.vol_title}، صفحه
${item?._source?.address?.page_num}`; ${item?._source?.address?.page_num}`;
}; };
function goToSearchShowPage(selectedItem) { function goToSearchShowPage(item) {
// modal.open(SearchShow, { title: "Welcome" }); selectedItem.value = item;
// isModalOpen.value = true; // modal.open(SearchShow, { title: item.title });
isModalOpen.value = true;
const slug = selectedItem?._source?.content // const slug = selectedItem.value?._source?.content
.split(" ") // .split(" ")
.filter((v, i) => i < 4) // .filter((v, i) => i < 4)
.join("-"); // .join("-");
router.push({ // router.push({
name: "hadithaSearchShow", // name: "hadithaSearchShow",
params: { // params: {
id: selectedItem?._source?.id, // id: selectedItem.value?._source?.id,
slug: slug, // slug: slug,
}, // },
query: { // query: {
q: props.searchTerm, // q: props.searchTerm,
}, // },
}); // });
}
async function closeModal() {
// await modal.close();
isModalOpen.value = false;
}
function resetModal() {
modal.reset();
}
function updateModalTitle() {
modal.patch({ title: "Updated Title" });
} }
// async function closeModal() {
// await modal.close();
// }
// function resetModal() {
// modal.reset();
// }
// function updateModalTitle() {
// modal.patch({ title: "Updated Title" });
// }
// components declaration
// const SearchShow = defineAsyncComponent(() =>
// import("@haditha/components/haditha/search-page/SearchShow.vue")
// );
const removeFromFavorites = async (item = {}, index = 0) => { const removeFromFavorites = async (item = {}, index = 0) => {
let url = repoUrl() + hadithaApi.favorite.deleteByRefid; let url = repoUrl() + hadithaApi.favorite.deleteByRefid;
url = url.replace("{{data_type}}", "bookmark"); url = url.replace("{{data_type}}", "bookmark");
@ -84,6 +82,10 @@ const removeFromFavorites = async (item = {}, index = 0) => {
// this.updateListAnswer(index, "tbookmark", 0); // this.updateListAnswer(index, "tbookmark", 0);
}); });
}; };
// components declaration
const SearchShow = defineAsyncComponent(() =>
import("@haditha/components/haditha/search-page/SearchShow.vue")
);
</script> </script>
<template> <template>
@ -171,7 +173,7 @@ const removeFromFavorites = async (item = {}, index = 0) => {
</div> </div>
<!-- </template> --> <!-- </template> -->
<!-- <UModal <UModal
v-model:open="isModalOpen" v-model:open="isModalOpen"
:dismissible="false" :dismissible="false"
:ui="{ :ui="{
@ -186,13 +188,13 @@ const removeFromFavorites = async (item = {}, index = 0) => {
close: 'modal-close', close: 'modal-close',
}" }"
> >
<template #header><div class="hidden"></div></template> <!-- <template #header><div class="hidden"></div></template> -->
<template #content></template> <!-- <template #content></template> -->
<template #body> <template #body>
<search-show @close="isModalOpen = !isModalOpen"></search-show> <search-show :selectedItem="selectedItem" @close="closeModal"></search-show>
</template> </template>
<<template #footer></template> <!-- <<template #footer></template> -->
</UModal> --> </UModal>
</template> </template>
<style scoped> <style scoped>
@ -269,3 +271,78 @@ const removeFromFavorites = async (item = {}, index = 0) => {
} }
} }
</style> </style>
<style>
.text__orange {
color: orange;
}
.modal-content {
border: 0.3px solid #e0e0e0;
box-shadow: 0px 8px 20px 0px #0000001a;
background: #ffffff;
width: 100%;
max-width: 720px;
border-radius: 16px;
gap: 8px;
border-width: 0.3px;
.modal-body {
border-radius: 16px;
height: 800px;
position: relative;
.top-left-bgi {
position: absolute;
top: 0;
left: 0;
background-image: url("../../../assets/haditha/images/modal-top-bgi.png");
backdrop-filter: blur(54px);
width: 447px;
height: 447px;
top: 0;
left: 0;
background-repeat: no-repeat;
background-size: auto;
z-index: -1;
}
&::before {
content: "";
position: absolute;
right: 0;
bottom: 0;
background-image: url("../../../assets/haditha/images/modal-bttom-right-bgi.png");
backdrop-filter: blur(54px);
width: 438px;
height: 238px;
mix-blend-mode: Multiply;
background-repeat: no-repeat;
background-size: cover;
z-index: -1;
}
&::after {
content: "";
position: absolute;
bottom: 0;
left: 0;
width: 458px;
height: 239px;
mix-blend-mode: Multiply;
background-image: url("../../../assets/haditha/images/modal-bottom-left-bgi.png");
background-repeat: no-repeat;
background-size: cover;
backdrop-filter: blur(54px);
z-index: -1;
}
}
}
.modal-overlay {
background: #00000033;
}
</style>

View File

@ -1,4 +1,6 @@
<script setup> <script setup lang="ts">
import hadithaApi from "@haditha/apis/hadithaApi";
const props = defineProps({ const props = defineProps({
selectedItem: { selectedItem: {
type: Object, type: Object,
@ -7,12 +9,156 @@ const props = defineProps({
}, },
}, },
}); });
const emit = defineEmits(["close"]); const emit = defineEmits(["close"]);
let hadithItem = ref();
const route = useRoute();
const router = useRouter();
const loading = ref(false);
const httpService = useNuxtApp()["$http"];
const toast = useToast();
hadithItem.value = props.selectedItem;
const hadithAddress = computed(() => {
return `${hadithItem.value?._source?.address?.vol_title}، صفحه
${hadithItem.value?._source?.address?.page_num}`;
});
// const open = ref(false); // const open = ref(false);
const closeModal = () => { const closeModal = () => {
emit("close"); emit("close");
}; };
const goToTheSearch = () => {
emit("on-search-similar", hadithItem.value);
};
const goToTheChatbot = () => {
router.push({
name: "hadithaChatBot",
});
};
const handleFavorite = async () => {
if (hadithItem.value?._source?.tbookmark) {
await removeFromFavorites(hadithItem.value);
hadithItem.value._source.tbookmark = false;
} else {
await addToFavorites(hadithItem.value);
hadithItem.value._source.tbookmark = true;
}
};
const addToFavorites = async (item = {}) => {
let url = repoUrl() + hadithaApi.favorite.add;
url = url.replace("{{data_type}}", "bookmark");
url = url.replace("{{ref_key}}", "dhparag");
const formData = {
ref_id: item._id,
title: item._source.content,
};
httpService
.postRequest(url, formData)
.then((res) => {
toast.add({
title: "انجام شد.",
description: "به نشان شده ها افزوده شد",
color: "success",
});
})
.catch((err) => {
toast.add({
title: "خطا",
description: "خطایی رخ داد.لطفا دوباره امتحان کنید.",
color: "error",
});
});
};
const removeFromFavorites = async (item = {}, index = 0) => {
let url = repoUrl() + hadithaApi.favorite.deleteByRefid;
url = url.replace("{{data_type}}", "bookmark");
url = url.replace("{{index_key}}", "dhparag");
url = url.replace("{{ref_id}}", item._id);
const formData = {
ref_id: item._id,
title: item._source.title,
};
httpService
.postRequest(url, formData)
.then((res) => {
toast.add({
title: "انجام شد.",
description: "به نشان شده ها افزوده شد",
color: "success",
});
})
.catch((err) => {
toast.add({
title: "خطا",
description: "خطایی رخ داد.لطفا دوباره امتحان کنید.",
color: "error",
});
});
};
const handlePagination = (prevNextIndicator: string) => {
if (loading.value) return;
loading.value = true;
let url = repoUrl() + hadithaApi.search.prevNextHadith;
url = url.replace("@index_key", "dhparag");
url = url.replace("@vol_id", hadithItem.value?._source?.address?.vol_id);
url = url.replace("@parag_order", hadithItem.value?._source?.parag_order);
url = url.replace("@step", prevNextIndicator);
httpService
.getRequest(url)
.then((res) => {
hadithItem.value = res.hits.hits?.[0];
})
.finally(() => (loading.value = false));
};
const onKeyWordClick = (keyword) => {
// router.push({
// name: "hadithaSearch",
// query: {
// q: query.q ?? "",
// f_aik: keyword ?? "",
// },
// });
};
const onClassClick = (aiclass) => {
// router.push({
// name: "hadithaSearch",
// query: {
// q: route.query.q ?? "",
// f_aik: aiclass ?? "",
// },
// });
};
// const localCopyTextToClipboard = (text: string) => {
// copyTextToClipboard(text);
// };
// #endregion methods
const showArabicText = computed(() => {
return hadithItem.value?._source?.content_ar?.length;
});
const showPersianText = computed(() => {
return hadithItem.value?._source?.content?.length;
});
const showDescriptionText = computed(() => {
return hadithItem.value?._source?.description?.length;
});
const showKewrodAndClassesText = computed(() => {
return (
hadithItem.value?._source?.ai_keywords?.length ||
hadithItem.value?._source?.ai_classes?.length
);
});
</script> </script>
<template> <template>
@ -39,81 +185,175 @@ const closeModal = () => {
<div class="body-content"> <div class="body-content">
<div class="h-full flex flex-col justify-center z-2"> <div class="h-full flex flex-col justify-center z-2">
<div class="bg-container h-full"> <div class="bg-container">
<div class="header flex"> <div class="header flex">
<UButton <UButton
variant="ghost" @click="handleFavorite"
:variant="hadithItem?._source?.tbookmark ? 'soft' : 'ghost'"
color="primary"
class="bookmark-btn" class="bookmark-btn"
icon="i-haditha-tag" :icon="
hadithItem?._source?.tbookmark
? 'i-haditha-tag-active'
: 'i-haditha-tag'
"
> >
</UButton> </UButton>
<div class="referene">
<ULink
:to="{
name: 'hadithaLibraryShow',
params: {
id: hadithItem?._source?.address.vol_id,
slug: hadithAddress,
},
query: {
page_num: hadithItem?._source?.address?.page_num,
},
}"
color="neutral"
variant="ghost"
:ui="{
leadingIcon: 'text-(--ui-primary)',
}"
class="referene bg-white hover:bg-gray-100"
>
<span> نشانی: </span> <span> نشانی: </span>
الکافی، جلد ۱، صفحه ۱۰۳ {{ hadithAddress ?? "" }}
</div> </ULink>
</div> </div>
<div class="content"> <div class="content firefox-scrollbar">
<div class="search-item"> <div class="search-item">
<template v-if="showArabicText">
<div class="text-arabic-section"> <div class="text-arabic-section">
<div class="section-header"> <div class="section-header">
<span class="section-title">امام جعفر صادق علیهالسلام </span> <span class="section-title">
{{
hadithItem?._source?.meta?.hadith_masoum ??
hadithItem?._source?.meta?.hadith_sanad
}}
</span>
<UButton variant="ghost" class="copy-btn" label="کپی" /> <UButton
v-if="
hadithItem?._source?.meta?.hadith_masoum?.length ||
hadithItem?._source?.meta?.hadith_sanad
"
@click="
copyTextToClipboard(
hadithItem?._source?.content_ar ?? ''
)
"
variant="ghost"
class="copy-btn"
label="کپی"
/>
</div> </div>
<div class="arabic-text"> <div
v-if="hadithItem?._source?.content_ar?.length"
class="arabic-text"
>
<p> <p>
عَنِ الْحَسَنِ بْنِ عَلِيِّ بْنِ يُوسُفَ، عَنْ جَدِّهِ، {{ hadithItem?._source?.content_ar ?? "" }}
قَالَ:
</p>
<p>قَالَ أَبُو عَبْدِ اللَّهِ (عَلَيْهِ السَّلَامُ):</p>
<p>
إِنَّمَا يَدْرُسُ الْإِنسَانُ لِيَعْلَمَ، وَإِنَّمَا
يَعْلَمُ لِيَعْمَلَ، وَإِنَّمَا يَعْمَلُ لِيُعْرَفَ بِهِ،
وَإِنَّمَا يُعْرَفُ بِهِ لِيُقْبَلَ بِهِ، وَإِنَّمَا
يُقْبَلُ بِهِ لِيُؤْمَنَ عَلَيْهِ، وَإِنَّمَا يُؤْمَنُ
عَلَيْهِ لِيُدْخَلَ الْجَنَّةَ
</p> </p>
</div> </div>
</div> </div>
<div class="separator"></div> <div class="separator"></div>
</template>
<template v-if="showPersianText">
<div class="text-persian-section"> <div class="text-persian-section">
<div class="section-header"> <div class="section-header">
<span class="section-title"> ترجمه </span> <span class="section-title"> ترجمه </span>
<UButton variant="ghost" class="copy-btn" label="کپی" /> <UButton
@click="copyTextToClipboard(hadithItem?._source?.content)"
variant="ghost"
class="copy-btn"
label="کپی"
/>
</div> </div>
<p class="from">امام جعفر صادق علیهالسلام:</p> <p
<p class="persian-text"> class="from"
انسان دانش میآموزد تا بداند، و میداند تا عمل کند، و عمل v-if="
میکند تا به سبب آن شناخته شود، و شناخته میشود تا (عمل او) hadithItem?._source?.meta?.hadith_masoum ||
پذیرفته گردد، و پذیرفته میشود تا در امان قرار گیرد، و در امان hadithItem?._source?.meta?.hadith_sanad
قرار میگیرد تا وارد بهشت شود. "
>
{{
hadithItem?._source?.meta?.hadith_masoum ??
hadithItem?._source?.meta?.hadith_sanad
}}:
</p> </p>
<p
class="persian-text"
v-html="hadithItem?._source?.content"
></p>
</div> </div>
<div class="separator"></div> <div class="separator"></div>
</template>
<div class="text-description-section"> <template v-if="showDescriptionText">
<div
v-if="hadithItem?._source?.description?.length"
class="text-description-section"
>
<div class="section-header"> <div class="section-header">
<span class="section-title"> شرح </span> <span class="section-title"> شرح </span>
<UButton variant="ghost" class="copy-btn" label="کپی" /> <UButton
@click="
copyTextToClipboard(hadithItem?._source?.description)
"
variant="ghost"
class="copy-btn"
label="کپی"
/>
</div> </div>
<p class="description-item"> <p
این حدیث به سلسله مراتب علم و عمل اشاره دارد و تأکید میکند که class="description-item"
علم باید به عمل منتهی شود و عمل نیز باید با نیت خالص و برای v-html="hadithItem?._source?.description"
رضای خداوند باشد تا مورد قبول واقع شود و انسان را به سعادت ></p>
ابدی برساند.
</p>
<p class="description-item">
این حدیث به سلسله مراتب علم و عمل اشاره دارد و تأکید میکند که
علم باید به عمل منتهی شود و عمل نیز باید با نیت خالص و برای
رضای خداوند باشد تا مورد قبول واقع شود و انسان را به سعادت
ابدی برساند.
</p>
</div> </div>
<div class="separator"></div>
</template>
<template v-if="showKewrodAndClassesText">
<div class="text-description-section">
<div
v-if="hadithItem?._source?.ai_keywords?.length"
class="mb-4"
>
<span class="text-sm"> کلیدواژگان: </span>
<UButton
class="me-1 text-sm"
v-for="(keyword, i) in hadithItem?._source?.ai_keywords"
:key="i"
@click.prevent="onKeyWordClick(keyword)"
variant="soft"
>
<!-- {{ i > 0 ? "," : "" }} -->
{{ keyword }}
</UButton>
</div>
<div v-if="hadithItem?._source?.ai_classes?.length">
<span class="text-sm"> دسته بندی ها: </span>
<UButton
class="me-1 text-sm"
v-for="(aiClass, i) in hadithItem?._source?.ai_classes"
:key="i"
@click.prevent="onClassClick(aiClass)"
variant="soft"
>
<!-- {{ i > 0 ? "," : "" }} -->
{{ aiClass.label }}
</UButton>
</div>
</div>
</template>
</div> </div>
</div> </div>
</div> </div>
@ -124,21 +364,26 @@ const closeModal = () => {
<div class="mt-5 z-2"> <div class="mt-5 z-2">
<div class="flex justify-between actions"> <div class="flex justify-between actions">
<UButton <UButton
disabled
class="similar-btn" class="similar-btn"
icon="i-haditha-search-3" icon="i-haditha-search-3"
label="مشابه" label="مشابه"
color="neutral" color="neutral"
variant="outline" variant="outline"
@click.prevent="goToTheSearch()"
/> />
<UButton <UButton
class="explore-btn" disabled
class="explore-btn mr-8"
trailing-icon="i-haditha-explore" trailing-icon="i-haditha-explore"
label="کاوش" label="کاوش"
variant="solid" variant="solid"
@click.prevent="goToTheChatbot()"
/> />
</div> </div>
<div class="flex justify-between pagination"> <div class="flex justify-between pagination">
<UButton <UButton
@click="handlePagination('-1')"
class="prev-haditha" class="prev-haditha"
label="حدیث قبل" label="حدیث قبل"
color="" color=""
@ -146,6 +391,7 @@ const closeModal = () => {
icon="i-haditha-chevron-right" icon="i-haditha-chevron-right"
/> />
<UButton <UButton
@click="handlePagination('1')"
class="next-haditha" class="next-haditha"
label="حدیث بعد" label="حدیث بعد"
color="" color=""
@ -179,6 +425,7 @@ const closeModal = () => {
.body-content { .body-content {
.header { .header {
.bookmark-btn { .bookmark-btn {
width: 49px;
width: 49px; width: 49px;
height: 32px; height: 32px;
gap: 4px; gap: 4px;
@ -189,7 +436,7 @@ const closeModal = () => {
padding-bottom: 4px; padding-bottom: 4px;
padding-left: 12px; padding-left: 12px;
border: 0.5px solid #d9d9d9; border: 0.5px solid #d9d9d9;
background: #ffffff; /* background: #ffffff; */
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
@ -212,7 +459,7 @@ const closeModal = () => {
padding-right: 12px; padding-right: 12px;
padding-bottom: 4px; padding-bottom: 4px;
padding-left: 12px; padding-left: 12px;
background: #ffffff; /* background-color: #ffffff; */
border: 0.5px solid #d9d9d9; border: 0.5px solid #d9d9d9;
font-family: var(--font); font-family: var(--font);
@ -285,12 +532,12 @@ const closeModal = () => {
/* height: 24px; */ /* height: 24px; */
gap: 4px; gap: 4px;
border-radius: 6px; border-radius: 6px;
border-width: 0.5px; /* border-width: 0.5px; */
padding-top: 4px; padding-top: 4px;
padding-right: 12px; padding-right: 12px;
padding-bottom: 4px; padding-bottom: 4px;
padding-left: 12px; padding-left: 12px;
background: #ffffff; /* background: #ffffff; */
border: 0.5px solid #d9d9d9; border: 0.5px solid #d9d9d9;
font-family: var(--font); font-family: var(--font);
@ -327,9 +574,11 @@ const closeModal = () => {
.from, .from,
.persian-text { .persian-text {
font-family: var(--ar-font); /* font-family: Takrim; */
font-family: var(--font);
font-weight: 400; font-weight: 400;
font-size: 18px; /* font-size: 18px; */
font-size: 0.85rem;
line-height: 30px; line-height: 30px;
letter-spacing: 0%; letter-spacing: 0%;
text-align: right; text-align: right;
@ -350,9 +599,11 @@ const closeModal = () => {
padding: 2em 0; padding: 2em 0;
.description-item { .description-item {
font-family: var(--ar-font); font-family: var(--font);
font-weight: 400; font-weight: 400;
font-size: 18px; /* font-size: 18px; */
font-size: 0.85rem;
line-height: 30px; line-height: 30px;
letter-spacing: 0%; letter-spacing: 0%;
text-align: right; text-align: right;

View File

@ -4,19 +4,30 @@ definePageMeta({
layout: false, layout: false,
}); });
// const route = useRoute();
onMounted(() => { onMounted(() => {
clearBodyClass(); clearBodyClass();
}); });
onUnmounted(() => { onUnmounted(() => {
clearBodyClass(); clearBodyClass();
}); });
// const HadithaFooter = defineAsyncComponent(() =>
// import("@haditha/components/haditha/HadithaFooter.vue")
// );
</script> </script>
<template> <template>
<!-- <main :class="{ 'h-full': route.name != 'haditha' }"> -->
<main class="h-full"> <main class="h-full">
<slot name="named-slot"></slot> <slot name="named-slot"></slot>
<slot></slot> <slot></slot>
</main> </main>
<!-- <haditha-footer
v-if="route.name != 'hadithaLibraryShow' && route.name != 'hadithaSearch'"
:class="{ static: route.name == 'haditha' }"
></haditha-footer> -->
</template> </template>
<style> <style>

View File

@ -2,7 +2,18 @@
import hadithaApi from "@haditha/apis/hadithaApi"; import hadithaApi from "@haditha/apis/hadithaApi";
import headLinks from "@haditha/json/haditha/headLinks"; import headLinks from "@haditha/json/haditha/headLinks";
import headMetas from "@haditha/json/haditha/headMetas"; import headMetas from "@haditha/json/haditha/headMetas";
import { useInfiniteScroll } from "@vueuse/core"; // const { loggedIn, user, session, fetch, clear, openInPopup } = useUserSession()
// console.info(loggedIn, user, session, fetch, clear, openInPopup);
// 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({ definePageMeta({
layout: false, layout: false,
@ -16,20 +27,17 @@ useHead({
...headMetas, ...headMetas,
], ],
bodyAttrs: { bodyAttrs: {
class: import.meta.env.VITE_HADITH_SYSTEM, class: `${import.meta.env.VITE_HADITH_SYSTEM} favorites-page`,
}, },
link: headLinks, link: headLinks,
}); });
// #region refs // #region refs
const el = ref(null); // const el = ref(null);
const httpService = useNuxtApp()["$http"]; const httpService = useNuxtApp()["$http"];
const offset = useState("offset", () => 0); const favOffset = useState("favOffset", () => 0);
const total = useState("total", () => 0); const total = useState("total", () => 0);
const loading = useState("loading", () => false);
const hasMore = useState("hasMore", () => true);
// #endregion refs // #endregion refs
// #region reactive // #region reactive
@ -39,7 +47,7 @@ const state = reactive({
page: 1, page: 1,
pages: 1, pages: 1,
// offset: 0, // offset: 0,
limit: 500, limit: 15,
}, },
}); });
// #endregion reactive // #endregion reactive
@ -51,61 +59,87 @@ const getFavorites = async (dataType = "bookmark") => {
url = url.replace("@data_type", dataType); url = url.replace("@data_type", dataType);
url = url.replace("@time_key", "all"); url = url.replace("@time_key", "all");
url = url.replace("@source", "main"); url = url.replace("@source", "main");
url = url.replace("@offset", offset.value); url = url.replace("@offset", favOffset.value);
url = url.replace("@limit", state.pagination.limit); url = url.replace("@limit", state.pagination.limit);
url = url.replace("@q", "none"); url = url.replace("@q", "none");
return await httpService.getRequest(url).then((res) => { return await httpService.getRequest(url).then((data) => {
console.info(res); total.value = data.hits?.total?.value ?? 0;
total.value = res.hits?.total?.value ?? 0; favOffset.value += state.pagination.limit;
offset.value += state.pagination.limit; return data.hits?.hits;
});
// return await requestFetch(url, {
// headers: {
// method: "get",
// Authorization: token,
// },
// }).then((data) => {
// total.value = data.hits?.total?.value ?? 0;
// favOffset.value += state.pagination.limit;
// return data.hits?.hits;
// });
};
const { data: favoriteList } = await useAsyncData("favorites", () =>
getFavorites()
);
// Client-side infinite scroll
const loadMore = async () => {
return await getFavorites().then((res) => {
const hits = res ?? [];
favoriteList.value = [...favoriteList.value, ...hits];
return res; return res;
}); });
}; };
const { data: favoriteList } = await useAsyncData( // const { isFetching } = useInfiniteScroll(loadMore, "favoriteInfiniteScroll");
"favorites", const { isFetching } = useInfiniteScroll(async () => {
() => getFavorites(), await loadMore();
{ });
transform: (data) => data.hits.hits,
}
);
// Client-side infinite scroll
useInfiniteScroll(
el,
async () => {
if (!hasMore.value || loading.value) return;
loading.value = true;
try {
await getFavorites().then((res) => {
const hits = res?.hits?.hits ?? [];
if (hits.length) {
// Use spread operator to create new array reference
favoriteList.value = [...favoriteList.value, ...hits];
} else {
hasMore.value = false;
}
});
} catch (error) {
hasMore.value = false;
// console.error("Error loading more items:", error);
// Consider setting hasMore.value = false if you want to stop on error
} finally {
loading.value = false;
}
},
{
distance: 100,
}
);
const updateList = (index) => { const updateList = (index) => {
favoriteList.value.splice(index, 1); favoriteList.value.splice(index, 1);
}; };
onUnmounted(() => {
favOffset.value = total.value = 0;
});
// Client-side infinite scroll
// useInfiniteScroll(
// el,
// async () => {
// if (!hasMore.value || loading.value) return;
// loading.value = true;
// try {
// await getFavorites().then((res) => {
// const hits = res?.hits?.hits ?? [];
// if (hits.length) {
// // Use spread operator to create new array reference
// favoriteList.value = [...favoriteList.value, ...hits];
// } else {
// hasMore.value = false;
// }
// });
// } catch (error) {
// hasMore.value = false;
// // console.error("Error loading more items:", error);
// // Consider setting hasMore.value = false if you want to stop on error
// } finally {
// loading.value = false;
// }
// },
// {
// distance: 100,
// }
// );
const HadithaLayout = defineAsyncComponent(() => const HadithaLayout = defineAsyncComponent(() =>
import("@haditha/layouts/HadithaLayout.vue") import("@haditha/layouts/HadithaLayout.vue")
); );
@ -121,7 +155,7 @@ const SearchList = defineAsyncComponent(() =>
<template> <template>
<HadithaLayout> <HadithaLayout>
<div class="h-full flex flex-col justify-center"> <div class="h-full flex flex-col justify-center">
<div class="bg-container h-full"> <div class="bg-container">
<navigation-menu></navigation-menu> <navigation-menu></navigation-menu>
<div class="text-logo"> <div class="text-logo">
@ -136,7 +170,8 @@ const SearchList = defineAsyncComponent(() =>
</div> </div>
<div <div
ref="el" ref="favoriteInfiniteScroll"
id="favoriteInfiniteScroll"
class="search-list firefox-scrollbar hadithaFavorites" class="search-list firefox-scrollbar hadithaFavorites"
> >
<search-list <search-list
@ -167,7 +202,6 @@ const SearchList = defineAsyncComponent(() =>
/* height: 100dvh; */ /* height: 100dvh; */
background-size: cover; background-size: cover;
background-repeat: no-repeat; background-repeat: no-repeat;
background: #f7fffd;
} }
.text-logo { .text-logo {
@ -204,11 +238,11 @@ const SearchList = defineAsyncComponent(() =>
} }
.search-list { .search-list {
padding: 1em 1.3em; padding: 1em 1.3em;
height: calc(100dvh - 16em); /* height: calc(100dvh - 16em); */
overflow-y: auto; /* overflow-y: auto; */
&.hadithaFavorites { &.hadithaFavorites {
height: calc(100dvh - 8em); /* height: calc(100dvh - 8em); */
} }
&:not(:last-child) { &:not(:last-child) {

View File

@ -189,13 +189,11 @@ const onSearch = () => {
name: "hadithaSearch", name: "hadithaSearch",
}); });
}; };
const onClose = () => { const onCloseModal = () => {
router.push({ isModalOpen.value = false;
name: "hadithLibrary",
});
}; };
const handlePagination = ( const handlePagination = async (
prevNextIndicator: number, prevNextIndicator: number,
userEnteredPage: number | undefined = undefined userEnteredPage: number | undefined = undefined
) => { ) => {
@ -222,7 +220,7 @@ const handlePagination = (
// اگر کاربر شماره صفحه ای را وارد نکرده باشد.. // اگر کاربر شماره صفحه ای را وارد نکرده باشد..
if (!userEnteredPage) page_num.value = +page_num.value + prevNextIndicator; if (!userEnteredPage) page_num.value = +page_num.value + prevNextIndicator;
httpService return await httpService
.getRequest(url) .getRequest(url)
.then((res: HadithResponseModel) => { .then((res: HadithResponseModel) => {
selectedItem.value = res.hits.hits; selectedItem.value = res.hits.hits;
@ -250,22 +248,153 @@ const getDataTree = () => {
}); });
}; };
const prepareTreeData = (data) => { // const prepareTreeData = (rawTree, startIndex = 0) => {
return data.map((item) => { // const tree = [];
const res = { // let i = startIndex;
...item,
...item._source, // // Base case: if we've reached the end of the array, return an empty tree
title: item._source.content, // if (i >= rawTree.length) {
}; // return tree;
delete res._source; // }
return res;
// // Process nodes with level 1
// while (i < rawTree.length && rawTree[i]._source.meta.level === 1) {
// // Create a tree node for the current element
// const currentNode = {
// ...rawTree[i],
// title: rawTree[i]._source.content,
// icon: "no-icon",
// children: [],
// };
// // Recursively process children (nodes with level > 1)
// let childIndex = i + 1;
// while (
// childIndex < rawTree.length &&
// rawTree[childIndex]._source.meta.level > 1
// ) {
// const childNode = {
// ...rawTree[childIndex],
// title: rawTree[childIndex]._source.content,
// };
// currentNode.children.push(childNode);
// childIndex++;
// }
// // Update the icon if there are children
// if (currentNode.children.length > 0) {
// currentNode.icon = "lucide:plus";
// }
// // Add the processed node to the tree
// tree.push(currentNode);
// // Move the index to the next level-1 node
// i = childIndex;
// }
// // Recursively process the remaining part of the array
// if (i < rawTree.length) {
// tree.push(...prepareTreeData(rawTree, i));
// }
// return tree;
// };
// const prepareTreeData = (rawTree) => {
// const tree = [];
// let mainIndex = 0;
// for (let i = mainIndex; i < rawTree.length; i++) {
// if (rawTree[i]._source.meta.level == 1) {
// rawTree[i].title = rawTree[i]._source.content;
// rawTree[i].icon = "no-icon";
// tree.push(rawTree[i]);
// tree[tree.length - 1].children = [];
// for (let j = i + 1; j < rawTree.length; j++) {
// if (rawTree[j]._source.meta.level == 1) {
// mainIndex = j;
// break;
// } else {
// rawTree[j].title = rawTree[j]._source.content;
// tree[tree.length - 1].children.push(rawTree[j]);
// }
// }
// if (tree[tree.length - 1].children.length)
// tree[tree.length - 1].icon = "lucide:plus";
// }
// }
// return tree;
// };
const prepareTreeData = (rawTree) => {
const tree = [];
let mainIndex = 0;
// level 1
for (let i = mainIndex; i < rawTree.length; i++) {
if (rawTree[i]._source.meta.level == 1) {
rawTree[i].title = rawTree[i]._source.content;
rawTree[i].icon = "no-icon";
tree.push(rawTree[i]);
tree[tree.length - 1].children = [];
// level 2
for (let j = i + 1; j < rawTree.length; j++) {
if (rawTree[j]._source.meta.level == 1) {
mainIndex = j;
break;
} else {
rawTree[j].title = rawTree[j]._source.content;
tree[tree.length - 1].children.push(rawTree[j]);
// level 3
// let secondIndex = j;
// tree[tree.length - 1].children[tree[tree.length - 1].children.length -1].children = [];
// console.info(tree[tree.length - 1].children);
// for (let k = secondIndex + 1; k < rawTree.length; k++) {
// if (rawTree[k]._source.meta.level == 2) {
// secondIndex = k;
// break;
// } else {
// console.info(j);
// rawTree[k].title = rawTree[k]._source.content;
// tree[tree.length - 1].children[tree[tree.length - 1].children.length -1].children.push(rawTree[k]);
// }
// }
// if (tree[tree.length - 1].children[j].length)
// tree[tree.length - 1].children[j].icon = "lucide:plus";
}
}
if (tree[tree.length - 1].children.length)
tree[tree.length - 1].icon = "lucide:plus";
}
}
return tree;
};
const onselectItem = (item) => {
handlePagination(1, item._source.meta.page).then(() => {
page_num.value = item._source.meta.page;
}); });
}; };
// getDataTree(); getDataTree();
// #endregion methods // #endregion methods
onUnmounted(() => {
loading.value = false;
page_num.value = 1;
volumeInfo.value = {};
});
// components declaration // components declaration
const HadithaLayout = defineAsyncComponent( const HadithaLayout = defineAsyncComponent(
() => import("@haditha/layouts/HadithaLayout.vue") () => import("@haditha/layouts/HadithaLayout.vue")
@ -290,13 +419,13 @@ const NavigationMenu = defineAsyncComponent(
}" }"
class="page-inner-container sm:px-6 lg:px-4" class="page-inner-container sm:px-6 lg:px-4"
> >
<navigation-menu></navigation-menu> <!-- <navigation-menu></navigation-menu> -->
<div class="page-header py-4 flex justify-between items-center"> <div class="page-header py-4 flex justify-between items-center">
<div class="flex items-center"> <div class="flex items-center">
<UButton <UButton
class="menu p-1 me-8" class="menu p-0 me-8"
@click="onOpenList" @click.prevent="onOpenList"
icon="i-lucide-menu" icon="i-lucide-menu"
variant="" variant=""
/> />
@ -399,6 +528,7 @@ const NavigationMenu = defineAsyncComponent(
}" }"
title="فهرست" title="فهرست"
:close="{ :close="{
onClick: onCloseModal,
color: 'primary', color: 'primary',
variant: 'outline', variant: 'outline',
class: 'rounded-full', class: 'rounded-full',
@ -407,7 +537,7 @@ const NavigationMenu = defineAsyncComponent(
<!-- <template #header></template> --> <!-- <template #header></template> -->
<!-- <template #content></template> --> <!-- <template #content></template> -->
<template #body> <template #body>
<UTree :items="state.treeItems" /> <UTree :items="state.treeItems" @on-select-item="onselectItem" />
<!-- <accordion-menu @close="isModalOpen = !isModalOpen"></accordion-menu> --> <!-- <accordion-menu @close="isModalOpen = !isModalOpen"></accordion-menu> -->
</template> </template>
<!-- <template #footer></template> --> <!-- <template #footer></template> -->
@ -417,10 +547,10 @@ const NavigationMenu = defineAsyncComponent(
<style scoped> <style scoped>
.page-container { .page-container {
/* background: #f7fffd; */ background: #f7fffd;
.page-inner-container { .page-inner-container {
padding-top: 6em; /* padding-top: 6em; */
/* position: relative; */ /* position: relative; */
/* padding-bottom: 4em; */ /* padding-bottom: 4em; */
width: 100%; width: 100%;
@ -487,7 +617,7 @@ const NavigationMenu = defineAsyncComponent(
font-size: 0.9rem; font-size: 0.9rem;
line-height: 40px; line-height: 40px;
letter-spacing: 0%; letter-spacing: 0%;
text-align: right; text-align: justify;
color: var(--ui-color-two); color: var(--ui-color-two);
@ -651,5 +781,3 @@ body.hadith-system.library-show-page {
} }
} }
</style> </style>
<!-- http://localhost:3000/haditha/library/vdh9971/%D8%AA%D8%B1%D8%AC%D9%85%D9%87%20%D8%A7%D8%B5%D9%88%D9%84%20%DA%A9%D8%A7%D9%81%DB%8C%20%D8%AC%D9%84%D8%AF%20%D8%A7%D9%88%D9%84%D8%8C%20%D8%B5%D9%81%D8%AD%D9%87%0A%20%20%20384 -->

View File

@ -3,15 +3,15 @@ import hadithaApi from "@haditha/apis/hadithaApi";
import headLinks from "@haditha/json/haditha/headLinks"; import headLinks from "@haditha/json/haditha/headLinks";
import headMetas from "@haditha/json/haditha/headMetas"; import headMetas from "@haditha/json/haditha/headMetas";
// import { useInfiniteScroll } from "@vueuse/core"; // import { useInfiniteScroll } from "@vueuse/core";
const id_token = useCookie("id_token"); // const id_token = useCookie("id_token");
const token = id_token.value ?? "GuestAccess"; // const token = id_token.value ?? "GuestAccess";
const config = useRuntimeConfig(); // const config = useRuntimeConfig();
const baseUrl = // const baseUrl =
config.public.NUXT_PUBLIC_BASE_URL + config.public.NUXT_PUBLIC_API_NAME; // config.public.NUXT_PUBLIC_BASE_URL + config.public.NUXT_PUBLIC_API_NAME;
// this enable us to send cookies. // this enable us to send cookies.
const requestFetch = useRequestFetch(); // const requestFetch = useRequestFetch();
definePageMeta({ definePageMeta({
layout: false, layout: false,
@ -24,13 +24,13 @@ useHead({
...headMetas, ...headMetas,
], ],
bodyAttrs: { bodyAttrs: {
class: import.meta.env.VITE_HADITH_SYSTEM, class: `${import.meta.env.VITE_HADITH_SYSTEM} library-page`,
}, },
link: headLinks, link: headLinks,
}); });
// #region refs // #region refs
// const httpService = useNuxtApp()["$http"]; const httpService = useNuxtApp()["$http"];
// const { $api } = useNuxtApp() // const { $api } = useNuxtApp()
const offset = useState("offset", () => 0); const offset = useState("offset", () => 0);
const total = useState("total", () => 0); const total = useState("total", () => 0);
@ -52,19 +52,21 @@ const state = reactive({
// #region methods // #region methods
const getLibraryList = () => { const getLibraryList = async () => {
let url = baseUrl + repoUrl() + hadithaApi.library.list; // let url = baseUrl + repoUrl() + hadithaApi.library.list;
let url = repoUrl() + hadithaApi.library.list;
url = url.replace("@field_collapsed", "normal"); url = url.replace("@field_collapsed", "normal");
url = url.replace("@offset", offset.value); url = url.replace("@offset", offset.value);
url = url.replace("@limit", state.pagination.limit); url = url.replace("@limit", state.pagination.limit);
url = url.replace("@q", "none"); url = url.replace("@q", "none");
return requestFetch(url, { // return requestFetch(url, {
method: "POST", // method: "POST",
headers: { // headers: {
Authorization: token, // Authorization: token,
}, // },
}).then((data) => { // })
return httpService.postRequest(url).then((data) => {
total.value = data.hits?.total?.value ?? 0; total.value = data.hits?.total?.value ?? 0;
offset.value += state.pagination.limit; offset.value += state.pagination.limit;
return data.hits?.hits; return data.hits?.hits;
@ -99,6 +101,7 @@ const loadMore = async () => {
// status.value = "success"; // status.value = "success";
return res; return res;
}); });
// }, 300); // }, 300);
// } else { // } else {
// toast.add({ // toast.add({
@ -110,9 +113,19 @@ const loadMore = async () => {
// } // }
// } else status.value = "idle"; // } else status.value = "idle";
}; };
const { isFetching } = useInfiniteScroll(loadMore, "libraryInfiniteScroll"); // const { isFetching } = useInfiniteScroll(loadMore, "libraryInfiniteScroll");
const { isFetching } = useInfiniteScroll(async () => {
await loadMore();
});
// #endregion methods // #endregion methods
// #region hooks
onUnmounted(() => {
offset.value = total.value = 0;
});
// #endregion hooks
// components declaration // components declaration
const HadithaLayout = defineAsyncComponent( const HadithaLayout = defineAsyncComponent(
() => import("@haditha/layouts/HadithaLayout.vue") () => import("@haditha/layouts/HadithaLayout.vue")
@ -127,7 +140,7 @@ const CardList = defineAsyncComponent(
<template> <template>
<HadithaLayout> <HadithaLayout>
<div class="search-box-container h-full flex flex-col justify-center"> <div class="search-box-container h-fullsd flex flex-col justify-center">
<navigation-menu></navigation-menu> <navigation-menu></navigation-menu>
<div class="library-list-contianer"> <div class="library-list-contianer">
@ -164,7 +177,6 @@ const CardList = defineAsyncComponent(
<style scoped> <style scoped>
.search-box-container { .search-box-container {
padding-top: 8.3em; padding-top: 8.3em;
background: #f7fffd;
.library-list-contianer { .library-list-contianer {
height: 100%; height: 100%;
@ -192,9 +204,9 @@ const CardList = defineAsyncComponent(
.library-list { .library-list {
/* padding: 1em 1.3em; */ /* padding: 1em 1.3em; */
height: calc(100dvh - 13.5em); /* height: calc(100dvh - 13.5em); */
overflow-y: auto; /* overflow-y: auto; */
scroll-behavior: smooth; /* scroll-behavior: smooth; */
} }
.no-data-text { .no-data-text {
font-family: var(--font); font-family: var(--font);

View File

@ -81,11 +81,11 @@ const goToTheSearch = (type: string) => {
}, },
}); });
}; };
// const goToTheChatbot = () => { const goToTheChatbot = () => {
// router.push({ router.push({
// name: "hadithaChatBot", name: "hadithaChatBot",
// }); });
// }; };
const handleFavorite = async () => { const handleFavorite = async () => {
if (selectedItem.value?._source?.tbookmark) { if (selectedItem.value?._source?.tbookmark) {
@ -192,6 +192,22 @@ const onClassClick = (aiclass) => {
// }; // };
// #endregion methods // #endregion methods
const showArabicText = computed(() => {
return selectedItem.value?._source?.content_ar?.length;
});
const showPersianText = computed(() => {
return selectedItem.value?._source?.content?.length;
});
const showDescriptionText = computed(() => {
return selectedItem.value?._source?.description?.length;
});
const showKewrodAndClassesText = computed(() => {
return (
selectedItem.value?._source?.ai_keywords?.length ||
selectedItem.value?._source?.ai_classes?.length
);
});
// #region hooks // #region hooks
// onMounted(() => { // onMounted(() => {
// console.info("mounted"); // console.info("mounted");
@ -209,16 +225,62 @@ const NavigationMenu = defineAsyncComponent(
<template> <template>
<HadithaLayout> <HadithaLayout>
<div class="page-container h-full"> <div class="page-container h-full">
<div class="page-header">
<UContainer <UContainer
ui="{ ui="{
base: 'sm:px-6 lg:px-4', base: 'sm:px-6 lg:px-4',
}" }"
class="page-inner-container sm:px-6 lg:px-4 py-8" class="max-w-[var(--ui-container-two)] sm:px-6 lg:px-4"
> >
<navigation-menu></navigation-menu> <navigation-menu class="static py-4"></navigation-menu>
</UContainer>
</div>
<UContainer
ui="{
base: 'sm:px-6 lg:px-4',
}"
class="page-inner-container search sm:px-6 lg:px-0 mt-6"
>
<div class="search-show-page lg:px-12 py-4">
<div class="body-header pb-6 flex justify-between">
<div class="flex justify-between pagination flex-1 items-center">
<UButton
@click="handlePagination('-1')"
class="prev-haditha"
label="حدیث قبل"
color=""
variant="soft"
icon="i-haditha-chevron-right"
/>
<UButton
@click="handlePagination('1')"
class="next-haditha"
label="حدیث بعد"
color=""
variant="soft"
trailing-icon="i-haditha-chevron-left"
/>
</div>
<div class="search-show-page py"> <div class="flex justify-between actions mr-8">
<div class="body-header"> <UButton
disabled
class="similar-btn"
icon="i-haditha-search-3"
label="مشابه"
color="neutral"
variant="outline"
@click.prevent="goToTheSearch('similar')"
/>
<UButton
class="explore-btn mr-8"
trailing-icon="i-haditha-explore"
label="کاوش"
variant="solid"
@click.prevent="goToTheChatbot"
/>
</div>
<!-- <div>
<span class="top-left-bgi z-0"></span> <span class="top-left-bgi z-0"></span>
<div class="modal-title flex justify-between"> <div class="modal-title flex justify-between">
<ULink <ULink
@ -241,11 +303,12 @@ const NavigationMenu = defineAsyncComponent(
@click="goToTheSearch('normal')" @click="goToTheSearch('normal')"
/> />
</div> </div>
</div> -->
</div> </div>
<div class="body-content"> <div class="body-content">
<div class="h-full flex flex-col justify-center z-2"> <div class="h-full flex flex-col justify-center z-2">
<div class="bg-container h-full"> <div class="bg-container">
<div class="header flex"> <div class="header flex">
<UButton <UButton
@click="handleFavorite" @click="handleFavorite"
@ -287,6 +350,7 @@ const NavigationMenu = defineAsyncComponent(
<div class="content firefox-scrollbar"> <div class="content firefox-scrollbar">
<div class="search-item"> <div class="search-item">
<template v-if="showArabicText">
<div class="text-arabic-section"> <div class="text-arabic-section">
<div class="section-header"> <div class="section-header">
<span class="section-title"> <span class="section-title">
@ -323,13 +387,16 @@ const NavigationMenu = defineAsyncComponent(
</div> </div>
<div class="separator"></div> <div class="separator"></div>
</template>
<template v-if="showPersianText">
<div class="text-persian-section"> <div class="text-persian-section">
<div class="section-header"> <div class="section-header">
<span class="section-title"> ترجمه </span> <span class="section-title"> ترجمه </span>
<UButton <UButton
@click=" @click="
copyTextToClipboard(selectedItem?._source?.content) copyTextToClipboard(
selectedItem?._source?.content
)
" "
variant="ghost" variant="ghost"
class="copy-btn" class="copy-btn"
@ -337,7 +404,13 @@ const NavigationMenu = defineAsyncComponent(
/> />
</div> </div>
<p class="from"> <p
class="from"
v-if="
selectedItem?._source?.meta?.hadith_masoum ||
selectedItem?._source?.meta?.hadith_sanad
"
>
{{ {{
selectedItem?._source?.meta?.hadith_masoum ?? selectedItem?._source?.meta?.hadith_masoum ??
selectedItem?._source?.meta?.hadith_sanad selectedItem?._source?.meta?.hadith_sanad
@ -350,7 +423,9 @@ const NavigationMenu = defineAsyncComponent(
</div> </div>
<div class="separator"></div> <div class="separator"></div>
</template>
<template v-if="showDescriptionText">
<div <div
v-if="selectedItem?._source?.description?.length" v-if="selectedItem?._source?.description?.length"
class="text-description-section" class="text-description-section"
@ -375,7 +450,9 @@ const NavigationMenu = defineAsyncComponent(
</div> </div>
<div class="separator"></div> <div class="separator"></div>
</template>
<template v-if="showKewrodAndClassesText">
<div class="text-description-section"> <div class="text-description-section">
<div <div
v-if="selectedItem?._source?.ai_keywords?.length" v-if="selectedItem?._source?.ai_keywords?.length"
@ -410,14 +487,15 @@ const NavigationMenu = defineAsyncComponent(
</UButton> </UButton>
</div> </div>
</div> </div>
</template>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="body-footer"> <!-- <div class="body-footer"> -->
<div class="mt-5 pb-5 z-2"> <!-- <div class="mt-5 pb-5 z-2"> -->
<!-- <div class="flex justify-between actions"> <!-- <div class="flex justify-between actions">
<UButton <UButton
disabled disabled
@ -436,26 +514,8 @@ const NavigationMenu = defineAsyncComponent(
@click.prevent="goToTheChatbot" @click.prevent="goToTheChatbot"
/> />
</div> --> </div> -->
<div class="flex justify-between pagination"> <!-- </div> -->
<UButton <!-- </div> -->
@click="handlePagination('-1')"
class="prev-haditha"
label="حدیث قبل"
color=""
variant="soft"
icon="i-haditha-chevron-right"
/>
<UButton
@click="handlePagination('1')"
class="next-haditha"
label="حدیث بعد"
color=""
variant="soft"
trailing-icon="i-haditha-chevron-left"
/>
</div>
</div>
</div>
</div> </div>
</UContainer> </UContainer>
</div> </div>
@ -465,20 +525,141 @@ const NavigationMenu = defineAsyncComponent(
<!-- because of the buttons, using without scoped. --> <!-- because of the buttons, using without scoped. -->
<style> <style>
body.hadith-system.search-show-page { body.hadith-system.search-show-page {
background-color: #f7fffd; /* background-color: #f7fffd; */
} }
body.hadith-system.search-show-page {
.page-header {
width: 1920;
height: 100;
/* gap: 24px; */
border-bottom: 0.5px solid #76ffda;
/* padding-top: 8px; */
/* padding-right: 24px; */
/* padding-bottom: 24px; */
/* padding-left: 24px; */
background-image: url("/img/haditha/search-show-header.png");
background-repeat: no-repeat;
background-size: cover;
}
}
.page-inner-container { .page-inner-container {
height: 100%; /* height: 100%; */
max-width: 1200px; max-width: 1200px;
width: 100%; width: 100%;
&.search {
box-shadow: 0px 8px 20px 0px #0000001a;
border: 0.3px solid #e0e0e0;
/* width: 1200; */
/* height: 1028; */
gap: 8px;
border-radius: 16px;
}
} }
.search-show-page { .search-show-page {
.body-header { .body-header {
padding-top: 5em; /* padding-top: 5em; */
.actions {
/* margin-bottom: 1em; */
.similar-btn {
width: 114;
height: 56;
gap: 8px;
border-radius: 12px;
/* border-width: 0.5px; */
padding-top: 8px;
padding-right: 20px;
padding-bottom: 8px;
padding-left: 24px;
/* background: #ffffff; */
/* border: 0.5px solid; */
/* border-image-source: linear-gradient(
102.02deg,
#4be8ae 7.38%,
#00a762 91.78%
); */
/* box-shadow: 0px 8px 20px 0px #0000001a; */
font-family: var(--font);
font-weight: 400;
font-size: 15px;
line-height: 22.5px;
letter-spacing: 0%;
text-align: right;
color: var(--ui-color-two);
}
.explore-btn {
width: 118;
height: 56;
gap: 4px;
border-radius: 12px;
padding-top: 8px;
padding-right: 24px;
padding-bottom: 8px;
padding-left: 20px;
background: linear-gradient(268.94deg, #d284ff -0.65%, #4d00ff 104.59%);
/* box-shadow: 0px 8px 20px 0px #0000001a; */
font-family: var(--font);
font-weight: 400;
font-size: 16px;
line-height: 24px;
letter-spacing: 0%;
text-align: right;
color: #fff;
}
}
.pagination {
padding: 0.7em 0px;
/* width: 672; */
/* height: 56; */
justify-content: space-between;
border-radius: 16px;
/* border-width: 0.3px; */
padding-right: 32px;
padding-left: 32px;
background: #ffffff;
border: 0.3px solid #e0e0e0;
/* box-shadow: 0px 8px 20px 0px #0000001a; */
.prev-haditha {
font-family: var(--font);
font-weight: 300;
font-size: 12px;
line-height: 20px;
letter-spacing: 0%;
text-align: right;
color: var(--ui-color-two);
}
.next-haditha {
font-family: var(--font);
font-weight: 300;
font-size: 12px;
line-height: 20px;
letter-spacing: 0%;
text-align: right;
color: var(--ui-color-two);
}
.prev-haditha,
.next-haditha {
&:hover {
cursor: pointer;
background-color: #eee;
}
}
}
.modal-title { .modal-title {
padding: 0 0.5em 1.5em; /* padding: 0 0.5em 1.5em; */
margin-bottom: 2.5em; /* margin-bottom: 2.5em; */
.close-btn { .close-btn {
/* color: var(--ui-color-two); */ /* color: var(--ui-color-two); */
@ -554,7 +735,7 @@ body.hadith-system.search-show-page {
.content { .content {
/* height: calc(100dvh - 15em); */ /* height: calc(100dvh - 15em); */
/* overflow-y: auto; */ /* overflow-y: auto; */
padding-bottom: 5em; /* padding-bottom: 5em; */
.search-item { .search-item {
padding: 1em 0 1em 1em; padding: 1em 0 1em 1em;
@ -600,7 +781,7 @@ body.hadith-system.search-show-page {
/* height: 24px; */ /* height: 24px; */
gap: 4px; gap: 4px;
border-radius: 6px; border-radius: 6px;
border-width: 0.5px; /* border-width: 0.5px; */
padding-top: 4px; padding-top: 4px;
padding-right: 12px; padding-right: 12px;
padding-bottom: 4px; padding-bottom: 4px;
@ -615,7 +796,7 @@ body.hadith-system.search-show-page {
letter-spacing: 0%; letter-spacing: 0%;
text-align: right; text-align: right;
/* color: #8a92a8; */ color: #8a92a8;
} }
} }
.text-arabic-section { .text-arabic-section {
@ -715,7 +896,7 @@ body.hadith-system.search-show-page {
} }
} }
} }
.body-footer { /* .body-footer {
position: fixed; position: fixed;
bottom: 0em; bottom: 0em;
left: 0; left: 0;
@ -723,100 +904,8 @@ body.hadith-system.search-show-page {
max-width: 1200px; max-width: 1200px;
margin: auto; margin: auto;
.actions {
margin-bottom: 1em;
.similar-btn { } */
width: 114;
height: 56;
gap: 8px;
border-radius: 12px;
border-width: 0.5px;
padding-top: 8px;
padding-right: 20px;
padding-bottom: 8px;
padding-left: 24px;
background: #ffffff;
border: 0.5px solid;
border-image-source: linear-gradient(
102.02deg,
#4be8ae 7.38%,
#00a762 91.78%
);
box-shadow: 0px 8px 20px 0px #0000001a;
font-family: var(--font);
font-weight: 400;
font-size: 15px;
line-height: 22.5px;
letter-spacing: 0%;
text-align: right;
color: var(--ui-color-two);
}
.explore-btn {
width: 118;
height: 56;
gap: 4px;
border-radius: 12px;
padding-top: 8px;
padding-right: 24px;
padding-bottom: 8px;
padding-left: 20px;
background: linear-gradient(268.94deg, #d284ff -0.65%, #4d00ff 104.59%);
box-shadow: 0px 8px 20px 0px #0000001a;
font-family: var(--font);
font-weight: 400;
font-size: 16px;
line-height: 24px;
letter-spacing: 0%;
text-align: right;
color: #fff;
}
}
.pagination {
padding: 0.7em 0px;
/* width: 672; */
/* height: 56; */
justify-content: space-between;
border-radius: 16px;
border-width: 0.3px;
padding-right: 32px;
padding-left: 32px;
background: #ffffff;
border: 0.3px solid #e0e0e0;
box-shadow: 0px 8px 20px 0px #0000001a;
.prev-haditha {
font-family: var(--font);
font-weight: 300;
font-size: 12px;
line-height: 20px;
letter-spacing: 0%;
text-align: right;
color: var(--ui-color-two);
}
.next-haditha {
font-family: var(--font);
font-weight: 300;
font-size: 12px;
line-height: 20px;
letter-spacing: 0%;
text-align: right;
color: var(--ui-color-two);
}
.prev-haditha,
.next-haditha {
&:hover {
cursor: pointer;
background-color: #eee;
}
}
}
}
} }
/* @media screen and (max-width: 719.99px) { */ /* @media screen and (max-width: 719.99px) { */
/* .search-show-page { */ /* .search-show-page { */

View File

@ -493,7 +493,7 @@ const onAddNewTitle = (subTitles) => {
const loadMore = async () => { const loadMore = async () => {
// const listElm = $event.target; // const listElm = $event.target;
if (!hasMore.value) return; if (!hasMore.value || searchTerm.value.length == 0) return;
// // window.innerHeight + window.scrollY >= document.body.offsetHeight - 100 // // window.innerHeight + window.scrollY >= document.body.offsetHeight - 100
// if (listElm.scrollTop + listElm.clientHeight >= listElm.scrollHeight) { // if (listElm.scrollTop + listElm.clientHeight >= listElm.scrollHeight) {
// status.value = "pending"; // status.value = "pending";
@ -522,7 +522,14 @@ const loadMore = async () => {
// } // }
// } else status.value = "idle"; // } else status.value = "idle";
}; };
const { isFetching } = useInfiniteScroll(loadMore, "searchInfiniteScroll"); // For window scrolling
const { isFetching } = useInfiniteScroll(async () => {
await loadMore();
});
// For a specific element
// const { isFetching } = useInfiniteScroll(async () => {
// await loadMore();
// }, "scroll-container");
// Add the scroll event listener when the component is mounted // Add the scroll event listener when the component is mounted
// onMounted(() => { // onMounted(() => {
@ -560,9 +567,10 @@ const SearchList = defineAsyncComponent(
<HadithaLayout> <HadithaLayout>
<div class="h-full flex flex-col justify-center"> <div class="h-full flex flex-col justify-center">
<div class="background-image h-full" :style="backgroundImageStyle"> <div class="background-image h-full" :style="backgroundImageStyle">
<navigation-menu></navigation-menu> <navigation-menu class="static"></navigation-menu>
<div class="logo-container pt-0 xl:pt-19"> <!-- <div class="logo-container pt-0 xl:pt-19"> -->
<div class="logo-container pt-0">
<div <div
class="search-box-container flex justify-center" class="search-box-container flex justify-center"
:class="[route.name == 'hadithaSearch' ? 'py-6' : 'pb-16']" :class="[route.name == 'hadithaSearch' ? 'py-6' : 'pb-16']"
@ -644,7 +652,7 @@ const SearchList = defineAsyncComponent(
<!-- </client-only> --> <!-- </client-only> -->
</div> </div>
<div <div
class="search-filter flex items-center justify-between" class="search-filter flex items-center justify-between md:mr-16"
v-if="loadedItems" v-if="loadedItems"
> >
<div class="flex items-center space-x-2"> <div class="flex items-center space-x-2">
@ -886,7 +894,7 @@ const SearchList = defineAsyncComponent(
<!-- v-show="!showNoData" --> <!-- v-show="!showNoData" -->
<div <div
class="search-box-container pb-0 bg-white flex justify-center" class="search-box-container pb-12 bg-white flex justify-center"
:class="{ 'pt-0': loadedItems == undefined }" :class="{ 'pt-0': loadedItems == undefined }"
> >
<div class="search-list-contianer"> <div class="search-list-contianer">
@ -988,7 +996,7 @@ const SearchList = defineAsyncComponent(
margin: 0 1em; margin: 0 1em;
.total { .total {
padding: 0.5em 1.8em; padding: 1.1em 1.8em;
font-family: var(--font); font-family: var(--font);
font-weight: 400; font-weight: 400;
@ -1001,13 +1009,14 @@ const SearchList = defineAsyncComponent(
.search-list { .search-list {
&.enable-scroll { &.enable-scroll {
padding: 1em 1.3em; padding: 1em 1.3em;
height: calc(100dvh - 16em); /* height: calc(100dvh - 16em); */
overflow-y: auto; /* overflow-y: auto; */
scroll-behavior: smooth; scroll-behavior: smooth;
} }
&.hadithaFavorites { &.hadithaFavorites {
height: calc(100dvh - 8em); /* height: calc(100dvh - 8em); */
height: calc(100dvh - 10em);
} }
&:not(:last-child) { &:not(:last-child) {