diff --git a/src/components/Content/MoreArticles.astro b/src/components/Content/MoreArticles.astro
new file mode 100644
index 0000000..df57864
--- /dev/null
+++ b/src/components/Content/MoreArticles.astro
@@ -0,0 +1,18 @@
+---
+import { getLatestPosts } from '@api/posts.js';
+import ContentGrid from '@components/ContentGrid.astro';
+
+const { posts, pageInfo } = await getLatestPosts(11);
+
+---
+
+
+
+
+
diff --git a/src/components/Content/RelatedPosts.astro b/src/components/Content/RelatedPosts.astro
new file mode 100644
index 0000000..31d2767
--- /dev/null
+++ b/src/components/Content/RelatedPosts.astro
@@ -0,0 +1,41 @@
+---
+// RelatedPosts.astro
+import { getRelatedPosts } from '@api/posts.js';
+
+const relatedPosts = await getRelatedPosts();
+const hasPosts = relatedPosts && relatedPosts.length > 0;
+---
+
+{
+ hasPosts && (
+
+ )
+}
\ No newline at end of file
diff --git a/src/components/NewsSingle.astro b/src/components/NewsSingle.astro
index 122097c..d50f8f6 100644
--- a/src/components/NewsSingle.astro
+++ b/src/components/NewsSingle.astro
@@ -4,6 +4,8 @@ import Author from '@components/AuthorDisplay.astro';
import Subscribe from '@components/SubscribePost.astro';
import ShareButtons from '@components/ShareButtons.astro';
import EmbeddedPost from '@components/EmbeddedPost.astro'; // шаблоны ссылок на статьи
+import RelatedPosts from '@components/Content/RelatedPosts.astro';
+import MoreArticles from '@components/Content/MoreArticles.astro';
@@ -73,6 +75,8 @@ const { post, pageInfo } = Astro.props;
Новость не найдена
)}
+
+
{/* Блок с тегами */}
{post.tags?.nodes && post.tags.nodes.length > 0 && (
@@ -91,3 +95,5 @@ const { post, pageInfo } = Astro.props;
)}
+
+
\ No newline at end of file
diff --git a/src/lib/api/posts.ts b/src/lib/api/posts.ts
index 55548a5..dc444db 100644
--- a/src/lib/api/posts.ts
+++ b/src/lib/api/posts.ts
@@ -244,6 +244,50 @@ export async function getPostsByCategory(slug, first = 14, after = null) {
);
}
+export async function getRelatedPosts() {
+
+ const cacheKey = 'related-posts-widget';
+
+ return await cache.wrap(
+ cacheKey,
+ async () => {
+ const query = `
+ query GetRelatedPosts {
+ profileArticles(
+ first: 3
+ where: { orderby: { field: DATE, order: DESC } }
+ ) {
+ nodes {
+ title
+ uri
+ featuredImage {
+ node {
+ sourceUrl(size: THUMBNAIL) # THUMBNAIL для компактности
+ altText
+ }
+ }
+ }
+ }
+ }
+ `;
+
+ const data = await fetchGraphQL(query);
+
+ // Форматируем данные для удобного использования
+ const posts = data.profileArticles?.nodes?.map(post => ({
+ title: post.title,
+ // Убираем домен из URL, оставляем только путь
+ url: post.uri.replace(/^https?:\/\/[^\/]+/, ''),
+ image: post.featuredImage?.node?.sourceUrl || null,
+ imageAlt: post.featuredImage?.node?.altText || post.title
+ })) || [];
+
+ return posts;
+ },
+ { ttl: CACHE_TTL.POSTS } // Кэш на 1 час, так как это виджет
+ );
+}
+
export async function getPostsByTag(slug, first = 14, after = null) {
// Создаем уникальный ключ для кэша
diff --git a/src/styles/components/RelatedPosts.css b/src/styles/components/RelatedPosts.css
new file mode 100644
index 0000000..616db76
--- /dev/null
+++ b/src/styles/components/RelatedPosts.css
@@ -0,0 +1,152 @@
+ /* Сброс отступов для контейнера */
+ .related-posts {
+ padding: 40px 0;
+ margin: 0;
+ width: 100%;
+ }
+
+ .related-container {
+ width: 100%;
+ }
+
+ /* Хедер с серым фоном и черной рамкой */
+ .related-posts__header {
+ background-color: #f5f5f5;
+ border-top: 4px solid #000;
+ padding: 15px 0 15px 15px;
+ margin-bottom: 20px;
+ }
+
+ /* Заголовок */
+ .related-posts__title {
+ font-size: 1rem;
+ font-weight: bold;
+ margin: 0;
+ color: #333;
+ text-transform: uppercase;
+ letter-spacing: 1px;
+ }
+
+ /* Flex контейнер - строго 3 колонки на десктопе */
+ .related-posts__flex {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 30px;
+ }
+
+ /* Карточка поста - строго 3 в ряд на всех десктопах */
+ .related-post {
+ text-decoration: none;
+ color: inherit;
+ display: flex;
+ flex-direction: column;
+ transition: transform 0.2s ease;
+ background-color: transparent;
+ flex: 0 1 calc(33.333% - 20px); /* Изменил с 1 1 на 0 1 */
+ min-width: 0; /* Сбрасываем min-width для десктопа */
+ }
+
+ .related-post:hover {
+ transform: translateY(-4px);
+ }
+
+ /* Контейнер для изображения */
+ .related-post__image-wrapper {
+ position: relative;
+ width: 100%;
+ padding-bottom: 66.67%; /* Соотношение сторон 3:2 */
+ background-color: #e0e0e0;
+ border-radius: 8px;
+ overflow: hidden;
+ margin-bottom: 15px;
+ }
+
+ .related-post__image {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ object-fit: cover;
+ }
+
+ /* Плейсхолдер если нет изображения */
+ .related-post__image-wrapper--placeholder {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: #999;
+ font-size: 14px;
+ }
+
+ /* Заголовок поста */
+ .related-post__title {
+ font-size: 16px;
+ line-height: 1.4;
+ margin: 0;
+ color: #333;
+ font-weight: 500;
+ }
+
+ .related-post:hover .related-post__title {
+ color: #0066cc;
+ }
+
+ /* ТОЛЬКО для мобильных - один в ряд */
+ @media (max-width: 768px) {
+ .related-posts {
+ padding: 30px 0;
+ }
+
+ .related-posts__header {
+ padding: 12px 0;
+ margin-bottom: 20px;
+ }
+
+ .related-posts__title {
+ font-size: 20px;
+ }
+
+ .related-posts__flex {
+ gap: 20px;
+ }
+
+ .related-post {
+ flex: 1 1 100%; /* На мобильных полная ширина */
+ flex-direction: row;
+ align-items: center;
+ gap: 15px;
+ }
+
+ .related-post__image-wrapper {
+ width: 100px;
+ padding-bottom: 75px;
+ margin-bottom: 0;
+ flex-shrink: 0;
+ }
+
+ .related-post__title {
+ font-size: 15px;
+ flex: 1;
+ }
+ }
+
+ /* Очень маленькие экраны */
+ @media (max-width: 480px) {
+ .related-posts__header {
+ padding: 10px 0;
+ }
+
+ .related-posts__title {
+ font-size: 18px;
+ }
+
+ .related-post__image-wrapper {
+ width: 80px;
+ padding-bottom: 60px;
+ }
+
+ .related-post__title {
+ font-size: 14px;
+ }
+ }
\ No newline at end of file
diff --git a/src/styles/global.css b/src/styles/global.css
index 6ac2258..52de374 100644
--- a/src/styles/global.css
+++ b/src/styles/global.css
@@ -5,6 +5,7 @@
@import './embedded-content.css';
@import './components/ContentGrid.css';
@import './components/theme-colors.css';
+@import './components/RelatedPosts.css';
html{