diff --git a/src/components/ContentGrid.astro b/src/components/ContentGrid.astro
index f9d50f0..84fe33b 100644
--- a/src/components/ContentGrid.astro
+++ b/src/components/ContentGrid.astro
@@ -2,14 +2,24 @@
export interface Props {
items: any[];
showCount?: boolean;
+ pageInfo?: {
+ hasNextPage: boolean;
+ endCursor: string | null;
+ };
+ loadMoreConfig?: {
+ type: 'latest' | 'category' | 'author' | 'tag';
+ slug?: string;
+ first?: number;
+ };
}
const {
items = [],
showCount = false,
+ pageInfo = { hasNextPage: false, endCursor: null },
+ loadMoreConfig = { type: 'latest', first: 11 }
} = Astro.props;
-// Функция для извлечения класса цвета из строки
function extractColorClass(colorString: string): string {
if (!colorString) return 'bg-blue';
@@ -44,7 +54,6 @@ function extractColorClass(colorString: string): string {
}
}
-// Функция для получения списка имен соавторов
function getCoauthorsNames(coauthors: any[]): string {
if (!coauthors || coauthors.length === 0) return '';
@@ -53,6 +62,14 @@ function getCoauthorsNames(coauthors: any[]): string {
.filter(Boolean)
.join(' ');
}
+
+// ✅ ИСПРАВЛЕННАЯ функция для определения больших карточек
+// Большие карточки на индексах: 8, 19, 30, 41, 52...
+// Формула: (index - 8) % 11 === 0
+function shouldBeLarge(index: number): boolean {
+ if (index < 8) return false;
+ return (index - 8) % 11 === 0;
+}
---
@@ -72,25 +89,14 @@ function getCoauthorsNames(coauthors: any[]): string {
const rawColor = item.categories?.nodes?.[0]?.color || '';
const categoryBgClass = extractColorClass(rawColor);
- let isLarge = false;
- let largePosition = '';
-
- const rowNumber = Math.floor(index / 4) + 1;
- const positionInRow = index % 4;
-
- if (index >= 8) {
- const largeRowStart = (rowNumber - 3) % 3 === 0 && rowNumber >= 3;
-
- if (largeRowStart && positionInRow === 0) {
- isLarge = true;
- largePosition = 'first';
- }
- }
+ // ✅ ИСПРАВЛЕННАЯ логика
+ const isLarge = shouldBeLarge(index);
+ const largePosition = isLarge ? 'first' : '';
return (
+
+
+
+
+
+
+ Все статьи загружены
+
+
+
+ {pageInfo.hasNextPage && (
+
+ )}
+
+
diff --git a/src/pages/api/posts.ts b/src/pages/api/posts.ts
new file mode 100644
index 0000000..e511543
--- /dev/null
+++ b/src/pages/api/posts.ts
@@ -0,0 +1,78 @@
+import type { APIRoute } from 'astro';
+
+// ✅ Добавьте эту строку!
+export const prerender = false;
+
+export const POST: APIRoute = async ({ request }) => {
+ console.log('[API] Request received');
+ console.log('[API] Content-Type:', request.headers.get('content-type'));
+
+ try {
+ // ✅ Используйте request.text() вместо request.json()
+ const rawBody = await request.text();
+ console.log('[API] Raw body length:', rawBody?.length || 0);
+ console.log('[API] Raw body:', rawBody);
+
+ if (!rawBody || rawBody.trim() === '') {
+ throw new Error('Request body is empty');
+ }
+
+ const body = JSON.parse(rawBody);
+ console.log('[API] Parsed body:', body);
+
+ const {
+ first = 14,
+ after = null,
+ type = 'latest',
+ slug = null
+ } = body;
+
+ console.log('[API] Parsed params:', { first, after, type, slug });
+
+ // ✅ Используйте относительный путь, НЕ алиас @api
+ const { getLatestPosts } = await import('../../lib/api/posts.js');
+
+ console.log('[API] Calling getLatestPosts with:', { first, after });
+
+ const data = await getLatestPosts(first, after);
+
+ console.log('[API] Data received:', {
+ postsCount: data?.posts?.length || 0,
+ hasNextPage: data?.pageInfo?.hasNextPage,
+ endCursor: data?.pageInfo?.endCursor
+ });
+
+ if (!data || !data.posts) {
+ throw new Error('Invalid data structure returned from getLatestPosts');
+ }
+
+ return new Response(JSON.stringify(data), {
+ status: 200,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ });
+
+ } catch (error) {
+ console.error('[API] Error details:', {
+ message: error.message,
+ stack: error.stack,
+ name: error.name
+ });
+
+ return new Response(
+ JSON.stringify({
+ error: error.message || 'Ошибка загрузки постов',
+ details: process.env.NODE_ENV === 'development' ? error.stack : undefined,
+ posts: [],
+ pageInfo: { hasNextPage: false, endCursor: null }
+ }),
+ {
+ status: 500,
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ }
+ );
+ }
+};
diff --git a/src/pages/index.astro b/src/pages/index.astro
index 6e31374..dbb4601 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -3,17 +3,15 @@ import { getSiteInfo } from "../lib/wp-api.js";
import { getLatestPosts } from '@api/posts.js';
const site = await getSiteInfo();
-const initialPosts = await getLatestPosts(37); // Начальная загрузка 12 постов
+const { posts, pageInfo } = await getLatestPosts(41); // Сразу деструктурируем
// визуальные компоненты
import MainLayout from '@layouts/MainLayout.astro';
import ContentGrid from '@components/ContentGrid.astro';
import EndnewsList from '@components/EndnewsList.astro';
-
//ISR
export const prerender = false;
-//export const revalidate = 1;
---
-
-
+
-
-
\ No newline at end of file
+
diff --git a/src/styles/components/ContentGrid.css b/src/styles/components/ContentGrid.css
index a5cee93..ca49317 100644
--- a/src/styles/components/ContentGrid.css
+++ b/src/styles/components/ContentGrid.css
@@ -167,6 +167,34 @@
font-weight: 400;
}
+/* Убедитесь что индикаторы не занимают лишнее место */
+#infinity-scroll-sentinel {
+ height: 1px;
+ width: 100%;
+ visibility: hidden;
+ pointer-events: none;
+}
+
+.loading-indicator {
+ text-align: center;
+ padding: 40px 0;
+ color: #666;
+ min-height: auto; /* ← Важно! */
+}
+
+.no-more-posts {
+ text-align: center;
+ padding: 30px 0;
+ color: #666;
+ font-size: 16px;
+ border-top: 1px solid #eee;
+ margin-top: 20px;
+ min-height: auto; /* ← Важно! */
+}
+
+
+
+
/* Улучшения для больших карточек */
@media (min-width: 1200px) {
.post-card-large .post-category-badge {