From 0940493c21539d7da405105db15c59b0b6f34178 Mon Sep 17 00:00:00 2001 From: Profile Profile Date: Fri, 27 Feb 2026 00:12:33 +0300 Subject: [PATCH] add categories --- src/components/ContentGrid.astro | 35 +++++++----- src/components/Header/Header.astro | 7 +++ src/components/NewsSingle.astro | 1 + src/layouts/MainLayout.astro | 4 +- src/lib/wpInfo.js | 87 ++++++++++++++++++++++++++++++ src/middleware.js | 0 src/pages/[...slug].astro | 23 +++++--- 7 files changed, 135 insertions(+), 22 deletions(-) create mode 100644 src/lib/wpInfo.js create mode 100644 src/middleware.js diff --git a/src/components/ContentGrid.astro b/src/components/ContentGrid.astro index 66297e7..f01cc99 100644 --- a/src/components/ContentGrid.astro +++ b/src/components/ContentGrid.astro @@ -11,7 +11,7 @@ export interface Props { hasNextPage: boolean; endCursor: string | null; }; - perLoad?: number; // Переименовали first в perLoad + perLoad?: number; } const { @@ -20,15 +20,14 @@ const { type = 'latest', slug = '', pageInfo = { hasNextPage: false, endCursor: null }, - perLoad = 11 // perLoad на верхнем уровне с дефолтом 11 + perLoad = 11 } = Astro.props; -// Формируем конфиг для sentinel из пропсов верхнего уровня -// Внутри оставляем поле first для совместимости с API и скриптом +// Используем perLoad везде const loadMoreConfig = { type, slug, - first: perLoad // Маппим perLoad в first для обратной совместимости + perLoad // Теперь используем perLoad вместо first }; function getCoauthorsNames(coauthors: any[]): string { @@ -163,7 +162,7 @@ function shouldBeLarge(index: number): boolean { interface LoadMoreConfig { type: 'latest' | 'category' | 'author' | 'tag'; slug?: string; - perLoad?: number; // В скрипте оставляем first для совместимости + perLoad: number; // Только perLoad, никакого first } class InfinityScroll { @@ -186,15 +185,25 @@ function shouldBeLarge(index: number): boolean { this.noMorePosts = document.getElementById('no-more-posts'); this.postsCount = document.getElementById('posts-count'); - const defaultConfig: LoadMoreConfig = { type: 'latest', first: 11 }; + // Дефолтный конфиг только с perLoad + const defaultConfig: LoadMoreConfig = { + type: 'latest', + perLoad: 11 + }; if (this.sentinel) { this.endCursor = this.sentinel.dataset.endCursor || null; this.currentIndex = parseInt(this.sentinel.dataset.currentIndex || '0'); try { - this.loadMoreConfig = JSON.parse(this.sentinel.dataset.loadConfig || '{}'); - this.loadMoreConfig = { ...defaultConfig, ...this.loadMoreConfig }; + // Парсим конфиг из data-атрибута + const parsedConfig = JSON.parse(this.sentinel.dataset.loadConfig || '{}'); + this.loadMoreConfig = { + ...defaultConfig, + ...parsedConfig, + // Убеждаемся, что perLoad определен + perLoad: parsedConfig.perLoad || defaultConfig.perLoad + }; } catch { this.loadMoreConfig = defaultConfig; } @@ -233,13 +242,14 @@ function shouldBeLarge(index: number): boolean { this.showLoading(); try { + // Отправляем только perLoad (никакого first) const response = await fetch('/load-more-posts', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ - perLoad: this.loadMoreConfig.perLoad || 11, + perLoad: this.loadMoreConfig.perLoad, after: this.endCursor, type: this.loadMoreConfig.type, slug: this.loadMoreConfig.slug, @@ -248,7 +258,7 @@ function shouldBeLarge(index: number): boolean { }); if (!response.ok) { - throw new Error('Ошибка загрузки постов'); + throw new Error(`Ошибка загрузки постов: ${response.status}`); } const html = await response.text(); @@ -274,7 +284,8 @@ function shouldBeLarge(index: number): boolean { this.grid?.appendChild(fragment); - this.currentIndex += this.loadMoreConfig.first || 11; + // Используем perLoad для увеличения индекса + this.currentIndex += this.loadMoreConfig.perLoad; this.endCursor = newEndCursor; this.hasMore = hasNextPage; diff --git a/src/components/Header/Header.astro b/src/components/Header/Header.astro index 1aefcb6..0d8e9fa 100644 --- a/src/components/Header/Header.astro +++ b/src/components/Header/Header.astro @@ -1,5 +1,7 @@ --- + const { category } = Astro.props; + import Stores from './LazyStores.astro'; import MainMenu from '@components/MainMenu.astro'; @@ -12,6 +14,11 @@
Профиль + {category && ( +
+ {category.name} +
+ )}
diff --git a/src/components/NewsSingle.astro b/src/components/NewsSingle.astro index 0d92bba..d5185cb 100644 --- a/src/components/NewsSingle.astro +++ b/src/components/NewsSingle.astro @@ -4,6 +4,7 @@ import Author from '@components/AuthorDisplay.astro'; import Subscribe from '@components/SubscribePost.astro'; import ShareButtons from '@components/ShareButtons.astro'; + interface Props { post: any; pageInfo?: any; diff --git a/src/layouts/MainLayout.astro b/src/layouts/MainLayout.astro index cd844f4..cc0ddbd 100644 --- a/src/layouts/MainLayout.astro +++ b/src/layouts/MainLayout.astro @@ -1,6 +1,6 @@ --- -const { title, description } = Astro.props; +const { title, description, category } = Astro.props; import Header from '../components/Header/Header.astro'; import Header_lite from '../components/Header/Header_lite.astro'; @@ -28,7 +28,7 @@ import '../styles/global.css';
-
+
diff --git a/src/lib/wpInfo.js b/src/lib/wpInfo.js new file mode 100644 index 0000000..6debe6d --- /dev/null +++ b/src/lib/wpInfo.js @@ -0,0 +1,87 @@ +import { fetchGraphQL } from './graphql-client.js'; + +class WPInfo { + constructor() { + this.categories = null; + } + + // Запрос всех рубрик используя вашу библиотеку + async fetchAllCategories() { + const query = ` + query GetCategories($first: Int) { + categories(first: $first) { + edges { + node { + id + name + color + slug + uri + databaseId + } + } + } + } + `; + + try { + // Используем вашу существующую функцию fetchGraphQL + const data = await fetchGraphQL(query, { first: 100 }); + + // Извлекаем node из каждого edge (как в getLatestPosts) + if (data?.categories?.edges) { + this.categories = data.categories.edges.map(edge => edge.node); + } else if (data?.data?.categories?.edges) { + this.categories = data.data.categories.edges.map(edge => edge.node); + } + + return this.categories; + } catch (error) { + console.error('Error fetching categories:', error); + return []; + } + } + + // Получить рубрику по ID + getCategoryById(id) { + if (!this.categories) return null; + return this.categories.find(cat => + cat.id === id || + cat.databaseId === parseInt(id) + ); + } + + // Получить рубрику по slug + getCategoryBySlug(slug) { + if (!this.categories) return null; + return this.categories.find(cat => cat.slug === slug); + } + + // Получить все рубрики + getAllCategories() { + return this.categories || []; + } + + // Получить рубрики с фильтрацией + getCategories(filterFn) { + if (!this.categories) return []; + return this.categories.filter(filterFn); + } + + // Проверить, загружены ли рубрики + isLoaded() { + return this.categories !== null; + } + + // Очистить кеш (если нужно обновить) + clearCache() { + this.categories = null; + } +} + +// Создаем и экспортируем единственный экземпляр +export const wpInfo = new WPInfo(); + +wpInfo.fetchAllCategories().then(() => { + console.log('✅ WPInfo: данные рубрик загружены в память и будут храниться постоянно'); +}); \ No newline at end of file diff --git a/src/middleware.js b/src/middleware.js new file mode 100644 index 0000000..e69de29 diff --git a/src/pages/[...slug].astro b/src/pages/[...slug].astro index 3463974..81a45b9 100644 --- a/src/pages/[...slug].astro +++ b/src/pages/[...slug].astro @@ -6,10 +6,9 @@ import ContentGrid from '@components/ContentGrid.astro'; import { getNodeByURI } from '@lib/api/all'; import { getProfileArticleById, getPostsByCategory } from '@lib/api/posts'; //логика + import { getCategory } from '@lib/api/categories'; //логика - - - +import { wpInfo } from '@lib/wpInfo'; import { detectPageType } from '@lib/detect-page-type'; export const prerender = false; @@ -18,12 +17,19 @@ const pathname = Astro.url.pathname; // "/news/society/chto-sluchilos-nochju-27- const pageInfo = detectPageType(pathname); //определяем тип страницы - - let response; let article = null; let posts = null; let result = null; +let category; + +// Определяем категорию +if (!wpInfo.isLoaded()) { + await wpInfo.fetchAllCategories(); +} + +category = wpInfo.getCategoryBySlug(pageInfo.categorySlug); + let title = 'Профиль'; //title page @@ -37,8 +43,8 @@ if (pageInfo.type === 'single') { //одиночная статья } } else if (pageInfo.type === 'archive') { - - result = await getPostsByCategory(pageInfo.categorySlug, 11); //получвем данные поста + + result = await getPostsByCategory(pageInfo.categorySlug, 21); //получвем данные поста posts = result.posts; @@ -55,6 +61,7 @@ if (pageInfo.type === 'single') { //одиночная статья {/* Single post */} @@ -67,7 +74,7 @@ if (pageInfo.type === 'single') { //одиночная статья {pageInfo.type === 'archive' && posts && (