add categories
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
87
src/lib/wpInfo.js
Normal 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
0
src/middleware.js
Normal 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
|
||||
|
||||
@@ -38,7 +44,7 @@ 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'
|
||||
|
||||
Reference in New Issue
Block a user