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

View File

@@ -1,5 +1,7 @@
---
const { category } = Astro.props;
import Stores from './LazyStores.astro';
import MainMenu from '@components/MainMenu.astro';
@@ -12,6 +14,11 @@
<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">
{category && (
<div class="parttile-block">
{category.name}
</div>
)}
<Stores />
</div>

View File

@@ -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;

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_lite from '../components/Header/Header_lite.astro';
@@ -28,7 +28,7 @@ import '../styles/global.css';
</div>
</div>
<div class="container">
<Header />
<Header category={category} />
<main>
<slot></slot>
</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 { 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') { //одиночная статья
<MainLayout
title={title}
description="Информационное агентство Деловой журнал Профиль"
category={category}
>
{/* Single post */}
@@ -67,7 +74,7 @@ if (pageInfo.type === 'single') { //одиночная статья
{pageInfo.type === 'archive' && posts && (
<ContentGrid
items={posts}
pageInfo={pageInfo}
pageInfo={result.pageInfo}
slug={pageInfo.categorySlug}
showCount={false}
type='category'