Compare commits
10 Commits
version_1_
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 4484689f32 | |||
|
|
dd7b7c5d00 | ||
| 0c914ca51e | |||
|
|
0e384e98f6 | ||
| 41c95d4055 | |||
|
|
d7fcd8ca72 | ||
| 0eefa4dfbd | |||
|
|
69fdadf86b | ||
| 68fbb4dfe5 | |||
|
|
b28a08711d |
@@ -1,11 +1,14 @@
|
||||
import FooterSimpleCard from '@/components/sections/footer/FooterSimpleCard';
|
||||
import NavbarFloating from '@/components/ui/NavbarFloating';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
import SiteBackgroundSlot from "@/components/ui/SiteBackgroundSlot";
|
||||
import { Outlet } from 'react-router-dom';
|
||||
import { StyleProvider } from "@/components/ui/StyleProvider";
|
||||
import { useState, useEffect } from 'react';
|
||||
import { motion } from 'motion/react';
|
||||
|
||||
export default function Layout() {
|
||||
const [activeTab, setActiveTab] = useState("hero");
|
||||
|
||||
const navItems = [
|
||||
{
|
||||
"name": "Home",
|
||||
@@ -31,30 +34,84 @@ export default function Layout() {
|
||||
"name": "Metrics",
|
||||
"href": "#metrics"
|
||||
},
|
||||
{
|
||||
"name": "Pricing",
|
||||
"href": "#pricing"
|
||||
},
|
||||
{
|
||||
"name": "Faq",
|
||||
"href": "#faq"
|
||||
}
|
||||
];
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
const sections = navItems.map(item => item.href.slice(1));
|
||||
let current = "hero";
|
||||
for (const section of sections) {
|
||||
const el = document.getElementById(section);
|
||||
if (el && window.scrollY >= el.offsetTop - 200) {
|
||||
current = section;
|
||||
}
|
||||
}
|
||||
setActiveTab(current);
|
||||
};
|
||||
window.addEventListener("scroll", handleScroll);
|
||||
return () => window.removeEventListener("scroll", handleScroll);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<StyleProvider buttonVariant="default" siteBackground="gridDots" heroBackground="gradientBars">
|
||||
<StyleProvider buttonVariant="default" siteBackground="none" heroBackground="none">
|
||||
<SiteBackgroundSlot />
|
||||
<SectionErrorBoundary name="navbar">
|
||||
<NavbarFloating
|
||||
logo="GreenScape"
|
||||
ctaButton={{
|
||||
text: "Get Quote",
|
||||
href: "#contact",
|
||||
}}
|
||||
navItems={navItems} />
|
||||
<div className="fixed top-6 left-1/2 -translate-x-1/2 z-50 hidden md:flex items-center gap-2 p-1.5 card rounded-full shadow-lg">
|
||||
<img src="https://storage.googleapis.com/webild/users/user_3FUQa0ZWeM3nmyILoJWMMWG8CWg/uploaded-1782127565329-9f81y6uc.png" alt="Logo" className="h-8 w-8 rounded-full object-cover ml-2" />
|
||||
<div className="flex items-center gap-1">
|
||||
{navItems.map(item => (
|
||||
<button
|
||||
key={item.name}
|
||||
onClick={() => {
|
||||
setActiveTab(item.href.slice(1));
|
||||
document.getElementById(item.href.slice(1))?.scrollIntoView({ behavior: 'smooth' });
|
||||
}}
|
||||
className={`relative px-4 py-2 text-sm font-medium rounded-full transition-colors ${activeTab === item.href.slice(1) ? 'text-primary-cta-text' : 'text-foreground hover:text-accent'}`}
|
||||
>
|
||||
{activeTab === item.href.slice(1) && (
|
||||
<motion.div layoutId="nav-tab" className="absolute inset-0 bg-primary-cta rounded-full -z-10" />
|
||||
)}
|
||||
{item.name}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="fixed top-4 left-4 right-4 z-50 md:hidden flex items-center p-2 card rounded-2xl shadow-lg overflow-x-auto">
|
||||
<img src="https://storage.googleapis.com/webild/users/user_3FUQa0ZWeM3nmyILoJWMMWG8CWg/uploaded-1782127565329-9f81y6uc.png" alt="Logo" className="h-8 w-8 rounded-full object-cover shrink-0 mr-4 ml-1" />
|
||||
<div className="flex items-center gap-1 shrink-0">
|
||||
{navItems.map(item => (
|
||||
<button
|
||||
key={item.name}
|
||||
onClick={() => {
|
||||
setActiveTab(item.href.slice(1));
|
||||
document.getElementById(item.href.slice(1))?.scrollIntoView({ behavior: 'smooth' });
|
||||
}}
|
||||
className={`relative px-3 py-1.5 text-xs font-medium rounded-full transition-colors whitespace-nowrap ${activeTab === item.href.slice(1) ? 'text-primary-cta-text' : 'text-foreground'}`}
|
||||
>
|
||||
{activeTab === item.href.slice(1) && (
|
||||
<motion.div layoutId="nav-tab-mobile" className="absolute inset-0 bg-primary-cta rounded-full -z-10" />
|
||||
)}
|
||||
{item.name}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</SectionErrorBoundary>
|
||||
<main className="flex-grow">
|
||||
<Outlet />
|
||||
</main>
|
||||
<SectionErrorBoundary name="footer">
|
||||
<FooterSimpleCard
|
||||
brand="GreenScape Landscaping"
|
||||
brand="Fourieearthworks"
|
||||
columns={[
|
||||
{
|
||||
title: "Services",
|
||||
@@ -99,7 +156,7 @@ export default function Layout() {
|
||||
],
|
||||
},
|
||||
]}
|
||||
copyright="© 2024 GreenScape Landscaping. All rights reserved."
|
||||
copyright="© 2024 Fourieearthworks. All rights reserved."
|
||||
links={[
|
||||
{
|
||||
label: "Privacy Policy",
|
||||
|
||||
@@ -1,267 +1,55 @@
|
||||
import AboutTextSplit from '@/components/sections/about/AboutTextSplit';
|
||||
import ContactCta from '@/components/sections/contact/ContactCta';
|
||||
import FaqTabbedAccordion from '@/components/sections/faq/FaqTabbedAccordion';
|
||||
import FeaturesBentoGrid from '@/components/sections/features/FeaturesBentoGrid';
|
||||
import FeaturesRevealCardsBento from '@/components/sections/features/FeaturesRevealCardsBento';
|
||||
import HeroTiltedCards from '@/components/sections/hero/HeroTiltedCards';
|
||||
import MetricsSimpleCards from '@/components/sections/metrics/MetricsSimpleCards';
|
||||
import TestimonialTrustCard from '@/components/sections/testimonial/TestimonialTrustCard';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
// AUTO-GENERATED shell by per-section-migrate.
|
||||
// Section bodies live in ./<PageBase>/sections/<X>.tsx. Edit the section
|
||||
// files directly. Non-block content (wrappers, non-inlinable sections) is
|
||||
// preserved inline; extracted section blocks become <XSection/> refs.
|
||||
|
||||
export default function HomePage() {
|
||||
import React from 'react';
|
||||
import HeroSection from './HomePage/sections/Hero';
|
||||
import AboutSection from './HomePage/sections/About';
|
||||
import FeaturesSection from './HomePage/sections/Features';
|
||||
import ProductSection from './HomePage/sections/Product';
|
||||
import MetricsSection from './HomePage/sections/Metrics';
|
||||
import TestimonialsSection from './HomePage/sections/Testimonials';
|
||||
import FaqSection from './HomePage/sections/Faq';
|
||||
import ContactSection from './HomePage/sections/Contact';
|
||||
|
||||
|
||||
import PricingSection from './HomePage/sections/Pricing';
|
||||
|
||||
const SectionBg = ({ children, src }: { children: React.ReactNode, src: string }) => (
|
||||
<div className="relative bg-cover bg-center" style={{ backgroundImage: `url('${src}')` }}>
|
||||
<div className="absolute inset-0 bg-background/80"></div>
|
||||
<div className="relative z-10 [&>section]:!bg-transparent [&>div]:!bg-transparent">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export default function HomePage(): React.JSX.Element {
|
||||
return (
|
||||
<>
|
||||
<div id="hero" data-section="hero">
|
||||
<SectionErrorBoundary name="hero">
|
||||
<HeroTiltedCards
|
||||
tag="Expert Landscaping Services"
|
||||
title="We Cultivate Your Outdoor Dream Spaces"
|
||||
description="Transforming residential and commercial properties into lush, sustainable landscapes with precision, care, and professional expertise."
|
||||
primaryButton={{
|
||||
text: "Book Consultation",
|
||||
href: "#contact",
|
||||
}}
|
||||
secondaryButton={{
|
||||
text: "View Projects",
|
||||
href: "#product",
|
||||
}}
|
||||
items={[
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/luxury-outdoor-hotel_1150-12915.jpg",
|
||||
},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/division-sign-made-green-grass-isolated_169016-57948.jpg",
|
||||
},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/abstract-blur-defocused-hotel-resort_74190-6848.jpg",
|
||||
},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/relaxation-space-garden-with-beds_1232-3472.jpg",
|
||||
},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/gardener_23-2148013417.jpg",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<>
|
||||
<SectionBg src="https://storage.googleapis.com/webild/users/user_3FUQa0ZWeM3nmyILoJWMMWG8CWg/uploaded-1782128289234-2l64vswo.jpg">
|
||||
<HeroSection />
|
||||
</SectionBg>
|
||||
|
||||
<div id="about" data-section="about">
|
||||
<SectionErrorBoundary name="about">
|
||||
<AboutTextSplit
|
||||
title="Decades of Horticultural Excellence"
|
||||
descriptions={[
|
||||
"GreenScape Landscaping has been serving the community for over 15 years, providing exceptional landscape management and creative design solutions. Our team of certified horticulturists brings passion and science together in every project.",
|
||||
"We believe that a beautiful landscape is more than just plants—it's an extension of your home. Whether it's sustainable lawn care or complex hardscaping, we approach every task with the same commitment to detail and quality.",
|
||||
]}
|
||||
primaryButton={{
|
||||
text: "Learn About Our Process",
|
||||
href: "#",
|
||||
}}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<AboutSection />
|
||||
|
||||
<div id="features" data-section="features">
|
||||
<SectionErrorBoundary name="features">
|
||||
<FeaturesBentoGrid
|
||||
tag="Our Core Services"
|
||||
title="Complete Property Maintenance"
|
||||
description="Comprehensive solutions tailored to your unique landscape needs throughout every season."
|
||||
features={[
|
||||
{
|
||||
title: "Precision Mowing",
|
||||
description: "Professional-grade lawn care and edge trimming for a perfect finish.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/meadow_1136-294.jpg",
|
||||
},
|
||||
{
|
||||
title: "Seasonal Planting",
|
||||
description: "Curated flower beds and plant installations suited to our regional climate.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/nature-orange-yard-leaf-public-white_1417-1006.jpg",
|
||||
},
|
||||
{
|
||||
title: "Hardscaping & Patios",
|
||||
description: "Stunning stone masonry and durable outdoor living structures.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/dirt-road-countryside_1112-871.jpg",
|
||||
},
|
||||
{
|
||||
title: "Nightscaping",
|
||||
description: "Elegant low-voltage lighting to highlight your home and landscape.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/town-square-shenzhen_1359-1110.jpg",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<SectionBg src="https://storage.googleapis.com/webild/users/user_3FUQa0ZWeM3nmyILoJWMMWG8CWg/uploaded-1782128289235-iu181g1w.jpg">
|
||||
<FeaturesSection />
|
||||
</SectionBg>
|
||||
|
||||
<div id="product" data-section="product">
|
||||
<SectionErrorBoundary name="product">
|
||||
<FeaturesRevealCardsBento
|
||||
tag="Portfolio"
|
||||
title="Selected Projects"
|
||||
description="Take a look at some of our recent transformations and landscaping projects."
|
||||
items={[
|
||||
{
|
||||
title: "Modern Garden",
|
||||
description: "A complete redesign of a suburban residential backyard.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/stone-road_1417-1558.jpg",
|
||||
},
|
||||
{
|
||||
title: "Stone Pathways",
|
||||
description: "Hand-laid natural stone walkways and garden paths.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/mossy-ground-middle-cobblestone-pathway_181624-17204.jpg",
|
||||
},
|
||||
{
|
||||
title: "Custom Designs",
|
||||
description: "Bespoke garden plans tailored to specific property layouts.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/plants-pots-blurred-background-yard-blurred-background_169016-19894.jpg",
|
||||
},
|
||||
{
|
||||
title: "Water Features",
|
||||
description: "Tranquil koi ponds and decorative stone fountains.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/outdoor-swimming-pool-with-umbrella-chair-lounge-around-there-leisure-travel_74190-7873.jpg",
|
||||
},
|
||||
{
|
||||
title: "Tree Care",
|
||||
description: "Professional pruning and health assessment for large trees.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/gardener-looking-fresh-green-plant_23-2147844325.jpg",
|
||||
},
|
||||
{
|
||||
title: "Hedge Styling",
|
||||
description: "Precision shaping and maintenance of large privacy hedges.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/long-shot-woman-mowing-grass_23-2148579932.jpg",
|
||||
},
|
||||
{
|
||||
title: "Full Overhaul",
|
||||
description: "Comprehensive property rejuvenation project.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/male-gardener-working-garden_23-2148165264.jpg",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<ProductSection />
|
||||
|
||||
<div id="metrics" data-section="metrics">
|
||||
<SectionErrorBoundary name="metrics">
|
||||
<MetricsSimpleCards
|
||||
tag="Our Impact"
|
||||
title="Proven Track Record"
|
||||
description="Quality landscaping statistics that demonstrate our commitment and reach."
|
||||
metrics={[
|
||||
{
|
||||
value: "15+",
|
||||
description: "Years in Business",
|
||||
},
|
||||
{
|
||||
value: "500+",
|
||||
description: "Successful Projects",
|
||||
},
|
||||
{
|
||||
value: "98%",
|
||||
description: "Client Satisfaction",
|
||||
},
|
||||
{
|
||||
value: "120+",
|
||||
description: "Annual Maintenance",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<SectionBg src="https://storage.googleapis.com/webild/users/user_3FUQa0ZWeM3nmyILoJWMMWG8CWg/uploaded-1782128289235-56h4behn.jpg">
|
||||
<MetricsSection />
|
||||
</SectionBg>
|
||||
<PricingSection />
|
||||
|
||||
<div id="testimonials" data-section="testimonials">
|
||||
<SectionErrorBoundary name="testimonials">
|
||||
<TestimonialTrustCard
|
||||
quote="GreenScape transformed my barren yard into a botanical paradise. Their crew is incredibly professional and always leaves the property pristine."
|
||||
rating={5}
|
||||
author="Robert M., Homeowner"
|
||||
avatars={[
|
||||
{
|
||||
name: "Client 1",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/close-up-outdoors-portrait-young-attractive-bearded-caucasian-male-gardener-blue-t-shirt-smiling-camera-planting-seeds-garden-watering-plants_176420-19925.jpg",
|
||||
},
|
||||
{
|
||||
name: "Client 2",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/real-communication-concept-positive-young-married-couple-mixed-race-friends-enjoys-spare-time-have-fun-talk-each-other_273609-18716.jpg",
|
||||
},
|
||||
{
|
||||
name: "Client 3",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/women-taking-care-their-plants-greenhouse_23-2149037250.jpg",
|
||||
},
|
||||
{
|
||||
name: "Client 4",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/black-woman-running-flower-business-medium-shot_23-2149871117.jpg",
|
||||
},
|
||||
{
|
||||
name: "Client 5",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/women-working-greenhouse-with-green-trees_1157-30882.jpg",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<TestimonialsSection />
|
||||
|
||||
<div id="faq" data-section="faq">
|
||||
<SectionErrorBoundary name="faq">
|
||||
<FaqTabbedAccordion
|
||||
tag="Support"
|
||||
title="Frequently Asked Questions"
|
||||
description="Find answers about our services, pricing, and scheduling."
|
||||
categories={[
|
||||
{
|
||||
name: "General",
|
||||
items: [
|
||||
{
|
||||
question: "What areas do you serve?",
|
||||
answer: "We currently serve the greater metro area within a 50-mile radius of our main office.",
|
||||
},
|
||||
{
|
||||
question: "Do you provide estimates?",
|
||||
answer: "Yes, we provide free onsite estimates for all new project inquiries.",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Services",
|
||||
items: [
|
||||
{
|
||||
question: "Do you handle seasonal cleanups?",
|
||||
answer: "Absolutely, we specialize in both spring and fall leaf and garden bed cleanups.",
|
||||
},
|
||||
{
|
||||
question: "Is landscaping maintenance a contract service?",
|
||||
answer: "We offer both seasonal maintenance contracts and one-time service calls.",
|
||||
},
|
||||
],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<FaqSection />
|
||||
|
||||
<div id="contact" data-section="contact">
|
||||
<SectionErrorBoundary name="contact">
|
||||
<ContactCta
|
||||
tag="Contact Us"
|
||||
text="Ready to revitalize your garden? Let's discuss your project today."
|
||||
primaryButton={{
|
||||
text: "Schedule Consultation",
|
||||
href: "#",
|
||||
}}
|
||||
secondaryButton={{
|
||||
text: "Call Now",
|
||||
href: "tel:+15550123",
|
||||
}}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<ContactSection />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
26
src/pages/HomePage/sections/About.tsx
Normal file
26
src/pages/HomePage/sections/About.tsx
Normal file
@@ -0,0 +1,26 @@
|
||||
// AUTO-GENERATED by per-section-migrate. Edit freely — Bob will treat this
|
||||
// file as the canonical source for the "about" section.
|
||||
|
||||
import React from 'react';
|
||||
import AboutTextSplit from '@/components/sections/about/AboutTextSplit';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function AboutSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="about" data-section="about">
|
||||
<SectionErrorBoundary name="about">
|
||||
<AboutTextSplit
|
||||
title="Decades of Horticultural Excellence"
|
||||
descriptions={[
|
||||
"Fourieearthworks has been serving the community for over 15 years, providing exceptional landscape management and creative design solutions. Our team of certified horticulturists brings passion and science together in every project.",
|
||||
"We believe that a beautiful landscape is more than just plants—it's an extension of your home. Whether it's sustainable lawn care or complex hardscaping, we approach every task with the same commitment to detail and quality.",
|
||||
]}
|
||||
primaryButton={{
|
||||
text: "Learn About Our Process",
|
||||
href: "#",
|
||||
}}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
27
src/pages/HomePage/sections/Contact.tsx
Normal file
27
src/pages/HomePage/sections/Contact.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
// AUTO-GENERATED by per-section-migrate. Edit freely — Bob will treat this
|
||||
// file as the canonical source for the "contact" section.
|
||||
|
||||
import React from 'react';
|
||||
import ContactCta from '@/components/sections/contact/ContactCta';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function ContactSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="contact" data-section="contact">
|
||||
<SectionErrorBoundary name="contact">
|
||||
<ContactCta
|
||||
tag="Contact Us"
|
||||
text="Ready to revitalize your garden? Let's discuss your project today."
|
||||
primaryButton={{
|
||||
text: "Schedule Consultation",
|
||||
href: "#",
|
||||
}}
|
||||
secondaryButton={{
|
||||
text: "Call Now",
|
||||
href: "tel:+15550123",
|
||||
}}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
48
src/pages/HomePage/sections/Faq.tsx
Normal file
48
src/pages/HomePage/sections/Faq.tsx
Normal file
@@ -0,0 +1,48 @@
|
||||
// AUTO-GENERATED by per-section-migrate. Edit freely — Bob will treat this
|
||||
// file as the canonical source for the "faq" section.
|
||||
|
||||
import React from 'react';
|
||||
import FaqTabbedAccordion from '@/components/sections/faq/FaqTabbedAccordion';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function FaqSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="faq" data-section="faq">
|
||||
<SectionErrorBoundary name="faq">
|
||||
<FaqTabbedAccordion
|
||||
tag="Support"
|
||||
title="Frequently Asked Questions"
|
||||
description="Find answers about our services, pricing, and scheduling."
|
||||
categories={[
|
||||
{
|
||||
name: "General",
|
||||
items: [
|
||||
{
|
||||
question: "What areas do you serve?",
|
||||
answer: "We currently serve the greater metro area within a 50-mile radius of our main office.",
|
||||
},
|
||||
{
|
||||
question: "Do you provide estimates?",
|
||||
answer: "Yes, we provide free onsite estimates for all new project inquiries.",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Services",
|
||||
items: [
|
||||
{
|
||||
question: "Do you handle seasonal cleanups?",
|
||||
answer: "Absolutely, we specialize in both spring and fall leaf and garden bed cleanups.",
|
||||
},
|
||||
{
|
||||
question: "Is landscaping maintenance a contract service?",
|
||||
answer: "We offer both seasonal maintenance contracts and one-time service calls.",
|
||||
},
|
||||
],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
42
src/pages/HomePage/sections/Features.tsx
Normal file
42
src/pages/HomePage/sections/Features.tsx
Normal file
@@ -0,0 +1,42 @@
|
||||
// AUTO-GENERATED by per-section-migrate. Edit freely — Bob will treat this
|
||||
// file as the canonical source for the "features" section.
|
||||
|
||||
import React from 'react';
|
||||
import FeaturesBentoGrid from '@/components/sections/features/FeaturesBentoGrid';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function FeaturesSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="features" data-section="features">
|
||||
<SectionErrorBoundary name="features">
|
||||
<FeaturesBentoGrid
|
||||
tag="Our Core Services"
|
||||
title="Complete Property Maintenance"
|
||||
description="Comprehensive solutions tailored to your unique landscape needs throughout every season."
|
||||
features={[
|
||||
{
|
||||
title: "Precision Mowing",
|
||||
description: "Professional-grade lawn care and edge trimming for a perfect finish.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/meadow_1136-294.jpg",
|
||||
},
|
||||
{
|
||||
title: "Seasonal Planting",
|
||||
description: "Curated flower beds and plant installations suited to our regional climate.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/nature-orange-yard-leaf-public-white_1417-1006.jpg",
|
||||
},
|
||||
{
|
||||
title: "Hardscaping & Patios",
|
||||
description: "Stunning stone masonry and durable outdoor living structures.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/dirt-road-countryside_1112-871.jpg",
|
||||
},
|
||||
{
|
||||
title: "Nightscaping",
|
||||
description: "Elegant low-voltage lighting to highlight your home and landscape.",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/town-square-shenzhen_1359-1110.jpg",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
45
src/pages/HomePage/sections/Hero.tsx
Normal file
45
src/pages/HomePage/sections/Hero.tsx
Normal file
@@ -0,0 +1,45 @@
|
||||
// AUTO-GENERATED by per-section-migrate. Edit freely — Bob will treat this
|
||||
// file as the canonical source for the "hero" section.
|
||||
|
||||
import React from 'react';
|
||||
import HeroTiltedCards from '@/components/sections/hero/HeroTiltedCards';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function HeroSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="hero" data-section="hero">
|
||||
<SectionErrorBoundary name="hero">
|
||||
<HeroTiltedCards
|
||||
tag="Expert Landscaping Services"
|
||||
title="We Cultivate Your Outdoor Dream Spaces"
|
||||
description="Transforming residential and commercial properties into lush, sustainable landscapes with precision, care, and professional expertise."
|
||||
primaryButton={{
|
||||
text: "Book Consultation",
|
||||
href: "#contact",
|
||||
}}
|
||||
secondaryButton={{
|
||||
text: "View Projects",
|
||||
href: "#product",
|
||||
}}
|
||||
items={[
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/luxury-outdoor-hotel_1150-12915.jpg",
|
||||
},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/division-sign-made-green-grass-isolated_169016-57948.jpg",
|
||||
},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/abstract-blur-defocused-hotel-resort_74190-6848.jpg",
|
||||
},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/relaxation-space-garden-with-beds_1232-3472.jpg",
|
||||
},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/gardener_23-2148013417.jpg",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
38
src/pages/HomePage/sections/Metrics.tsx
Normal file
38
src/pages/HomePage/sections/Metrics.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
// AUTO-GENERATED by per-section-migrate. Edit freely — Bob will treat this
|
||||
// file as the canonical source for the "metrics" section.
|
||||
|
||||
import React from 'react';
|
||||
import MetricsSimpleCards from '@/components/sections/metrics/MetricsSimpleCards';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function MetricsSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="metrics" data-section="metrics">
|
||||
<SectionErrorBoundary name="metrics">
|
||||
<MetricsSimpleCards
|
||||
tag="Our Impact"
|
||||
title="Proven Track Record"
|
||||
description="Quality landscaping statistics that demonstrate our commitment and reach."
|
||||
metrics={[
|
||||
{
|
||||
value: "15+",
|
||||
description: "Years in Business",
|
||||
},
|
||||
{
|
||||
value: "500+",
|
||||
description: "Successful Projects",
|
||||
},
|
||||
{
|
||||
value: "98%",
|
||||
description: "Client Satisfaction",
|
||||
},
|
||||
{
|
||||
value: "120+",
|
||||
description: "Annual Maintenance",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
25
src/pages/HomePage/sections/Pricing.tsx
Normal file
25
src/pages/HomePage/sections/Pricing.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import ImageOrVideo from '@/components/ui/ImageOrVideo';
|
||||
import ScrollReveal from '@/components/ui/ScrollReveal';
|
||||
|
||||
export default function PricingSection() {
|
||||
return (
|
||||
<section data-webild-section="pricing" id="pricing" className="relative w-full py-24 bg-background">
|
||||
<div className="w-content-width mx-auto">
|
||||
<ScrollReveal variant="fade">
|
||||
<div className="text-center mb-16">
|
||||
<h2 className="text-4xl md:text-5xl font-bold text-foreground mb-4">Our Pricing</h2>
|
||||
<p className="text-lg text-accent max-w-2xl mx-auto">Transparent pricing for all our services.</p>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
<ScrollReveal variant="fade" delay={0.2}>
|
||||
<div className="w-full max-w-4xl mx-auto rounded-lg overflow-hidden shadow-lg">
|
||||
<ImageOrVideo
|
||||
imageSrc="https://storage.googleapis.com/webild/users/user_3FUQa0ZWeM3nmyILoJWMMWG8CWg/uploaded-1782127565331-lvd6pjbn.jpg"
|
||||
className="w-full h-auto object-contain"
|
||||
/>
|
||||
</div>
|
||||
</ScrollReveal>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
64
src/pages/HomePage/sections/Product.tsx
Normal file
64
src/pages/HomePage/sections/Product.tsx
Normal file
@@ -0,0 +1,64 @@
|
||||
// AUTO-GENERATED by per-section-migrate. Edit freely — Bob will treat this
|
||||
// file as the canonical source for the "product" section.
|
||||
|
||||
import React from 'react';
|
||||
import FeaturesRevealCardsBento from '@/components/sections/features/FeaturesRevealCardsBento';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function ProductSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="product" data-section="product">
|
||||
<SectionErrorBoundary name="product">
|
||||
<FeaturesRevealCardsBento
|
||||
tag="Portfolio"
|
||||
title="Selected Projects"
|
||||
description="Take a look at some of our recent transformations and landscaping projects."
|
||||
items={[
|
||||
{
|
||||
title: "Modern Garden",
|
||||
description: "A complete redesign of a suburban residential backyard.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/stone-road_1417-1558.jpg",
|
||||
},
|
||||
{
|
||||
title: "Stone Pathways",
|
||||
description: "Hand-laid natural stone walkways and garden paths.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/mossy-ground-middle-cobblestone-pathway_181624-17204.jpg",
|
||||
},
|
||||
{
|
||||
title: "Custom Designs",
|
||||
description: "Bespoke garden plans tailored to specific property layouts.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/plants-pots-blurred-background-yard-blurred-background_169016-19894.jpg",
|
||||
},
|
||||
{
|
||||
title: "Water Features",
|
||||
description: "Tranquil koi ponds and decorative stone fountains.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/outdoor-swimming-pool-with-umbrella-chair-lounge-around-there-leisure-travel_74190-7873.jpg",
|
||||
},
|
||||
{
|
||||
title: "Tree Care",
|
||||
description: "Professional pruning and health assessment for large trees.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/gardener-looking-fresh-green-plant_23-2147844325.jpg",
|
||||
},
|
||||
{
|
||||
title: "Hedge Styling",
|
||||
description: "Precision shaping and maintenance of large privacy hedges.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/long-shot-woman-mowing-grass_23-2148579932.jpg",
|
||||
},
|
||||
{
|
||||
title: "Full Overhaul",
|
||||
description: "Comprehensive property rejuvenation project.",
|
||||
href: "#",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/male-gardener-working-garden_23-2148165264.jpg",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
42
src/pages/HomePage/sections/Testimonials.tsx
Normal file
42
src/pages/HomePage/sections/Testimonials.tsx
Normal file
@@ -0,0 +1,42 @@
|
||||
// AUTO-GENERATED by per-section-migrate. Edit freely — Bob will treat this
|
||||
// file as the canonical source for the "testimonials" section.
|
||||
|
||||
import React from 'react';
|
||||
import TestimonialTrustCard from '@/components/sections/testimonial/TestimonialTrustCard';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function TestimonialsSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="testimonials" data-section="testimonials">
|
||||
<SectionErrorBoundary name="testimonials">
|
||||
<TestimonialTrustCard
|
||||
quote="GreenScape transformed my barren yard into a botanical paradise. Their crew is incredibly professional and always leaves the property pristine."
|
||||
rating={5}
|
||||
author="Robert M., Homeowner"
|
||||
avatars={[
|
||||
{
|
||||
name: "Client 1",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/close-up-outdoors-portrait-young-attractive-bearded-caucasian-male-gardener-blue-t-shirt-smiling-camera-planting-seeds-garden-watering-plants_176420-19925.jpg",
|
||||
},
|
||||
{
|
||||
name: "Client 2",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/real-communication-concept-positive-young-married-couple-mixed-race-friends-enjoys-spare-time-have-fun-talk-each-other_273609-18716.jpg",
|
||||
},
|
||||
{
|
||||
name: "Client 3",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/women-taking-care-their-plants-greenhouse_23-2149037250.jpg",
|
||||
},
|
||||
{
|
||||
name: "Client 4",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/black-woman-running-flower-business-medium-shot_23-2149871117.jpg",
|
||||
},
|
||||
{
|
||||
name: "Client 5",
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/women-working-greenhouse-with-green-trees_1157-30882.jpg",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user