Compare commits

..

5 Commits

Author SHA1 Message Date
victorAnumudu da96bd6028 chat support added 2024-08-06 18:21:46 +01:00
CHIEFSOFT\ameye eec247d7bb Home text fixed 2024-08-04 17:04:32 -04:00
ameye a41318d0e7 Merge branch 'blog-detail-page' of WrenchBoard/WrenchBoardMainSite2025 into master 2024-08-03 19:29:11 +00:00
victorAnumudu 83e664eab4 blog details page added 2024-08-03 20:20:08 +01:00
ameye e59d96b60d Merge branch 'link-bug-fix' of WrenchBoard/WrenchBoardMainSite2025 into master 2024-08-03 13:13:15 +00:00
36 changed files with 279 additions and 67 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 190 KiB

+64
View File
@@ -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;
+69
View File
@@ -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;
+84
View File
@@ -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
-24
View File
@@ -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
-24
View File
@@ -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 -1
View File
@@ -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>
+2 -1
View File
@@ -7,7 +7,7 @@ import HeroHomeOne from './HeroHomeOne';
import ServicesHomeOne from './ServicesHomeOne';
import TrafficHomeOne from './TrafficHomeOne';
import TrafficHomeTwo from './TrafficHomeTwo';
//import FeaturedScreen from './FeaturedScreen';
//import FeaturedScreen from './FeaturedScreen';
import AfterHero from './AfterHero';
import NextAfterHero from './NextAfterHero';
import BackToTop from './BackToTop';
@@ -28,6 +28,7 @@ function HomeOne() {
{/*<ServicesHomeOne />*/}
<TrafficHomeOne />
{/*<TrafficHomeTwo />*/}
{/*<FeaturedScreen />*/}
<BlogHomeOne />
<FooterHomeOne />
<BackToTop className='' />
+1
View File
@@ -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.
+29 -17
View File
@@ -1,7 +1,7 @@
"use client"
import React, { useState } from 'react';
//import { Link } from 'react-router-dom';
import thumb from '../assets/images/features-thumb-01.png';
import thumb from '../assets/images/features-thumb-11.png';
import shapeSix from '../assets/images/shape/shape-6.png';
import shapeSeven from '../assets/images/shape/shape-7.png';
import shapeEight from '../assets/images/shape/shape-8.png';
@@ -103,13 +103,14 @@ function SelectFeatures({ className }) {
data-wow-duration="2000ms"
data-wow-delay="600ms"
>
<span>Custom Reactions</span>
<span>
{/*Reward Achievement*/}
</span>
<h3 className="title">
Let the <br /> Conversation flow
Reward <br /> Achievement
</h3>
<p>
Car boot absolutely bladdered posh burke the
wireless mush some dodg.
Reward with points, badges, recognition, or money rewards with easy steps
</p>
<a className="main-btn" href="/about-us">
Learn More
@@ -141,13 +142,14 @@ function SelectFeatures({ className }) {
data-wow-duration="2000ms"
data-wow-delay="600ms"
>
<span>Custom Reacyions</span>
<span>
{/*Reward Achievement ee*/}
</span>
<h3 className="title">
Let the <br /> Conversation flow
Assign <br /> tasks or chores
</h3>
<p>
Car boot absolutely bladdered posh burke the
wireless mush some dodg.
Adapt to your family's needs with the flexibility of using one-time or repeated tasks or chores with the option to find any task.
</p>
<a className="main-btn" href="#">
Learn More
@@ -179,13 +181,14 @@ function SelectFeatures({ className }) {
data-wow-duration="2000ms"
data-wow-delay="600ms"
>
<span>Custom Reacyions</span>
<span>
{/*Custom Reacyions 77*/}
</span>
<h3 className="title">
Let the <br /> Conversation flow
Family <br /> engagement
</h3>
<p>
Car boot absolutely bladdered posh burke the
wireless mush some dodg.
Connect with education challenges, such as quizzes or learning tasks, and private chats, and invite others to your family.
</p>
<a className="main-btn" href="#">
Learn More
@@ -217,13 +220,14 @@ function SelectFeatures({ className }) {
data-wow-duration="2000ms"
data-wow-delay="600ms"
>
<span>Custom Reacyions</span>
<span>
{/*Reward Achievement*/}
</span>
<h3 className="title">
Let the <br /> Conversation flow
Fund <br /> wallets
</h3>
<p>
Car boot absolutely bladdered posh burke the
wireless mush some dodg.
Take control and feel secure by creating a virtual or physical card, allocating funds, and managing wallets for your kids. .
</p>
<a className="main-btn" href="#">
Learn More
@@ -250,3 +254,11 @@ function SelectFeatures({ className }) {
}
export default SelectFeatures;
+28
View File
@@ -1,6 +1,7 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import Script from "next/script";
const inter = Inter({ subsets: ["latin"] });
@@ -31,6 +32,33 @@ export default function RootLayout({
<meta property="og:image" content="%PUBLIC_URL%/favicon-32x32.png" />
<body className={inter.className}>{children}</body>
<Script>
{`
var LHC_API = LHC_API || {};
LHC_API.args = {
mode: "widget",
lhc_base_url: "//chat.live.wrenchboard.com/",
wheight: 450,
wwidth: 350,
pheight: 520,
pwidth: 500,
leaveamessage: true,
check_messages: false,
};
(function () {
var po = document.createElement("script");
po.type = "text/javascript";
po.setAttribute("crossorigin", "anonymous");
po.async = true;
var date = new Date();
po.src =
"//chat.live.wrenchboard.com/design/defaulttheme/js/widgetv2/index.js?" +
("" + date.getFullYear() + date.getMonth() + date.getDate());
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(po, s);
})();
`}
</Script>
</html>
);
}
+1
View File
@@ -1,3 +1,4 @@
"use client"
import React, { useEffect, useRef, useState } from 'react';
/**
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 629 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 600 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 545 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 443 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 399 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 524 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 478 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 582 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 626 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 765 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 690 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 485 KiB