Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 5 additions & 46 deletions app/(root)/(routes)/(home)/components/button-row.tsx
Original file line number Diff line number Diff line change
@@ -1,46 +1,5 @@
"use client";

import Link from "next/link";
import { motion } from "framer-motion";
import React from "react";

const ButtonRow = () => {
const buttonVariants = {
hidden: { opacity: 0, y: 20 },
visible: { opacity: 1, y: 0, transition: { duration: 0.5, ease: "easeOut" } },
hover: { scale: 1.1, transition: { duration: 0.2, ease: "easeInOut" } },
tap: { scale: 0.95 },
};

return (
<div className="flex py-3 sticky top-0 z-10 bg-gradient-to-b from-zinc-100 to-gray-500 items-center justify-center w-full gap-3 px-4 md:px-8 lg:px-12">
{[
"/services/exterior-cleaning",
"/services/commercial-services",
"/services/holiday-lighting",
].map((href, index) => (
<motion.div
key={href}
variants={buttonVariants}
initial="hidden"
animate="visible"
whileHover="hover"
whileTap="tap"
transition={{ delay: index * 0.15 }} // Stagger effect
>
<Link
className="text-xs sm:text-sm md:text-base font-semibold tracking-wide flex items-center justify-center px-3 sm:px-4 md:px-5 py-1.5 sm:py-2 bg-blue-600 text-white rounded-lg shadow-lg border border-blue-800 hover:bg-blue-700 active:bg-blue-800 transition-all"
href={href}
>
{href
.replace("/services/", "")
.replace(/-/g, " ")
.replace(/\b\w/g, (c) => c.toUpperCase())}
</Link>
</motion.div>
))}
</div>
);
};

export default ButtonRow;
// This component has been removed as per the improvement plan
// Navigation is now handled by the main header component
export default function ButtonRow() {
return null;
}
13 changes: 5 additions & 8 deletions app/(root)/(routes)/(home)/components/social-proof.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,14 @@ import { motion } from "framer-motion";
import Script from "next/script";
import React from "react";
import { useRouter } from "next/navigation";
import { Button } from "@mui/material";

const SocialProof = () => {
const router = useRouter();

return (
// TODO: UPGRADE TO BASIC PLAN FOR ELFSIGHT TO TAKE OFF ELFSIGHT BRANDING
<motion.section
className="bg-white w-full flex flex-col items-center py-24 px-10 justify-center relative overflow-hidden"
className="bg-slate-50 w-full flex flex-col items-center py-24 px-10 justify-center relative overflow-hidden"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 1 }}
Expand All @@ -27,14 +26,12 @@ const SocialProof = () => {
data-elfsight-app-lazy
></div>

<Button
variant="contained"
color="primary"
className="mt-10 w-[300px] bg-blue-500"
onClick={() => router.push("/estimate")} // Redirect to /estimate page on click
<button
className="mt-10 px-8 py-4 bg-blue-600 text-white font-semibold rounded-full shadow-lg hover:bg-blue-700 transition-all duration-300 transform hover:scale-105"
onClick={() => router.push("/estimate")}
>
Get Your Free Estimate!
</Button>
</button>
</motion.section>
);
};
Expand Down
86 changes: 25 additions & 61 deletions app/(root)/(routes)/(home)/page.tsx
Original file line number Diff line number Diff line change
@@ -1,78 +1,42 @@
import React from "react";

import type { Metadata } from "next";
import HeroSection from "@/components/home/hero-section";
import TrustBar from "@/components/home/trust-bar";
import ServicesOverview from "@/components/home/services-overview";
import HowItWorks from "@/components/home/how-it-works";
import BeforeAfterShowcase from "@/components/home/before-after-showcase";
import FeaturesGrid from "@/components/home/features-grid";
import CTASection from "@/components/home/cta-section";
import SocialProof from "./components/social-proof";
import ProductRow from "../../../../components/products/product-row";
import { Metadata } from "next";
import ContactFormOverlay from "../../../../components/forms/overlay";
import SplashPic from "@/public/assets/imgs/action-2.jpg";
import Splash from "../../../../components/splash";
import ButtonRow from "./components/button-row";

export const metadata: Metadata = {
title: "Brite Exterior Cleaning Services | Clean Your Property with Experts",
title: "Brite Exterior Cleaning Services | Transform Your Property",
description:
"Brite offers professional exterior cleaning services to make your home or business shine. Explore our services and get a free estimate today.",
"Premium exterior cleaning services for homes and businesses. Professional pressure washing, window cleaning, and holiday lighting in Charlotte, NC. Get your free estimate today!",
openGraph: {
title: "Brite Exterior Cleaning Services",
title: "Brite Exterior Cleaning Services | Transform Your Property",
description:
"Brite offers professional exterior cleaning services to make your home or business shine.",
"Premium exterior cleaning services for homes and businesses. Professional, reliable, and worry-free maintenance solutions.",
url: "https://briteclt.com",
},
twitter: {
card: "summary_large_image",
title: "Brite Exterior Cleaning Services",
title: "Brite Exterior Cleaning Services | Transform Your Property",
description:
"Brite offers professional exterior cleaning services to make your home or business shine.",
"Premium exterior cleaning services for homes and businesses. Professional, reliable, and worry-free maintenance solutions.",
},
};

export default async function HomePage() {
return (
<section>
<ButtonRow />
<div className="relative flex w-full flex-col">
<Splash
img={SplashPic}
title="Brite Exterior Services"
description="Your home deserves the best — Brite
provides elite maintenance services that keep your
space pristine, efficient, and worry-free.
From luxury estates to modern residences,
we handle every detail with precision and care.
Experience effortless homeownership with Brite."
/>
<div className="flex justify-center w-full">
<div className="absolute h-[1000px] w-full bg-gradient-to-b from-black via-blue-500 to-white"></div>
{/* Logo */}
{/* <div className="absolute z-10 top-[1300px] left-32 hidden xl:flex">
<Image src={Logo} alt="brite-logo" className="w-48" />
</div> */}
<div className="absolute flex items-center justify-center top-[820px] w-[95%] md:w-[80%] lg:w-[70%] xl:w-[45%]">
<ContactFormOverlay />
</div>
{/* Logo */}
{/* <div className="absolute z-10 top-[1300px] right-32 hidden xl:flex">
<Image src={Logo} alt="brite-logo" className="w-48" />
</div> */}
</div>
</div>
<div className="pt-[1100px]">
<SocialProof />
</div>
<ProductRow
category="Exterior Cleaning"
title="Transform Your Estate’s Curb Appeal – Premium Exterior Cleaning for the Finest Homes!"
/>
<ProductRow
category="Holiday Lighting"
title="Illuminate Your Luxury Home – Exquisite Holiday Lighting for a Spectacular Display!"
/>
<ProductRow
className="pb-24"
category="Commercial Services"
title="Enhance Your Business’s Image – Professional Commercial Exterior Cleaning & Holiday Lighting Services!"
/>
{/* <WelcomeMessage /> */}
</section>
<main className="w-full">
<HeroSection />
<TrustBar />
<ServicesOverview />
<HowItWorks />
<BeforeAfterShowcase />
<FeaturesGrid />
<SocialProof/>
<CTASection />
</main>
);
}
}
2 changes: 1 addition & 1 deletion app/(root)/(routes)/blog/[slug]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default async function BlogPageBySlug({ params }: { params: Promise<{ slu
: "Unknown Date";

return (
<div className="max-w-3xl mx-auto p-6">
<div className="max-w-3xl mx-auto mt-20 p-6">
<BackButton title="Back to Blog" link="/blog" />

<h1 className="text-3xl font-bold mb-4">{blog.title}</h1>
Expand Down
79 changes: 44 additions & 35 deletions app/(root)/(routes)/blog/components/blog-card.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { Blog } from "@/sanity.types";
import type { Blog } from "@/sanity.types";
import { imageUrl } from "@/sanity/lib/image-url";
import Image from "next/image";
import Link from "next/link";
import React from "react";
import UserDefaultImage from "@/public/assets/icons/user (1).png"; // Make sure to import the default image
import { FaCalendarAlt, FaClock } from "react-icons/fa";

interface IBlogCardProps {
blog: Blog;
Expand All @@ -12,10 +12,6 @@ interface IBlogCardProps {
const BlogCard = (props: IBlogCardProps) => {
const { blog } = props;

// Handle author image and name with fallback options
// const authorImageUrl = blog.author!._ref ? imageUrl(blog.author!._ref).url() : UserDefaultImage; // Use default image if no image exists
// const authorName = blog.author!._ref || "Unknown Author";

// Format the published date
const publishedDate = new Intl.DateTimeFormat("en-US", {
year: "numeric",
Expand All @@ -25,44 +21,57 @@ const BlogCard = (props: IBlogCardProps) => {

// Truncate the excerpt for a cleaner look
const truncatedExcerpt =
blog.excerpt!.length > 100 ? `${blog.excerpt!.slice(0, 100)}...` : blog.excerpt;
blog.excerpt && blog.excerpt.length > 120
? `${blog.excerpt.slice(0, 120)}...`
: blog.excerpt;

return (
<Link key={blog._id} href={`/blog/${blog.slug?.current || ""}`}>
<div className="bg-white shadow-lg rounded-lg overflow-hidden cursor-pointer hover:shadow-xl transition transform hover:scale-105">
<Link
href={`/blog/${blog.slug?.current || ""}`}
className="group"
>
<article className="bg-white shadow-lg rounded-2xl overflow-hidden hover:shadow-2xl transition-all duration-500 transform hover:-translate-y-2 h-full flex flex-col">
{/* Blog image */}
<Image
src={blog.mainImage?.asset ? imageUrl(blog.mainImage.asset).url() : ""}
alt={blog.title || "Blog Image"}
width={400}
height={250}
className="w-full h-48 object-cover"
/>
<div className="p-4">
<div className="relative w-full h-56 overflow-hidden">
<Image
src={blog.mainImage?.asset ? imageUrl(blog.mainImage.asset).url() : ""}
alt={blog.title || "Blog Image"}
fill
className="object-cover group-hover:scale-110 transition-transform duration-700"
/>
<div className="absolute inset-0 bg-gradient-to-t from-slate-900/50 to-transparent"></div>
</div>

<div className="p-6 flex flex-col flex-grow">
{/* Blog title */}
<h2 className="text-xl font-semibold">{blog.title}</h2>
{/* Author and published date */}
<div className="flex items-center gap-2 text-sm text-gray-600 mt-2">
{/* <Image
src={authorImageUrl}
alt={authorName}
width={24}
height={24}
className="rounded-full"
/> */}
<span className="flex flex-col">
{/* <p>{authorName}</p> */}
<p className="">{publishedDate}</p>
</span>
<h2 className="text-2xl font-bold text-slate-900 mb-3 group-hover:text-blue-600 transition-colors line-clamp-2">
{blog.title}
</h2>

{/* Published date */}
<div className="flex items-center gap-4 text-sm text-slate-500 mb-4">
<div className="flex items-center gap-2">
<FaCalendarAlt className="text-blue-600" />
<span>{publishedDate}</span>
</div>
</div>

{/* Truncated excerpt */}
<p className="text-gray-700 mt-2">{truncatedExcerpt}</p>
<p className="text-slate-600 mb-4 flex-grow line-clamp-3">
{truncatedExcerpt}
</p>

{/* Read more link */}
<p className="text-blue-500 mt-2 font-semibold">Read More →</p>
<div className="pt-4 border-t border-slate-200">
<span className="text-blue-600 font-semibold group-hover:gap-2 inline-flex items-center transition-all">
Read More
<span className="ml-2 group-hover:ml-0 transition-all">→</span>
</span>
</div>
</div>
</div>
</article>
</Link>
);
};

export default BlogCard;
export default BlogCard;
35 changes: 26 additions & 9 deletions app/(root)/(routes)/blog/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getAllBlogs } from "@/sanity/lib/blogs/getAllBlogs";
import BlogCard from "./components/blog-card";
import { Metadata } from "next";
import type { Metadata } from "next";

export const metadata: Metadata = {
title: "Brite Exterior Cleaning Blog | Tips, News, and Updates",
Expand Down Expand Up @@ -28,17 +28,34 @@ export default async function BlogPage() {
}

if (blogs.length < 1) {
return <div className="py-48 flex items-center justify-center">No blogs posted.</div>;
return (
<div className="min-h-screen bg-gradient-to-b from-slate-900 via-blue-900 to-slate-50 flex mt-10 items-center justify-center">
<div className="text-center">
<p className="text-slate-400 text-xl">No blog posts available yet.</p>
<p className="text-slate-500 mt-4">Check back soon for expert tips and insights!</p>
</div>
</div>
);
}

return (
<div className="mx-auto p-6 h-full lg:h-screen w-full bg-gradient-to-b from-blue-500 bg-white">
<h1 className="text-3xl font-bold text-center mb-6">Latest Blog Posts</h1>
<div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
{blogs.map((blog: any) => (
<BlogCard key={blog._id} blog={blog} />
))}
<div className="min-h-screen bg-gradient-to-b from-slate-900 via-blue-900 to-slate-50 mt-10">
{/* Hero Section */}
<div className="text-white px-4 py-24 text-center max-w-4xl mx-auto">
<h1 className="text-5xl md:text-6xl font-bold mb-6">Our Blog</h1>
<p className="text-xl text-slate-300">
Expert tips, industry insights, and the latest news from Brite Exterior Cleaning
</p>
</div>

{/* Blog Grid */}
<div className="max-w-7xl mx-auto px-4 pb-24">
<div className="grid gap-8 md:grid-cols-2 lg:grid-cols-3">
{blogs.map((blog: any) => (
<BlogCard key={blog._id} blog={blog} />
))}
</div>
</div>
</div>
);
}
}
11 changes: 8 additions & 3 deletions app/(root)/(routes)/faqs/components/container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@ interface IFAQContainerProps {

const FAQContainer = (props: IFAQContainerProps) => {
return (
<div id={props.id} className="flex flex-col w-full flex-1 px-10 lg:px-32 px">
<h5 className="text-blue-600 text-4xl font-semibold">{props.title}</h5>
{props.children}
<div id={props.id} className="flex flex-col w-full flex-1 mb-16">
<div className="flex items-center gap-3 mb-8">
<div className="w-3 h-3 bg-blue-500 rounded-full animate-pulse"></div>
<h2 className="text-3xl font-bold text-white">{props.title}</h2>
</div>
<div className="bg-white rounded-2xl shadow-lg p-8">
{props.children}
</div>
</div>
);
};
Expand Down
6 changes: 3 additions & 3 deletions app/(root)/(routes)/faqs/components/item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ interface IFAQItemProps {

const FAQItem = (props: IFAQItemProps) => {
return (
<div className="flex flex-col border-b-[1px] border-zinc-300 w-full mb-10 pb-10">
<h5 className="text-slate-500 my-6 text-xl font-bold">{props.question}</h5>
<p className="text-sm text-slate-500">{props.answer}</p>
<div className="flex flex-col border-b border-slate-200 w-full mb-8 pb-8 last:border-b-0 last:mb-0 last:pb-0">
<h5 className="text-slate-900 my-4 text-xl font-bold">{props.question}</h5>
<p className="text-slate-600 leading-relaxed">{props.answer}</p>
</div>
);
};
Expand Down
Loading