Skip to content

Commit

Permalink
Refactor api request (tmp)
Browse files Browse the repository at this point in the history
  • Loading branch information
igor.la committed Nov 25, 2024
1 parent d192b89 commit 9d17836
Show file tree
Hide file tree
Showing 2 changed files with 184 additions and 108 deletions.
267 changes: 159 additions & 108 deletions frontend/components/search/Pagination.vue
Original file line number Diff line number Diff line change
@@ -1,162 +1,213 @@
<script lang="ts">
import { defineComponent, reactive, ref, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import type { EventOnPoster } from '../../../common/types';
<script setup lang="ts">
import { useRoute } from 'vue-router';
interface ResponsiveDevice {
value: boolean;
}
interface PaginationResponse {
docs: EventOnPoster[];
totalDocs: number;
limit: number;
page: number;
totalPages: number;
hasPrevPage: boolean;
hasNextPage: boolean;
prevPage: number | null;
nextPage: number | null;
}
const route = useRoute();
const dateStart = computed(() =>
dateFromQueryToFilter('first', getFirstQuery(route.query.startDate as string))
);
const dateEnd = computed(() => {
return dateFromQueryToFilter('second', getFirstQuery(route.query.endDate as string));
});
const currentPage = computed(() => {
return parseInt(getFirstQuery(route.query.page as string));
});
export default defineComponent({
setup() {
const mobile = inject <ResponsiveDevice>('mobile');
const tablet = inject<ResponsiveDevice>('tablet');
const desktop = inject<ResponsiveDevice>('desktop');
const tags = computed(() =>
getFirstQuery(route.query.tags)
.split(', ')
.filter((item) => item !== '')
);
const { sendAnalytics } = useSendTrackingEvent();
const {
data: posterEvents,
error: errorEvents,
pending
} = await apiRouter.filters.findEventsPagination.useQuery({
data: {
query: {
tags,
startDate: dateStart,
endDate: dateEnd
},
options: {
page: currentPage,
limit: 15
},
watch: [tags.value, dateStart.value, dateEnd.value, currentPage.value]
}
});
const scrollOnTop = (width) => {
console.log(width);
watch(
() => route.query,
(value) => {
if (route.query.page) {
window.scrollTo({
top: width,
top: 450,
behavior: 'smooth'
});
};
const response = reactive<PaginationResponse>({
docs: [],
totalDocs: 0,
limit: 15,
page: 1,
totalPages: 1,
hasPrevPage: false,
hasNextPage: false,
prevPage: null,
nextPage: null
});
const loading = ref(false);
const route = useRoute();
const router = useRouter();
const getLimit = () => {
return mobile?.value ? 10 : tablet.value ? 14 : 15;
};
const fetchPage = async (page: number | null) => {
if (!page || loading.value) return;
loading.value = true;
try {
const res = await fetch('/api/events/find/pagination', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
query: {},
options: { page: page, limit: getLimit() }
})
});
if (!res.ok) {
throw new Error(`Ошибка запроса: ${res.status}`);
}
const data: PaginationResponse = await res.json();
Object.assign(response, data);
// scrollOnTop(mobile?.value ? 150 : tablet?.value ? 250 : 450);
} catch (error) {
console.error('Ошибка загрузки данных:', error);
} finally {
loading.value = false;
}
};
watch(
() => route.query.page,
(newPage) => {
const page = parseInt(newPage as string, 10) || 1;
fetchPage(page);
},
{ immediate: true }
);
return {
response,
loading,
router,
route
};
}
});
}
if (Object.keys(value).length) {
sendAnalytics.search({
search_term: route.fullPath.split('?')[1],
tags: value.tags ? getFirstQuery(value.tags) : ''
});
}
},
{ deep: true }
);
watch(
() => posterEvents,
(posterEvents) => {
if (posterEvents.value.page > posterEvents.value.totalPages) {
const currentParams = { ...route.query, ...{ page: 1 } };
navigateTo({ query: currentParams });
}
},
{ deep: true }
);
// export default defineComponent({
// setup() {
// const mobile = inject <ResponsiveDevice>('mobile');
// const tablet = inject<ResponsiveDevice>('tablet');
// const desktop = inject<ResponsiveDevice>('desktop');
//
// const scrollOnTop = (width) => {
// console.log(width);
// window.scrollTo({
// top: width,
// behavior: 'smooth'
// });
// };
// const response = reactive<PaginationResponse>({
// docs: [],`
// totalDocs: 0,
// limit: 15,
// page: 1,
// totalPages: 1,
// hasPrevPage: false,
// hasNextPage: false,
// prevPage: null,
// nextPage: null
// });
//
// const loading = ref(false);
// const route = useRoute();
// const router = useRouter();
//
// const getLimit = () => {
// return mobile?.value ? 10 : tablet.value ? 14 : 15;
// };
//
// const fetchPage = async (page: number | null) => {
// if (!page || loading.value) return;
// loading.value = true;
// try {
// const res = await fetch('/api/events/find/pagination', {
// method: 'POST',
// headers: {
// 'Content-Type': 'application/json'
// },
// body: JSON.stringify({
// query: {},
// options: { page: page, limit: getLimit() }
// })
// });
// if (!res.ok) {
// throw new Error(`Ошибка запроса: ${res.status}`);
// }
// const data: PaginationResponse = await res.json();
// Object.assign(response, data);
// // scrollOnTop(mobile?.value ? 150 : tablet?.value ? 250 : 450);
// } catch (error) {
// console.error('Ошибка загрузки данных:', error);
// } finally {
// loading.value = false;
// }
// };
//
// watch(
// () => route.query.page,
// (newPage) => {
// const page = parseInt(newPage as string, 10) || 1;
// fetchPage(page);
// },
// { immediate: true }
// );
//
// return {
// response,
// loading,
// router,
// route
// };
// }
// });
</script>

<template>
<div class="pagination-container">
<!-- Компонент отображения событий -->
<SearchEventCardsList
v-if="response.docs && response.docs.length !== 0"
:events="response.docs"
v-if="posterEvents.docs && posterEvents.docs.length !== 0"
:events="posterEvents.docs"
/>

<!-- Элементы управления пагинацией -->
<div class="pagination-controls">
<!-- Первая страница -->
<NuxtLink
v-if="response.page > 1"
v-if="posterEvents.page > 1"
:to="{ query: { ...route.query, page: 1 } }"
class="pagination-link"
:class="{ disabled: loading }"
:class="{ disabled: pending }"
>
{{ '<<' }}
</NuxtLink>

<!-- Кнопка назад -->
<NuxtLink
v-if="response.hasPrevPage"
:to="{ query: { ...route.query, page: response.prevPage } }"
v-if="posterEvents.hasPrevPage"
:to="{ query: { ...posterEvents.query, page: posterEvents.prevPage } }"
class="pagination-link"
:class="{ disabled: loading }"
:class="{ disabled: pending }"
>
{{ '<' }}
</NuxtLink>

<!-- Текущая и следующая страницы -->
<NuxtLink
v-for="page in [
response.page,
response.hasNextPage ? response.nextPage : null
posterEvents.page,
posterEvents.hasNextPage ? posterEvents.nextPage : null
].filter(Boolean)"
:key="page"
:to="{ query: { ...route.query, page } }"
:to="{ query: { ...route.query, ...{ page } } }"
class="pagination-link"
:class="{ active: response.page === page, disabled: loading }"
:class="{ active: posterEvents.page === page, disabled: pending }"
>
{{ page }}
</NuxtLink>

<!-- Кнопка вперед -->
<NuxtLink
v-if="response.hasNextPage"
:to="{ query: { ...route.query, page: response.nextPage } }"
v-if="posterEvents.hasNextPage"
:to="{ query: { ...route.query, page: posterEvents.nextPage } }"
class="pagination-link"
:class="{ disabled: loading }"
:class="{ disabled: pending }"
>
{{ '>' }}
</NuxtLink>

<!-- Последняя страница -->
<NuxtLink
v-if="response.page < response.totalPages"
:to="{ query: { ...route.query, page: response.totalPages } }"
v-if="posterEvents.page < posterEvents.totalPages"
:to="{ query: { ...route.query, page: posterEvents.totalPages } }"
class="pagination-link"
:class="{ disabled: loading }"
:class="{ disabled: pending }"
>
{{ '>>' }}
</NuxtLink>
Expand Down
25 changes: 25 additions & 0 deletions frontend/composables/useApiRouter/filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { Country, City } from '../../stores/location.store';
import type { UsedCitiesInternType, UsedLocationType } from '../../../common/types/location';
import type { Tag } from '../../../common/const/tags';
import type { EventOnPoster } from '../../../common/types';
import type { PaginatedResponse } from '../../../common/types/pagination';

export const filters = {
findEventsByCountry: defineQuery<
Expand All @@ -22,6 +23,7 @@ export const filters = {
{ watch }
);
}),

findEventsByCity: defineQuery<
(input?: {
city?: string | string[];
Expand All @@ -40,6 +42,7 @@ export const filters = {
{ watch }
);
}),

findEvents: defineQuery<
(input?: {
query: {
Expand All @@ -52,6 +55,28 @@ export const filters = {
>((input) => {
return useBackendFetch('events/find', { body: input?.query ?? {} }, { watch });
}),

findEventsPagination: defineQuery<
(input?: {
query: {
tags?: Tag[];
startDate: number;
endDate: number;
};
options: {
page: number;
limit: number;
};
watch: any;
}) => PaginatedResponse<EventOnPoster>
>((input) => {
return useBackendFetch(
'events/find/pagination',
{ body: { query: input?.query, options: input?.options } ?? {} },
{ watch }
);
}),

getUsedCountries: defineQuery<() => Country[]>(() => useBackendFetch('location/usedCountries')),
getUsedCitiesByCountry: defineQuery<(input: { country: Country }) => City[]>((input) =>
useBackendFetch(`location/usedCities/${input.country}`)
Expand Down

0 comments on commit 9d17836

Please sign in to comment.