add categories

This commit is contained in:
Profile Profile
2026-02-27 00:12:33 +03:00
parent 3da5b48c40
commit 0940493c21
7 changed files with 135 additions and 22 deletions

View File

@@ -11,7 +11,7 @@ export interface Props {
hasNextPage: boolean; hasNextPage: boolean;
endCursor: string | null; endCursor: string | null;
}; };
perLoad?: number; // Переименовали first в perLoad perLoad?: number;
} }
const { const {
@@ -20,15 +20,14 @@ const {
type = 'latest', type = 'latest',
slug = '', slug = '',
pageInfo = { hasNextPage: false, endCursor: null }, pageInfo = { hasNextPage: false, endCursor: null },
perLoad = 11 // perLoad на верхнем уровне с дефолтом 11 perLoad = 11
} = Astro.props; } = Astro.props;
// Формируем конфиг для sentinel из пропсов верхнего уровня // Используем perLoad везде
// Внутри оставляем поле first для совместимости с API и скриптом
const loadMoreConfig = { const loadMoreConfig = {
type, type,
slug, slug,
first: perLoad // Маппим perLoad в first для обратной совместимости perLoad // Теперь используем perLoad вместо first
}; };
function getCoauthorsNames(coauthors: any[]): string { function getCoauthorsNames(coauthors: any[]): string {
@@ -163,7 +162,7 @@ function shouldBeLarge(index: number): boolean {
interface LoadMoreConfig { interface LoadMoreConfig {
type: 'latest' | 'category' | 'author' | 'tag'; type: 'latest' | 'category' | 'author' | 'tag';
slug?: string; slug?: string;
perLoad?: number; // В скрипте оставляем first для совместимости perLoad: number; // Только perLoad, никакого first
} }
class InfinityScroll { class InfinityScroll {
@@ -186,15 +185,25 @@ function shouldBeLarge(index: number): boolean {
this.noMorePosts = document.getElementById('no-more-posts'); this.noMorePosts = document.getElementById('no-more-posts');
this.postsCount = document.getElementById('posts-count'); this.postsCount = document.getElementById('posts-count');
const defaultConfig: LoadMoreConfig = { type: 'latest', first: 11 }; // Дефолтный конфиг только с perLoad
const defaultConfig: LoadMoreConfig = {
type: 'latest',
perLoad: 11
};
if (this.sentinel) { if (this.sentinel) {
this.endCursor = this.sentinel.dataset.endCursor || null; this.endCursor = this.sentinel.dataset.endCursor || null;
this.currentIndex = parseInt(this.sentinel.dataset.currentIndex || '0'); this.currentIndex = parseInt(this.sentinel.dataset.currentIndex || '0');
try { try {
this.loadMoreConfig = JSON.parse(this.sentinel.dataset.loadConfig || '{}'); // Парсим конфиг из data-атрибута
this.loadMoreConfig = { ...defaultConfig, ...this.loadMoreConfig }; const parsedConfig = JSON.parse(this.sentinel.dataset.loadConfig || '{}');
this.loadMoreConfig = {
...defaultConfig,
...parsedConfig,
// Убеждаемся, что perLoad определен
perLoad: parsedConfig.perLoad || defaultConfig.perLoad
};
} catch { } catch {
this.loadMoreConfig = defaultConfig; this.loadMoreConfig = defaultConfig;
} }
@@ -233,13 +242,14 @@ function shouldBeLarge(index: number): boolean {
this.showLoading(); this.showLoading();
try { try {
// Отправляем только perLoad (никакого first)
const response = await fetch('/load-more-posts', { const response = await fetch('/load-more-posts', {
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}, },
body: JSON.stringify({ body: JSON.stringify({
perLoad: this.loadMoreConfig.perLoad || 11, perLoad: this.loadMoreConfig.perLoad,
after: this.endCursor, after: this.endCursor,
type: this.loadMoreConfig.type, type: this.loadMoreConfig.type,
slug: this.loadMoreConfig.slug, slug: this.loadMoreConfig.slug,
@@ -248,7 +258,7 @@ function shouldBeLarge(index: number): boolean {
}); });
if (!response.ok) { if (!response.ok) {
throw new Error('Ошибка загрузки постов'); throw new Error(`Ошибка загрузки постов: ${response.status}`);
} }
const html = await response.text(); const html = await response.text();
@@ -274,7 +284,8 @@ function shouldBeLarge(index: number): boolean {
this.grid?.appendChild(fragment); this.grid?.appendChild(fragment);
this.currentIndex += this.loadMoreConfig.first || 11; // Используем perLoad для увеличения индекса
this.currentIndex += this.loadMoreConfig.perLoad;
this.endCursor = newEndCursor; this.endCursor = newEndCursor;
this.hasMore = hasNextPage; this.hasMore = hasNextPage;

View File

@@ -1,5 +1,7 @@
--- ---
const { category } = Astro.props;
import Stores from './LazyStores.astro'; import Stores from './LazyStores.astro';
import MainMenu from '@components/MainMenu.astro'; import MainMenu from '@components/MainMenu.astro';
@@ -12,6 +14,11 @@
<div class="top-bar"> <div class="top-bar">
<img alt="Профиль" width="249" height="55" src="https://cdn.profile.ru/wp-content/themes/profile/assets/img/profile-logo-delovoy.svg"> <img alt="Профиль" width="249" height="55" src="https://cdn.profile.ru/wp-content/themes/profile/assets/img/profile-logo-delovoy.svg">
{category && (
<div class="parttile-block">
{category.name}
</div>
)}
<Stores /> <Stores />
</div> </div>

View File

@@ -4,6 +4,7 @@ import Author from '@components/AuthorDisplay.astro';
import Subscribe from '@components/SubscribePost.astro'; import Subscribe from '@components/SubscribePost.astro';
import ShareButtons from '@components/ShareButtons.astro'; import ShareButtons from '@components/ShareButtons.astro';
interface Props { interface Props {
post: any; post: any;
pageInfo?: any; pageInfo?: any;

View File

@@ -1,6 +1,6 @@
--- ---
const { title, description } = Astro.props; const { title, description, category } = Astro.props;
import Header from '../components/Header/Header.astro'; import Header from '../components/Header/Header.astro';
import Header_lite from '../components/Header/Header_lite.astro'; import Header_lite from '../components/Header/Header_lite.astro';
@@ -28,7 +28,7 @@ import '../styles/global.css';
</div> </div>
</div> </div>
<div class="container"> <div class="container">
<Header /> <Header category={category} />
<main> <main>
<slot></slot> <slot></slot>
</main> </main>

87
src/lib/wpInfo.js Normal file
View File

@@ -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: данные рубрик загружены в память и будут храниться постоянно');
});

0
src/middleware.js Normal file
View File

View File

@@ -6,10 +6,9 @@ import ContentGrid from '@components/ContentGrid.astro';
import { getNodeByURI } from '@lib/api/all'; import { getNodeByURI } from '@lib/api/all';
import { getProfileArticleById, getPostsByCategory } from '@lib/api/posts'; //логика import { getProfileArticleById, getPostsByCategory } from '@lib/api/posts'; //логика
import { getCategory } from '@lib/api/categories'; //логика import { getCategory } from '@lib/api/categories'; //логика
import { wpInfo } from '@lib/wpInfo';
import { detectPageType } from '@lib/detect-page-type'; import { detectPageType } from '@lib/detect-page-type';
export const prerender = false; export const prerender = false;
@@ -18,12 +17,19 @@ const pathname = Astro.url.pathname; // "/news/society/chto-sluchilos-nochju-27-
const pageInfo = detectPageType(pathname); //определяем тип страницы const pageInfo = detectPageType(pathname); //определяем тип страницы
let response; let response;
let article = null; let article = null;
let posts = null; let posts = null;
let result = null; let result = null;
let category;
// Определяем категорию
if (!wpInfo.isLoaded()) {
await wpInfo.fetchAllCategories();
}
category = wpInfo.getCategoryBySlug(pageInfo.categorySlug);
let title = 'Профиль'; //title page let title = 'Профиль'; //title page
@@ -38,7 +44,7 @@ if (pageInfo.type === 'single') { //одиночная статья
} else if (pageInfo.type === 'archive') { } else if (pageInfo.type === 'archive') {
result = await getPostsByCategory(pageInfo.categorySlug, 11); //получвем данные поста result = await getPostsByCategory(pageInfo.categorySlug, 21); //получвем данные поста
posts = result.posts; posts = result.posts;
@@ -55,6 +61,7 @@ if (pageInfo.type === 'single') { //одиночная статья
<MainLayout <MainLayout
title={title} title={title}
description="Информационное агентство Деловой журнал Профиль" description="Информационное агентство Деловой журнал Профиль"
category={category}
> >
{/* Single post */} {/* Single post */}
@@ -67,7 +74,7 @@ if (pageInfo.type === 'single') { //одиночная статья
{pageInfo.type === 'archive' && posts && ( {pageInfo.type === 'archive' && posts && (
<ContentGrid <ContentGrid
items={posts} items={posts}
pageInfo={pageInfo} pageInfo={result.pageInfo}
slug={pageInfo.categorySlug} slug={pageInfo.categorySlug}
showCount={false} showCount={false}
type='category' type='category'