Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added src/assets/1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/mountain.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
144 changes: 107 additions & 37 deletions src/pages/Blog/BlogContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,68 +6,119 @@ import {

import MaxWidthWrapper from '@/components/MaxWidthWrapper';

interface Blog {
export interface Tag {
id: number;
name: string;
slug: string;
}

export interface Blog {
id: number;
title: string;
excerpt: string;
slug: string;
cover_image: string;
content: string;
date: string;
author: string;
category: string;
image: string;
readTime: string;
author_name: string;
tags: Tag[];
reading_time: number;
published_at: string;
status: string;
created_at: string;
updated_at: string;
}

interface BlogContentProps {
selectedCategory: string;
blogs: Blog[];
}

// Helper function to format date
const formatDate = (dateString: string) => new Date(dateString).toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric',
});

// Helper function to strip HTML and create excerpt
const createExcerpt = (htmlContent: string, maxLength: number = 150) => {
const tempDiv = document.createElement('div');
tempDiv.innerHTML = htmlContent;
const textContent = tempDiv.textContent || tempDiv.innerText || '';
return textContent.length > maxLength
? `${textContent.substring(0, maxLength)}...`
: textContent;
};

function BlogContent(props: BlogContentProps) {
const {
selectedCategory, blogs,
} = props;
const { selectedCategory, blogs } = props;

if (!blogs || blogs.length === 0) {
return (
<section className="py-16 bg-white">
<MaxWidthWrapper>
<div className="text-center">
<p className="text-gray-600">No blog posts available.</p>
</div>
</MaxWidthWrapper>
</section>
);
}

return (
<section className="py-16 bg-white">
<MaxWidthWrapper>
{/* Featured Post */}

<div className="mb-16">
<div className="bg-white rounded-lg shadow-lg overflow-hidden">
<div className="md:flex">
<div className="md:w-1/2">
<img
src={blogs[0].image}
src={blogs[0].cover_image}
alt={blogs[0].title}
className="w-full h-64 md:h-full object-cover"
/>
</div>
<div className="md:w-1/2 p-8">
<div className="flex items-center text-sm text-gray-500 mb-4">
<span className="bg-primary text-white px-3 py-1 rounded-full mr-4">
{blogs[0].category}
</span>
<Calendar className="h-4 w-4 mr-2" />
{blogs[0].date}
<div className="flex items-center flex-wrap text-sm text-gray-500 mb-4">
<div className="flex flex-wrap gap-2 mr-4 mb-2">
{blogs[0].tags.map((tag) => (
<span
key={tag.id}
className="bg-primary text-white px-3 py-1 rounded-full text-xs"
>
{tag.name}
</span>
))}
</div>
<div className="flex items-center mb-2">
<Calendar className="h-4 w-4 mr-2" />
{formatDate(blogs[0].published_at)}
</div>
</div>
<h2 className="text-2xl md:text-3xl font-bold text-gray-900 mb-4">
{blogs[0].title}
</h2>
<p className="text-gray-600 mb-6 text-lg">
{blogs[0].excerpt}
{createExcerpt(blogs[0].content, 200)}
</p>
<div className="flex items-center justify-between">
<div className="flex items-center">
<Users className="h-4 w-4 mr-2 text-gray-400" />
<span className="text-gray-600">{blogs[0].author}</span>
<span className="text-gray-600">{blogs[0].author_name}</span>
</div>
<div className="flex items-center gap-4">
<span className="text-sm text-gray-500">
{blogs[0].reading_time}
{' '}
min read
</span>
<Link
to={`/blog/${blogs[0].id}`}
className="bg-primary hover:brightness-90 text-white px-6 py-2 rounded-lg font-medium transition-colors"
>
Read More
</Link>
</div>
<Link
to={`/blog/${blogs[0].id}`}
className="bg-primary hover:brightness-90 text-white px-6 py-2 rounded-lg font-medium transition-colors"
>
Read More
</Link>
</div>
</div>
</div>
Expand All @@ -79,31 +130,50 @@ function BlogContent(props: BlogContentProps) {
{blogs.slice(selectedCategory === 'All' ? 1 : 0).map((blog) => (
<article key={blog.id} className="bg-white rounded-lg shadow-md overflow-hidden hover:shadow-lg transition-shadow">
<img
src={blog.image}
src={blog.cover_image}
alt={blog.title}
className="w-full h-48 object-cover"
/>
<div className="p-6">
<div className="flex items-center text-sm text-gray-500 mb-3">
<span className="bg-primary text-white px-2 py-1 rounded mr-3 text-xs">
{blog.category}
</span>
<Calendar className="h-3 w-3 mr-1" />
{blog.date}
<div className="flex items-center flex-wrap text-sm text-gray-500 mb-3">
<div className="flex flex-wrap gap-1 mr-3 mb-1">
{blog.tags.slice(0, 2).map((tag) => (
<span
key={tag.id}
className="bg-primary text-white px-2 py-1 rounded text-xs"
>
{tag.name}
</span>
))}
{blog.tags.length > 2 && (
<span className="text-xs text-gray-400">
+
{blog.tags.length - 2}
</span>
)}
</div>
<div className="flex items-center mb-1">
<Calendar className="h-3 w-3 mr-1" />
{formatDate(blog.published_at)}
</div>
</div>
<h3 className="text-xl font-semibold text-gray-900 mb-3 line-clamp-2">
{blog.title}
</h3>
<p className="text-gray-600 mb-4 line-clamp-3">
{blog.excerpt}
{createExcerpt(blog.content)}
</p>
<div className="flex items-center justify-between">
<div className="flex items-center text-sm text-gray-500">
<Users className="h-3 w-3 mr-1" />
{blog.author}
{blog.author_name}
</div>
<div className="flex items-center">
<span className="text-xs text-gray-500 mr-3">{blog.readTime}</span>
<div className="flex items-center gap-3">
<span className="text-xs text-gray-500">
{blog.reading_time}
{' '}
min read
</span>
<Link
to={`/blog/${blog.id}`}
className="text-primary hover:brightness-90 font-medium text-sm"
Expand Down
Loading
Loading