add support pages

This commit is contained in:
Profile Profile
2026-03-15 01:17:42 +03:00
parent 27fc54733e
commit 636bc47155
3 changed files with 232 additions and 96 deletions

85
src/lib/api/pages.ts Normal file
View File

@@ -0,0 +1,85 @@
import { fetchGraphQL } from './graphql-client.js';
/** подключаем страницу по slug */
interface PageData {
id: string;
title: string;
content: string;
image: string | null;
imageAlt: string;
type: 'page';
}
// Интерфейс для ответа GraphQL
interface GraphQLResponse {
data?: {
pages?: {
nodes: Array<{
id: string;
title: string;
content: string;
slug: string;
featuredImage?: {
node: {
sourceUrl: string;
altText: string;
};
} | null;
}>;
};
};
}
export async function getPageBySlug(slug: string): Promise<PageData | null> {
if (!slug) return null;
const query = `
query GetPageBySlug($slug: String!) {
pages(where: {name: $slug}) {
nodes {
id
title
content
slug
featuredImage {
node {
sourceUrl(size: LARGE)
altText
}
}
}
}
}
`;
try {
// Получаем данные
const response = await fetchGraphQL(query, { slug });
// ПРОВЕРЯЕМ СТРУКТУРУ ОТВЕТА
console.log('🔍 FULL RESPONSE:', JSON.stringify(response, null, 2));
// Пробуем разные варианты доступа к данным
const pages = response?.data?.pages?.nodes || response?.pages?.nodes || [];
const page = pages[0];
if (!page) {
console.log('❌ No page found for slug:', slug);
return null;
}
console.log('✅ Page found:', page.title);
return {
id: page.id,
title: page.title,
content: page.content,
image: page.featuredImage?.node?.sourceUrl || null,
imageAlt: page.featuredImage?.node?.altText || page.title || '',
type: 'page'
};
} catch (error) {
console.error('❌ Error in getPageBySlug:', error);
return null;
}
}

View File

@@ -1,3 +1,5 @@
import { wpInfo } from './wpInfo';
export interface PageTypeInfo { export interface PageTypeInfo {
type: 'single' | 'archive' | 'home' | 'unknown'; type: 'single' | 'archive' | 'home' | 'unknown';
contentType?: 'news' | 'post'; contentType?: 'news' | 'post';
@@ -5,14 +7,33 @@ export interface PageTypeInfo {
postSlug?: string; postSlug?: string;
postId?: number; postId?: number;
page: number; page: number;
pageSlug?: string;
uriParts: string[]; uriParts: string[];
} }
export function detectPageType(uri: string): PageTypeInfo { export function detectPageType(uri: string): PageTypeInfo {
//console.log('🔍 detectPageType INPUT:', uri);
// Убираем query параметры если есть
const uriWithoutQuery = uri.split('?')[0];
// Убираем слэши по краям // Убираем слэши по краям
const cleanUri = uri.replace(/^\/|\/$/g, ''); const cleanUri = uriWithoutQuery.replace(/^\/|\/$/g, '');
const parts = cleanUri ? cleanUri.split('/') : [];
console.log('📌 Clean URI:', cleanUri);
// Если URI пустой - это главная
if (cleanUri === '') {
console.log('🏠 Home page detected');
return {
type: 'home',
page: 1,
uriParts: []
};
}
const parts = cleanUri.split('/');
console.log('📦 Parts:', parts);
// Ищем пагинацию // Ищем пагинацию
const processedParts: string[] = []; const processedParts: string[] = [];
@@ -23,20 +44,27 @@ export function detectPageType(uri: string): PageTypeInfo {
const pageNum = parseInt(parts[i + 1]); const pageNum = parseInt(parts[i + 1]);
if (pageNum > 0) { if (pageNum > 0) {
page = pageNum; page = pageNum;
i++; // Пропускаем номер страницы i++;
continue; continue;
} }
} }
processedParts.push(parts[i]); processedParts.push(parts[i]);
} }
//console.log('🔄 Processed parts:', processedParts);
// Определяем, это новость или нет // Определяем, это новость или нет
const isNews = processedParts[0] === 'news'; const isNews = processedParts[0] === 'news';
//console.log('📰 isNews:', isNews);
// Для анализа убираем 'news' из начала если есть // Для анализа убираем 'news' из начала если есть
const partsWithoutNews = isNews ? processedParts.slice(1) : processedParts; const partsWithoutNews = isNews ? processedParts.slice(1) : processedParts;
const partsCount = partsWithoutNews.length; //console.log('✂️ Parts without news:', partsWithoutNews);
const partsCount = partsWithoutNews.length;
//console.log('🔢 Parts count:', partsCount);
// Домашняя страница
if (partsCount === 0) { if (partsCount === 0) {
return { return {
type: 'home', type: 'home',
@@ -45,42 +73,66 @@ export function detectPageType(uri: string): PageTypeInfo {
}; };
} }
// Одиночный пост // Проверяем, является ли последний сегмент постом (содержит ID)
if (partsCount === 1 || partsCount === 2) {
const lastPart = partsWithoutNews[partsWithoutNews.length - 1]; const lastPart = partsWithoutNews[partsWithoutNews.length - 1];
const match = lastPart.match(/-(\d+)$/); //console.log('🔚 Last part:', lastPart);
const match = lastPart.match(/-(\d+)$/);
//console.log('🎯 Post ID match:', match);
// Одиночный пост
if (match) { if (match) {
const id = parseInt(match[1]); const id = parseInt(match[1]);
if (id > 0) { if (id > 0) {
const slugWithoutId = lastPart.substring(0, lastPart.lastIndexOf('-')); const slugWithoutId = lastPart.substring(0, lastPart.lastIndexOf('-'));
//console.log('📄 Single post detected:', { id, slugWithoutId });
return { return {
type: 'single', type: 'single',
contentType: isNews ? 'news' : 'post', // Теперь правильно contentType: isNews ? 'news' : 'post',
categorySlug: partsCount === 2 ? partsWithoutNews[0] : undefined, categorySlug: partsCount === 2 ? partsWithoutNews[0] : undefined,
postSlug: slugWithoutId, postSlug: slugWithoutId,
postId: id, postId: id,
page, page,
uriParts: processedParts // Сохраняем исходные части uriParts: processedParts
}; };
} }
} }
// Проверяем, является ли первый сегмент существующей рубрикой
if (partsCount === 1) {
const potentialCategorySlug = partsWithoutNews[0];
//console.log('📁 Checking if category exists:', potentialCategorySlug);
// Ждем загрузки рубрик если нужно
if (!wpInfo.isLoaded()) {
//console.log('⏳ Waiting for categories to load...');
// В синхронной функции не можем ждать, поэтому проверяем позже
} }
// Рубрика const category = wpInfo.getCategoryBySlug(potentialCategorySlug);
if (partsCount === 1) { //console.log('🏷️ Category found:', category ? 'YES' : 'NO');
if (category) {
//console.log('📁 Archive detected (existing category):', potentialCategorySlug);
return { return {
type: 'archive', type: 'archive',
contentType: isNews ? 'news' : undefined, contentType: isNews ? 'news' : undefined,
categorySlug: partsWithoutNews[0], categorySlug: potentialCategorySlug,
page, page,
uriParts: processedParts uriParts: processedParts
}; };
} }
}
// Если это не рубрика - это обычная страница
const pageSlug = partsWithoutNews.join('/');
//console.log('📄 PAGE DETECTED with slug:', pageSlug);
return { return {
type: 'unknown', type: 'unknown',
pageSlug: pageSlug,
page, page,
uriParts: processedParts uriParts: processedParts
}; };

View File

@@ -4,58 +4,57 @@ import NewsSingle from '@components/NewsSingle.astro';
import ContentGrid from '@components/ContentGrid.astro'; 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 { getPageBySlug } from '@lib/api/pages';
import { getCategory } from '@lib/api/categories';
import { getCategory } from '@lib/api/categories'; //логика
import { wpInfo } from '@lib/wpInfo'; 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;
const pathname = Astro.url.pathname; const pathname = Astro.url.pathname;
const pageInfo = detectPageType(pathname); //определяем тип страницы
// Убеждаемся что рубрики загружены перед определением типа
let response;
let article = null;
let posts = null;
let result = null;
let category;
// Определяем категорию
if (!wpInfo.isLoaded()) { if (!wpInfo.isLoaded()) {
await wpInfo.fetchAllCategories(); await wpInfo.fetchAllCategories();
} }
const pageInfo = detectPageType(pathname);
let article = null;
let posts = null;
let result = null;
let category;
let page = null;
// Получаем категорию если есть
category = wpInfo.getCategoryBySlug(pageInfo.categorySlug); category = wpInfo.getCategoryBySlug(pageInfo.categorySlug);
let title = 'Профиль';
let title = 'Профиль'; //title page console.log(pageInfo);
if (pageInfo.type === 'single') { //одиночная статья
if (pageInfo.type === 'single') {
try { try {
article = await getProfileArticleById(pageInfo.postId); //получвем данные поста article = await getProfileArticleById(pageInfo.postId);
title=article.title title = article?.title || title;
} catch (error) { } catch (error) {
console.error('Error fetching node:', error); console.error('Error fetching node:', error);
} }
} else if (pageInfo.type === 'archive') { } else if (pageInfo.type === 'archive') {
result = await getPostsByCategory(pageInfo.categorySlug, 21);
result = await getPostsByCategory(pageInfo.categorySlug, 21); //получвем данные поста posts = result?.posts;
posts = result.posts; } else if (pageInfo.type === 'unknown' && pageInfo.pageSlug) {
try {
page = await getPageBySlug(pageInfo.pageSlug);
if (page) {
title = page.title;
}
} catch (error) {
console.error('Error fetching page:', error);
}
} }
// ISR кэширование
//Astro.response.headers.set(
// 'Cache-Control',
// 'public, s-maxage=3600, stale-while-revalidate=86400'
//);
--- ---
<ContentLayout <ContentLayout
@@ -64,23 +63,26 @@ if (pageInfo.type === 'single') { //одиночная статья
category={category} category={category}
> >
{/* Page (страница) */} {/* СТРАНИЦА */}
{pageInfo.type === 'unknown' && ( {pageInfo.type === 'unknown' && page && (
<div>✅ Это страница: {pageInfo.pageSlug}</div> <div class="article-wrapper">
<article class="news-single">
<h1>{page.title}</h1>
<div set:html={page.content} />
</article>
</div>
)} )}
{/* Single post */} {/* Single post */}
{pageInfo.type === 'single' && article && ( {pageInfo.type === 'single' && article && (
<NewsSingle post={article} pageInfo={pageInfo} /> <NewsSingle post={article} pageInfo={pageInfo} />
)} )}
{/* Category archive */} {/* Category archive */}
{pageInfo.type === 'archive' && posts && ( {pageInfo.type === 'archive' && posts && (
<ContentGrid <ContentGrid
items={posts} items={posts}
pageInfo={result.pageInfo} pageInfo={result?.pageInfo}
slug={pageInfo.categorySlug} slug={pageInfo.categorySlug}
showCount={false} showCount={false}
type='category' type='category'
@@ -89,7 +91,4 @@ if (pageInfo.type === 'single') { //одиночная статья
/> />
)} )}
</ContentLayout> </ContentLayout>