351 lines
12 KiB
TypeScript
351 lines
12 KiB
TypeScript
'use client'
|
|
|
|
import { useState, useEffect, Suspense } from 'react'
|
|
import { useSearchParams } from 'next/navigation'
|
|
import ModalVideo from 'react-modal-video'
|
|
import "@/node_modules/react-modal-video/css/modal-video.css"
|
|
import Countdown from '@/components/elements/Countdown'
|
|
import Layout from "@/components/layout/Layout"
|
|
import Link from "next/link"
|
|
import axios from 'axios'
|
|
|
|
interface BlogItem {
|
|
id: number;
|
|
title: string;
|
|
slug: string;
|
|
image: string;
|
|
description: string;
|
|
author: string;
|
|
profile: string;
|
|
date: string;
|
|
}
|
|
|
|
function BlogSingleContent() {
|
|
const [isOpen, setOpen] = useState(false)
|
|
const searchParams = useSearchParams();
|
|
const currentSlug = searchParams ? searchParams.get('slug') : null;
|
|
|
|
const [blog, setBlog] = useState<BlogItem | null>(null);
|
|
const [recentBlogs, setRecentBlogs] = useState<BlogItem[]>([]);
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
useEffect(() => {
|
|
const fetchBlogDetails = async () => {
|
|
try {
|
|
setLoading(true);
|
|
const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:3006/api';
|
|
|
|
// Fetch other blogs for "Read More" section and fallback
|
|
const listRes = await axios.get(`${API_BASE_URL}/blogs`);
|
|
const allBlogs = listRes.data?.success ? listRes.data.data : [];
|
|
setRecentBlogs(allBlogs);
|
|
|
|
if (currentSlug) {
|
|
// Fetch current blog details by slug
|
|
const detailRes = await axios.get(`${API_BASE_URL}/blogs/slug/${currentSlug}`);
|
|
if (detailRes.data && detailRes.data.success) {
|
|
setBlog(detailRes.data.data);
|
|
}
|
|
} else {
|
|
// No slug provided, load the most recent blog
|
|
if (allBlogs.length > 0) {
|
|
setBlog(allBlogs[0]);
|
|
}
|
|
}
|
|
} catch (error) {
|
|
console.error("Error fetching blog details:", error);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
fetchBlogDetails();
|
|
}, [currentSlug]);
|
|
|
|
if (loading) {
|
|
return (
|
|
<Layout headerStyle={1} footerStyle={1}>
|
|
<div style={{ padding: '150px 0', textAlign: 'center' }}>
|
|
<div className="spinner-border text-danger" role="status">
|
|
<span className="visually-hidden">Loading...</span>
|
|
</div>
|
|
</div>
|
|
</Layout>
|
|
);
|
|
}
|
|
|
|
if (!blog) {
|
|
return (
|
|
<Layout headerStyle={1} footerStyle={1}>
|
|
<div style={{ padding: '150px 0', textAlign: 'center' }}>
|
|
<h2>Blog post not found</h2>
|
|
<div className="space20" />
|
|
<Link href="/blog" className="vl-btn3">
|
|
<span className="demo">Back to Blogs</span>
|
|
</Link>
|
|
</div>
|
|
</Layout>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<>
|
|
|
|
<Layout headerStyle={1} footerStyle={1}>
|
|
<div>
|
|
<div className="inner-page-header" style={{ backgroundImage: 'url(/assets/img/bg/header-bg14.png)' }}>
|
|
<div className="container">
|
|
<div className="row">
|
|
<div className="col-lg-12 m-auto">
|
|
<div className="heading1">
|
|
<h1>Blog Details</h1>
|
|
<div className="space20" />
|
|
<Link href="/">Home <i className="fa-solid fa-angle-right" /> <span>Blog Details</span></Link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{/*===== HERO AREA ENDS =======*/}
|
|
{/*===== BLOG AREA STARTS =======*/}
|
|
<div className="blog-details-section sp8">
|
|
<div className="container">
|
|
<div className="row">
|
|
<div className="col-lg-8">
|
|
<div className="blog-deatils-content heading2">
|
|
<div className="img1">
|
|
<img src={blog.image || "/assets/img/all-images/blog/blog-img7.png"} alt={blog.title} style={{ width: '100%', height: 'auto', maxHeight: '450px', objectFit: 'cover', borderRadius: '10px' }} />
|
|
</div>
|
|
<div className="space32" />
|
|
<ul>
|
|
<li>
|
|
<Link href="#"><img src="/assets/img/icons/calender1.svg" alt="" />{blog.date} <span> | </span></Link>
|
|
</li>
|
|
<li>
|
|
<Link href="#"><img src="/assets/img/icons/user1.svg" alt="" />{blog.author} <span> | </span></Link>
|
|
</li>
|
|
<li>
|
|
<Link href="#"><img src="/assets/img/icons/comments1.svg" alt="" />Comments Disabled</Link>
|
|
</li>
|
|
</ul>
|
|
<div className="space18" />
|
|
<h2>{blog.title}</h2>
|
|
<div className="space16" />
|
|
|
|
{/* Render rich text from Quill editor safely */}
|
|
<div className="blog-rich-text-content" dangerouslySetInnerHTML={{ __html: blog.description }} />
|
|
|
|
<div className="space48" />
|
|
<div className="tags-social-area">
|
|
<div className="tags">
|
|
<h4>Tags:</h4>
|
|
<ul>
|
|
<li><Link href="/#">#TamilCulture</Link></li>
|
|
<li><Link href="/#" className="m-0">#Community</Link></li>
|
|
</ul>
|
|
</div>
|
|
<div className="social">
|
|
<h4>Social:</h4>
|
|
<ul>
|
|
<li>
|
|
<Link href="/#"><i className="fa-brands fa-facebook-f" /></Link>
|
|
</li>
|
|
<li>
|
|
<Link href="/#"><i className="fa-brands fa-instagram" /></Link>
|
|
</li>
|
|
<li>
|
|
<Link href="/#" className="m-0"><i className="fa-brands fa-youtube" /></Link>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="col-lg-4">
|
|
<div className="space30 d-lg-none d-block" />
|
|
<div className="blog-auhtor-details">
|
|
<div className="search-area">
|
|
<h3>Search</h3>
|
|
<div className="space24" />
|
|
<form onSubmit={(e) => e.preventDefault()}>
|
|
<input type="text" placeholder="Search..." />
|
|
<button type="submit"><i className="fa-solid fa-magnifying-glass" /></button>
|
|
</form>
|
|
</div>
|
|
<div className="space32" />
|
|
<div className="blog-categories">
|
|
<h3>Blog Category</h3>
|
|
<div className="space12" />
|
|
<ul>
|
|
<li>
|
|
<Link href="/#">Business Innovation <span><i className="fa-solid fa-angle-right" /></span></Link>
|
|
</li>
|
|
<li>
|
|
<Link href="/#">Leadership & Strategy <span><i className="fa-solid fa-angle-right" /></span></Link>
|
|
</li>
|
|
<li>
|
|
<Link href="/#">Networking & Collaboration <span><i className="fa-solid fa-angle-right" /></span></Link>
|
|
</li>
|
|
<li>
|
|
<Link href="/#">Entrepreneurship Startups <span><i className="fa-solid fa-angle-right" /></span></Link>
|
|
</li>
|
|
<li>
|
|
<Link href="/#">Marketing & Branding <span><i className="fa-solid fa-angle-right" /></span></Link>
|
|
</li>
|
|
<li>
|
|
<Link href="/#">Event Highlights & Recaps <span><i className="fa-solid fa-angle-right" /></span></Link>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div className="space32" />
|
|
<div className="tags-area">
|
|
<h3>Popular Hashtag</h3>
|
|
<div className="space12" />
|
|
<ul>
|
|
<li><Link href="/#">#Conferences</Link></li>
|
|
<li><Link href="/#">#Meetup</Link></li>
|
|
<li><Link href="/#">#Event</Link></li>
|
|
</ul>
|
|
<ul>
|
|
<li><Link href="/#">#Eventify2024</Link></li>
|
|
<li><Link href="/#">#DigitalTransformation</Link></li>
|
|
</ul>
|
|
<ul>
|
|
<li><Link href="/#">#BusinessLeadership</Link></li>
|
|
<li><Link href="/#">#IndustryTrends</Link></li>
|
|
</ul>
|
|
</div>
|
|
<div className="space32" />
|
|
<div className="author-images-area">
|
|
<h3>Popular Author</h3>
|
|
<div className="space12" />
|
|
<ul>
|
|
<li><img src="/assets/img/all-images/blog/blog-img11.png" alt="" /></li>
|
|
<li><img src="/assets/img/all-images/blog/blog-img12.png" alt="" /></li>
|
|
<li><img src="/assets/img/all-images/blog/blog-img13.png" alt="" /></li>
|
|
<li><img src="/assets/img/all-images/blog/blog-img14.png" alt="" /></li>
|
|
</ul>
|
|
<ul>
|
|
<li><img src="/assets/img/all-images/blog/blog-img15.png" alt="" /></li>
|
|
<li><img src="/assets/img/all-images/blog/blog-img16.png" alt="" /></li>
|
|
<li><img src="/assets/img/all-images/blog/blog-img17.png" alt="" /></li>
|
|
<li><img src="/assets/img/all-images/blog/blog-img18.png" alt="" /></li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{/*===== BLOG AREA ENDS =======*/}
|
|
{/*===== BLOG AREA STARTS =======*/}
|
|
<div className="bloginner-section-area sp1">
|
|
<div className="container">
|
|
<div className="row">
|
|
<div className="col-lg-5 m-auto">
|
|
<div className="heading2 text-center space-margin60">
|
|
<h2>Read More Blogs</h2>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="row">
|
|
{recentBlogs
|
|
.filter(post => post.slug !== currentSlug)
|
|
.slice(0, 3)
|
|
.map((post) => (
|
|
|
|
<div key={post.id} className="col-lg-4 col-md-6" data-aos="zoom-in" data-aos-duration={800}>
|
|
<div className="blog4-boxarea">
|
|
<div className="img1">
|
|
<img src={post.image || "/assets/img/all-images/blog/blog-img4.png"} alt={post.title} style={{ width: '100%', height: '240px', objectFit: 'cover' }} />
|
|
</div>
|
|
<div className="content-area">
|
|
<ul>
|
|
<li>
|
|
<Link href="#"><img src="/assets/img/icons/calender1.svg" alt="" />{post.date}<span> | </span></Link>
|
|
</li>
|
|
<li>
|
|
<Link href="#"><img src="/assets/img/icons/user1.svg" alt="" />{post.author}</Link>
|
|
</li>
|
|
</ul>
|
|
<div className="space20" />
|
|
<Link href={`/blog-single`}> {post.title.length > 40 ? `${post.title.slice(0, 40)}...` : post.title}</Link>
|
|
<div className="space24" />
|
|
<Link href={`/blog-single`} className="readmore">read more <i className="fa-solid fa-arrow-right" /></Link>
|
|
<div className="arrow">
|
|
<Link href={`/blog-single`}><i className="fa-solid fa-arrow-right" /></Link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{/*===== BLOG AREA ENDS =======*/}
|
|
{/*===== CTA AREA STARTS =======*/}
|
|
<div className="cta1-section-area d-lg-block d-block">
|
|
<div className="container">
|
|
<div className="row">
|
|
<div className="col-lg-10 m-auto">
|
|
<div className="cta1-main-boxarea">
|
|
<div className="timer-btn-area">
|
|
<Countdown />
|
|
<div className="btn-area1">
|
|
<Link href="/pricing-plan" className="vl-btn1">Buy Ticket</Link>
|
|
</div>
|
|
</div>
|
|
<ul>
|
|
<li>
|
|
<Link href="#"><img src="/assets/img/icons/calender1.svg" alt="" />30 January 2025 - 6pm to 11:30pm</Link>
|
|
</li>
|
|
<li className="m-0">
|
|
<Link href="#"><img src="/assets/img/icons/location1.svg" alt="" />Secret Location In The UK</Link>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{/*===== CTA AREA ENDS =======*/}
|
|
{/*===== CTA AREA STARTS =======*/}
|
|
<div className="cta1-section-area d-lg-none d-block">
|
|
<div className="container">
|
|
<div className="row">
|
|
<div className="col-lg-10 m-auto">
|
|
<div className="cta1-main-boxarea">
|
|
<div className="timer-btn-area">
|
|
<Countdown />
|
|
<div className="btn-area1">
|
|
<Link href="/pricing-plan" className="vl-btn1">Buy Ticket</Link>
|
|
</div>
|
|
</div>
|
|
<ul>
|
|
<li>
|
|
<Link href="#"><img src="/assets/img/icons/calender1.svg" alt="" />30 January 2025 - 6pm to 11:30pm</Link>
|
|
</li>
|
|
<li className="m-0">
|
|
<Link href="#"><img src="/assets/img/icons/location1.svg" alt="" />Secret Location In The UK</Link>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<ModalVideo channel='youtube' isOpen={isOpen} videoId="JXMWOmuR1hU" onClose={() => setOpen(false)} />
|
|
</Layout>
|
|
</>
|
|
)
|
|
}
|
|
|
|
export default function BlogSingle() {
|
|
return (
|
|
<Suspense fallback={<div>Loading...</div>}>
|
|
<BlogSingleContent />
|
|
</Suspense>
|
|
)
|
|
} |