Compare commits
9 Commits
version_2_
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 4484689f32 | |||
|
|
dd7b7c5d00 | ||
| 0c914ca51e | |||
|
|
0e384e98f6 | ||
| 41c95d4055 | |||
|
|
d7fcd8ca72 | ||
| 0eefa4dfbd | |||
|
|
69fdadf86b | ||
| 68fbb4dfe5 |
@@ -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,23 +34,77 @@ 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="Fourieearthworks"
|
||||
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 />
|
||||
|
||||
@@ -13,18 +13,37 @@ 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 (
|
||||
<>
|
||||
<HeroSection />
|
||||
<SectionBg src="https://storage.googleapis.com/webild/users/user_3FUQa0ZWeM3nmyILoJWMMWG8CWg/uploaded-1782128289234-2l64vswo.jpg">
|
||||
<HeroSection />
|
||||
</SectionBg>
|
||||
|
||||
<AboutSection />
|
||||
|
||||
<FeaturesSection />
|
||||
<SectionBg src="https://storage.googleapis.com/webild/users/user_3FUQa0ZWeM3nmyILoJWMMWG8CWg/uploaded-1782128289235-iu181g1w.jpg">
|
||||
<FeaturesSection />
|
||||
</SectionBg>
|
||||
|
||||
<ProductSection />
|
||||
|
||||
<MetricsSection />
|
||||
<SectionBg src="https://storage.googleapis.com/webild/users/user_3FUQa0ZWeM3nmyILoJWMMWG8CWg/uploaded-1782128289235-56h4behn.jpg">
|
||||
<MetricsSection />
|
||||
</SectionBg>
|
||||
<PricingSection />
|
||||
|
||||
<TestimonialsSection />
|
||||
|
||||
|
||||
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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user