diff --git a/src/components/AuthorDisplay.astro b/src/components/AuthorDisplay.astro new file mode 100644 index 0000000..72c5ad8 --- /dev/null +++ b/src/components/AuthorDisplay.astro @@ -0,0 +1,29 @@ +--- +// src/components/DisplayAuthor.astro + +const { post } = Astro.props; + +// Ваша логика, адаптированная для компонента +let authorDisplay = ''; + +if (post?.coauthors && post.coauthors.length > 0) { + authorDisplay = post.coauthors.map(author => { + if (author.firstName && author.lastName) { + return `${author.firstName} ${author.lastName}`; + } + return `${author.name}`; + }).join(' '); +} else if (post?.author?.node) { + const author = post.author.node; + const name = author.firstName && author.lastName + ? `${author.firstName} ${author.lastName}` + : author.name; + authorDisplay = `${name}`; +} +--- + +{authorDisplay ? ( + +) : ( + Автор не указан +)} \ No newline at end of file diff --git a/src/components/ColonPost.astro b/src/components/ColonPost.astro new file mode 100644 index 0000000..715e286 --- /dev/null +++ b/src/components/ColonPost.astro @@ -0,0 +1,185 @@ +--- +import { getLatestColonPost } from '@lib/api/colon-posts'; +import Author from '@components/AuthorDisplay.astro'; + +const colonPost = await getLatestColonPost(); + +--- + +{colonPost && ( +
+
+
+ {colonPost.featuredImage?.node?.sourceUrl && ( + + {colonPost.featuredImage.node.altText + + )} + + +
+ +
+ +

{colonPost.secondaryTitle || colonPost.title}

+
+
+
+
+)} + diff --git a/src/components/ContentGrid.astro b/src/components/ContentGrid.astro index 84fe33b..bc02cd4 100644 --- a/src/components/ContentGrid.astro +++ b/src/components/ContentGrid.astro @@ -1,4 +1,7 @@ --- + + + export interface Props { items: any[]; showCount?: boolean; diff --git a/src/components/MainPostWidget.astro b/src/components/MainPostWidget.astro index 4d59c7c..5b71faf 100644 --- a/src/components/MainPostWidget.astro +++ b/src/components/MainPostWidget.astro @@ -1,95 +1,191 @@ --- // src/components/MainPostWidget.astro import { getLatestMainPost } from '@lib/api/main-posts'; +import Author from '@components/AuthorDisplay.astro'; const mainPost = await getLatestMainPost(); -const postDate = mainPost ? new Date(mainPost.date) : null; +if (!mainPost) return null; + +const postDate = new Date(mainPost.date); const imageUrl = mainPost?.featuredImage?.node?.sourceUrl; const imageAlt = mainPost?.featuredImage?.node?.altText || mainPost?.title || ''; +const isoDate = postDate.toISOString(); const category = mainPost?.categories?.nodes?.[0]; const categoryName = category?.name || ''; -const categoryColor = category?.color || '#2271b1'; // цвет по умолчанию +const categoryColor = category?.color || '#2271b1'; + +const formattedDate = postDate.toLocaleDateString('ru-RU', { + day: 'numeric', + month: 'short', + year: 'numeric' +}).replace(' г.', ''); -let authorName = ''; -if (mainPost?.coauthors && mainPost.coauthors.length > 0) { - authorName = mainPost.coauthors.map(author => { - if (author.firstName && author.lastName) { - return `${author.firstName} ${author.lastName}`; - } - return author.name; - }).join(', '); -} else if (mainPost?.author) { - const author = mainPost.author.node; - authorName = author.firstName && author.lastName - ? `${author.firstName} ${author.lastName}` - : author.name; -} --- -{mainPost && ( -
- -
- {imageUrl ? ( - {imageAlt} - ) : ( -
- )} - - {categoryName && ( - - )} - -
- - -

- {mainPost.title} -

- - {authorName && ( - - )} +
-)} + + + + + {authorName && } + {categoryName && } +
+ + \ No newline at end of file diff --git a/src/lib/api/colon-posts.ts b/src/lib/api/colon-posts.ts index 084e1b3..21cc6bf 100644 --- a/src/lib/api/colon-posts.ts +++ b/src/lib/api/colon-posts.ts @@ -10,6 +10,7 @@ export interface ColonPost { id: string; databaseId: number; title: string; + secondaryTitle: string; uri: string; date: string; colonItem: boolean; @@ -40,24 +41,7 @@ export interface ColonPost { url: string; description: string; }>; - categories: { - nodes: Array<{ - id: string; - name: string; - color?: string; - slug: string; - uri: string; - databaseId: number; - }>; - }; - tags: { - nodes: Array<{ - id: string; - name: string; - slug: string; - uri: string; - }>; - }; + } /** @@ -77,6 +61,7 @@ const LATEST_COLON_POST_QUERY = ` id databaseId title + secondaryTitle uri date colonItem @@ -107,24 +92,6 @@ const LATEST_COLON_POST_QUERY = ` url description } - categories { - nodes { - id - name - color - slug - uri - databaseId - } - } - tags { - nodes { - id - name - slug - uri - } - } } } } diff --git a/src/pages/index.astro b/src/pages/index.astro index 462d21c..adaf1e9 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,17 +1,20 @@ --- import { getSiteInfo } from "../lib/wp-api.js"; import { getLatestPosts } from '@api/posts.js'; -import { getLatestColonPost } from '@lib/api/colon-posts'; + + +import '../styles/home.css'; const site = await getSiteInfo(); const { posts, pageInfo } = await getLatestPosts(41); // Сразу деструктурируем -const colonPost = await getLatestColonPost(); //последний пост колонки + // визуальные компоненты import MainLayout from '@layouts/MainLayout.astro'; import ContentGrid from '@components/ContentGrid.astro'; import EndnewsList from '@components/EndnewsList.astro'; -import MainPostWidget from '@/components/MainPostWidget.astro'; +import MainLine from '@components/MainLine.astro'; + //ISR @@ -22,27 +25,20 @@ export const prerender = false; title={site.title} description="Информационное агентство Деловой журнал Профиль" > -

{site.title}

+

{site.title}

mainline_1 {site.description &&

{site.description}

} + + - + - {colonPost && ( -
-

{colonPost.title}

- Читать колонку -
-)} - -
- -
- - +/> + + diff --git a/src/styles/global.css b/src/styles/global.css index 83c620c..bb346ef 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -48,11 +48,6 @@ a { } -.maimnewsline{ - display: flex; -} - - @media (max-width: 767px) { diff --git a/src/styles/home.css b/src/styles/home.css new file mode 100644 index 0000000..d3b57b1 --- /dev/null +++ b/src/styles/home.css @@ -0,0 +1,56 @@ +/* Убедитесь, что эти стили применяются! */ +.mainline_1 { + display: flex; + gap: 20px; + max-width: 1400px; + margin: 0 auto; + padding: 0 20px; +} + +/* Левая колонка */ +.endnews-container { + flex: 0 0 264px; + width: 264px; +} + +/* Центральная колонка */ +.colons { + flex: 1; + min-width: 0; + display: flex; + flex-direction: column; + gap: 20px; + align-items: center; /* Центрируем содержимое */ +} + +/* Ограничиваем ширину MainPostWidget внутри .colons */ +.colons > * { + max-width: 800px; + width: 100%; +} + +/* Правая колонка */ +.main-partners { + flex: 0 0 300px; + width: 300px; +} + +/* Адаптивность */ +@media (max-width: 1023px) { + .mainline_1 { + flex-direction: column; + padding: 0 15px; + } + + .endnews-container, + .colons, + .main-partners { + flex: none; + width: 100%; + max-width: 100%; + } + + .colons > * { + max-width: 100%; + } +} \ No newline at end of file diff --git a/src/utils/author.ts b/src/utils/author.ts new file mode 100644 index 0000000..14d629e --- /dev/null +++ b/src/utils/author.ts @@ -0,0 +1,136 @@ +// src/utils/author.ts + +export interface Author { + id?: string; + slug?: string; + firstName?: string; + lastName?: string; + name?: string; + // Добавляем URL или slug для страницы автора + uri?: string; + url?: string; +} + +export interface Coauthor extends Author { + // дополнительные поля, если есть +} + +export interface PostData { + author?: { + node: Author; + }; + coauthors?: Coauthor[]; + // другие поля поста +} + +// Интерфейс для результата +export interface AuthorInfo { + name: string; + url: string; + id?: string; + slug?: string; +} + +export interface MultipleAuthorsResult { + type: 'single' | 'multiple'; + authors: AuthorInfo[]; +} + +// Функция для получения информации об авторе(ах) +export function getAuthorInfo(post?: PostData | null): MultipleAuthorsResult { + if (!post) { + return { + type: 'single', + authors: [{ name: '', url: '' }] + }; + } + + // Обработка соавторов + if (post.coauthors && post.coauthors.length > 0) { + const authors = post.coauthors.map(author => ({ + name: author.firstName && author.lastName + ? `${author.firstName} ${author.lastName}` + : author.name || '', + url: getAuthorUrl(author), + id: author.id, + slug: author.slug + })).filter(author => author.name); // Убираем пустые имена + + return { + type: authors.length > 1 ? 'multiple' : 'single', + authors + }; + } + + // Обработка основного автора + if (post.author?.node) { + const author = post.author.node; + const authorInfo = { + name: author.firstName && author.lastName + ? `${author.firstName} ${author.lastName}` + : author.name || '', + url: getAuthorUrl(author), + id: author.id, + slug: author.slug + }; + + return { + type: 'single', + authors: [authorInfo] + }; + } + + return { + type: 'single', + authors: [{ name: '', url: '' }] + }; +} + +// Вспомогательная функция для формирования URL +function getAuthorUrl(author: Author): string { + // Приоритеты формирования URL: + // 1. Готовый URL + // 2. URI (часто из WordPress) + // 3. Slug + // 4. ID + // 5. Имя в формате slug + + if (author.url) return author.url; + if (author.uri) return author.uri; + if (author.slug) return `/author/${author.slug}/`; + if (author.id) return `/author/${author.id}/`; + + // Формируем slug из имени + const name = author.firstName && author.lastName + ? `${author.firstName}-${author.lastName}` + : author.name || 'author'; + + return `/author/${slugify(name)}/`; +} + +// Функция для slugify (можно вынести в отдельную утилиту) +function slugify(text: string): string { + return text + .toLowerCase() + .replace(/[^\w\s-]/g, '') // Удаляем спецсимволы + .replace(/\s+/g, '-') // Заменяем пробелы на дефисы + .replace(/--+/g, '-') // Убираем двойные дефисы + .trim(); +} + +// Сохраняем старую функцию для обратной совместимости +export function getAuthorName(post?: PostData | null): string { + const info = getAuthorInfo(post); + + if (info.authors.length === 0) return ''; + if (info.authors.length === 1) return info.authors[0].name; + + // Для нескольких авторов + return info.authors.map(a => a.name).join(', '); +} + +// Новая функция для получения URL первого автора +export function getAuthorUrlFromPost(post?: PostData | null): string { + const info = getAuthorInfo(post); + return info.authors[0]?.url || ''; +} \ No newline at end of file