Compare commits

...

5 Commits

Author SHA1 Message Date
mustafa-rezae
612fc1cc25 Refactor 2025-04-30 10:48:20 +03:30
mustafa-rezae
30cad3040c Update files. 2025-04-26 13:11:56 +03:30
mustafa-rezae
0db2ba3f38 Work on search 2025-04-22 15:55:38 +03:30
mustafa-rezae
2cff09d0a0 Pull and merge from shadi and baghi 2025-04-20 16:01:16 +03:30
mustafa-rezae
8fd63ea172 work on search pagination
work on library pagination.
2025-04-20 15:57:04 +03:30
72 changed files with 2092 additions and 1227 deletions

View File

@ -22,7 +22,9 @@ export default {
},
library: {
list: "monir/book/volume/@field_collapsed/@offset/@limit/@q",
show: "@appname/book/page/@page_start/@page_end/@vol_id",
show: "@appname/book/page/@page_start/@page_len/@vol_id",
prevNextHadith: "monir/nextpage/@index_key/@vol_id/@page_num/@step",
getVolumeInfo: "public/get/byids/dhvolume",
get: "public/get/byid/dhvolume/@vol_id",
},
};

View File

Before

Width:  |  Height:  |  Size: 910 B

After

Width:  |  Height:  |  Size: 910 B

View File

Before

Width:  |  Height:  |  Size: 304 B

After

Width:  |  Height:  |  Size: 304 B

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

Before

Width:  |  Height:  |  Size: 566 B

After

Width:  |  Height:  |  Size: 566 B

View File

Before

Width:  |  Height:  |  Size: 341 B

After

Width:  |  Height:  |  Size: 341 B

View File

Before

Width:  |  Height:  |  Size: 341 B

After

Width:  |  Height:  |  Size: 341 B

View File

Before

Width:  |  Height:  |  Size: 302 B

After

Width:  |  Height:  |  Size: 302 B

View File

Before

Width:  |  Height:  |  Size: 441 B

After

Width:  |  Height:  |  Size: 441 B

View File

Before

Width:  |  Height:  |  Size: 251 B

After

Width:  |  Height:  |  Size: 251 B

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 868 B

After

Width:  |  Height:  |  Size: 868 B

View File

Before

Width:  |  Height:  |  Size: 915 B

After

Width:  |  Height:  |  Size: 915 B

View File

Before

Width:  |  Height:  |  Size: 212 B

After

Width:  |  Height:  |  Size: 212 B

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 781 B

After

Width:  |  Height:  |  Size: 781 B

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 529 B

After

Width:  |  Height:  |  Size: 529 B

View File

Before

Width:  |  Height:  |  Size: 203 B

After

Width:  |  Height:  |  Size: 203 B

View File

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 681 B

After

Width:  |  Height:  |  Size: 681 B

View File

Before

Width:  |  Height:  |  Size: 648 B

After

Width:  |  Height:  |  Size: 648 B

View File

Before

Width:  |  Height:  |  Size: 631 B

After

Width:  |  Height:  |  Size: 631 B

View File

Before

Width:  |  Height:  |  Size: 943 B

After

Width:  |  Height:  |  Size: 943 B

View File

Before

Width:  |  Height:  |  Size: 625 B

After

Width:  |  Height:  |  Size: 625 B

View File

Before

Width:  |  Height:  |  Size: 809 B

After

Width:  |  Height:  |  Size: 809 B

View File

Before

Width:  |  Height:  |  Size: 823 B

After

Width:  |  Height:  |  Size: 823 B

View File

@ -0,0 +1,16 @@
<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.99984 8.21598C9.84079 8.21598 11.3332 6.7236 11.3332 4.88265C11.3332 3.0417 9.84079 1.54932 7.99984 1.54932C6.15889 1.54932 4.6665 3.0417 4.6665 4.88265C4.6665 6.7236 6.15889 8.21598 7.99984 8.21598Z" stroke="#1B2132" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12.8061 10.7106L10.446 13.0707C10.3527 13.164 10.266 13.3373 10.246 13.464L10.1194 14.364C10.0727 14.6906 10.2994 14.9173 10.626 14.8706L11.526 14.744C11.6527 14.724 11.8327 14.6373 11.9194 14.544L14.2794 12.184C14.686 11.7773 14.8794 11.304 14.2794 10.704C13.686 10.1106 13.2127 10.304 12.8061 10.7106Z" stroke="url(#paint0_linear_67_3867)" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M12.4663 11.0498C12.6663 11.7698 13.2263 12.3298 13.9463 12.5298" stroke="url(#paint1_linear_67_3867)" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M2.27344 14.8825C2.27344 12.3025 4.84012 10.2158 8.00012 10.2158C8.69346 10.2158 9.3601 10.3158 9.9801 10.5025" stroke="#1B2132" stroke-linecap="round" stroke-linejoin="round"/>
<defs>
<linearGradient id="paint0_linear_67_3867" x1="14.6902" y1="10.3286" x2="9.81875" y2="10.4184" gradientUnits="userSpaceOnUse">
<stop stop-color="#D284FF"/>
<stop offset="1" stop-color="#4D00FF"/>
</linearGradient>
<linearGradient id="paint1_linear_67_3867" x1="13.956" y1="11.0498" x2="12.3704" y2="11.079" gradientUnits="userSpaceOnUse">
<stop stop-color="#D284FF"/>
<stop offset="1" stop-color="#4D00FF"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

View File

@ -16,9 +16,13 @@
/* custom imports */
@import "../../../../../assets/common/scss/_IRANSansX.scss";
@import "../../../../../assets/common/scss/_takrim.scss";
@import "../../../../../assets/common/scss/_vazir.scss";
@import "../../../../../assets/common/scss/_estedad.scss";
@import "../../../../../assets/common/scss/_sahel-single-font-weight.scss";
@theme {
--font-sans: "IRANSansX", "Public Sans", sans-serif;
--font: vazir, sahel, estadad, IRANSansX, "Public Sans", sans-serif;
--ar-font: Takrim;
--breakpoint-sm: 360px;
--breakpoint-md: 720px;
--breakpoint-lg: 992px;
@ -49,18 +53,23 @@ html {
height: 100%;
direction: rtl;
text-align: right;
font-family: IRANSansX;
font-family: var(--font);
scroll-behavior: smooth;
body {
height: 100%;
direction: rtl;
text-align: right;
font-family: IRANSansX;
font-family: var(--font);
scroll-behavior: smooth;
padding: 0 !important;
margin: 0px !important;
overflow: auto !important;
}
}
.haditha-system {
.haditha-system,
.hadith-system {
height: 100%;
display: flex;
flex-direction: column;
@ -68,7 +77,18 @@ html {
.isolate {
flex-grow: 1;
}
.text__orange {
padding: 0 3px;
background-color: rgb(255, 250, 155);
/* background-color: rgb(255, 223, 203); */
}
/* .iconify { */
/* width: 1.72em; */
/* height: 1.72em; */
/* } */
}
.firefox-scrollbar {
scrollbar-width: thin;
scrollbar-color: #ccc #eee;

View File

@ -3,7 +3,6 @@ import type { InputMenuItem } from "@nuxt/ui";
import hadithaApi from "../../apis/hadithaApi";
import { useStorage } from "@vueuse/core";
import * as z from "zod";
import routeGlobal from "~/middleware/route.global";
// import type { FormSubmitEvent } from "@nuxt/ui";
export type Synonym = {
@ -163,7 +162,7 @@ const state = reactive({
// #region methods
const clearSimilar = () => {
console.info("clearSimilar");
// console.info("clearSimilar");
};
// const onUpdateModel = (newVal: boolean | InputMenuItem | any) => {
@ -419,7 +418,8 @@ onMounted(() => {
<!-- <client-only> -->
<div class="search-input">
<UInputMenu
<!-- <UInputMenu -->
<UInput
class="w-full focus:placeholder-gray-800"
:items="<any>Array.from(userSearchHistory)"
v-model="searchTerm"
@ -445,7 +445,7 @@ onMounted(() => {
>
<!-- @update:modelValue="onUpdateModel" -->
<!-- @update:searchTerm="onUpdateModel" -->
</UInputMenu>
</UInput>
</div>
<UButton
class="my-trailing-button"
@ -727,7 +727,7 @@ onMounted(() => {
padding: 5px 7px;
background: #1b213266;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 500;
font-size: 10px;
line-height: 15px;
@ -736,7 +736,7 @@ onMounted(() => {
color: #ffffff;
}
.text {
font-family: Takrim;
font-family: var(--ar-font);
font-weight: 400;
font-size: 16px;
line-height: 32px;
@ -824,7 +824,7 @@ onMounted(() => {
border: 0.3px solid #e0e0e0;
box-shadow: 0px 1px 4px 0px #0000000d;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 14px;
line-height: 21px;
@ -847,7 +847,7 @@ onMounted(() => {
border: 0.3px solid #e0e0e0;
box-shadow: 0px 1px 4px 0px #0000000d;
color: #8a92a8;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 13px;
line-height: 20px;
@ -905,7 +905,7 @@ onMounted(() => {
.synonymItem {
.title {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 14px;
line-height: 100%;
@ -929,7 +929,7 @@ onMounted(() => {
border: 0.3px solid #d9d9d9;
background: #f0f1f4;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 12px;
line-height: 100%;
@ -974,6 +974,6 @@ onMounted(() => {
}
}
@media scrren and (min-width: 720px) and (max-width: 991.99px) {
}
/* @media scrren and (min-width: 720px) and (max-width: 991.99px) {
} */
</style>

View File

@ -53,11 +53,6 @@ const goToLibraryShow = (item) => {
id: item?._source?.id,
slug: item?._source?.title,
},
query: {
page_first: item._source.page_first,
page_last: item._source.page_last,
page_count: item._source.page_count,
},
}"
color="neutral"
variant="outline"
@ -69,8 +64,9 @@ const goToLibraryShow = (item) => {
fit="auto"
quality="80"
placeholder
src="/img/haditha/sample-bgi.svg"
src="/img/haditha/library/totally.webp"
/>
<!-- src="/img/haditha/sample-bgi.svg" -->
<p class="title">{{ item?._source?.title }}</p>
<p class="version">
{{ item?._source?.vol_title + item?._source?.vol_num }}
@ -97,7 +93,7 @@ const goToLibraryShow = (item) => {
.title {
margin-top: 0.7em;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 13px;
line-height: 19.5px;
@ -107,7 +103,7 @@ const goToLibraryShow = (item) => {
}
.version {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 10px;
line-height: 15px;

View File

@ -3,7 +3,7 @@ import { useAuthStore } from "@stores/authStore";
// {
// label: "چت بات",
// icon: "i-haditha-chat-bot",
// icon: "haditha:chat-bot",
// to: "/haditha/chat-bot",
// slot: "chat-bot",
// class: "flex flex-col lg:flex-row justify-center items-center",
@ -11,15 +11,15 @@ import { useAuthStore } from "@stores/authStore";
const items = ref([
{
label: "حانه",
icon: "i-haditha-home",
label: "خانه",
icon: "haditha:home",
to: "/haditha",
descrption: "صفحه اصلی",
class: "flex flex-col lg:flex-row justify-center items-center hide-label",
},
{
label: "جستجو",
icon: "i-haditha-search",
icon: "haditha:search",
to: "/haditha/search",
slot: "search",
class: "flex flex-col lg:flex-row justify-center items-center",
@ -27,7 +27,7 @@ const items = ref([
{
label: "کتابخانه",
icon: "i-haditha-library",
icon: "haditha:library",
to: "/haditha/library",
slot: "library",
class: "flex flex-col lg:flex-row justify-center items-center",
@ -35,46 +35,46 @@ const items = ref([
{
label: "نشان شده ها",
icon: "i-haditha-bookmark",
icon: "haditha:bookmark",
to: "/haditha/favorites",
class: "flex flex-col lg:hidden justify-center items-center",
},
{
label: "دیگر",
icon: "i-haditha-menu",
icon: "haditha:menu",
class:
"flex flex-col lg:hidden justify-center items-center hide-chevron other /haditha/other",
"flex flex-col lg:hidden justify-center items-center hide-chevron other haditha:other",
children: [
{
label: "ورود / ثبت نام",
icon: "i-haditha-user",
icon: "haditha:user-icon",
to: "/haditha/login",
},
{
label: "کتابخانه",
icon: "i-haditha-library",
icon: "haditha:library",
to: "/haditha/library",
},
{
label: "در باره ما",
icon: "i-haditha-about-us",
icon: "haditha:about-us",
to: "/haditha/about-us",
},
{
label: "تماس با ما",
icon: "i-haditha-contact-us",
icon: "haditha:contact-us",
to: "/haditha/contact-us",
},
{
label: "قوانین و مقررات",
icon: "i-haditha-copyright",
icon: "haditha:copyright",
to: "/haditha/rules",
},
{
label: "خروج از حساب",
icon: "i-haditha-logout",
icon: "haditha:logout",
type: "button" as const,
onSelect(e: Event) {
e.preventDefault();
@ -85,35 +85,41 @@ const items = ref([
},
]);
const leftItem = computed(() => [
const desktopLeftMenu = ref([
{
label: "نشان شده ها",
icon: "i-haditha-bookmark",
icon: "haditha:bookmark",
to: "/haditha/favorites",
},
{
label: "Guide",
icon: "i-haditha-menu",
icon: "haditha:menu",
children: [
{
label: "ورود / ثبت نام",
icon: "haditha:user-icon",
to: "/haditha/login",
},
{
label: "در باره ما",
icon: "i-haditha-about-us",
icon: "haditha:about-us",
to: "/haditha/about-us",
},
{
label: "تماس با ما",
icon: "i-haditha-contact-us",
icon: "haditha:contact-us",
to: "/haditha/contact-us",
},
{
label: "قوانین و مقررات",
icon: "i-haditha-copyright",
icon: "haditha:copyright",
to: "/haditha/rules",
},
{
label: "خروج از حساب",
icon: "i-haditha-logout",
icon: "haditha:logout",
type: "button" as const,
onSelect(e: Event) {
e.preventDefault();
@ -128,28 +134,50 @@ const isMobile = ref(false);
const rerenderNavigation = ref(1);
const { isAuthenticatedGetter, isRealUserGetter } = useAuthStore();
const setMenu = () => {
const filterLeftItem = () => {
if (isAuthenticatedGetter) {
let otherItemChildren = desktopLeftMenu.value[1].children.filter(
(i) => i.icon != "haditha:user-icon"
);
desktopLeftMenu.value[1].children = otherItemChildren;
} else {
let otherItemChildren = desktopLeftMenu.value[1].children.filter(
(i) => i.icon != "haditha:logout"
);
desktopLeftMenu.value[1].children = otherItemChildren;
rerenderNavigation.value++;
}
};
const filterRightItem = () => {
if (isAuthenticatedGetter) {
let otherItem = items.value.find((item) => {
return item.class.includes("/haditha/other");
return item.class.includes("haditha:other");
});
let otherItemChildren = otherItem.children.filter(
(i) => i.to != "/haditha/login"
(i) => i.icon != "haditha:user-icon"
);
otherItem.children = otherItemChildren;
} else {
let otherItem = items.value.find((item) => {
return item.class.includes("/haditha/other");
let otherItemIndex = items.value.findIndex((item) => {
return item.class.includes("haditha:other");
});
let otherItemChildren = otherItem.children.filter(
(i) => i.icon != "i-haditha-logout"
let otherItemChildren = items.value[otherItemIndex].children.filter(
(i) => i.icon != "haditha:logout"
);
otherItem.children = otherItemChildren;
items.value[otherItemIndex].children = otherItemChildren;
rerenderNavigation.value++;
}
};
const setMenu = () => {
filterRightItem();
filterLeftItem();
};
setMenu();
// if(!(isAuthenticatedGetter && isRealUserGetter))
@ -185,8 +213,8 @@ onMounted(() => {
linkTrailingBadge: 'linkTrailingBadge',
}"
/>
<div class="hidden lg:flex items-center">
<template v-for="(item, index) in leftItem">
<div class="hidden lg:flex items-center hamburger-menu">
<template v-for="(item, index) in desktopLeftMenu">
<UDropdownMenu
v-if="item.children?.length"
:items="item.children"
@ -202,9 +230,14 @@ onMounted(() => {
itemLeadingAvatarSize: 'itemLeadingAvatarSize',
itemTrailing: 'itemTrailing',
}"
:content="{
align: 'end',
side: 'bottom',
sideOffset: 15,
}"
>
<UButton
icon="i-haditha-menu"
icon="haditha:menu"
variant="ghost"
:ui="{
base: 'string[]',
@ -257,6 +290,7 @@ onMounted(() => {
.isolate.min-w-0.flex.items-center.list {
li {
margin-left: 0.5em;
padding: 0;
.group {
@ -265,11 +299,16 @@ onMounted(() => {
}
&:hover {
&::before {
background-color: color-mix(in oklab, #00a762 50%, transparent);
box-shadow: 0px 4px 10px 0px #00745933;
border-radius: 0.75em; //12px;
}
background: linear-gradient(
320.71deg,
#b9fde0 6.56%,
#e4f9f0 69.69%
);
// &::before {
// background-color: color-mix(in oklab, #00a762 50%, transparent);
// box-shadow: 0px 4px 10px 0px #00745933;
// border-radius: 0.75em; //12px;
// }
}
// max-width: 112px;
@ -281,7 +320,7 @@ onMounted(() => {
padding-bottom: 0.37em; /*6px*/
padding-left: 1.2em;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 0.87rem; /*14px*/
line-height: 1.3rem; /*6px*/
@ -342,6 +381,11 @@ onMounted(() => {
}
}
}
.group.item {
&:hover {
background: linear-gradient(320.71deg, #b9fde0 6.56%, #e4f9f0 69.69%);
}
}
@media screen and (max-width: 991.99px) {
.fixed {
@ -386,7 +430,7 @@ onMounted(() => {
border-radius: 8px;
padding: 12px;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 14px;
line-height: 100%;

View File

@ -2,28 +2,28 @@
const state = reactive({
items: [
{
img: "https://picsum.photos/640/640?random=1",
img: "/img/haditha/khosro-panahi.png",
title: "حجت‌الاسلام خسروپناه",
job: "پژوهشگر",
summary:
"این سرویس برای هر کسی که به دنبال احادیث است، ضروری است. با این سرویس، پژوهش‌های من بسیار ساده‌تر شده است. این سرویس برای هر کسی که به دنبال احادیث است، ضروری است. با این سرویس، پژوهش‌های من بسیار ساده‌تر شده است.",
},
{
img: "https://picsum.photos/640/640?random=1",
img: "/img/haditha/khosro-panahi.png",
title: "حجت‌الاسلام خسروپناه",
job: "پژوهشگر",
summary:
"این سرویس برای هر کسی که به دنبال احادیث است، ضروری است. با این سرویس، پژوهش‌های من بسیار ساده‌تر شده است. این سرویس برای هر کسی که به دنبال احادیث است، ضروری است. با این سرویس، پژوهش‌های من بسیار ساده‌تر شده است.",
},
{
img: "https://picsum.photos/640/640?random=1",
img: "/img/haditha/khosro-panahi.png",
title: "حجت‌الاسلام خسروپناه",
job: "پژوهشگر",
summary:
"این سرویس برای هر کسی که به دنبال احادیث است، ضروری است. با این سرویس، پژوهش‌های من بسیار ساده‌تر شده است. این سرویس برای هر کسی که به دنبال احادیث است، ضروری است. با این سرویس، پژوهش‌های من بسیار ساده‌تر شده است.",
},
{
img: "https://picsum.photos/640/640?random=1",
img: "/img/haditha/khosro-panahi.png",
title: "حجت‌الاسلام خسروپناه",
job: "پژوهشگر",
summary:
@ -106,7 +106,7 @@ const state = reactive({
.header {
.title {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 1.25rem; /* 20px;*/
line-height: 1.87rem; /* 30px;*/
@ -118,7 +118,7 @@ const state = reactive({
}
.carousel-item {
.title {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 1rem;
line-height: 1.5rem; /* 24px;*/
@ -141,7 +141,7 @@ const state = reactive({
}
.job {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 1rem;
line-height: 1.5rem;
@ -153,7 +153,7 @@ const state = reactive({
.summary {
/* padding: 2.5em 0 2.5em; */
margin-bottom: 0.3em;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 1rem;
line-height: 1.5rem;

View File

@ -9,12 +9,12 @@ const state = reactive({
},
{
img: "/img/haditha/section-four_card-two.png",
title: "تشخیص موجودیت",
title: "خلاصه سازی",
description: "تجمیع نکات کلیدی از احادیث و شروح مختلف",
},
{
img: "/img/haditha/section-four_card-three.png",
title: "تشخیص موجودیت",
title: "چت بات هوشمند",
description:
"امکان تعامل مستقیم با سامانه برای پاسخ به سوالات یا دریافت توضیحات از مفاهیم حدیثی",
},
@ -86,7 +86,7 @@ const state = reactive({
.header {
.title {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 1.25rem; /* 20px;*/
line-height: 1.87rem; /* 30px;*/
@ -101,7 +101,7 @@ const state = reactive({
border: none;
.title {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 600;
font-size: 1rem;
line-height: 1.5rem; /* 24px;*/
@ -109,7 +109,7 @@ const state = reactive({
text-align: center;
}
.description {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 0.87rem; /* 14px;*/
line-height: 1.31rem; /* 21px;*/

View File

@ -42,7 +42,7 @@ const AutoComplation = defineAsyncComponent(() =>
<navigation-menu></navigation-menu>
<div class="logo-container flex justify-center flex-col items-center">
<img fit="auto" quality="80" placeholder src="/img/haditha/logo.webp" />
<img fit="auto" quality="80" placeholder src="/img/haditha/logo.png" />
<div class="title">
کاوش با
<span class="badge-style me-1"> هوش مصنوعی </span>
@ -78,7 +78,7 @@ const AutoComplation = defineAsyncComponent(() =>
.title {
margin-top: 3.5em;
font-family: IRANSansX;
font-family: var(--font);
font-size: 14px;
line-height: 21px;
letter-spacing: 0%;

View File

@ -17,7 +17,25 @@ const img = useImage();
</script>
<template>
<section class="section-three flex">
<div class="section-container md:flex md:flex-col md:items-center xl:block mx-auto">
<!-- <video class="background-video" loop autoplay>
<source
src="/img/haditha/video/section-three-gif.mp4"
type="video/webm"
/>
<source src="/img/haditha/video/section-three-gif.mp4" type="video/mp4" />
Download the
<a href="/img/haditha/video/section-three-gif.mp4">WEBM</a>
or
<a href="/img/haditha/video/section-three-gif.mp4">MP4</a>
video.F
</video> -->
<div
class="section-container md:flex md:flex-col md:items-center xl:block mx-auto"
>
<div class="header flex items-center mb-2">
<img
fit="auto"
@ -53,11 +71,25 @@ const img = useImage();
padding-left: 2em; /*32px;*/
background-color: #1b2132;
background-size: cover;
position: relative;
.background-video {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
height: 36.5em;
object-fit:fill;
aspect-ratio: 16 / 9; /* Replace with your desired ratio (e.g., 4/3, 1/1) */
width: 100%; /* Adjust width as needed */
}
.section-container {
width: 56.7em; /*907px;*/
/*height: 15.5em; 249px;*/
gap: 9px;
z-index:1;
.header {
max-width: 30em; /*480px;*/
@ -77,7 +109,7 @@ const img = useImage();
height: 2.1em; /*"34";*/
}
.title {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 2rem; /*32px;*/
line-height: 3rem; /*48px;*/
@ -100,7 +132,7 @@ const img = useImage();
border-radius: 1em;
background: #1b2132cc;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 1rem;
line-height: 1.5rem; /*24px;*/
@ -113,7 +145,7 @@ const img = useImage();
@media screen and (max-width: 1199.99px) {
.section-three {
background-image: url("/img/haditha/mobile/section-three-bgi_md.png");
background-image: url("/img/haditha/section-three-bgi.webp");
height: 46.87em;
background-position: center 65%;
padding-top: 7.5em;
@ -139,7 +171,7 @@ const img = useImage();
.content {
background: transparent;
color: #626b84;
/* color: #626b84; */
max-width: 40em; /*480px;*/
font-size: 1rem;

View File

@ -30,7 +30,7 @@
fit="auto"
quality="80"
placeholder
src="/img/haditha/card-one.webp"
src="/img/haditha/card-one.png"
/>
</div>
</div>
@ -48,7 +48,7 @@
fit="auto"
quality="80"
placeholder
src="/img/haditha/card-two.webp"
src="/img/haditha/card-two.png"
/>
</div>
</div>
@ -68,7 +68,7 @@
fit="auto"
quality="80"
placeholder
src="/img/haditha/card-three.webp"
src="/img/haditha/card-three.png"
/>
</div>
</div>
@ -95,7 +95,7 @@
margin: auto;
}
.title {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 700;
font-size: 1.5rem; /*24px*/
line-height: 2.25rem; /* 36px;*/

View File

@ -0,0 +1,17 @@
<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>

After

Width:  |  Height:  |  Size: 961 B

View File

@ -139,7 +139,7 @@ function toggleAccordion(id, event) {
<style scoped>
.accordion-menu {
.accordion-menu-item {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 13px;
line-height: 19.5px;

View File

@ -45,7 +45,7 @@ const props = defineProps({
<style scoped>
.tree-item[aria-expanded="true"] {
background: linear-gradient(320.71deg, #b9fde0 6.56%, #e4f9f0 69.69%);
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 13px;
line-height: 19.5px;

View File

@ -134,7 +134,7 @@ async function onSubmit(event: FormSubmitEvent<Schema>) {
.title {
margin-bottom: 1.2em;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 20px;
line-height: 30px;
@ -156,7 +156,7 @@ async function onSubmit(event: FormSubmitEvent<Schema>) {
}
.description {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 14px;
line-height: 21px;
@ -185,7 +185,7 @@ async function onSubmit(event: FormSubmitEvent<Schema>) {
border: 0.3px solid #d9d9d9;
box-shadow: 0px 1px 4px 0px #0000000d;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 16px;
line-height: 24px;
@ -225,7 +225,7 @@ async function onSubmit(event: FormSubmitEvent<Schema>) {
border: 0.3px solid #d9d9d9;
box-shadow: 0px 1px 4px 0px #0000000d;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 16px;
line-height: 100%;

View File

@ -139,7 +139,7 @@ onMounted(() => {
.title {
margin-bottom: 1.2em;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 20px;
line-height: 30px;
@ -161,7 +161,7 @@ onMounted(() => {
}
.description {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 14px;
line-height: 21px;
@ -190,7 +190,7 @@ onMounted(() => {
border: 0.3px solid #d9d9d9;
box-shadow: 0px 1px 4px 0px #0000000d;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 16px;
line-height: 24px;
@ -230,7 +230,7 @@ onMounted(() => {
border: 0.3px solid #d9d9d9;
box-shadow: 0px 1px 4px 0px #0000000d;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 16px;
line-height: 100%;

View File

@ -16,6 +16,9 @@ const props = defineProps({
noDataIcon: {
default: "/img/haditha/no-data.png",
},
searchTerm: {
default: "",
},
});
const router = useRouter();
const route = useRoute();
@ -23,7 +26,12 @@ const route = useRoute();
// const modal = useModal();
// const isModalOpen = ref(false);
function openModal(selectedItem) {
const hadithAddress = (item) => {
return `${item?._source?.address?.vol_title}، صفحه
${item?._source?.address?.page_num}`;
};
function goToSearchShowPage(selectedItem) {
// modal.open(SearchShow, { title: "Welcome" });
// isModalOpen.value = true;
@ -39,8 +47,7 @@ function openModal(selectedItem) {
slug: slug,
},
query: {
firstPage: 1,
page_count: props.total,
q: props.searchTerm,
},
});
}
@ -75,15 +82,8 @@ const removeFromFavorites = async (item = {}, index = 0) => {
</script>
<template>
<div class="search-list-contianer">
<div class="total">
<span>{{ total }}</span>
نتیجه
</div>
<div class="search-list firefox-scrollbar">
<div
v-if="props.list.length"
v-if="props?.list?.length"
class="search-list-item"
v-for="(item, index) in props.list"
:key="index"
@ -94,7 +94,7 @@ const removeFromFavorites = async (item = {}, index = 0) => {
item?._source?.meta?.hadith_masoum ??
item?._source?.meta?.hadith_sanad
}`"
@click.prevent="openModal(item)"
@click.prevent="goToSearchShowPage(item)"
class="from-person block"
>
{{
@ -113,35 +113,44 @@ const removeFromFavorites = async (item = {}, index = 0) => {
</div>
<a
@click.prevent="openModal(item)"
@click.prevent="goToSearchShowPage(item)"
class="arabic-text block"
:href="`/haditha/search/${item?._source?.id}/${item?._source?.content_ar}`"
v-html="item?._source?.content_ar"
>
{{ item?._source?.content_ar }}
</a>
<a
@click.prevent="openModal(item)"
@click.prevent="goToSearchShowPage(item)"
:href="`/haditha/search/${item?._source?.id}/${item?._source?.content}`"
class="persian-text block"
v-html="item?.highlight?.['content.fa'] ?? item?._source?.content"
></a>
<div class="flex justify-end">
<p class="reference">
<ULink
:to="{
name: 'hadithaLibraryShow',
params: {
id: item?._source?.address.vol_id,
slug: hadithAddress(item),
},
}"
color="neutral"
variant="outline"
:ui="{
leadingIcon: 'text-(--ui-primary)',
}"
class="reference"
>
{{ hadithAddress(item) ?? "" }}
</ULink>
<!-- <p class="reference">
{{ item?._source?.address?.vol_title }}، صفحه
{{ item?._source?.address?.page_num }}
</p>
</p> -->
</div>
</div>
<no-data
class="h-full w-full flex flex-col justify-center items-center"
v-else
>
<img fit="auto" quality="80" placeholder :src="props.noDataIcon" />
<p class="no-data-text">{{ props.noDataText }}</p>
</no-data>
</div>
<!-- <UModal
v-model:open="isModalOpen"
:dismissible="false"
@ -164,42 +173,12 @@ const removeFromFavorites = async (item = {}, index = 0) => {
</template>
<<template #footer></template>
</UModal> -->
</div>
</template>
<style scoped>
.search-list-contianer {
max-width: 41em; /*656px*/
width: 100%;
margin: 0 1em;
.total {
padding: 0.5em 1.8em;
font-family: IRANSansX;
font-weight: 400;
font-size: 0.68rem; /*11px*/
line-height: 1rem;
letter-spacing: 0%;
text-align: right;
color: #b4c2cf;
}
.search-list {
padding: 1em 1.3em;
height: calc(100dvh - 16em);
overflow-y: auto;
&.hadithaFavorites {
height: calc(100dvh - 8em);
}
&:not(:last-child) {
border-bottom: 0.3px solid #d9d9d9;
}
.search-list-item {
.from-person {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 0.75rem; /*12px*/
line-height: 1.125rem; /*18px*/
@ -216,7 +195,7 @@ const removeFromFavorites = async (item = {}, index = 0) => {
}
}
.arabic-text {
font-family: Takrim;
font-family: var(--ar-font);
font-weight: 400;
font-size: 1.125rem; /*18px*/
line-height: 2rem; /*23px*/
@ -233,9 +212,9 @@ const removeFromFavorites = async (item = {}, index = 0) => {
}
}
.persian-text {
font-family: Takrim;
font-family: var(--font);
font-weight: 400;
font-size: 1rem; /*16px*/
font-size: 0.8rem; /*16px*/
line-height: 1.375rem; /*22px*/
letter-spacing: 0%;
text-align: right;
@ -253,10 +232,10 @@ const removeFromFavorites = async (item = {}, index = 0) => {
border-width: 0.5px;
border: 0.5px solid #d9d9d9;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 0.625rem; /*10px*/
line-height: 0.9rem; /*15px*/
line-height: 1.1rem; /*15px*/
letter-spacing: 0%;
text-align: right;
color: #8a92a8;
@ -269,113 +248,4 @@ const removeFromFavorites = async (item = {}, index = 0) => {
}
}
}
}
.no-data-text {
font-family: IRANSansX;
font-weight: 300;
font-size: 1rem;
line-height: 1.5rem; /*24px*/
letter-spacing: 0%;
text-align: center;
}
}
</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; /*18px*/
border-radius: 16px; /*18px*/
gap: 8px;
border-width: 0.3px;
.modal-body {
border-radius: 16px; /*18px*/
height: 800px; /*18px*/
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;
}
.copy-btn {
padding: 0.2em 1em;
/* width: 44px; */
/* height: 24px; */
gap: 4px;
border-radius: 6px;
border-width: 0.5px;
padding-top: 4px;
padding-right: 12px;
padding-bottom: 4px;
padding-left: 12px;
/* background: #ffffff; */
/* border: 0.5px solid #d9d9d9; */
font-family: IRANSansX;
font-weight: 300;
font-size: 12px;
line-height: 18px;
letter-spacing: 0%;
text-align: right;
/* color: #a71111; */
}
</style>

View File

@ -215,7 +215,7 @@ const closeModal = () => {
background: #ffffff;
border: 0.5px solid #d9d9d9;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 12px;
line-height: 18px;
@ -227,7 +227,7 @@ const closeModal = () => {
span {
margin-left: 0.1em;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 12px;
line-height: 18px;
@ -252,7 +252,7 @@ const closeModal = () => {
margin-bottom: 0.5em;
.section-title {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 14px;
line-height: 21px;
@ -293,7 +293,7 @@ const closeModal = () => {
background: #ffffff;
border: 0.5px solid #d9d9d9;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 12px;
line-height: 18px;
@ -307,7 +307,7 @@ const closeModal = () => {
padding: 2em 0;
.arabic-text {
font-family: Takrim;
font-family: var(--ar-font);
font-weight: 400;
font-size: 18px;
line-height: 32px;
@ -327,7 +327,7 @@ const closeModal = () => {
.from,
.persian-text {
font-family: Takrim;
font-family: var(--ar-font);
font-weight: 400;
font-size: 18px;
line-height: 30px;
@ -336,7 +336,7 @@ const closeModal = () => {
color: var(--ui-color-two);
}
/* .persian-text {
font-family: Takrim;
font-family: var(--ar-font);
font-weight: 400;
font-size: 16px;
line-height: 22px;
@ -350,7 +350,7 @@ const closeModal = () => {
padding: 2em 0;
.description-item {
font-family: Takrim;
font-family: var(--ar-font);
font-weight: 400;
font-size: 18px;
line-height: 30px;
@ -369,7 +369,7 @@ const closeModal = () => {
border-width: 0.5px;
border: 0.5px solid #d9d9d9;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 10px;
line-height: 15px;
@ -420,7 +420,7 @@ const closeModal = () => {
);
box-shadow: 0px 8px 20px 0px #0000001a;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 15px;
line-height: 22.5px;
@ -440,7 +440,7 @@ const closeModal = () => {
background: linear-gradient(268.94deg, #d284ff -0.65%, #4d00ff 104.59%);
box-shadow: 0px 8px 20px 0px #0000001a;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 16px;
line-height: 24px;
@ -464,7 +464,7 @@ const closeModal = () => {
box-shadow: 0px 8px 20px 0px #0000001a;
.prev-haditha {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 12px;
line-height: 20px;
@ -473,7 +473,7 @@ const closeModal = () => {
color: var(--ui-color-two);
}
.next-haditha {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 12px;
line-height: 20px;

View File

@ -356,7 +356,7 @@ const NavigationMenu = defineAsyncComponent(() =>
);
}
.message {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 14px;
line-height: 27px;
@ -392,7 +392,7 @@ const NavigationMenu = defineAsyncComponent(() =>
border: 0.3px solid #d9d9d9;
box-shadow: 0px 1px 4px 0px #0000000d;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 13px;
line-height: 26px;
@ -419,7 +419,7 @@ const NavigationMenu = defineAsyncComponent(() =>
padding: 8px;
box-shadow: 0px 1px 4px 0px #0000000d;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 11px;
line-height: 16.5px;
@ -476,7 +476,7 @@ const NavigationMenu = defineAsyncComponent(() =>
);
box-shadow: 0px 1px 4px 0px #0000000d;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 14px;
line-height: 21px;

View File

@ -195,7 +195,17 @@ const SearchList = defineAsyncComponent(() =>
<navigation-menu></navigation-menu>
<div class="text-logo">
<div class="search-box-container pb-0 flex justify-center">
<div
v-if="state.list?.length"
class="search-box-container pb-0 flex justify-center"
>
<div class="search-list-contianer">
<div class="total">
<span>{{ total }}</span>
نتیجه
</div>
<div ref="el" class="search-list firefox-scrollbar hadithaFavorites">
<search-list
no-data-text="هنوز چیزی ذخیره نکرده‌اید!"
no-data-icon="/img/haditha/save.png"
@ -205,6 +215,15 @@ const SearchList = defineAsyncComponent(() =>
</div>
</div>
</div>
<no-data
v-else
class="h-full w-full flex flex-col justify-center items-center"
>
<img fit="auto" quality="80" src="/img/haditha/save.png" />
<p class="no-data-text">هنوز چیزی ذخیره نکردهاید!</p>
</no-data>
</div>
</div>
</div>
</HadithaLayout>
</template>
@ -231,4 +250,36 @@ const SearchList = defineAsyncComponent(() =>
padding-bottom: 0 !important;
}
}
.search-list-contianer {
/*max-width: 41em; 656px*/
max-width: 75em; /*1200px*/
width: 100%;
margin: 0 1em;
.total {
padding: 0.5em 1.8em;
font-family: var(--font);
font-weight: 400;
font-size: 0.68rem; /*11px*/
line-height: 1rem;
letter-spacing: 0%;
text-align: right;
color: #b4c2cf;
}
.search-list {
padding: 1em 1.3em;
height: calc(100dvh - 16em);
overflow-y: auto;
&.hadithaFavorites {
height: calc(100dvh - 8em);
}
&:not(:last-child) {
border-bottom: 0.3px solid #d9d9d9;
}
}
}
</style>

View File

@ -34,26 +34,26 @@ useHead({
...headMetas,
],
bodyAttrs: {
class: import.meta.env.VITE_HADITH_SYSTEM,
class: [import.meta.env.VITE_HADITH_SYSTEM, "library-show-page"],
},
link: headLinks,
});
// #endregion imports
// #region props
const props = defineProps({
list: {
default() {
return [];
},
},
noDataText: {
default: "نتیجه‌ای یافت نشد!",
},
noDataIcon: {
default: "/img/haditha/no-data.png",
},
});
// const props = defineProps({
// list: {
// default() {
// return [];
// },
// },
// noDataText: {
// default: "نتیجهای یافت نشد!",
// },
// noDataIcon: {
// default: "/img/haditha/no-data.png",
// },
// });
// #endregion props
// #region refs and reactives
@ -132,48 +132,72 @@ const state = reactive({
{ title: "فصل چهارم", icon: "vscode-icons:file-type-vue" },
{ title: "فصل پنجم", icon: "vscode-icons:file-type-nuxt" },
],
volumeInfo: {},
});
const pageIsLessThanOne = computed(() => {
console.info("pageIsLessThanOne");
return page_num.value <= 1;
});
const pageIsBiggerThanTotal = computed(() => {
console.info("pageIsBiggerThanTotal");
const page_count = +route.query.page_count;
const page_count = state.volumeInfo._source?.page_count;
return page_num.value + 1 >= page_count;
});
// #endregion refs and reactives
// #region methods
const fetchData = async () => {
let url = repoUrl() + hadithaApi.library.show;
url = url.replace("@appname", "monir");
url = url.replace("@page_start", state.volumeInfo._source?.page_first);
url = url.replace("@page_len", 1);
url = url.replace("@vol_id", state.volumeInfo?._source.id);
// const { data, status, error, refresh, clear } =
// await useHadithaSearchComposable<HadithResponseModel>(url, {
// method: "get",
// });
// if (status.value == "success") {
// state.selectedItem = <Hit[]>data.value.hits.hits;
// loading.value = false;
// }
httpService
.getRequest(url)
.then((res: HadithResponseModel) => {
state.selectedItem = <Hit[]>res.hits.hits;
})
.finally(() => (loading.value = false));
};
const fetchVolume = async () => {
if (loading.value) return;
loading.value = true;
let page_first = +route.query.page_first;
const volId = route.params.id;
let url = repoUrl() + hadithaApi.library.show;
url = url.replace("@appname", "monir");
url = url.replace("@page_start", 0);
url = url.replace("@page_end", 1);
let url = repoUrl() + hadithaApi.library.get;
url = url.replace("@vol_id", volId);
console.info("urlurlurlurl", url);
// fetch search list from backend(ssr)
const { data, status, error, refresh, clear } =
await useHadithaSearchComposable<HadithResponseModel>(url, {
method: "get",
// const { data, status, error, refresh, clear } =
// await useHadithaSearchComposable<HadithResponseModel>(url, {
// method: "get",
// });
// if (status.value == "success") {
// state.volumeInfo = data.value;
// page_num.value = state.volumeInfo._source.page_first;
// }
httpService.getRequest(url).then((res: HadithResponseModel) => {
state.volumeInfo = res;
page_num.value = state.volumeInfo._source?.page_first;
fetchData();
});
if (status.value == "success") {
state.selectedItem = <Hit[]>data.value.hits.hits;
}
loading.value = false;
};
fetchData();
fetchVolume();
const goToTheLibrary = (type: string) => {
router.push({
@ -181,17 +205,14 @@ const goToTheLibrary = (type: string) => {
});
};
const onOpenList = () => {
console.info("onOpenList");
isModalOpen.value = true;
};
const onSearch = () => {
// console.info("onSearch");
router.push({
name: "hadithaSearch",
});
};
const onClose = () => {
console.info("onClose");
router.push({
name: "hadithLibrary",
});
@ -199,14 +220,14 @@ const onClose = () => {
const handlePagination = (
prevNextIndicator: number,
pageNumber: number | undefined = undefined
userEnteredPage: number | undefined = undefined
) => {
if (loading.value) return;
loading.value = true;
const volId = route.params.id;
const page_count = +route.query.page_count;
const page_first = +route.query.page_first;
const page_count = state.volumeInfo._source?.page_count;
const isPageBiggerThanOne = +page_num.value + prevNextIndicator > 0;
const isPageLessThanTotal = +page_num.value + prevNextIndicator < page_count;
@ -215,10 +236,14 @@ const handlePagination = (
let url = repoUrl() + hadithaApi.library.prevNextHadith;
url = url.replace("@index_key", "dhparag");
url = url.replace("@vol_id", volId);
url = url.replace("@page_num", (pageNumber ?? page_num.value).toString());
url = url.replace(
"@page_num",
(userEnteredPage ?? page_num.value).toString()
);
url = url.replace("@step", prevNextIndicator.toString());
page_num.value += prevNextIndicator;
// اگر کاربر شماره صفحه ای را وارد نکرده باشد..
if (!userEnteredPage) page_num.value = +page_num.value + prevNextIndicator;
httpService
.getRequest(url)
@ -248,19 +273,18 @@ const getDataTree = () => {
const prepareTreeData = (data) => {
return data.map((item) => {
return {
const res = {
...item,
...item._source,
title: item._source.content,
};
delete res._source;
return res;
});
};
getDataTree();
onMounted(() => {
page_num.value = +route.query.page_first;
});
// #endregion methods
// components declaration
@ -270,6 +294,9 @@ const HadithaLayout = defineAsyncComponent(
const UTree = defineAsyncComponent(
() => import("@haditha/components/haditha/library-show/UTree.vue")
);
const NavigationMenu = defineAsyncComponent(
() => import("@haditha/components/haditha/NavigationMenu.vue")
);
// const AccordionMenu = defineAsyncComponent(
// () => import("@haditha/components/haditha/library-show/AccordionMenu..vue")
// );
@ -284,6 +311,8 @@ const UTree = defineAsyncComponent(
}"
class="page-inner-container sm:px-6 lg:px-4"
>
<navigation-menu></navigation-menu>
<div class="page-header py-4 flex justify-between items-center">
<div class="flex items-center">
<UButton
@ -320,18 +349,19 @@ const UTree = defineAsyncComponent(
</div>
<div class="separator"></div>
<div class="page-content py-14 p-2">
<!-- <h2></h2> -->
<div class="page-content firefox-scrollbar py-14 p-2">
<template v-if="state.selectedItem?.length">
<p
v-if="state.selectedItem?.length"
v-for="(parag, index) in state.selectedItem"
:key="index"
v-html="parag?._source?.content"
></p>
</template>
<no-data v-else></no-data>
</div>
<div class="body-footer">
<div class="mt-5 z-2">
<div class="mt-5 pb-5 z-2">
<div class="flex justify-between pagination">
<UButton
@click="handlePagination(-1)"
@ -343,7 +373,9 @@ const UTree = defineAsyncComponent(
:disabled="pageIsLessThanOne"
/>
<div class="flex items-center">
<span class="total-pages">{{ route.query.page_count }}</span>
<span class="total-pages">{{
state.volumeInfo._source?.page_count
}}</span>
<span class="mx-2">/</span>
<UInput
:disabled="loading"
@ -411,15 +443,16 @@ const UTree = defineAsyncComponent(
<style scoped>
.page-container {
background: #f7fffd;
/* background: #f7fffd; */
.page-inner-container {
padding-top: 6em;
/* position: relative; */
/* padding-bottom: 4em; */
/* width: 100%; */
/* max-width: 1200px; */
/* margin-right: auto; */
/* margin-left: auto; */
width: 100%;
max-width: 1200px;
margin-right: auto;
margin-left: auto;
.page-header {
color: var(--ui-color-two);
@ -430,9 +463,12 @@ const UTree = defineAsyncComponent(
margin-left: 2.2em;
}
.title {
font-family: IRANSansX;
/* font-family: IRANSansX; */
font-family: var(--font);
font-weight: 400;
font-size: 16px;
/* font-size: 16px; */
font-size: 0.9rem;
line-height: 20px;
letter-spacing: 0%;
text-align: right;
@ -467,22 +503,32 @@ const UTree = defineAsyncComponent(
);
}
.page-content {
padding-bottom: 5em;
/* margin: 1.5em; */
font-family: Takrim;
/* font-family: var(--ar-font); */
font-family: var(--font);
font-weight: 400;
font-size: 20px;
/* font-size: 20px; */
font-size: 0.9rem;
line-height: 40px;
letter-spacing: 0%;
text-align: right;
color: var(--ui-color-two);
height: calc(100dvh - 8em);
overflow-y: auto;
/* height: calc(100dvh - 13em); */
/* overflow-y: auto; */
}
.body-footer {
position: fixed;
bottom: 0em;
left: 0;
right: 0;
max-width: 1200px;
margin: auto;
.actions {
margin-bottom: 1em;
@ -506,7 +552,7 @@ const UTree = defineAsyncComponent(
);
box-shadow: 0px 8px 20px 0px #0000001a;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 15px;
line-height: 22.5px;
@ -530,7 +576,7 @@ const UTree = defineAsyncComponent(
);
box-shadow: 0px 8px 20px 0px #0000001a;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 16px;
line-height: 24px;
@ -554,7 +600,7 @@ const UTree = defineAsyncComponent(
box-shadow: 0px 8px 20px 0px #0000001a;
.total-pages {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 12px;
line-height: 100%;
@ -563,23 +609,32 @@ const UTree = defineAsyncComponent(
color: #8a92a8;
}
.prev-haditha {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 12px;
font-size: 0.6rem;
line-height: 20px;
letter-spacing: 0%;
text-align: right;
color: var(--ui-color-two);
}
.next-haditha {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 12px;
/* font-size: 12px; */
font-size: 0.6rem;
line-height: 20px;
letter-spacing: 0%;
text-align: right;
color: var(--ui-color-two);
}
.prev-haditha,
.next-haditha {
&:hover {
cursor: pointer;
background-color: #eee;
}
}
}
}
}
@ -587,6 +642,9 @@ const UTree = defineAsyncComponent(
</style>
<style>
body.hadith-system.library-show-page {
background-color: #f7fffd;
}
.page-container {
.page-inner-container {
.body-footer {
@ -602,7 +660,7 @@ const UTree = defineAsyncComponent(
border-width: 0.5px;
border: 0.3px solid #e0e0e0;
box-shadow: 0px 8px 20px 0px #0000001a;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 0.75rem;
line-height: 100%;
@ -615,3 +673,5 @@ const UTree = defineAsyncComponent(
}
}
</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

@ -24,14 +24,16 @@ useHead({
// #region refs
const el = useTemplateRef<HTMLElement>("el");
const httpService = useNuxtApp()["$http"];
const route = useRoute();
const page = ref(Number(route.query.page) || 1);
const total = ref(0);
const currentPage = useState("currentPage", () => 0);
// Client-side state
const loading = ref(false);
const hasMore = ref(true);
// #endregion refs
// #region reactive
const state = reactive({
pagination: {
offset: 0,
limit: 10,
page: 1,
pages: 1,
@ -43,33 +45,50 @@ const state = reactive({
const getLibraryList = async (dataType = "bookmark") => {
let url = repoUrl() + hadithaApi.library.list;
url = url.replace("@field_collapsed", "normal");
url = url.replace("@offset", state.pagination.offset);
url = url.replace("@offset", currentPage.value);
url = url.replace("@limit", state.pagination.limit);
url = url.replace("@q", "none");
return await httpService.postRequest(url);
return await httpService.postRequest(url).then((res) => {
total.value = res.hits.total.value ?? 0;
currentPage.value += state.pagination.limit;
return res;
});
};
// Server-side initial load
const { data: initialItems } = await useAsyncData(
const { data: loadedItems } = await useAsyncData(
"libraryList",
() => getLibraryList(),
async () => {
if (loading.value) return;
loading.value = true;
let url = repoUrl() + hadithaApi.library.list;
url = url.replace("@field_collapsed", "normal");
url = url.replace("@offset", currentPage.value);
url = url.replace("@limit", state.pagination.limit);
url = url.replace("@q", "none");
return await httpService
.postRequest(url)
.then((res) => {
total.value = res.hits.total.value ?? 0;
currentPage.value += state.pagination.limit;
return res;
})
.finally(() => {
loading.value = false;
});
},
{
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,
@ -84,7 +103,6 @@ useInfiniteScroll(
if (hits.length) {
loadedItems.value.push(...hits);
state.pagination.offset += state.pagination.limit;
} else {
hasMore.value = false;
}
@ -122,23 +140,15 @@ const CardList = defineAsyncComponent(
<div
ref="el"
class="library-list grid grid-cols-2 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="library-list pl-4 firefox-scrollbar grid grid-cols-2 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"
>
<!-- Client-side loaded content -->
<card-list
v-if="loadedItems.length"
v-if="loadedItems?.length"
no-data-text="هنوز چیزی ذخیره نکرده‌اید!"
no-data-icon="/img/haditha/no-data.png"
: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>
@ -163,7 +173,7 @@ const CardList = defineAsyncComponent(
margin-bottom: 2em;
.title {
margin-left: 0.4em;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 24px;
line-height: 36px;
@ -180,7 +190,7 @@ const CardList = defineAsyncComponent(
overflow-y: auto;
}
.no-data-text {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 16px;
line-height: 24px;

View File

@ -1,4 +1,7 @@
<script setup lang="ts">
import headLinks from "@haditha/json/haditha/headLinks";
import headMetas from "@haditha/json/haditha/headMetas";
definePageMeta({
layout: false,
name: "hadithaLogin",
@ -7,94 +10,12 @@ 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,
});
const stepOne = ref(true);
@ -155,7 +76,7 @@ const EnterVerifyCode = defineAsyncComponent(
.title {
margin-bottom: 1.2em;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 20px;
line-height: 30px;
@ -177,7 +98,7 @@ const EnterVerifyCode = defineAsyncComponent(
}
.description {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 14px;
line-height: 21px;
@ -206,7 +127,7 @@ const EnterVerifyCode = defineAsyncComponent(
border: 0.3px solid #d9d9d9;
box-shadow: 0px 1px 4px 0px #0000000d;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 16px;
line-height: 24px;
@ -246,7 +167,7 @@ const EnterVerifyCode = defineAsyncComponent(
border: 0.3px solid #d9d9d9;
box-shadow: 0px 1px 4px 0px #0000000d;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 16px;
line-height: 100%;

View File

@ -89,7 +89,7 @@ const NavigationMenu = defineAsyncComponent(() =>
color: var(--ui-color-two);
.title {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 24px;
line-height: 36px;
@ -104,7 +104,7 @@ const NavigationMenu = defineAsyncComponent(() =>
color: var(--ui-color-two);
p {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 14px;
line-height: 21px;

View File

@ -144,7 +144,7 @@ const NavigationMenu = defineAsyncComponent(() =>
color: var(--ui-color-two);
.title {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 24px;
line-height: 36px;
@ -159,7 +159,7 @@ const NavigationMenu = defineAsyncComponent(() =>
.label {
display: inline-block;
margin-inline-end: 1em;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 14px;
line-height: 21px;
@ -170,7 +170,7 @@ const NavigationMenu = defineAsyncComponent(() =>
height: 21;
}
.value {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 14px;
line-height: 21px;

View File

@ -163,7 +163,7 @@ onMounted(() => {
color: var(--ui-color-two);
.title {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 24px;
line-height: 36px;
@ -176,7 +176,7 @@ onMounted(() => {
color: var(--ui-color-two);
p {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 14px;
line-height: 21px;

View File

@ -102,7 +102,7 @@ const NavigationMenu = defineAsyncComponent(() =>
color: var(--ui-color-two);
.title {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 24px;
line-height: 36px;
@ -116,7 +116,7 @@ const NavigationMenu = defineAsyncComponent(() =>
overflow: auto;
color: var(--ui-color-two);
ul li {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 14px;
line-height: 21px;

View File

@ -12,6 +12,8 @@
import hadithaApi from "@haditha/apis/hadithaApi";
import type { HadithResponseModel } from "@haditha/types/hadithType";
import type { HadithResponseShowModel } from "~/systems/hadith_ui/types/hadithType";
import headLinks from "@haditha/json/haditha/headLinks";
import headMetas from "@haditha/json/haditha/headMetas";
// #endregion imports
// #region meta
@ -20,98 +22,19 @@ definePageMeta({
name: "hadithaSearchShow",
});
const route = useRoute();
const router = useRouter();
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,
class: [import.meta.env.VITE_HADITH_SYSTEM, "search-show-page"],
},
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,
});
// #endregion imports
@ -128,69 +51,50 @@ useHead({
// #region refs and reactives
const emit = defineEmits(["close"]);
const route = useRoute();
const router = useRouter();
const loading = ref(false);
const httpService = useNuxtApp()["$http"];
const toast = useToast();
const state = reactive({
selectedItem: {} as HadithResponseShowModel,
});
// #endregion refs and reactives
// #region methods
const fetchData = async () => {
if (loading.value) return;
loading.value = true;
const fetchData = () => {
let url = hadithaApi.search.show;
url = url.replace("@index_key", "dhparag");
url = url.replace("@id", route.params.id);
// fetch search list from backend(ssr)
const { data, status, error, refresh, clear } =
await useHadithaSearchComposable<HadithResponseShowModel>(url, {
method: "get",
});
if (status.value == "success") {
state.selectedItem = <HadithResponseShowModel>data.value;
}
loading.value = false;
return httpService.getRequest(url);
};
fetchData();
const { data: selectedItem } = useAsyncData("parags", () => fetchData());
const hadithAddress = computed(() => {
return `${selectedItem.value?._source?.address?.vol_title}، صفحه
${selectedItem.value?._source?.address?.page_num}`;
});
const goToTheSearch = (type: string) => {
router.push({
name: "hadithaSearch",
query: {
q: route.query.q ?? "",
},
});
};
const goToTheChatbot = () => {
router.push({
name: "hadithaChatBot",
});
};
// const goToTheChatbot = () => {
// router.push({
// name: "hadithaChatBot",
// });
// };
const handleFavorite = async () => {
if (state.selectedItem?._source?.tbookmark) {
await removeFromFavorites(state.selectedItem);
state.selectedItem._source.tbookmark = false;
if (selectedItem.value?._source?.tbookmark) {
await removeFromFavorites(selectedItem.value);
selectedItem.value._source.tbookmark = false;
} else {
await addToFavorites(state.selectedItem);
state.selectedItem._source.tbookmark = true;
await addToFavorites(selectedItem.value);
selectedItem.value._source.tbookmark = true;
}
// // add
// if (!state.selectedItem._source.tbookmark) {
// addToFavorites(state.selectedItem);
// }
// // delete
// else {
// removeFromFavorites(state.selectedItem);
// }
};
const addToFavorites = async (item = {}) => {
@ -201,23 +105,21 @@ const addToFavorites = async (item = {}) => {
ref_id: item._id,
title: item._source.content,
};
httpService.postRequest(url, formData).then((res) => {
// this.updateListAnswer(index, "tbookmark", 1);
try {
httpService
.postRequest(url, formData)
.then((res) => {
toast.add({
title: "انجام شد.",
description: "به نشان شده ها افزوده شد",
color: "success",
});
} catch (err) {
console.log(err.message);
})
.catch((err) => {
toast.add({
title: "انجام شد.",
title: "خطا",
description: "خطایی رخ داد.لطفا دوباره امتحان کنید.",
color: "error",
});
}
});
};
@ -231,23 +133,21 @@ const removeFromFavorites = async (item = {}, index = 0) => {
ref_id: item._id,
title: item._source.title,
};
httpService.postRequest(url, formData).then((res) => {
// this.updateListAnswer(index, "tbookmark", 0);
try {
httpService
.postRequest(url, formData)
.then((res) => {
toast.add({
title: "انجام شد.",
description: "از لیست نشان شده ها حذف شد",
description: "به نشان شده ها افزوده شد",
color: "success",
});
} catch (err) {
console.log(err.message);
})
.catch((err) => {
toast.add({
title: "انجام شد.",
title: "خطا",
description: "خطایی رخ داد.لطفا دوباره امتحان کنید.",
color: "error",
});
}
});
};
@ -257,18 +157,36 @@ const handlePagination = (prevNextIndicator: string) => {
let url = repoUrl() + hadithaApi.search.prevNextHadith;
url = url.replace("@index_key", "dhparag");
url = url.replace("@vol_id", state.selectedItem?._source?.address?.vol_id);
url = url.replace("@parag_order", state.selectedItem?._source?.parag_order);
url = url.replace("@vol_id", selectedItem.value?._source?.address?.vol_id);
url = url.replace("@parag_order", selectedItem.value?._source?.parag_order);
url = url.replace("@step", prevNextIndicator);
httpService
.getRequest(url)
.then((res) => {
state.selectedItem = res.hits.hits?.[0];
selectedItem.value = res.hits.hits?.[0];
})
.finally(() => (loading.value = false));
};
const onKeyWordClick = (keyword) => {
router.push({
name: "hadithaSearch",
query: {
q: route.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);
// };
@ -279,16 +197,27 @@ const handlePagination = (prevNextIndicator: string) => {
// console.info("mounted");
// });
// #endregion methods
// components declaration
const HadithaLayout = defineAsyncComponent(
() => import("@haditha/layouts/HadithaLayout.vue")
);
const NavigationMenu = defineAsyncComponent(
() => import("@haditha/components/haditha/NavigationMenu.vue")
);
</script>
<template>
<HadithaLayout>
<div class="page-container h-full">
<UContainer
ui="{
base: 'sm:px-6 lg:px-4',
}"
class="page-inner-container sm:px-6 lg:px-4 py-8"
>
<div class="search-show-page">
<navigation-menu></navigation-menu>
<div class="search-show-page py">
<div class="body-header">
<span class="top-left-bgi z-0"></span>
<div class="modal-title flex justify-between">
@ -297,14 +226,18 @@ const handlePagination = (prevNextIndicator: string) => {
:to="{ name: 'haditha' }"
class="flex justify-center items-center me-3"
>
<img fit="auto" quality="80" src="/img/haditha/haditha-title.svg" />
<img
fit="auto"
quality="80"
src="/img/haditha/haditha-title.svg"
/>
</ULink>
<UButton
icon="i-haditha-close"
color="neutral"
variant="ghost"
class="close-btn"
class="close-btn text-[var(--ui-color-two)] hover:bg-gray-300"
@click="goToTheSearch('normal')"
/>
</div>
@ -317,44 +250,58 @@ const handlePagination = (prevNextIndicator: string) => {
<UButton
@click="handleFavorite"
:variant="
state.selectedItem?._source?.tbookmark ? 'soft' : 'ghost'
selectedItem?._source?.tbookmark ? 'soft' : 'ghost'
"
color="primary"
class="bookmark-btn"
:icon="
state.selectedItem?._source?.tbookmark
selectedItem?._source?.tbookmark
? 'i-haditha-tag-active'
: 'i-haditha-tag'
"
>
</UButton>
<div class="referene">
<ULink
:to="{
name: 'hadithaLibraryShow',
params: {
id: selectedItem?._source?.address.vol_id,
slug: hadithAddress,
},
}"
color="neutral"
variant="ghost"
:ui="{
leadingIcon: 'text-(--ui-primary)',
}"
class="referene bg-white hover:bg-gray-100"
>
<span> نشانی: </span>
{{ state.selectedItem?._source?.address?.vol_title }}، صفحه
{{ state.selectedItem?._source?.address?.page_num }}
</div>
{{ hadithAddress ?? "" }}
</ULink>
</div>
<div class="content">
<div class="content firefox-scrollbar">
<div class="search-item">
<div class="text-arabic-section">
<div class="section-header">
<span class="section-title">
{{
state.selectedItem?._source?.meta?.hadith_masoum ??
state.selectedItem?._source?.meta?.hadith_sanad
selectedItem?._source?.meta?.hadith_masoum ??
selectedItem?._source?.meta?.hadith_sanad
}}
</span>
<UButton
v-if="
state.selectedItem?._source?.meta?.hadith_masoum
selectedItem?._source?.meta?.hadith_masoum
?.length ||
state.selectedItem?._source?.meta?.hadith_sanad
selectedItem?._source?.meta?.hadith_sanad
"
@click="
copyTextToClipboard(
state.selectedItem?._source?.content_ar ?? ''
selectedItem?._source?.content_ar ?? ''
)
"
variant="ghost"
@ -363,11 +310,11 @@ const handlePagination = (prevNextIndicator: string) => {
/>
</div>
<div
v-if="state.selectedItem?._source?.content_ar?.length"
v-if="selectedItem?._source?.content_ar?.length"
class="arabic-text"
>
<p>
{{ state.selectedItem?._source?.content_ar ?? "" }}
{{ selectedItem?._source?.content_ar ?? "" }}
</p>
</div>
</div>
@ -379,9 +326,7 @@ const handlePagination = (prevNextIndicator: string) => {
<span class="section-title"> ترجمه </span>
<UButton
@click="
copyTextToClipboard(
state.selectedItem?._source?.content
)
copyTextToClipboard(selectedItem?._source?.content)
"
variant="ghost"
class="copy-btn"
@ -391,20 +336,20 @@ const handlePagination = (prevNextIndicator: string) => {
<p class="from">
{{
state.selectedItem?._source?.meta?.hadith_masoum ??
state.selectedItem?._source?.meta?.hadith_sanad
selectedItem?._source?.meta?.hadith_masoum ??
selectedItem?._source?.meta?.hadith_sanad
}}:
</p>
<p
class="persian-text"
v-html="state.selectedItem?._source?.content"
v-html="selectedItem?._source?.content"
></p>
</div>
<div class="separator"></div>
<div
v-if="state.selectedItem?._source?.description?.length"
v-if="selectedItem?._source?.description?.length"
class="text-description-section"
>
<div class="section-header">
@ -412,7 +357,7 @@ const handlePagination = (prevNextIndicator: string) => {
<UButton
@click="
copyTextToClipboard(
state.selectedItem?._source?.description
selectedItem?._source?.description
)
"
variant="ghost"
@ -422,7 +367,7 @@ const handlePagination = (prevNextIndicator: string) => {
</div>
<p
class="description-item"
v-html="state.selectedItem?._source?.description"
v-html="selectedItem?._source?.description"
></p>
</div>
@ -430,35 +375,36 @@ const handlePagination = (prevNextIndicator: string) => {
<div class="text-description-section">
<div
v-if="state.selectedItem?._source?.ai_keywords?.length"
class="text-sm mb-1"
v-if="selectedItem?._source?.ai_keywords?.length"
class="mb-4"
>
<span class=""> کلیدواژگان: </span>
<span
class="me-1 text-gray-400 font-light"
v-for="(aiClass, i) in state.selectedItem?._source
<span class="text-sm"> کلیدواژگان: </span>
<UButton
class="me-1 text-sm"
v-for="(keyword, i) in selectedItem?._source
?.ai_keywords"
:key="i"
@click.prevent="onKeyWordClick(keyword)"
variant="soft"
>
{{ i > 0 ? "," : "" }}
{{ aiClass }}
</span>
<!-- {{ i > 0 ? "," : "" }} -->
{{ keyword }}
</UButton>
</div>
<div
class="text-sm"
v-if="state.selectedItem?._source?.ai_classes?.length"
>
<span class=""> دسته بندی ها: </span>
<span
class="me-1 text-gray-400 font-light"
v-for="(aiClass, i) in state.selectedItem?._source
<div v-if="selectedItem?._source?.ai_classes?.length">
<span class="text-sm"> دسته بندی ها: </span>
<UButton
class="me-1 text-sm"
v-for="(aiClass, i) in selectedItem?._source
?.ai_classes"
:key="i"
@click.prevent="onClassClick(aiClass)"
variant="soft"
>
{{ i > 0 ? "," : "" }}
<!-- {{ i > 0 ? "," : "" }} -->
{{ aiClass.label }}
</span>
</UButton>
</div>
</div>
</div>
@ -468,7 +414,7 @@ const handlePagination = (prevNextIndicator: string) => {
</div>
<div class="body-footer">
<div class="mt-5 z-2">
<div class="mt-5 pb-5 z-2">
<!-- <div class="flex justify-between actions">
<UButton
disabled
@ -509,27 +455,35 @@ const handlePagination = (prevNextIndicator: string) => {
</div>
</div>
</UContainer>
</div>
</HadithaLayout>
</template>
<!-- because of the buttons, using without scoped. -->
<style>
body.hadith-system.search-show-page {
background-color: #f7fffd;
}
.page-inner-container {
height: 100%;
max-width: 1200px;
width: 100%;
}
.search-show-page {
.body-header {
padding-top: 5em;
.modal-title {
padding: 0 0.5em 1.5em;
margin-bottom: 2.5em;
.close-btn {
color: var(--ui-color-two);
/* color: var(--ui-color-two); */
/* width: 24px; */
/* height: 24px; */
padding: 0.2em;
background-color: transparent;
/* background-color: transparent; */
}
}
}
@ -569,10 +523,10 @@ const handlePagination = (prevNextIndicator: string) => {
padding-right: 12px;
padding-bottom: 4px;
padding-left: 12px;
background: #ffffff;
/* background-color: #ffffff; */
border: 0.5px solid #d9d9d9;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 12px;
line-height: 18px;
@ -584,7 +538,7 @@ const handlePagination = (prevNextIndicator: string) => {
span {
margin-left: 0.1em;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 12px;
line-height: 18px;
@ -595,11 +549,12 @@ const handlePagination = (prevNextIndicator: string) => {
}
}
.content {
height: calc(100dvh - 15em);
overflow-y: auto;
/* height: calc(100dvh - 15em); */
/* overflow-y: auto; */
padding-bottom: 5em;
.search-item {
padding: 1em 0 1em 0.1em;
padding: 1em 0 1em 1em;
.section-header {
display: flex;
@ -609,7 +564,7 @@ const handlePagination = (prevNextIndicator: string) => {
margin-bottom: 0.5em;
.section-title {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 14px;
line-height: 21px;
@ -650,7 +605,7 @@ const handlePagination = (prevNextIndicator: string) => {
/* background: #ffffff; */
border: 0.5px solid #d9d9d9;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 12px;
line-height: 18px;
@ -664,7 +619,7 @@ const handlePagination = (prevNextIndicator: string) => {
padding: 2em 0;
.arabic-text {
font-family: Takrim;
font-family: var(--ar-font);
font-weight: 400;
font-size: 18px;
line-height: 32px;
@ -684,16 +639,18 @@ const handlePagination = (prevNextIndicator: string) => {
.from,
.persian-text {
font-family: Takrim;
/* font-family: Takrim; */
font-family: var(--font);
font-weight: 400;
font-size: 18px;
/* font-size: 18px; */
font-size: 0.85rem;
line-height: 30px;
letter-spacing: 0%;
text-align: right;
color: var(--ui-color-two);
}
/* .persian-text {
font-family: Takrim;
font-family: var(--ar-font);
font-weight: 400;
font-size: 16px;
line-height: 22px;
@ -707,9 +664,11 @@ const handlePagination = (prevNextIndicator: string) => {
padding: 2em 0;
.description-item {
font-family: Takrim;
font-family: var(--font);
font-weight: 400;
font-size: 18px;
/* font-size: 18px; */
font-size: 0.85rem;
line-height: 30px;
letter-spacing: 0%;
text-align: right;
@ -726,7 +685,7 @@ const handlePagination = (prevNextIndicator: string) => {
border-width: 0.5px;
border: 0.5px solid #d9d9d9;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 10px;
line-height: 15px;
@ -754,6 +713,13 @@ const handlePagination = (prevNextIndicator: string) => {
}
}
.body-footer {
position: fixed;
bottom: 0em;
left: 0;
right: 0;
max-width: 1200px;
margin: auto;
.actions {
margin-bottom: 1em;
@ -777,7 +743,7 @@ const handlePagination = (prevNextIndicator: string) => {
);
box-shadow: 0px 8px 20px 0px #0000001a;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 15px;
line-height: 22.5px;
@ -797,7 +763,7 @@ const handlePagination = (prevNextIndicator: string) => {
background: linear-gradient(268.94deg, #d284ff -0.65%, #4d00ff 104.59%);
box-shadow: 0px 8px 20px 0px #0000001a;
font-family: IRANSansX;
font-family: var(--font);
font-weight: 400;
font-size: 16px;
line-height: 24px;
@ -821,7 +787,7 @@ const handlePagination = (prevNextIndicator: string) => {
box-shadow: 0px 8px 20px 0px #0000001a;
.prev-haditha {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 12px;
line-height: 20px;
@ -830,7 +796,7 @@ const handlePagination = (prevNextIndicator: string) => {
color: var(--ui-color-two);
}
.next-haditha {
font-family: IRANSansX;
font-family: var(--font);
font-weight: 300;
font-size: 12px;
line-height: 20px;
@ -838,17 +804,25 @@ const handlePagination = (prevNextIndicator: string) => {
text-align: right;
color: var(--ui-color-two);
}
}
}
}
@media screen and (max-width: 719.99px) {
.search-show-page {
.body-content {
.content {
height: calc(100dvh - 15em);
overflow-y: auto;
.prev-haditha,
.next-haditha {
&:hover {
cursor: pointer;
background-color: #eee;
}
}
}
}
}
/* @media screen and (max-width: 719.99px) { */
/* .search-show-page { */
/* .body-content { */
/* .content { */
/* height: calc(100dvh - 15em); */
/* overflow-y: auto; */
/* } */
/* } */
/* } */
/* } */
</style>

File diff suppressed because it is too large Load Diff

View File

@ -1,228 +1,18 @@
import type {
activeSearchChartSchema,
activeSearchListSchema,
Domain,
helpActiveSchema,
helpSchema,
searchActiveTab,
searchChartActiveTab,
searchListActiveTab,
searchSchema,
searchSynonymForm,
searchSynonymTitle,
selectionFilterItems,
} from "~/types/searchTypes";
import type {
isReturnFromItemshowPage,
list,
listComponentName,
listId,
projects,
selectedItem,
selectedProject,
} from "~/types/listTypes";
export const useHadithaStore = defineStore("hadithaStore", {
persist: {
storage: piniaPluginPersistedstate.localStorage(),
}, state: () => ({
selectedProject: undefined as selectedProject | undefined,
isReturnFromItemshowPage: false as isReturnFromItemshowPage,
list: undefined as list | undefined,
listId: undefined as listId | undefined,
listComponentName: "ItemList" as listComponentName | undefined,
projects: [] as projects[],
// pieData: [],
selectedItem: undefined as selectedItem | undefined,
domainActive: undefined as Domain | undefined,
// activeTab: undefined,
searchActiveTab: undefined as searchActiveTab | undefined,
searchSchema: undefined as searchSchema | undefined,
helpSchema: undefined as helpSchema | undefined,
searchActiveSchema: undefined as searchActiveTab | undefined,
helpActiveSchema: undefined as helpActiveSchema | undefined,
searchListActiveTab: undefined as searchListActiveTab | undefined,
searchListSchema: undefined as searchListActiveTab[] | undefined,
activeSearchListSchema: undefined as activeSearchListSchema | undefined,
searchChartActiveTab: undefined as searchChartActiveTab | undefined,
searchChartSchema: undefined as searchChartActiveTab[] | undefined,
activeSearchChartSchema: undefined as activeSearchChartSchema | undefined,
searchSynonymTitle: undefined as searchSynonymTitle | undefined,
searchSynonymForm: undefined as searchSynonymForm | undefined,
selectionFilterItems: [] as selectionFilterItems,
},
state: () => ({
searchPhrase: "" as string,
}),
getters: {
projectsGetter(state) {
return state.projects;
},
selectedProjectGetter(state) {
return state.selectedProject;
},
listIdGetter(state) {
return state.listId;
},
listComponentNameGetter(state) {
return state.listComponentName;
},
selectedItemGetter(state) {
return state.selectedItem;
},
isReturnFromItemshowPageGetter(state) {
return state.isReturnFromItemshowPage;
},
listGetter(state) {
return state.list;
},
searchSynonymTitleGetter(state) {
return state.searchSynonymTitle;
},
searchSynonymFormGetter(state) {
return state.searchSynonymForm;
},
domainActiveGetter(state) {
return state.domainActive;
},
// activeTabGetter(state) {
// return state.activeTab;
// },
// search page
searchActiveTabGetter(state) {
return state.searchActiveTab;
},
searchSchemaGetter(state) {
return state.searchSchema;
},
helpSchemaGetter(state) {
return state.helpSchema;
},
helpActiveSchemaGetter(state) {
return state.helpActiveSchema;
},
searchActiveSchemaGetter(state) {
return state.searchActiveSchema;
},
// search list
searchListActiveTabGetter(state) {
return state.searchListActiveTab;
},
searchListSchemaGetter(state) {
return state.searchListSchema;
},
searchListActiveSchemaGetter(state) {
return state.activeSearchListSchema;
},
// search chart
searchChartActiveTabGetter(state) {
return state.searchChartActiveTab;
},
searchChartSchemaGetter(state) {
return state.searchChartSchema;
},
searchChartActiveSchemaGetter(state) {
return state.activeSearchChartSchema;
},
selectionFilterItemsGetter(state) {
return state.selectionFilterItems;
searchPhraseGetter(state) {
return state.searchPhrase;
},
},
actions: {
SET_SELECTED_PROJECT(selectedProject = undefined) {
this.selectedProject = selectedProject;
},
SET_LIST_ID(listId = undefined) {
this.listId = listId;
},
SET_LIST_COMPONENT_NAME(
payload = { selectedItem: undefined, listComponentName: undefined }
) {
this.selectedItem = payload.selectedItem;
this.listComponentName = payload.listComponentName;
},
SET_SELECTED_ITEM(selectedItem = undefined) {
this.selectedItem = selectedItem;
},
SET_IS_RETURN_FROM_ITEM_SHOW_PAGE(isReturnFromItemshowPage = false) {
this.isReturnFromItemshowPage = isReturnFromItemshowPage;
},
SET_LIST(list = undefined) {
this.list = list;
},
searchSynonymFormSetter(searchSynonymForm = undefined) {
this.searchSynonymForm = searchSynonymForm;
},
searchSynonymTitleSetter(searchSynonymTitle = undefined) {
this.searchSynonymTitle = searchSynonymTitle;
},
domainActiveSetter(domain = undefined) {
this.domainActive = domain;
},
// activeTabSetter(activeTab = undefined) {
// this.activeTab = activeTab;
// },
// search page
searchActiveTabSetter(searchActiveTab: searchActiveTab = undefined) {
this.searchActiveTab = searchActiveTab;
},
searchSchemaSetter(searchSchema = undefined) {
this.searchSchema = searchSchema;
},
helpSchemaSetter(helpSchema = undefined) {
this.helpSchema = helpSchema;
},
helpActiveSchemaSetter(helpActiveSchema = undefined) {
this.helpActiveSchema = helpActiveSchema;
},
searchActiveSchemaSetter(searchActiveSchema = undefined) {
this.searchActiveSchema = searchActiveSchema;
},
// search list
searchListActiveTabSetter(searchListActiveTab = undefined) {
this.searchListActiveTab = searchListActiveTab;
},
searchListSchemaSetter(searchListSchema = undefined) {
this.searchListSchema = searchListSchema;
},
searchListActiveSchemaSetter(activeSearchListSchema = undefined) {
this.activeSearchListSchema = activeSearchListSchema;
},
// search chart
searchChartActiveTabSetter(searchChartActiveTab = undefined) {
this.searchChartActiveTab = searchChartActiveTab;
},
searchChartSchemaSetter(searchChartSchema = undefined) {
this.searchChartSchema = searchChartSchema;
},
searchChartActiveSchemaSetter(activeSearchChartSchema = undefined) {
this.activeSearchChartSchema = activeSearchChartSchema;
},
selectionFilterItemsSetter(selectionFilterItems = []) {
this.selectionFilterItems = <selectionFilterItems>selectionFilterItems;
searchPhraseSetter(newVal = "") {
this.searchPhrase = newVal;
},
},
});
// export default {
// namespaced:true,
// state,
// actions,
// mutations,
// getters
// };

View File

@ -359,3 +359,15 @@ export interface Root {
_source: Source
sort: number[]
}
export type Synonym = {
title: string;
enable: boolean;
enableForm: boolean;
subTitles: [
{
title: string;
active: boolean;
}
];
};