hadith_ui/pages/haditha/search/index.vue
mustafa-rezae 8fd63ea172 work on search pagination
work on library pagination.
2025-04-20 15:57:04 +03:30

1170 lines
33 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import { useStorage } from "@vueuse/core";
import { useInfiniteScroll } from "@vueuse/core";
import * as z from "zod";
// const myCookie = useCookie("searchPhrase");
// const myCookieOffset = useCookie("offset");
import headLinks from "@haditha/json/haditha/headLinks";
import headMetas from "@haditha/json/haditha/headMetas";
import hadithaApi from "@haditha/apis/hadithaApi";
import type { Synonym } from "@haditha/types/hadithType";
// const searchTerm = useState("searchTerm", () => ''); // Tracks the searchTerm
const offset = useState("offset", () => 0); // Tracks the current offset
definePageMeta({
layout: false,
name: "hadithaSearch",
});
useHead({
name: "hadithaSearch",
title: `${import.meta.env.VITE_HADITH_PAGE_TITLE} | جستجو`,
meta: [
{ name: "description", content: "کاوش با هوش مصنوعی در احادیث اسلامی" },
...headMetas,
],
bodyAttrs: {
class: import.meta.env.VITE_HADITH_SYSTEM,
},
link: headLinks,
});
// #region refs
// وقتی از صفحه حدیث با کلیک بر روی دکمه مشابه، وارد صفحه جستجو میشویم
const showPrevSearch = ref(false);
// لیست جستجو در حالت اسکرول
// const loadedItems = ref([]);
// لودینگ
const loading = ref(false);
// هنگام اسکرول، چک میشود که ایا صفحه بعدی هم وجود دارد یا نه.
const hasMore = ref(true);
// عنصری که برای اسکرول استفاده میشه.
const el = ref(null);
// پلاگین ارسال درخواست
const httpService = useNuxtApp()["$http"];
// استفاده از روت
const route = useRoute();
const router = useRouter();
// تعداد کل نتایج
const total = ref(0);
// رکوردهای جتسجو شده توسط کاربر
const userSearchHistory = useStorage(
"userSearchHistory",
new Set() // Initial value
);
// کلمه ی جستجو شده توسط کاربر
const searchTerm = ref(route.query.q ?? "");
// وقتی کاربر از صفحه اصلی وارد جستجو میشود.
// if (route.query.q) {
// searchTerm.value = route.query.q ?? "";
// route.query.q = undefined;
// }
// باز کردن دراپ داون اینپوت اصلی
const open = ref(false);
// نوع جستجو
const search_type = ref("normal");
// انتخاب ترجمه
const type_key = ref("hadith");
// نوع جستجو
const typeModelValue = ref("normal");
const typeModelValueFa = ref("");
// نمایش دکمه پاک کردن متن جستجو
const showclearButton = ref(false);
// اسکیمای مترادف
const schema = z.object({
name: z.string().min(1, "این فیلد ضروری است"),
});
// باز کردن دراپ داون مترادف
const isSynonymPopupOpen = ref(false);
// فرم افزودن مترادف
const Formstate = reactive({
name: "",
});
// #endregion refs
// #region reactive
const AutoComplationState = reactive({
vector: {
label: "معنایی",
value: "vector",
icon: "i-haditha-robot-indicator",
},
type: {
icon: "",
value: "normal",
label: "نوع",
items: [
{
label: "جستجو در همه",
value: "normal",
// onSelect(e: Event) {
// search_type.value = "normal";
// state.type.label = e.explicitOriginalTarget?.innerText;
// sendQuery();
// state.type.items[0].class = "active";
// },
},
{
label: "فقط در متن عربی حدیث",
value: "arabic",
valueFa: "عربی",
},
{
label: "فقط در ترجمه ها",
value: "translations",
valueFa: "ترجمه",
},
{
label: "فقط در شروح",
value: "descriptions",
valueFa: "شروح",
},
],
},
synonym: {
value: "synonym",
label: "مترادف",
icon: "i-haditha-chevron-down",
items: [],
},
type_key: {
label: "ترجمه",
value: "hadith",
},
phrase: {
label: "عین عبارت",
value: "normal",
},
});
const mainState = reactive({
pagination: {
limit: 10,
page: 1,
pages: 1,
},
});
// If you want to share state across multiple components,
// you can use the same key in useState. Nuxt will ensure
// that the state is shared and reactive across your application.
// const typingTimer = useState<number>("typingTimer", () => 0);
// const doneTypingInterval = useState<number>("doneTypingInterval", () => 1000);
// حالت ارسال اتوماتیک درخواست ها، غیر فعال شده است.
// const typingTimer = ref<number | any>(0);
// const doneTypingInterval = ref<number>(1000);
// #endregion reactive
// #region computed
const backgroundImageStyle = computed(() => {
// Use $img to generate an optimized image URL
// let optimizedImageUrl = img("/img/haditha/background.webp", {
// quality: 40,
// });
let optimizedImageUrl = "/img/haditha/background.webp";
if (searchTerm.value?.length) {
// optimizedImageUrl = img("/img/haditha/sub-header-bgi.webp", {
// quality: 80,
// });
optimizedImageUrl = "/img/haditha/sub-header-bgi.webp";
return {
backgroundImage: `url(${optimizedImageUrl}), linear-gradient(199.05deg, #ffffff 9.99%, #e4fff7 42.07%, #ffffff 97.12%)`,
};
}
return {
backgroundImage: `url(${optimizedImageUrl}), linear-gradient(199.05deg, #ffffff 9.99%, #e4fff7 42.07%, #ffffff 97.12%)`,
};
});
// const searchButtonIcon = computed(() => {
// return showclearButton.value ? "i-lucide-x" : "i-haditha-search";
// });
const synonymIsSwitchedOn = computed(() => {
return AutoComplationState.synonym.items.filter((i) => i.enable).length;
});
// #endregion computed
// #region methods
// خروج از حالت مشابه
const exitSimilarMode = () => {};
// ارسال درخواست
const sendQuery = async (payload = {}) => {
let url = hadithaApi.search.list;
url = url.replace("@index_key", "dhparag");
url = url.replace("@search_type", search_type.value); // normal, and , phrase, vector, synonym
url = url.replace("@type_key", type_key.value); // hadith, hadith_fa, hadith_ar, hadith_shr
url = url.replace("@offset", offset.value);
url = url.replace("@limit", mainState.pagination.limit);
url = url.replace("@listkey", "normal");
url = url.replace("@field_collapsed", "normal");
// اگر نوع انتخاب شود.
const isTypeSelected =
typeModelValue.value == "arabic" ||
typeModelValue.value == "translations" ||
typeModelValue.value == "descriptions";
url = url.replace(
"@q=none",
searchTerm.value.length
? `q=${isTypeSelected ? "#" + typeModelValueFa.value + " " : ""}${
searchTerm.value
}`
: "q=none"
);
// fetch search list from backend(ssr)
return await httpService.postRequest(url, payload).then((res) => {
total.value = res.hits.total.value ?? 0;
offset.value += mainState.pagination.limit;
return res;
});
};
// Server-side initial load
const { data: loadedItems } = await useAsyncData("search", () => sendQuery(), {
transform: (data) => data.hits.hits,
getCachedData: (key) => {
return useNuxtApp().payload.data[key] || useNuxtApp().static.data[key];
},
});
const onBeforeSendQuery = () => {
route.query.q = searchTerm.value;
history?.pushState(
{},
document?.title,
route.path + `?q=${searchTerm.value}`
);
sendQuery().then((res) => {
loadedItems.value = res.hits.hits;
});
};
// Client-side infinite scroll
useInfiniteScroll(
el,
async () => {
if (!hasMore.value || loading.value) return;
loading.value = true;
try {
// const nextPage = page.value + 1;
await sendQuery().then((res) => {
const hits = res.hits.hits;
if (hits.length) {
// if (initialItems.value.length) {
// loadedItems.value.push(...initialItems.value);
// loadedItems.value.push(...hits);
// initialItems.value = [];
// } else loadedItems.value.push(...hits);
loadedItems.value.push(...hits);
offset.value += mainState.pagination.limit;
} else {
hasMore.value = false;
}
});
} finally {
loading.value = false;
}
},
{ distance: 100 }
);
// دکمه جستجو کردن
const handleSearchClearButton = () => {
// showclearButton.value = true;
sendQuery().then((res) => {
loadedItems.value = res.hits.hits;
});
};
// وقتی کاربر کلیدی فشار میدهد
// const onKeyDown = () => {
// showclearButton.value = false;
// // clearTimeout(typingTimer.value);
// };
// وقتی کاربر کلیدی فشار میدهد
// const onKeyUp = () => {
// clearTimeout(typingTimer.value);
// typingTimer.value = setTimeout(() => {
// if (props.autoRedirection) sendQuery();
// }, doneTypingInterval.value);
// };
// تنظیم نوع جستجو
const setType = (type: string) => {
search_type.value = type;
loadedItems.value = [];
offset.value = 0;
sendQuery().then((res) => {
loadedItems.value = res.hits.hits;
});
};
// const setKey = (type: string) => {
// type_key.value = type;
// sendQuery();
// };
// async function onSubmit(event: FormSubmitEvent<Schema>) {
// toast.add({
// title: "Success",
// description: "The form has been submitted.",
// color: "success",
// });
// console.log(event.data);
// }
// get synonyms
const onClearSynonymClear = () => {
search_type.value = "normal";
AutoComplationState.synonym.items.forEach((element) => {
element.enable = false;
});
};
async function openSynonymPopup(type: string) {
search_type.value = type;
getSynonyms().then(() => {
isSynonymPopupOpen.value = true;
});
}
const onTypeSelectChanged = (value: string) => {
if (value == "translations") typeModelValueFa.value = "ترجمه";
else if (value == "arabic") typeModelValueFa.value = "عربی";
else if (value == "descriptions") typeModelValueFa.value = "شروح";
else typeModelValueFa.value = "همه";
sendQuery().then((res) => {
loadedItems.value = res.hits.hits;
});
};
const getSynonyms = async () => {
let url = repoUrl() + hadithaApi.search.synonym;
const payload = {
query: searchTerm.value,
};
// fetch search list from backend(ssr)
return await httpService.postRequest(url, payload).then((res) => {
AutoComplationState.synonym.items = [];
Object.entries(res.data).forEach((item, index) => {
const synonyms = {} as Synonym;
synonyms.title = item[0];
synonyms.enable = false;
synonyms.enableForm = false;
const subTitlesStrList = item[1].value.split(",");
const subTitlesObjList = subTitlesStrList
.filter((i) => i)
.map((i) => {
return {
title: i,
active: false,
};
});
synonyms.subTitles = subTitlesObjList;
AutoComplationState.synonym.items.push(synonyms);
});
});
};
const prepareSynonym = () => {
const enabledSwitches = AutoComplationState.synonym.items.filter(
(i) => i.enable
);
const res = {};
enabledSwitches.forEach((item) => {
if (item.subTitles.length)
res[item.title] = item.subTitles
.filter((i) => i.active)
.map((i) => i.title)
.join(",");
});
return {
synonym: res,
};
};
const onUpdateSwitch = () => {
sendQuery(prepareSynonym()).then((res) => {
loadedItems.value = res.hits.hits;
});
};
const onUpdateSubTitle = (subTitle) => {
subTitle.active = !subTitle.active;
sendQuery(prepareSynonym()).then((res) => {
loadedItems.value = res.hits.hits;
});
};
const onAddNewTitle = (subTitles) => {
subTitles.push({
active: true,
title: Formstate.name,
});
Formstate.name = "";
sendQuery(prepareSynonym()).then((res) => {
loadedItems.value = res.hits.hits;
});
};
// #endregion methods
// #region components
const HadithaLayout = defineAsyncComponent(
() => import("@haditha/layouts/HadithaLayout.vue")
);
const NavigationMenu = defineAsyncComponent(
() => import("@haditha/components/haditha/NavigationMenu.vue")
);
const SearchList = defineAsyncComponent(
() => import("@haditha/components/haditha/search-page/SearchList.vue")
);
// #endregion components
</script>
<template>
<HadithaLayout>
<div class="h-full flex flex-col justify-center">
<div class="background-image h-full" :style="backgroundImageStyle">
<navigation-menu></navigation-menu>
<div class="logo-container pt-0 xl:pt-18">
<div
class="search-box-container flex justify-center"
:class="{ 'pb-0': route.name == 'hadithaSearch' }"
>
<div class="haditha-search-root-wrapper search-page">
<div
class="haditha-search-root"
:class="{ 'no-backdrop': showPrevSearch }"
>
<!-- وقتی کاربر در صفحه نمایش بر روی مشابه کلیک میکند و به صفحه جستجو وارد میشود. -->
<div
v-if="showPrevSearch"
class="prev-search-item flex items-center"
>
<span class="total">۴۷ مشابه </span>
<span class="text me-auto">
عَنِ الْحَسَنِ بْنِ عَلِيِّ بْنِ يُوسُفَ، عَنْ جَدِّهِ،
قَالَ:
</span>
<UButton
icon="i-lucide:x"
color="neutral"
variant="ghost"
class="clear-similar-btn"
@click="exitSimilarMode"
/>
</div>
<!-- <client-only> -->
<div class="search-input">
<UInputMenu
class="w-full focus:placeholder-gray-800"
:items="<any>Array.from(userSearchHistory)"
v-model="searchTerm"
v-model:open="open"
v-model:search-term="searchTerm"
placeholder="هوشمند جستجو کنید..."
:ui="{
base: 'haditha-search-input',
}"
:content="{
align: 'start',
side: 'bottom',
sideOffset: 4,
}"
:loading="loading"
highlight
highlightOnHover
@focus="open = true"
@blur="open = false"
@change="onBeforeSendQuery"
@keydown.enter="onBeforeSendQuery"
>
<!-- @keydown="onKeyDown" -->
<!-- @update:modelValue="onUpdateModel" -->
<!-- @update:searchTerm="onUpdateModel" -->
</UInputMenu>
</div>
<UButton
class="my-trailing-button"
:class="{ 'close-mode': showclearButton }"
@click.prevent="handleSearchClearButton"
icon="i-haditha-search"
>
<!-- <UIcon name="i-lucide-search" /> -->
</UButton>
<!-- </client-only> -->
</div>
<div
class="search-filter flex items-center my-3 justify-between"
v-if="searchTerm.length"
>
<div class="flex items-center space-x-2">
<!-- #region معنایی -->
<!-- @click.self="search_type = 'vector'" -->
<UButton
@click.self="setType('vector')"
:class="{ active: search_type == 'vector' }"
type="button"
class="filter-item"
:icon="AutoComplationState.vector.icon"
>
{{ AutoComplationState.vector.label }}
<UIcon
v-if="search_type == 'vector'"
@click.self="setType('normal')"
name="i-haditha-close-bg-circle"
size="20px"
>
</UIcon>
</UButton>
<!-- #endregion -->
<!-- #region مترادف -->
<UPopover
:content="{
align: 'start',
side: 'bottom',
sideOffset: 8,
}"
:ui="{
content: 'popover-root-content',
}"
v-model:open="isSynonymPopupOpen"
>
<UButton
@click="openSynonymPopup('synonym')"
:class="{ active: search_type == 'synonym' }"
class="filter-item"
type="button"
trailingIcon="i-haditha-dropdown-chevron-down"
>
{{ AutoComplationState.synonym.label }}
<UIcon
v-if="synonymIsSwitchedOn"
@click.self="onClearSynonymClear"
name="i-haditha-close-bg-circle"
size="20px"
>
</UIcon>
</UButton>
<template #content>
<!-- synonym item -->
<template
v-for="(syn, itemIndex) in AutoComplationState.synonym
.items"
>
<div class="synonymItem px-2 py-4">
<div
class="flex justify-between items-center p-3 mb-2"
>
<span class="title"> {{ syn.title }} </span>
<USwitch
dir="ltr"
v-model="syn.enable"
@update:modelValue="
onUpdateSwitch(syn.subTitles, itemIndex)
"
/>
</div>
<div class="flex items-center px-2 flex-wrap">
<UButton
v-for="(sub, subIndex) in syn.subTitles"
:disabled="!syn.enable"
:key="subIndex"
type="button"
@click="
onUpdateSubTitle(sub, itemIndex, subIndex)
"
class="me-2.5 mb-3.5 promotion-item"
:class="{ active: sub.active }"
>
{{ sub.title }}
<!-- <UIcon name="i-haditha-close-bg-circle" size="12px"> </UIcon> -->
</UButton>
<UButton
v-if="syn.enable && !syn.enableForm"
type="button"
@click="syn.enableForm = true"
class="me-2.5 mb-3.5 add-button"
:class="{ active: syn.enable }"
icon="i-haditha-add"
>
</UButton>
<UForm
v-if="syn.enable && syn.enableForm"
:schema="schema"
:state="AutoComplationState"
class="w-25 me-2.5 mb-3.5"
>
<UFormField name="name" size="md">
<UInput
v-model="Formstate.name"
placeholder="بنویسید ..."
@keyup.enter="onAddNewTitle(syn.subTitles)"
>
<template v-if="syn.enableForm" #trailing>
<UButton
color=""
variant=""
size="sm"
icon="i-lucide-x"
aria-label="Clear input"
@click="syn.enableForm = false"
/>
</template>
</UInput>
</UFormField>
</UForm>
</div>
</div>
<USeparator
class="px-2"
color="neutral"
type="solid"
size="xs"
/>
</template>
</template>
</UPopover>
<!-- #endregion -->
<!-- #region ترجمه -->
<!-- <UButton
@click.self="setKey('hadith_fa')"
:class="{ active: type_key == 'hadith_fa' }"
type="button"
class="filter-item"
>
{{ state.type_key.label }}
<UIcon
v-if="type_key == 'hadith_fa'"
@click.self="setKey('hadith')"
name="i-haditha-close-bg-circle"
size="20px"
>
</UIcon>
</UButton> -->
<!-- #endregion -->
<!-- #region عین عبارت -->
<UButton
@click.self="setType('phrase')"
:class="{ active: search_type == 'phrase' }"
class="filter-item"
>
{{ AutoComplationState.phrase.label }}
<UIcon
v-if="search_type == 'phrase'"
@click.self="setType('normal')"
name="i-haditha-close-bg-circle"
size="20px"
>
</UIcon>
</UButton>
<!-- #endregion -->
</div>
<!-- #region نوع -->
<div class="ms-2">
<USelect
:items="AutoComplationState.type.items"
:content="{
align: 'start',
side: 'bottom',
sideOffset: 8,
}"
:ui="{
content: 'w-48',
}"
class="filter-item"
:class="{
active: AutoComplationState.type.value == 'hadith',
}"
v-model="typeModelValue"
trailing-icon=""
value-key="value"
@update:modelValue="onTypeSelectChanged"
>
<!-- <UButton
class="filter-item"
:label="state.type.label"
trailingIcon="i-haditha-dropdown-chevron-down"
:class="{
active:
search_type == 'arabic' ||
search_type == 'translations' ||
search_type == 'descriptions',
}"
>
{{ state.type.label }}
<UIcon
v-if="
search_type == 'arabic' ||
search_type == 'translations' ||
search_type == 'descriptions'
"
@click.self="closeTypeDropdown"
name="i-haditha-close-bg-circle"
size="20px"
>
</UIcon>
</UButton>-->
<!-- <template #item> item </template> -->
<!-- <template #item-label> item label </template> -->
</USelect>
</div>
<!-- #endregion -->
</div>
</div>
</div>
<div
v-if="searchTerm?.length == 0"
class="flex justify-center flex-col items-center mt-10"
>
<img
fit="auto"
quality="80"
placeholder
src="/img/haditha/logo.webp"
/>
<div class="title">
کاوش با
<span class="badge-style mx-1">هوش مصنوعی</span>
در احادیث اسلامی
</div>
</div>
<div
v-if="loadedItems.length"
class="search-box-container pb-0 bg-white flex justify-center"
>
<div class="search-list-contianer">
<div class="total">
<span>{{ total }}</span>
نتیجه
</div>
<div ref="el" class="search-list firefox-scrollbar">
<search-list
no-data-text="نتیجه‌ای یافت نشد!"
no-data-icon="/img/haditha/no-data.png"
:total="total"
:list="loadedItems"
></search-list>
</div>
</div>
</div>
<no-data
class="h-full w-full flex flex-col justify-center items-center"
v-else
>
<img fit="auto" quality="80" src="/img/haditha/no-data.png" />
<p class="no-data-text">"نتیجه‌ای یافت نشد!</p>
</no-data>
</div>
</div>
</div>
</HadithaLayout>
</template>
<style scoped>
.background-image {
min-height: 100%;
/* height: 100dvh; */
background-size: auto;
background-repeat: no-repeat;
}
.logo-container {
/* padding-top: 4.5em; */
position: relative;
.title {
margin-top: 3.5em;
font-family: IRANSansX;
font-size: 14px;
line-height: 21px;
letter-spacing: 0%;
text-align: center;
color: var(--ui-color-two);
}
.badge-style {
width: 100;
height: 23;
border-radius: 40px;
padding-right: 8px;
padding-bottom: 2px;
padding-left: 8px;
gap: 10px;
color: #fff;
background: linear-gradient(270.29deg, #d284ff 8.12%, #4d00ff 109.58%);
}
}
.search-box-container {
padding-top: 0.7em;
padding-bottom: 4em; /*64px */
&.pb-0 {
padding-bottom: 0 !important;
}
}
.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;
}
}
}
.haditha-search-root-wrapper {
max-width: 656px;
width: 100%;
margin: 0 1em;
.haditha-search-root {
position: relative;
&::before {
content: "";
content: none;
position: absolute;
left: 1em;
right: 1em;
top: 50%;
backdrop-filter: blur(60px);
background: linear-gradient(137.41deg, #ffffff -42.82%, #e5e0ff 87.9%);
filter: blur(60px);
max-width: 626px;
width: 100%;
height: 68px;
z-index: 0;
}
.prev-search-item {
width: 328;
height: 49;
gap: 6px;
border-radius: 12px;
border-width: 0.5px;
padding-top: 8px;
padding-right: 12px;
padding-bottom: 8px;
padding-left: 12px;
background: #626b84;
border: 0.5px solid;
margin-bottom: 0.7em;
border-image-source: linear-gradient(
102.02deg,
#4be8ae 7.38%,
#00a762 91.78%
);
.total {
width: 53;
height: 24;
gap: 4px;
border-radius: 6px;
padding: 5px 7px;
background: #1b213266;
font-family: IRANSansX;
font-weight: 500;
font-size: 10px;
line-height: 15px;
letter-spacing: 0%;
text-align: right;
color: #ffffff;
}
.text {
font-family: Takrim;
font-weight: 400;
font-size: 16px;
line-height: 32px;
letter-spacing: 0%;
text-align: right;
color: #ffffff;
}
.clear-similar-btn {
width: 32px;
height: 32px;
gap: 4px;
border-radius: 60px;
padding-top: 11px;
padding-right: 6px;
padding-bottom: 11px;
padding-left: 6px;
background: #1b213266;
color: #fff;
}
}
.search-input {
position: relative;
}
}
}
</style>
<style>
.haditha-search-root-wrapper {
.my-trailing-button {
position: absolute;
z-index: 1;
width: 48px;
height: 48px;
justify-content: center;
align-items: center;
padding: 0;
border-radius: 50px;
background: linear-gradient(320.71deg, #b9fde0 6.56%, #e4f9f0 69.69%);
left: 12px;
top: 0;
bottom: 0;
margin: auto;
transition: all 0.2s ease-in-out;
&:hover {
transition: all 0.2s ease-in-out;
background: linear-gradient(320.71deg, #54ecaa 6.56%, #b6f0d9 69.69%);
}
& > span {
/* width: 18px; */
/* height: 18px; */
/* background-image: linear-gradient(
102.02deg,
#4be8ae 7.38%,
#00a762 91.78%
); */
}
}
.close-mode {
background: #f0f1f4;
color: #000; /* رنگ خاکستری */
&:hover {
background: #e0e0e0; /* رنگ خاکستری */
}
}
.haditha-search-input {
z-index: 0;
height: 72px;
justify-content: space-between;
padding-top: 12px;
/* padding-right: 12px; */
padding-bottom: 12px;
padding-left: 12px;
border-radius: 12px;
border-width: 0.3px;
background-color: #fff;
border: 0.3px solid #e0e0e0;
box-shadow: 0px 1px 4px 0px #0000000d;
font-family: IRANSansX;
font-weight: 300;
font-size: 14px;
line-height: 21px;
letter-spacing: 0%;
text-align: right;
color: #a7acbe;
}
.search-filter {
.filter-item {
/* width: 81px; */
height: 40px;
border-radius: 12px;
border-width: 0.3px;
padding-top: 8px;
padding-right: 12px;
padding-bottom: 8px;
padding-left: 12px;
gap: 4px;
background-color: #fff;
border: 0.3px solid #e0e0e0;
box-shadow: 0px 1px 4px 0px #0000000d;
color: #8a92a8;
font-family: IRANSansX;
font-weight: 400;
font-size: 13px;
line-height: 20px;
letter-spacing: 0%;
text-align: right;
&.active {
background-image: linear-gradient(
102.02deg,
#4be8ae 7.38%,
#00a762 91.78%
);
border-color: #4be8ae;
color: #fff;
box-shadow: none;
}
}
}
&.search-page {
.haditha-search-root {
&::before {
content: none;
}
.my-trailing-button {
width: 40px;
height: 40px;
span.iconify {
width: 25px;
height: 25px;
}
}
.haditha-search-input {
height: 56px;
}
}
}
}
.popover-root-content {
overflow-y: auto;
width: 20.5em;
height: 17.75em;
/* gap: 8px; */
/* border-radius: 16px; */
border-width: 0.3px;
/* padding-top: 16px; */
/* padding-right: 8px; */
/* padding-bottom: 16px; */
/* padding-left: 8px; */
background: #ffffff;
border: 0.3px solid #e0e0e0;
box-shadow: 0px 8px 20px 0px #0000001a;
.synonymItem {
.title {
font-family: IRANSansX;
font-weight: 400;
font-size: 14px;
line-height: 100%;
letter-spacing: 0%;
text-align: center;
vertical-align: middle;
color: #8a92a8;
}
/* border-bottom: 1px solid #d9d9d9; */
.promotion-item {
width: 52.599998474121094;
height: 36;
gap: 4px;
border-radius: 8px;
border-width: 0.3px;
padding-top: 11px;
padding-right: 12px;
padding-bottom: 11px;
padding-left: 12px;
border: 0.3px solid #d9d9d9;
background: #f0f1f4;
font-family: IRANSansX;
font-weight: 400;
font-size: 12px;
line-height: 100%;
letter-spacing: 0%;
text-align: right;
color: #626b84;
&.active {
background: linear-gradient(320.71deg, #b9fde0 6.56%, #e4f9f0 69.69%);
border: 0.3px solid #29d985;
color: #626b84;
}
&[disabled="true"] {
filter: grayscale(0.7);
}
}
.add-button {
width: 48;
height: 36;
gap: 4px;
border-radius: 8px;
border-width: 1px;
padding-right: 11px;
padding-left: 11px;
background: #ffffff;
border: 1px solid #f0f1f4;
color: #8a92a8;
}
}
}
@media screen and (max-width: 719.99px) {
.haditha-search-root-wrapper {
.search-filter {
/* width: 361px; */
overflow-x: auto;
white-space: nowrap;
width: 92dvw;
}
}
}
/* @media scrren and (min-width: 720px) and (max-width: 991.99px) {
} */
</style>