add categories
This commit is contained in:
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
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 { 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'
|
||||||
|
|||||||
Reference in New Issue
Block a user