A reusable card component for displaying article information in feeds and lists.
src/components/ArticleCard.tsx
The ArticleCard component displays a preview of an article with author information, cover image, metadata, and interaction buttons. It includes hover effects and user profile previews.
interface ArticleCardProps {
id: string;
title: string;
handle: string;
excerpt: string;
coverImage?: string;
author: {
id: string;
name: string;
avatar: string;
username: string;
};
publishedAt: string;
readingTime: number;
}id: Unique article identifiertitle: Article titlehandle: URL-friendly article identifierexcerpt: Brief article summaryauthor: Author information objectpublishedAt: Publication date (ISO string)readingTime: Estimated reading time in minutes
coverImage: URL to article cover image
import ArticleCard from '@/components/ArticleCard';
function ArticleFeed() {
const articles = [
{
id: "1",
title: "Getting Started with React Hooks",
handle: "getting-started-react-hooks",
excerpt: "Learn the fundamentals of React Hooks and how to use them effectively in your applications.",
coverImage: "https://example.com/cover.jpg",
author: {
id: "user1",
name: "John Doe",
avatar: "https://example.com/avatar.jpg",
username: "johndoe"
},
publishedAt: "2024-01-15T10:00:00Z",
readingTime: 5
}
];
return (
<div className="space-y-4">
{articles.map(article => (
<ArticleCard key={article.id} {...article} />
))}
</div>
);
}- Author avatar with hover card preview
- Author name linked to profile
- Publication date (localized)
- Reading time estimate
- Article title with hover effects
- Excerpt with "Read more" link
- Optional cover image with aspect ratio 16:9
- Reactions: Emoji-based reactions (like, love, etc.)
- Bookmarking: Save article for later reading
- Authentication: Login prompt for unauthenticated users
- Mobile-optimized layout
- Smooth hover transitions
- Adaptive spacing and typography
useTranslation: For internationalizationuseSession: For user authentication stateuseLoginPopup: For authentication prompts
UserInformationCard: Author profile previewResourceReaction: Article reaction systemResourceBookmark: Bookmark functionalityHoverCard: Author info hover preview
The component uses Tailwind CSS classes for styling:
- Container:
flex flex-col p-4 sm:p-5 group - Author section: Flex layout with avatar and metadata
- Title:
text-lg font-boldwith hover effects - Cover image:
aspect-[16/9]with responsive sizing
The component supports multiple languages:
- Reading time text is localized
- Date formatting respects language preference
- All interactive elements use translated text
- Memoized URL: Article URL is memoized to prevent recalculation
- Optimized images: Uses Next.js Image component with proper sizing
- Hover delays: HoverCard has optimized delay for better UX
- Semantic HTML structure
- Proper alt text for images
- Keyboard navigation support
- Screen reader friendly markup
- Time elements with proper datetime attributes
- Article data passed as props
- User authentication checked via session
- Internationalization applied to dates/text
- User interactions handled through child components
- Navigation handled via Next.js Link components
function Homepage() {
return (
<div className="article-feed">
{articles.map(article => (
<ArticleCard key={article.id} {...article} />
))}
</div>
);
}function SearchResults({ results }: { results: Article[] }) {
return (
<div className="search-results">
{results.map(article => (
<ArticleCard key={article.id} {...article} />
))}
</div>
);
}function UserArticles({ userId }: { userId: string }) {
const { data: articles } = useUserArticles(userId);
return (
<div className="user-articles">
{articles?.map(article => (
<ArticleCard key={article.id} {...article} />
))}
</div>
);
}The component can be customized through:
- CSS classes for styling overrides
- Props for different data structures
- Child component replacement for different functionality
- UserInformationCard: Displays detailed user information
- ResourceReaction: Handles article reactions
- ResourceBookmark: Manages article bookmarking
- AppImage: Optimized image handling
- Data validation: Ensure all required props are provided
- Error handling: Handle missing images or data gracefully
- Performance: Use proper keys when rendering lists
- Accessibility: Provide meaningful alt text and ARIA labels
- Responsive: Test on various screen sizes