"use client"
import { Badge } from "@/components/ui/badge";
import { Avatar, AvatarFallback } from "@/components/ui/avatar";
import { gql, useQuery } from "@apollo/client";
import Link from "next/link";
import { formatDistanceToNow } from "date-fns";
const BLOG = gql`
query Blog {
blogs(filter: {
isActive: true
status: "published"
},
sort: {
field: "createdAt"
direction: "DESC"
}
) {
items {
id
title
excerpt
slug
createdAt
createdBy
categoryId
featuredImage
}
}
}
`
const INFO = gql`
query Info($tagId: String!, $categoryId: String!, $authorId: String!) {
blogTag(id: $tagId) {
name
slug
color
}
blogCategory(id: $categoryId) {
name
slug
}
userWithGroups(id: $authorId) {
user {
username
}
}
}
`
export default function Blog() {
const { data, loading, error } = useQuery(BLOG);
const items = data?.blogs?.items || [];
if (loading) {
return (
);
}
if (error) {
return (
);
}
return (
Latest articles
{items.length === 0 ? (
No articles found
) : (
{items.map((blog: any, index: number) => (
))}
)}
);
}
interface BlogItemProps {
blog: {
id: string;
title: string;
excerpt: string;
slug: string;
createdAt: string;
createdBy: string;
categoryId: string;
featuredImage?: string;
};
featured?: boolean;
}
function BlogItem({ blog, featured = false }: BlogItemProps) {
const timeAgo = formatDistanceToNow(new Date(blog.createdAt), { addSuffix: true });
// 使用 INFO 查询获取详细信息
const { data: infoData, loading: infoLoading } = useQuery(INFO, {
variables: {
tagId: blog.categoryId || "",
categoryId: blog.categoryId,
authorId: blog.createdBy
},
skip: !blog.categoryId || !blog.createdBy,
});
const category = infoData?.blogCategory;
const author = infoData?.userWithGroups?.user;
const tag = infoData?.blogTag;
return (
{/* Featured Image */}
{blog.featuredImage ? (

) : (
No image
)}
{/* Meta Information */}
{category?.name || tag?.name || 'Article'}
By
{author?.username?.charAt(0)?.toUpperCase() || 'A'}
{infoLoading ? 'Loading...' : (author?.username || 'Anonymous')}
•
{timeAgo}
{/* Content */}
{blog.title}
{blog.excerpt || 'No excerpt available...'}
);
}