Work on search page
This commit is contained in:
parent
49b47bb97f
commit
1f9ed61d5b
|
@ -1,410 +1,122 @@
|
|||
<template>
|
||||
<UInput
|
||||
v-model="value"
|
||||
placeholder="هوشمند جستجو کنید..."
|
||||
:ui="{
|
||||
trailing: '',
|
||||
|
||||
root: ['hadith-search-root'],
|
||||
base: ['hadith-search-input'],
|
||||
}"
|
||||
:loading="loading"
|
||||
trailing-icon="i-lucide-search"
|
||||
autocomplete="on"
|
||||
autofocus
|
||||
highlight
|
||||
@blur="onBlur"
|
||||
@change="onChange"
|
||||
@update:modelValue="onUpdateModel"
|
||||
>
|
||||
</UInput>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from "pinia";
|
||||
import searchApi from "../../apis/searchApi.js";
|
||||
import { useCommonStore } from "@stores/commonStore";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
placeholder: {
|
||||
default: "جستجو در هزاران محتوای قوانین و مقرارت",
|
||||
},
|
||||
contentKey: {
|
||||
default: "qasection",
|
||||
},
|
||||
entityTheme: {
|
||||
default: false,
|
||||
},
|
||||
showAppendSearchButton: {
|
||||
default: true,
|
||||
},
|
||||
showPrepend: {
|
||||
default: false,
|
||||
},
|
||||
showAppend: {
|
||||
default: true,
|
||||
},
|
||||
textSearch: {
|
||||
default: "",
|
||||
},
|
||||
modeInit: {
|
||||
default: 0,
|
||||
},
|
||||
searchDomain: {
|
||||
default() {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
listAutocomplate: {
|
||||
default() {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
<script setup lang="ts">
|
||||
const props = defineProps({
|
||||
message: {
|
||||
type: String,
|
||||
},
|
||||
emits: ["getAutoComplateList"],
|
||||
watch: {
|
||||
modeInit(newVal = 1) {
|
||||
this.mode = newVal;
|
||||
},
|
||||
textSearch(newVal) {
|
||||
this.localTextSearch = newVal;
|
||||
},
|
||||
});
|
||||
const emit = defineEmits(["response-ready"]);
|
||||
|
||||
const users = ref<Sample[]>([
|
||||
{
|
||||
label: "Leanne Graham",
|
||||
value: "1",
|
||||
icon: "i-lucide-clock",
|
||||
},
|
||||
beforeMount() {
|
||||
// this.inputPopupState = this.inputPopupState;
|
||||
{
|
||||
label: "Ervin Howell",
|
||||
value: "2",
|
||||
icon: "i-lucide-clock",
|
||||
},
|
||||
mounted() {
|
||||
this.localTextSearch = this.textSearch;
|
||||
|
||||
if (window.localStorage.getItem([this.historySearchRecent])) {
|
||||
try {
|
||||
this.historySearch = JSON.parse(
|
||||
window.localStorage.getItem([this.historySearchRecent])
|
||||
);
|
||||
} catch (e) {
|
||||
window.localStorage.removeItem([this.historySearchRecent]);
|
||||
}
|
||||
}
|
||||
{
|
||||
label: "Clementine Bauch",
|
||||
value: "3",
|
||||
icon: "i-lucide-clock",
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener("resize", this.handleResize);
|
||||
window.removeEventListener("load", this.handleResize);
|
||||
document.removeEventListener("click", this.handleClickOutside);
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
value: "",
|
||||
localListAutocomplate: [],
|
||||
typingTimer: undefined,
|
||||
doneTypingInterval: 800,
|
||||
localTextSearch: "",
|
||||
historySearch: [],
|
||||
]);
|
||||
|
||||
inputPopupState: 0,
|
||||
mode: 1,
|
||||
tagLiSelected: null,
|
||||
inputfocused: false,
|
||||
isLastKeyCodeArrow: false,
|
||||
historySearchRecent: "historysearchrecent",
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapState(useCommonStore, ["domainActiveGetter"]),
|
||||
},
|
||||
methods: {
|
||||
// on input changed
|
||||
onUpdateModel() {
|
||||
console.info("onUpdateModel");
|
||||
},
|
||||
// on input blur
|
||||
onBlur() {
|
||||
// console.info("onblue");
|
||||
},
|
||||
// on button click
|
||||
onChange() {
|
||||
console.info("onChange");
|
||||
},
|
||||
/**
|
||||
* تنظیم آیتم انتخاب شده و شروع جستجو.
|
||||
* @param {Object} navItem - آیتم انتخابشده.
|
||||
*/
|
||||
setDomainField(navItem) {
|
||||
this.$emit("onSetDomainField", navItem);
|
||||
// this.prevSearchStart();
|
||||
},
|
||||
async getAutoComplateList() {
|
||||
this.localListAutocomplate = [];
|
||||
if (this.localTextSearch == "") return;
|
||||
export type Sample = { label: string; value: string; icon: string };
|
||||
|
||||
let index_key = this.contentKey;
|
||||
if (!index_key) return;
|
||||
const searchTerm = ref("");
|
||||
const open = ref(false);
|
||||
const value = ref<Sample>();
|
||||
const loading = ref(false);
|
||||
|
||||
let url = searchApi.search.autoComplate;
|
||||
// fetch history list from backend(ssr)
|
||||
// const { data: users, status } = await useFetch(
|
||||
// "https://jsonplaceholder.typicode.com/users",
|
||||
// {
|
||||
// transform: (data: { id: number; name: string }[]) => {
|
||||
// return (
|
||||
// data?.map((user) => ({
|
||||
// label: user.name,
|
||||
// value: String(user.id),
|
||||
// avatar: { src: `https://i.pravatar.cc/120?img=${user.id}` },
|
||||
// })) || []
|
||||
// );
|
||||
// },
|
||||
// lazy: true,
|
||||
// }
|
||||
// );
|
||||
|
||||
url = url.replace("{{appname}}", buildName());
|
||||
url = url.replace("{{index_key}}", index_key);
|
||||
url = url.replace("{{filter}}", "q=" + this.localTextSearch);
|
||||
const onBlur = () => {
|
||||
// console.info("onBlue");
|
||||
};
|
||||
const onChange = () => {
|
||||
// console.info("onChange");
|
||||
};
|
||||
const onUpdateModel = (newVal) => {
|
||||
// console.info("onUpdateModel", newVal);
|
||||
};
|
||||
const onSearch = () => {
|
||||
console.info("onSearch");
|
||||
};
|
||||
const onKeyDown = () => {
|
||||
// console.info("onKeyDown");
|
||||
};
|
||||
const onKeyUp = () => {
|
||||
// console.info("onKeyUp");
|
||||
};
|
||||
const onSend = () => {
|
||||
console.info("onSend");
|
||||
|
||||
try {
|
||||
const { $api } = useNuxtApp();
|
||||
const response = await $api(url, {
|
||||
baseURL: repoUrl(),
|
||||
});
|
||||
|
||||
this.localListAutocomplate = response.hits?.hits;
|
||||
this.inputPopupState = 3;
|
||||
} catch (err) {}
|
||||
},
|
||||
|
||||
onKeyDown() {
|
||||
clearTimeout(this.typingTimer);
|
||||
this.typingTimer = undefined;
|
||||
},
|
||||
/**
|
||||
* کنترل تایمر تکمیل خودکار و ارسال کوئری.
|
||||
* تایمر فعلی را پاک میکند و یک تایمر جدید با یک تاخیر مشخص تنظیم میکند تا کوئری را ارسال کند.
|
||||
*/
|
||||
toggleAutocomplete(event) {
|
||||
// برای کلید حرکت پایین درخواست اضافی نرود
|
||||
if (
|
||||
event.keyCode === 40 ||
|
||||
event.keyCode === 38 ||
|
||||
event.keyCode === 13
|
||||
) {
|
||||
this.isLastKeyCodeArrow = event.keyCode === 40 || event.keyCode === 38;
|
||||
return;
|
||||
}
|
||||
|
||||
this.isLastKeyCodeArrow = false;
|
||||
|
||||
if (!this.inputfocused && this.inputPopupState === 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.typingTimer) {
|
||||
clearTimeout(this.typingTimer);
|
||||
this.typingTimer = undefined;
|
||||
} else {
|
||||
this.typingTimer = setTimeout(() => {
|
||||
this.getAutoComplateList();
|
||||
this.typingTimer = undefined;
|
||||
}, this.doneTypingInterval);
|
||||
}
|
||||
},
|
||||
|
||||
setInputFocus() {
|
||||
this.inputfocused = true;
|
||||
// this.inputPopupfocused=false
|
||||
},
|
||||
/**
|
||||
* شروع جستجو را کنترل میکند.
|
||||
* @event prevSearchStart
|
||||
*/
|
||||
prevSearchStart(event) {
|
||||
if (
|
||||
this.isLastKeyCodeArrow &&
|
||||
event.keyCode === 13 &&
|
||||
this.inputPopupState != 0
|
||||
) {
|
||||
this.selectAutocomplate2();
|
||||
this.isLastKeyCodeArrow = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this.tagLiSelected = null;
|
||||
this.inputPopupState = 0;
|
||||
this.addHistorySearch(this.localTextSearch);
|
||||
|
||||
let tt = myEncodeQuery(this.localTextSearch);
|
||||
this.$emit("onSearchStart", tt);
|
||||
// this.searchStart(tt);
|
||||
},
|
||||
/**
|
||||
*نمایش سابقه جستجو.
|
||||
*/
|
||||
showHisory() {
|
||||
setTimeout(() => {
|
||||
if (this.localTextSearch == "") this.inputPopupState = 1;
|
||||
else {
|
||||
this.inputPopupState = 0;
|
||||
this.tagLiSelected = null;
|
||||
}
|
||||
}, 100);
|
||||
},
|
||||
/**
|
||||
* کنترل کلیکهای خارج از المان.
|
||||
*/
|
||||
keyupdiv(event) {
|
||||
// 13:enter
|
||||
// 8:backspace
|
||||
if (this.inputfocused == false) return;
|
||||
if (this.inputPopupState == 0 || this.inputPopupState == 2) return;
|
||||
var el = "";
|
||||
el =
|
||||
this.inputPopupState == 1
|
||||
? this.$refs["his_ul"]
|
||||
: this.$refs["auto_complate_ul"];
|
||||
|
||||
if (!el || !el.firstChild) return;
|
||||
|
||||
const selectItem = (item) => {
|
||||
this.tagLiSelected = item;
|
||||
this.tagLiSelected?.classList.add("selected");
|
||||
this.tagLiSelected?.focus();
|
||||
};
|
||||
|
||||
// 40: arrow down
|
||||
// 38: arrow up
|
||||
if (this.inputfocused == true && event.keyCode === 40) {
|
||||
if (this.tagLiSelected) {
|
||||
this.tagLiSelected?.classList.remove("selected");
|
||||
const next = this.tagLiSelected?.nextSibling || el.firstChild;
|
||||
selectItem(next);
|
||||
} else {
|
||||
selectItem(el?.firstChild);
|
||||
}
|
||||
} else if (this.inputfocused == true && event.keyCode === 38) {
|
||||
if (this.tagLiSelected) {
|
||||
this.tagLiSelected?.classList.remove("selected");
|
||||
const prev = this.tagLiSelected?.previousSibling || el.lastChild;
|
||||
selectItem(prev);
|
||||
} else {
|
||||
selectItem(el?.lastChild);
|
||||
}
|
||||
}
|
||||
// 46: delete
|
||||
else if (this.inputfocused == true && event.keyCode === 46) {
|
||||
let index = this.tagLiSelected?.getAttribute("data-key");
|
||||
|
||||
this.removeHistorySearch(index);
|
||||
}
|
||||
},
|
||||
onClickOutside() {
|
||||
if (this.inputPopupState == 1 || this.inputPopupState == 3) {
|
||||
this.inputPopupState = 0;
|
||||
this.tagLiSelected = null;
|
||||
}
|
||||
},
|
||||
selectAutocomplate(item) {
|
||||
this.tagLiSelected = null;
|
||||
this.inputPopupState = 0;
|
||||
this.localTextSearch = item;
|
||||
|
||||
this.$emit("onSearchStart", this.localTextSearch);
|
||||
// this.$emit("onSearchStart", {
|
||||
// textSearch: this.localTextSearch,
|
||||
// searchItem: item,
|
||||
// });
|
||||
},
|
||||
|
||||
selectHistorySearch(item) {
|
||||
this.localTextSearch = item;
|
||||
this.$emit("onSearchStart", this.localTextSearch);
|
||||
},
|
||||
|
||||
removeHistorySearch(x) {
|
||||
this.tagLiSelected = null;
|
||||
this.historySearch.splice(x, 1);
|
||||
this.saveHistorySearch();
|
||||
},
|
||||
saveHistorySearch() {
|
||||
const parsed = JSON.stringify(this.historySearch);
|
||||
window.localStorage.setItem([this.historySearchRecent], parsed);
|
||||
},
|
||||
getHighlightAutocomplate(item) {
|
||||
if (!item) return "";
|
||||
|
||||
let html = "";
|
||||
|
||||
let key = "title";
|
||||
if (this.contentKey == "qasection" || this.contentKey == "rgsection") {
|
||||
key = "qanon_title";
|
||||
if (item?.highlight[key]) html = item.highlight[key][0];
|
||||
if (!html) {
|
||||
let key1 = key + ".ph";
|
||||
if (item?.highlight[key1]) html = item.highlight[key1][0];
|
||||
}
|
||||
|
||||
if (!html) {
|
||||
let key1 = key + ".fa";
|
||||
if (item?.highlight[key1]) html = item.highlight[key1][0];
|
||||
}
|
||||
|
||||
let key2 = "ts_date";
|
||||
if (item?._source[key2]) {
|
||||
html += `<span style="color: #a7a098;"> - تاریخ: ${item._source[key2]}</span>`;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.contentKey == "sanad") {
|
||||
Object.values(item?.highlight).forEach((element, index) => {
|
||||
html += element[0];
|
||||
});
|
||||
}
|
||||
|
||||
return html;
|
||||
},
|
||||
|
||||
addHistorySearch(newSearch = "") {
|
||||
if (newSearch == "") {
|
||||
return;
|
||||
}
|
||||
var index = this.historySearch.indexOf(newSearch);
|
||||
if (index != -1) {
|
||||
this.historySearch.splice(index, 1);
|
||||
}
|
||||
|
||||
this.historySearch.unshift(newSearch);
|
||||
this.saveHistorySearch();
|
||||
},
|
||||
saveHistorySearch() {
|
||||
const parsed = JSON.stringify(this.historySearch);
|
||||
window.localStorage.setItem([this.historySearchRecent], parsed);
|
||||
},
|
||||
|
||||
selectAutocomplate2(item) {
|
||||
if (!item) {
|
||||
if (this.localListAutocomplate.length) {
|
||||
item = this.localListAutocomplate[this.tagLiSelected?.value];
|
||||
}
|
||||
}
|
||||
|
||||
let key = "title";
|
||||
if (this.contentKey == "qasection" || this.contentKey == "rgsection")
|
||||
key = "qanon_title";
|
||||
|
||||
this.inputfocused = false;
|
||||
this.searchinput?.blur();
|
||||
this.localTextSearch = item?._source[key];
|
||||
|
||||
this.$emit("onSearchStart", this.localTextSearch);
|
||||
// this.$emit("onSearchStart", {
|
||||
// textSearch: this.localTextSearch,
|
||||
// searchItem: item,
|
||||
// });
|
||||
|
||||
if (!item) {
|
||||
this.localTextSearch = this.tagLiSelected?.innerText;
|
||||
this.addHistorySearch(this.localTextSearch);
|
||||
|
||||
let tt = myEncodeQuery(this.localTextSearch);
|
||||
|
||||
this.$emit("onSearchStart", tt);
|
||||
// this.$emit("onSearchStart", { textSearch: tt, searchItem: item });
|
||||
}
|
||||
|
||||
this.inputPopupState = 0;
|
||||
this.tagLiSelected = null;
|
||||
},
|
||||
},
|
||||
emit("response-ready", "Hello from Child!");
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="hadith-search-root">
|
||||
<UInputMenu
|
||||
class="w-full"
|
||||
:items="users || []"
|
||||
v-model="value"
|
||||
v-model:open="open"
|
||||
v-model:search-term="searchTerm"
|
||||
placeholder="هوشمند جستجو کنید..."
|
||||
:ui="{
|
||||
base: ['hadith-search-input'],
|
||||
}"
|
||||
:content="{
|
||||
align: 'start',
|
||||
side: 'bottom',
|
||||
sideOffset: 4,
|
||||
}"
|
||||
:loading="loading"
|
||||
highlight
|
||||
highlightOnHover
|
||||
@focus="open = true"
|
||||
@blur="onBlur"
|
||||
@change="onChange"
|
||||
@update:modelValue="onUpdateModel"
|
||||
@update:searchTerm="onUpdateModel"
|
||||
@keydown="onKeyDown"
|
||||
@keyup="onKeyUp"
|
||||
@keydown.enter="onSend"
|
||||
>
|
||||
</UInputMenu>
|
||||
|
||||
<UButton class="my-trailing-button">
|
||||
<UIcon @click.prevent="onSearch" name="i-lucide-search" />
|
||||
</UButton>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.hadith-search-root {
|
||||
width: 656px;
|
||||
position: relative;
|
||||
max-width: 656px;
|
||||
width: 100%;
|
||||
margin: 0 1em;
|
||||
|
||||
&::before {
|
||||
content: "";
|
||||
|
||||
|
@ -416,58 +128,48 @@ export default {
|
|||
backdrop-filter: blur(60px);
|
||||
background: linear-gradient(137.41deg, #ffffff -42.82%, #e5e0ff 87.9%);
|
||||
filter: blur(60px);
|
||||
/* transform: rotate(180deg); */
|
||||
|
||||
width: 626px;
|
||||
height: 68px;
|
||||
z-index: 1;
|
||||
z-index: 0;
|
||||
}
|
||||
}
|
||||
.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 {
|
||||
z-index:3;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
|
||||
padding: 0;
|
||||
/* padding-bottom: 6px; */
|
||||
border-radius: 50px;
|
||||
/* border-bottom-width: 1px; */
|
||||
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, #90ceb3 6.56%, #daf1e8 69.69%);
|
||||
}
|
||||
|
||||
& > span {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
/* border-width: 1.5px; */
|
||||
/* border: 1.5px solid; */
|
||||
|
||||
/* border-image-source: linear-gradient(
|
||||
102.02deg,
|
||||
#4be8ae 7.38%,
|
||||
#00a762 91.78%
|
||||
); */
|
||||
}
|
||||
background-image: linear-gradient(102.02deg, #4be8ae 7.38%, #00a762 91.78%);
|
||||
}
|
||||
}
|
||||
|
||||
.hadith-search-input {
|
||||
z-index: 2;
|
||||
z-index: 0;
|
||||
|
||||
height: 72px;
|
||||
justify-content: space-between;
|
||||
padding-top: 12px;
|
||||
padding-right: 24px;
|
||||
padding-right: 12px;
|
||||
padding-bottom: 12px;
|
||||
padding-left: 12px;
|
||||
border-radius: 12px;
|
||||
|
|
|
@ -100,45 +100,52 @@ const leftItem = ref([
|
|||
},
|
||||
]);
|
||||
|
||||
const isMobile = ref(false);
|
||||
const rerenderNavigation = ref(1);
|
||||
|
||||
onMounted(() => {
|
||||
if (window?.outerWidth < 576)
|
||||
if (window?.outerWidth < 576) {
|
||||
isMobile.value = true;
|
||||
console.info("is less than 576");
|
||||
|
||||
items.value = items.value.filter((item) => item.to != "/hadith/favorites");
|
||||
rerenderNavigation.value++;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="fixed bottom-2 lg:top-2 right-0 left-0">
|
||||
<client-only>
|
||||
<UContainer class="flex justify-center my-navbar mx-3 lg:mx-auto">
|
||||
<UNavigationMenu
|
||||
highlight
|
||||
:items="items"
|
||||
class="data-[orientation=horizontal]:border-0 border-(--ui-border) data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-48"
|
||||
/>
|
||||
<div class="hidden lg:flex items-center">
|
||||
<template v-for="(item, index) in leftItem">
|
||||
<UDropdownMenu
|
||||
v-if="item.children?.length"
|
||||
:items="item.children"
|
||||
:ui="{
|
||||
content: 'w-48',
|
||||
}"
|
||||
>
|
||||
<UButton icon="i-lucide-menu" color="neutral" variant="outline" />
|
||||
</UDropdownMenu>
|
||||
<div class="fixed bottom-2 lg:bottom-auto lg:top-2 right-0 left-0">
|
||||
<UContainer class="flex justify-center my-navbar mx-3 lg:mx-auto">
|
||||
<UNavigationMenu
|
||||
:key="rerenderNavigation"
|
||||
:disableHoverTrigge="isMobile"
|
||||
:items="items"
|
||||
class="data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-48"
|
||||
/>
|
||||
<div class="hidden lg:flex items-center">
|
||||
<template v-for="(item, index) in leftItem">
|
||||
<UDropdownMenu
|
||||
v-if="item.children?.length"
|
||||
:items="item.children"
|
||||
:ui="{
|
||||
content: 'w-48',
|
||||
}"
|
||||
>
|
||||
<UButton icon="i-lucide-menu" color="neutral" variant="outline" />
|
||||
</UDropdownMenu>
|
||||
|
||||
<ULink
|
||||
v-else
|
||||
raw
|
||||
:to="item.to"
|
||||
class="w-full h-full flex justify-center items-center"
|
||||
>
|
||||
<UIcon :name="item.icon" class="size-7" />
|
||||
</ULink>
|
||||
</template>
|
||||
</div>
|
||||
</UContainer>
|
||||
</client-only>
|
||||
<ULink
|
||||
v-else
|
||||
raw
|
||||
:to="item.to"
|
||||
class="w-full h-full flex justify-center items-center"
|
||||
>
|
||||
<UIcon :name="item.icon" class="size-7" />
|
||||
</ULink>
|
||||
</template>
|
||||
</div>
|
||||
</UContainer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -167,10 +174,55 @@ onMounted(() => {
|
|||
|
||||
ul {
|
||||
li {
|
||||
padding: 0;
|
||||
|
||||
@media screen and (max-width: 991.99px) {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.group {
|
||||
&::before {
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&::before {
|
||||
background-color: color-mix(in oklab, #00a762 50%, transparent);
|
||||
box-shadow: 0px 4px 10px 0px #00745933;
|
||||
border-radius: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
max-width: 112px;
|
||||
height: 48px;
|
||||
gap: 4px;
|
||||
border-radius: 12px;
|
||||
padding-top: 6px;
|
||||
padding-right: 16px;
|
||||
padding-bottom: 6px;
|
||||
padding-left: 16px;
|
||||
|
||||
font-family: IRANSansX;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
line-height: 21px;
|
||||
letter-spacing: 0%;
|
||||
text-align: center;
|
||||
|
||||
&[data-active=""] {
|
||||
background: linear-gradient(
|
||||
102.02deg,
|
||||
#4be8ae 7.38%,
|
||||
#00a762 91.78%
|
||||
);
|
||||
box-shadow: 0px 4px 10px 0px #00745933;
|
||||
|
||||
* {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hide-label {
|
||||
.truncate {
|
||||
display: none;
|
||||
|
|
93
components/hadith/hero-page/SectionOne.vue
Normal file
93
components/hadith/hero-page/SectionOne.vue
Normal file
|
@ -0,0 +1,93 @@
|
|||
<template>
|
||||
<section class="section-one flex flex-col justify-center">
|
||||
<div class="bg-container h-full" :style="backgroundImageStyle">
|
||||
<navigation-menu></navigation-menu>
|
||||
|
||||
<div class="text-logo flex justify-center flex-col items-center">
|
||||
<NuxtImg fit="auto" quality="80" placeholder src="/img/logo.png" />
|
||||
<div class="title">
|
||||
کاوش با
|
||||
<span class="badge-style"> هوش مصنوعی </span>
|
||||
در احادیث اسلامی
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-box-container flex justify-center">
|
||||
<auto-complation></auto-complation>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
logo: "",
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
backgroundImageStyle() {
|
||||
// Use $img to generate an optimized image URL
|
||||
const optimizedImageUrl = this.$img("/img/background.png", {
|
||||
quality: 80,
|
||||
});
|
||||
|
||||
return {
|
||||
backgroundImage: `url(${optimizedImageUrl}), linear-gradient(199.05deg, #ffffff 9.99%, #e4fff7 42.07%, #ffffff 97.12%)`,
|
||||
};
|
||||
},
|
||||
},
|
||||
components: {
|
||||
NavigationMenu: defineAsyncComponent(() =>
|
||||
import("@hadith/components/hadith/NavigationMenu.vue")
|
||||
),
|
||||
AutoComplation: defineAsyncComponent(() =>
|
||||
import("@hadith/components/hadith/AutoComplation.vue")
|
||||
),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.section-one {
|
||||
.bg-container {
|
||||
height: 521px;
|
||||
background-size: 100% auto;
|
||||
background-repeat: no-repeat;
|
||||
/* background-attachment: fixed; */
|
||||
/* background-image: url("/img/background.svg"),
|
||||
linear-gradient(199.05deg, #ffffff 9.99%, #e4fff7 42.07%, #ffffff 97.12%); */
|
||||
}
|
||||
|
||||
.text-logo {
|
||||
padding-top: 10em;
|
||||
position: relative;
|
||||
|
||||
.title {
|
||||
margin-top: 3.5em;
|
||||
font-family: IRANSansX;
|
||||
font-size: 14px;
|
||||
line-height: 21px;
|
||||
letter-spacing: 0%;
|
||||
text-align: center;
|
||||
color: #1b2132;
|
||||
}
|
||||
.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: 1em;
|
||||
padding-bottom: 4em; /*64px */
|
||||
}
|
||||
}
|
||||
</style>
|
123
components/hadith/hero-page/SectionTwo.vue
Normal file
123
components/hadith/hero-page/SectionTwo.vue
Normal file
|
@ -0,0 +1,123 @@
|
|||
<template>
|
||||
<section class="section-two">
|
||||
<div class="flex flex-col items-center py-6">
|
||||
<div>قابلیت ها</div>
|
||||
<div>
|
||||
<NuxtImg
|
||||
width="32"
|
||||
height="32"
|
||||
fit="auto"
|
||||
quality="80"
|
||||
placeholder
|
||||
src="/img/chevron-down.svg"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col lg:flex-row">
|
||||
<div class="my-card card-one basis-full flex justify-center items-center">
|
||||
<div class="inner-container">
|
||||
<div>
|
||||
<p class="title">جستجوی معنایی</p>
|
||||
<p class="description">ارائه نتایج دقیق و معنادار از میان</p>
|
||||
<p class="description">حجم انبوه متون حدیثی</p>
|
||||
</div>
|
||||
|
||||
<NuxtImg
|
||||
fit="auto"
|
||||
quality="80"
|
||||
placeholder
|
||||
src="/img/card-one.png"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="my-card card-two basis-full flex justify-center items-center">
|
||||
<div class="inner-container">
|
||||
<div class="">
|
||||
<p class="title">جستجوی مترادفها</p>
|
||||
<p class="description">یافتن سریع واژگان مرتبط برای</p>
|
||||
<p class="description">درک بهتر مفاهیم حدیثی</p>
|
||||
</div>
|
||||
|
||||
<NuxtImg
|
||||
fit="auto"
|
||||
quality="80"
|
||||
placeholder
|
||||
src="/img/card-two.png"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="my-card card-three basis-full flex flex-col justify-center items-center"
|
||||
>
|
||||
<div class="inner-container">
|
||||
<div>
|
||||
<p class="title">مشابهتیابی حدیث</p>
|
||||
<p class="description">امکان یافتن احادیث یا مفاهیمی</p>
|
||||
<p class="description">با معنای مشابه یک حدیث</p>
|
||||
</div>
|
||||
|
||||
<NuxtImg
|
||||
fit="auto"
|
||||
quality="80"
|
||||
placeholder
|
||||
src="/img/card-three.png"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
<script>
|
||||
export default {};
|
||||
</script>
|
||||
<style scoped>
|
||||
.section-two {
|
||||
font-weight: 200;
|
||||
font-size: 20px;
|
||||
line-height: 30px;
|
||||
letter-spacing: 0%;
|
||||
text-align: center;
|
||||
|
||||
.my-card {
|
||||
background-repeat: no-repeat;
|
||||
background-size: auto;
|
||||
height: 660px;
|
||||
|
||||
.inner-container {
|
||||
max-width: 21.25em;
|
||||
margin: auto;
|
||||
}
|
||||
.title {
|
||||
font-weight: 500;
|
||||
font-size: 24px;
|
||||
line-height: 36px;
|
||||
letter-spacing: 0%;
|
||||
color: #1b2132;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.description {
|
||||
font-weight: 300;
|
||||
font-size: 20px;
|
||||
line-height: 30px;
|
||||
letter-spacing: 0%;
|
||||
text-align: right;
|
||||
color: #626b84;
|
||||
}
|
||||
|
||||
&.card-one {
|
||||
background-image: url("/img/card-one-bgi.png"),
|
||||
linear-gradient(134.17deg, #ffffff -9.81%, #e5e0ff 87.62%);
|
||||
}
|
||||
&.card-two {
|
||||
background-image: url("/img/card-two-bgi.png"),
|
||||
linear-gradient(329.16deg, #b9fde0 13.45%, #eefff8 63.57%);
|
||||
}
|
||||
&.card-three {
|
||||
background-image: url("/img/card-three-bgi.png"),
|
||||
linear-gradient(134.17deg, #ffffff -9.81%, #e5e0ff 87.62%);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,101 +1,10 @@
|
|||
<template>
|
||||
<HadithLayout :menu="sidbarMenu">
|
||||
<section class="section-one flex flex-col justify-center">
|
||||
<div class="bg-container h-full" :style="backgroundImageStyle">
|
||||
<navigation-menu></navigation-menu>
|
||||
|
||||
<div class="text-logo flex justify-center flex-col items-center">
|
||||
<NuxtImg fit="auto" quality="80" placeholder src="/img/logo.png" />
|
||||
<div class="title">
|
||||
کاوش با
|
||||
<span class="badge-style"> هوش مصنوعی </span>
|
||||
در احادیث اسلامی
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-box-container flex justify-center">
|
||||
<auto-complation></auto-complation>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section-two">
|
||||
<div class="flex flex-col items-center py-6">
|
||||
<div>قابلیت ها</div>
|
||||
<div>
|
||||
<NuxtImg
|
||||
width="32"
|
||||
height="32"
|
||||
fit="auto"
|
||||
quality="80"
|
||||
placeholder
|
||||
src="/img/chevron-down.svg"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col lg:flex-row">
|
||||
<div class="my-card card-one basis-full flex justify-center items-center">
|
||||
<div class="inner-container">
|
||||
<div>
|
||||
<p class="title">جستجوی معنایی</p>
|
||||
<p class="description">ارائه نتایج دقیق و معنادار از میان</p>
|
||||
<p class="description">حجم انبوه متون حدیثی</p>
|
||||
</div>
|
||||
|
||||
<NuxtImg
|
||||
fit="auto"
|
||||
quality="80"
|
||||
placeholder
|
||||
src="/img/card-one.png"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="my-card card-two basis-full flex justify-center items-center">
|
||||
<div class="inner-container">
|
||||
<div class="">
|
||||
<p class="title">جستجوی مترادفها</p>
|
||||
<p class="description">یافتن سریع واژگان مرتبط برای</p>
|
||||
<p class="description">درک بهتر مفاهیم حدیثی</p>
|
||||
</div>
|
||||
|
||||
<NuxtImg
|
||||
fit="auto"
|
||||
quality="80"
|
||||
placeholder
|
||||
src="/img/card-two.png"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="my-card card-three basis-full flex flex-col justify-center items-center"
|
||||
>
|
||||
<div class="inner-container">
|
||||
<div>
|
||||
<p class="title">مشابهتیابی حدیث</p>
|
||||
<p class="description">امکان یافتن احادیث یا مفاهیمی</p>
|
||||
<p class="description">با معنای مشابه یک حدیث</p>
|
||||
</div>
|
||||
|
||||
<NuxtImg
|
||||
fit="auto"
|
||||
quality="80"
|
||||
placeholder
|
||||
src="/img/card-three.png"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<HadithLayout>
|
||||
<section-one></section-one>
|
||||
<section-two></section-two>
|
||||
</HadithLayout>
|
||||
</template>
|
||||
<script>
|
||||
import { useStorage } from "@vueuse/core";
|
||||
import { mapActions, mapState } from "pinia";
|
||||
|
||||
import { useHadithStore } from "@hadith/stores/hadithStore";
|
||||
import { useCommonStore } from "~/stores/commonStore";
|
||||
import hadithApi from "@hadith/apis/hadithApi.js";
|
||||
import navbarMenu from "@hadith/json/hadith/menu.json";
|
||||
|
||||
export default {
|
||||
name: "hadith",
|
||||
|
@ -115,117 +24,12 @@ export default {
|
|||
name: "hadith",
|
||||
});
|
||||
},
|
||||
|
||||
created() {
|
||||
this.httpService = useNuxtApp()["$http"];
|
||||
},
|
||||
|
||||
async mounted() {
|
||||
let schemaExist = this.searchActiveTabGetter && this.searchSchemaGetter;
|
||||
|
||||
if (!schemaExist) this.getSchemas();
|
||||
else this.setSearchDomain(this.searchActiveTabGetter);
|
||||
|
||||
if (window.outerWidth < 992) {
|
||||
this.$store.commit("TOGGLE_SIDEBAR_MENU");
|
||||
this.showMobileFilterList = true;
|
||||
}
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
httpService: {},
|
||||
logo: "",
|
||||
sidbarMenuDefault: navbarMenu,
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
// ...mapState(useHadithStore, [
|
||||
// "domainActiveGetter",
|
||||
// "searchActiveTabGetter",
|
||||
// "searchSchemaGetter",
|
||||
// "searchSynonymTitleGetter",
|
||||
// ]),
|
||||
...mapState(useCommonStore, [
|
||||
"currentUser",
|
||||
"organNameGetter",
|
||||
"isSidebarCollapsed",
|
||||
"userPermisionGetter",
|
||||
]),
|
||||
|
||||
sidbarMenu() {
|
||||
return this.sidbarMenuDefault;
|
||||
},
|
||||
|
||||
backgroundImageStyle() {
|
||||
// Use $img to generate an optimized image URL
|
||||
const optimizedImageUrl = this.$img("/img/background.png", {
|
||||
quality: 80,
|
||||
});
|
||||
|
||||
return {
|
||||
backgroundImage: `url(${optimizedImageUrl}), linear-gradient(199.05deg, #ffffff 9.99%, #e4fff7 42.07%, #ffffff 97.12%)`,
|
||||
};
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions(useCommonStore, [
|
||||
"TOGGLE_SIDEBAR_MENU",
|
||||
"sidebarCollapsedSetter",
|
||||
]),
|
||||
|
||||
// ...mapActions(useHadithStore, [
|
||||
// "searchActiveTabSetter",
|
||||
// "searchSchemaSetter",
|
||||
// "domainActiveSetter",
|
||||
// "searchSynonymTitleSetter",
|
||||
// ]),
|
||||
|
||||
async getSchemas() {
|
||||
let localStoageSearchSchema = useStorage("searchSchema", undefined).value;
|
||||
|
||||
if (localStoageSearchSchema) {
|
||||
let searchSchema = JSON.parse(localStoageSearchSchema);
|
||||
this.searchSchemaSetter(searchSchema);
|
||||
this.searchActiveTabSetter(searchSchema[0]);
|
||||
} else {
|
||||
const payload = {
|
||||
organ: this.organNameGetter,
|
||||
system: "search",
|
||||
build_state: buildState(),
|
||||
};
|
||||
const url = repoUrl() + hadithApi.schema.list;
|
||||
|
||||
this.httpService
|
||||
.postRequest(url, payload)
|
||||
.then((res) => {
|
||||
this.searchSchemaSetter(res.data.search);
|
||||
this.searchActiveTabSetter(res.data.search[0]);
|
||||
this.fetchingData = false;
|
||||
|
||||
const toast = useToast();
|
||||
toast.add({
|
||||
title: "Success",
|
||||
description: "Your action was completed successfully.",
|
||||
color: "success",
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
this.fetchingData = false;
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
components: {
|
||||
AutoComplation: defineAsyncComponent(() =>
|
||||
import("@hadith/components/hadith/AutoComplation.vue")
|
||||
SectionOne: defineAsyncComponent(() =>
|
||||
import("@hadith/components/hadith/hero-page/SectionOne.vue")
|
||||
),
|
||||
NavigationMenu: defineAsyncComponent(() =>
|
||||
import("@hadith/components/hadith/NavigationMenu.vue")
|
||||
),
|
||||
AutoComplation: defineAsyncComponent(() =>
|
||||
import("@hadith/components/hadith/AutoComplation.vue")
|
||||
SectionTwo: defineAsyncComponent(() =>
|
||||
import("@hadith/components/hadith/hero-page/SectionTwo.vue")
|
||||
),
|
||||
HadithLayout: defineAsyncComponent(() =>
|
||||
import("@hadith/layouts/HadithLayout.vue")
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user