diff --git a/src/lib/api/authors.ts b/src/lib/api/authors.ts index 2abf81b..0785723 100644 --- a/src/lib/api/authors.ts +++ b/src/lib/api/authors.ts @@ -4,186 +4,96 @@ import { fetchGraphQL } from './graphql-client.js'; import { cache } from '@lib/cache/manager.js'; import { CACHE_TTL } from '@lib/cache/cache-ttl'; -export async function getPostsByCoauthorName(coauthorName, first = 14, after = null) { - // Создаем уникальный ключ для кэша - const cacheKey = `coauthor-posts-known:${coauthorName}:${first}:${after || 'first-page'}`; +// lib/api/authors.js +export async function getPostsByCoauthorLogin(coauthorLogin, perLoad = 14, after = null) { + const cacheKey = `coauthor-posts:${coauthorLogin}:${perLoad}:${after || 'first-page'}`; return await cache.wrap( cacheKey, async () => { - const query = ` - query GetPostsByCoauthorName($first: Int!, $after: String, $coauthorName: String!) { - # Информация об авторе - users(where: {search: $coauthorName}) { - nodes { - databaseId - name - nicename - email - avatar { - url - } - description - posts { - pageInfo { - total - } - } - } - } - - # Посты автора - contentNodes( - first: $first - after: $after - where: { - contentTypes: [PROFILE_ARTICLE, ANEW] - coauthorName: $coauthorName - orderby: { field: DATE, order: DESC } - } - ) { - pageInfo { - hasNextPage - endCursor - } - nodes { - __typename - id - databaseId - uri - date - - ... on NodeWithTitle { - title - } - - ... on NodeWithFeaturedImage { - featuredImage { - node { - sourceUrl(size: LARGE) - altText - } - } - } - - # Для кастомных типов - ... on ProfileArticle { - categories { - nodes { - name - slug - color - } - } - } + try { + const baseUrl = import.meta.env.WP_REST_BASE_URL?.replace(/\/$/, ''); - ... on ANew { - categories { - nodes { - name - slug - color - } - } - } - - ... on NodeWithAuthor { - author { - node { - name - avatar { - url - } - } - } - } - - # Coauthors для ProfileArticle - ... on ProfileArticle { - coauthors { - id - name - firstName - lastName - url - nicename - } - } - - # Coauthors для ANew - ... on ANew { - coauthors { - id - name - firstName - lastName - url - nicename - } - } - } + // Формируем URL + const url = `${baseUrl}/author/${coauthorLogin}/posts?per_page=${perLoad}${ + after ? `&cursor=${encodeURIComponent(after)}` : '' + }`; + + const response = await fetch(url); + + if (!response.ok) { + if (response.status === 404) { + return { posts: [], pageInfo: { hasNextPage: false, endCursor: null } }; } + throw new Error(`HTTP error: ${response.status}`); } - `; - - const data = await fetchGraphQL(query, { - first, - after, - coauthorName - }); - - // Находим автора (первый результат поиска) - const author = data.users?.nodes?.[0]; - - if (!author) { + + const data = await response.json(); + + // Преобразуем данные для компонента + const posts = (data.data || []).map(post => ({ + // ID и ссылки + databaseId: post.id, + uri: post.link, // компонент использует uri + + // Основные поля + title: post.title, + date: post.date, + + // Картинка - приводим к формату GraphQL + featuredImage: post.featured_image?.medium ? { + node: { + sourceUrl: post.featured_image.medium, + altText: post.title + } + } : null, + + // Категории - приводим к формату nodes + categories: { + nodes: (post.categories || []).map(cat => ({ + name: cat.name, + slug: cat.slug, + color: cat.color || null + })) + }, + + // Соавторы - компонент ожидает массив с name и nickname + coauthors: (post.coauthors || []).map(coauthor => ({ + name: coauthor.name, + nickname: coauthor.id, // id используем как nickname для ссылки + node: { + name: coauthor.name, + nickname: coauthor.id + } + })) + })); + return { - author: null, - posts: [], - pageInfo: { hasNextPage: false, endCursor: null }, - totalPosts: 0 + posts, + pageInfo: { + hasNextPage: data.pagination?.has_next || false, + endCursor: data.pagination?.next_cursor || null + } }; + + } catch (error) { + console.error(`❌ Error fetching author posts:`, error); + return { posts: [], pageInfo: { hasNextPage: false, endCursor: null } }; } - - // Обрабатываем посты - const posts = data.contentNodes?.nodes?.map(node => { - // Приводим coauthors к единому формату - if (node.coauthors) { - node.coauthors = node.coauthors.map(coauthor => ({ - id: coauthor.id, - nickname: coauthor.nickname, - name: coauthor.name || '', - firstName: coauthor.firstName || '', - lastName: coauthor.lastName || '', - url: coauthor.url || '' - })); - } - return node; - }) || []; - - return { - author: { - id: author.databaseId, - name: author.name, - login: author.nicename, - email: author.email, - avatar: author.avatar?.url, - description: author.description, - totalPosts: author.posts?.pageInfo?.total || posts.length - }, - posts, - pageInfo: data.contentNodes?.pageInfo || { - hasNextPage: false, - endCursor: null - }, - authorName: coauthorName - }; }, - { ttl: CACHE_TTL.POSTS } + { ttl: 3600 } ); } + + + + + + + // все посты автора -export async function getPostsByCoauthorLogin(login, first = 14, after = null) { +export async function getPostsByCoauthorLoginQL(login, first = 14, after = null) { // Создаем уникальный ключ для кэша const cacheKey = `coauthor-posts-by-login:${login}:${first}:${after || 'first-page'}`; diff --git a/src/pages/author/[slug]/index.astro b/src/pages/author/[slug]/index.astro index 75df7f8..ad62337 100644 --- a/src/pages/author/[slug]/index.astro +++ b/src/pages/author/[slug]/index.astro @@ -10,6 +10,7 @@ const { slug } = Astro.params; const author = await getAuthorData(slug); const data = await getPostsByCoauthorLogin(slug); +console.log(data); const posts = data.posts; // Если автор не найден - 404 @@ -27,6 +28,7 @@ const posts = data.posts; {author && (
{author.avatar && ( +
{author.name} - )} - -

{author.name}

- - {(author.firstName || author.lastName) && ( -

- {author.firstName} {author.lastName} -

- )} - - {author.bio && ( -
{author.bio}
- )} - - {author.social && Object.values(author.social).some(Boolean) && ( - )} + +
+ {(author.firstName || author.lastName) && ( +

+ {author.firstName} {author.lastName} +

+ )} + + {author.bio && ( +
{author.bio}
+ )} + + {author.social && Object.values(author.social).some(Boolean) && ( + + )} +
)} @@ -70,8 +73,83 @@ const posts = data.posts; slug={slug} showCount={false} type='author' - perLoad={11} + perLoad={5} /> + +