blog details page added
This commit was merged in pull request #15.
This commit is contained in:
@@ -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>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col-lg-12">
|
<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">
|
<div className="apps-download-btn">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import React, { useEffect, useState } from "react";
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import blogOne from "../../assets/images/blog/1.jpg";
|
import blogOne from "../../assets/images/blog/1.jpg";
|
||||||
import BlogData from "../../Services/BlogData";
|
import BlogData from "../../Services/BlogData";
|
||||||
|
// import Image from "next/image";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches blog data from an API and renders the blogs on the page.
|
* 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';
|
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