blog details page added #15
@@ -0,0 +1,64 @@
|
||||
import singlePost from "../../assets/images/single-post/1.jpg";
|
||||
import { BlogLoader, ImageLoader } from "../../lib/SkeletonLoaders";
|
||||
// import Image from "next/image";
|
||||
// import LazyImage from "../../lib/LazyImage";
|
||||
|
||||
/**
|
||||
* Renders a blog post component.
|
||||
* @returns {JSX.Element} The rendered blog post component.
|
||||
*/
|
||||
function Blog({ blogItem, imgUrl, loader }) {
|
||||
// Generate a unique ID
|
||||
const uniqueId = `element_${Math.random().toString(36).substr(2, 9)}`;
|
||||
|
||||
const blogImg = `${imgUrl}/${blogItem?.meta_value || singlePost}`;
|
||||
|
||||
const imgLoaderStyles = {
|
||||
"--loader-width": "750px",
|
||||
"--loader-height": "550px",
|
||||
};
|
||||
|
||||
const headerLoaderStyles = {
|
||||
"--text-container-width": "300px",
|
||||
"--text-container-height": "18px",
|
||||
};
|
||||
|
||||
const bodyTextLoaderStyles = {
|
||||
"--text-container-width": "770px",
|
||||
"--text-container-height": "15px",
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="single-post-area">
|
||||
<div className="post-thumb" style={{ marginTop: "0" }}>
|
||||
{loader ? (
|
||||
<div style={imgLoaderStyles}>
|
||||
<ImageLoader />
|
||||
</div>
|
||||
) : (
|
||||
<img src={blogImg} alt={blogItem?.meta_value || "single-post.jpg"} key={uniqueId} />
|
||||
)}
|
||||
</div>
|
||||
{loader ? (
|
||||
<div style={headerLoaderStyles}>
|
||||
<BlogLoader />
|
||||
</div>
|
||||
) : (
|
||||
<h4 className="article-title">{blogItem?.post_title}</h4>
|
||||
)}
|
||||
{loader ? (
|
||||
<div style={bodyTextLoaderStyles}>
|
||||
<BlogLoader />
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
dangerouslySetInnerHTML={{ __html: blogItem?.post_content }}
|
||||
></div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default Blog;
|
||||
@@ -0,0 +1,69 @@
|
||||
import React from "react";
|
||||
import Link from "next/link";
|
||||
import BlogImg1 from "../../assets/images/blog/p1.jpg";
|
||||
|
||||
/**
|
||||
* Renders a sidebar for a blog.
|
||||
* @param {Object} blogs - An object containing the data for the blog posts.
|
||||
* @returns {JSX.Element} - JSX code that renders the blog sidebar.
|
||||
*/
|
||||
function BlogSideBar({ blogs }) {
|
||||
/**
|
||||
* Renders other blog posts.
|
||||
* This is an Array of JSX elements representing the other blog posts.
|
||||
*/
|
||||
const renderOtherBlogPosts = () => {
|
||||
return blogs?.blogdata?.slice(0, 4).map((post) => {
|
||||
const blogDate = new Date(post.post_date).toLocaleDateString("en-US", {
|
||||
year: "numeric",
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
});
|
||||
|
||||
const blogImg =
|
||||
post.meta_value != null
|
||||
? `${blogs?.image_url}/${post.meta_value}`
|
||||
: BlogImg1;
|
||||
|
||||
return (
|
||||
<div className="popular-post" key={post.id}>
|
||||
<Link href={`/blog/blogdetail/${post?.id}`}>
|
||||
<img width='auto' height='auto' src={blogImg} alt="blog-img" style={{top: "20px"}} loading="lazy" />
|
||||
</Link>
|
||||
<h5>
|
||||
<Link href={`/blog/blogdetail/${post?.id}`}>{post?.post_title}</Link>
|
||||
</h5>
|
||||
<span>{blogDate}</span>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="blog-sidebar">
|
||||
<aside className="widget widget-categories">
|
||||
{/*<h3 className="widget-title">Categories</h3>*/}
|
||||
<ul>
|
||||
<li>
|
||||
<Link href="/about-us">About</Link>
|
||||
</li>
|
||||
<li>
|
||||
<a href={process.env.NEXT_PUBLIC_DASH_URL_SIGNUP}>Sign up</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href={process.env.NEXT_PUBLIC_DASH_URL_LOGIN}>Login</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://blog.wrenchboard.com/">More Articles</a>
|
||||
</li>
|
||||
</ul>
|
||||
</aside>
|
||||
<aside className="widget widget-trend-post">
|
||||
<h3 className="widget-title">Other Posts</h3>
|
||||
{renderOtherBlogPosts()}
|
||||
</aside>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default BlogSideBar;
|
||||
@@ -0,0 +1,84 @@
|
||||
"use client"
|
||||
import React, { useEffect, useMemo, useState } from 'react'
|
||||
import { useParams } from 'next/navigation';
|
||||
import ServiceNav from '@/app/components/navigation/ServiceNav';
|
||||
import HeroNews from '@/app/components/News/HeroNews';
|
||||
import FooterHomeOne from '../../../components/FooterHomeOne';
|
||||
import BackToTop from '@/app/components/BackToTop';
|
||||
import BlogData from '@/app/Services/BlogData';
|
||||
|
||||
import Blog from '../Blog'
|
||||
import BlogSideBar from '../BlogSideBar'
|
||||
|
||||
// must be a better way to centralize the style = TEMPORARY USE
|
||||
import '../../../assets/css/bootstrap.min.css';
|
||||
import '../../../assets/css/custom-animated.css';
|
||||
import '../../../assets/css/default.css';
|
||||
import '../../../assets/css/font-awesome.min.css';
|
||||
import '../../../assets/css/magnific-popup.css';
|
||||
import '../../../assets/css/main.css';
|
||||
import '../../../assets/css/style.css';
|
||||
|
||||
|
||||
function page() {
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [blogs, setBlogs] = useState([]);
|
||||
const { id } = useParams();
|
||||
|
||||
useEffect(() => {
|
||||
const fetchBlogs = async () => {
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const res = await BlogData();
|
||||
setBlogs(res.data);
|
||||
setIsLoading(false)
|
||||
} catch (err) {
|
||||
console.log("Error loading blogdata", err);
|
||||
setIsLoading(false)
|
||||
}
|
||||
};
|
||||
|
||||
fetchBlogs();
|
||||
}, []);
|
||||
|
||||
const blogItem = useMemo(() => {
|
||||
return blogs?.blogdata?.find((item) => item.id == id);
|
||||
}, [blogs, id]);
|
||||
return (
|
||||
<>
|
||||
<ServiceNav />
|
||||
|
||||
{/* Renders the hero section */}
|
||||
<HeroNews
|
||||
title="Blog"
|
||||
breadcrumb={[
|
||||
{ link: "/", title: "Home" },
|
||||
{ link: "/blog", title: "Blogs" },
|
||||
{
|
||||
link: `/blog/blogdetail/${id}`,
|
||||
title: isLoading ? "please wait..." : blogItem ? blogItem.post_title : "Post not found",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
{/* Renders the blog content and sidebar */}
|
||||
<section className="blogpage-section">
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
<div className="col-lg-8 col-md-7">
|
||||
<Blog blogItem={blogItem} imgUrl={blogs?.image_url} loader={isLoading} />
|
||||
</div>
|
||||
<div className="col-lg-4 col-md-5">
|
||||
<BlogSideBar blogs={blogs} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<FooterHomeOne className='' />
|
||||
<BackToTop className='' />
|
||||
</>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
export default page
|
||||
@@ -1,24 +0,0 @@
|
||||
import React from 'react'
|
||||
import FooterHomeOne from '../../../components/FooterHomeOne';
|
||||
|
||||
// must be a better way to centralize the style = TEMPORARY USE
|
||||
import '../../../assets/css/bootstrap.min.css';
|
||||
import '../../../assets/css/custom-animated.css';
|
||||
import '../../../assets/css/default.css';
|
||||
import '../../../assets/css/font-awesome.min.css';
|
||||
import '../../../assets/css/magnific-popup.css';
|
||||
import '../../../assets/css/main.css';
|
||||
import '../../../assets/css/style.css';
|
||||
|
||||
|
||||
function page() {
|
||||
return (
|
||||
<>
|
||||
<div>Bog Detail Here</div>
|
||||
<FooterHomeOne className={undefined} />
|
||||
</>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
export default page
|
||||
@@ -1,24 +0,0 @@
|
||||
import React from 'react'
|
||||
import FooterHomeOne from '../../components/FooterHomeOne';
|
||||
|
||||
// must be a better way to centralize the style = TEMPORARY USE
|
||||
import '../../assets/css/bootstrap.min.css';
|
||||
import '../../assets/css/custom-animated.css';
|
||||
import '../../assets/css/default.css';
|
||||
import '../../assets/css/font-awesome.min.css';
|
||||
import '../../assets/css/magnific-popup.css';
|
||||
import '../../assets/css/main.css';
|
||||
import '../../assets/css/style.css';
|
||||
|
||||
|
||||
function page() {
|
||||
return (
|
||||
<>
|
||||
<div>Bog Detail Here</div>
|
||||
<FooterHomeOne className={undefined} />
|
||||
</>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
export default page
|
||||
@@ -118,7 +118,7 @@ function FooterHomeOne({ className }) {
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-lg-12">
|
||||
<div className="footer-copyright d-flex align-items-center justify-content-between pt-2">
|
||||
<div className="footer-copyright d-lg-flex align-items-center justify-content-between pt-2">
|
||||
<div className="apps-download-btn">
|
||||
<ul>
|
||||
<li>
|
||||
|
||||
@@ -3,6 +3,7 @@ import React, { useEffect, useState } from "react";
|
||||
import Link from "next/link";
|
||||
import blogOne from "../../assets/images/blog/1.jpg";
|
||||
import BlogData from "../../Services/BlogData";
|
||||
// import Image from "next/image";
|
||||
|
||||
/**
|
||||
* Fetches blog data from an API and renders the blogs on the page.
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
"use client"
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
|
||||
/**
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.3 KiB |
Reference in New Issue
Block a user