Compare commits

..

2 Commits

Author SHA1 Message Date
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
6 changed files with 1126 additions and 324 deletions

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 = {
@ -974,6 +973,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

@ -75,15 +75,9 @@ 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"
@ -164,38 +158,36 @@ 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;
.search-list-item {
.from-person {
font-family: IRANSansX;
font-weight: 400;
font-size: 0.68rem; /*11px*/
line-height: 1rem;
font-weight: 300;
font-size: 0.75rem; /*12px*/
line-height: 1.125rem; /*18px*/
letter-spacing: 0%;
text-align: right;
color: #b4c2cf;
}
.search-list {
padding: 1em 1.3em;
height: calc(100dvh - 16em);
overflow-y: auto;
color: #00a762; /* #4be8ae 7.38% */
margin-bottom: 0.5em;
&.hadithaFavorites {
height: calc(100dvh - 8em);
&:hover,
&:focus,
&:active {
cursor: pointer;
background-color: #fafafa;
}
&:not(:last-child) {
border-bottom: 0.3px solid #d9d9d9;
}
.arabic-text {
font-family: Takrim;
font-weight: 400;
font-size: 1.125rem; /*18px*/
line-height: 2rem; /*23px*/
letter-spacing: 0%;
text-align: right;
color: var(--ui-color-two);
margin-bottom: 0.5em;
.search-list-item {
.from-person {
@ -270,18 +262,47 @@ const removeFromFavorites = async (item = {}, index = 0) => {
}
}
}
.no-data-text {
.persian-text {
font-family: Takrim;
font-weight: 400;
font-size: 1rem; /*16px*/
line-height: 1.375rem; /*22px*/
letter-spacing: 0%;
text-align: right;
color: #626b84;
margin-bottom: 0.5em;
}
.reference {
height: 24px;
gap: 4px;
padding-top: 0.25em; /*4px*/
padding-right: 0.5em; /*8px*/
padding-bottom: 0.25em; /*4px*/
padding-left: 0.5em; /*8px*/
border-radius: 6px; /*18px*/
border-width: 0.5px;
border: 0.5px solid #d9d9d9;
font-family: IRANSansX;
font-weight: 300;
font-size: 1rem;
line-height: 1.5rem; /*24px*/
letter-spacing: 0%;
text-align: center;
text-align: right;
color: #8a92a8;
&:hover,
&:focus,
&:active {
cursor: pointer;
background-color: #fafafa;
}
}
}
</style>
<!--
<style>
.text__orange {
color: orange;
}

View File

@ -24,14 +24,13 @@ 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);
// #endregion refs
// #region reactive
const state = reactive({
pagination: {
offset: 0,
limit: 10,
page: 1,
pages: 1,
@ -43,15 +42,20 @@ 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(),
{
@ -59,16 +63,12 @@ const { data: initialItems } = await useAsyncData(
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(
@ -84,7 +84,6 @@ useInfiniteScroll(
if (hits.length) {
loadedItems.value.push(...hits);
state.pagination.offset += state.pagination.limit;
} else {
hasMore.value = false;
}
@ -131,14 +130,6 @@ const CardList = defineAsyncComponent(
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>

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;
}
];
};