Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| da96bd6028 | |||
| eec247d7bb | |||
| a41318d0e7 | |||
| 83e664eab4 | |||
| e59d96b60d |
|
After Width: | Height: | Size: 190 KiB |
@@ -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>
|
||||
|
||||
@@ -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='' />
|
||||
|
||||
@@ -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,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;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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,3 +1,4 @@
|
||||
"use client"
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
|
||||
/**
|
||||
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 629 KiB |
|
After Width: | Height: | Size: 422 KiB |
|
After Width: | Height: | Size: 600 KiB |
|
After Width: | Height: | Size: 406 KiB |
|
After Width: | Height: | Size: 545 KiB |
|
After Width: | Height: | Size: 547 KiB |
|
After Width: | Height: | Size: 595 KiB |
|
After Width: | Height: | Size: 443 KiB |
|
After Width: | Height: | Size: 399 KiB |
|
After Width: | Height: | Size: 396 KiB |
|
After Width: | Height: | Size: 524 KiB |
|
After Width: | Height: | Size: 478 KiB |
|
After Width: | Height: | Size: 188 KiB |
|
After Width: | Height: | Size: 181 KiB |
|
After Width: | Height: | Size: 162 KiB |
|
After Width: | Height: | Size: 582 KiB |
|
After Width: | Height: | Size: 626 KiB |
|
After Width: | Height: | Size: 2.6 MiB |
|
After Width: | Height: | Size: 1.4 MiB |
|
After Width: | Height: | Size: 765 KiB |
|
After Width: | Height: | Size: 2.1 MiB |
|
After Width: | Height: | Size: 690 KiB |
|
After Width: | Height: | Size: 485 KiB |