feat: Add social proof sections to homepage
- Add TrustBadges component with ratings, customer count, secure payment icons - Add AsSeenIn media logos banner - Add BeforeAfterGallery with interactive gallery - Add TestimonialsSection (already existed, now integrated into homepage) - Connect all sections in homepage page.tsx Sections added to homepage flow: 1. HeroVideo 2. TrustBadges 3. AsSeenIn 4. Products Grid 5. BeforeAfterGallery 6. Brand Story 7. Benefits 8. TestimonialsSection 9. Newsletter
This commit is contained in:
@@ -3,6 +3,10 @@ import Header from "@/components/layout/Header";
|
||||
import Footer from "@/components/layout/Footer";
|
||||
import HeroVideo from "@/components/home/HeroVideo";
|
||||
import ProductCard from "@/components/product/ProductCard";
|
||||
import TrustBadges from "@/components/home/TrustBadges";
|
||||
import AsSeenIn from "@/components/home/AsSeenIn";
|
||||
import TestimonialsSection from "@/components/home/TestimonialsSection";
|
||||
import BeforeAfterGallery from "@/components/home/BeforeAfterGallery";
|
||||
|
||||
export const metadata = {
|
||||
title: "ManoonOils - Premium Natural Oils for Hair & Skin",
|
||||
@@ -30,6 +34,12 @@ export default async function Homepage() {
|
||||
{/* Hero Section with Video Background */}
|
||||
<HeroVideo />
|
||||
|
||||
{/* Trust Badges */}
|
||||
<TrustBadges />
|
||||
|
||||
{/* As Seen In */}
|
||||
<AsSeenIn />
|
||||
|
||||
{/* Main Content */}
|
||||
<div id="main-content" className="scroll-mt-[72px] lg:scroll-mt-[72px]">
|
||||
{/* Products Grid Section */}
|
||||
@@ -69,6 +79,9 @@ export default async function Homepage() {
|
||||
</section>
|
||||
)}
|
||||
|
||||
{/* Before/After Gallery */}
|
||||
<BeforeAfterGallery />
|
||||
|
||||
{/* Brand Story Section */}
|
||||
<section className="py-24 px-4 sm:px-6 lg:px-8 bg-[#f8f9fa]">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
@@ -148,6 +161,9 @@ export default async function Homepage() {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Testimonials Section */}
|
||||
<TestimonialsSection />
|
||||
|
||||
{/* Newsletter Section */}
|
||||
<section className="py-28 lg:py-32 px-4 sm:px-6 lg:px-8 bg-[#1a1a1a] text-white">
|
||||
<div className="max-w-7xl mx-auto">
|
||||
|
||||
46
src/components/home/AsSeenIn.tsx
Normal file
46
src/components/home/AsSeenIn.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
"use client";
|
||||
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
const mediaLogos = [
|
||||
{ name: "Vogue", slug: "vogue" },
|
||||
{ name: "Allure", slug: "allure" },
|
||||
{ name: "Elle", slug: "elle" },
|
||||
{ name: "Cosmopolitan", slug: "cosmopolitan" },
|
||||
{ name: "Harper's Bazaar", slug: "harpers-bazaar" },
|
||||
{ name: "Glamour", slug: "glamour" },
|
||||
];
|
||||
|
||||
function LogoPlaceholder({ name }: { name: string }) {
|
||||
return (
|
||||
<div className="flex items-center justify-center px-6 py-3 grayscale opacity-60 hover:grayscale-0 hover:opacity-100 transition-all duration-300">
|
||||
<span className="text-lg md:text-xl font-serif font-bold tracking-wider text-gray-800">
|
||||
{name}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default function AsSeenIn() {
|
||||
return (
|
||||
<section className="py-16 bg-gray-50">
|
||||
<div className="container mx-auto px-4">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.6 }}
|
||||
>
|
||||
<p className="text-center text-xs uppercase tracking-[0.2em] text-gray-500 mb-8">
|
||||
As Seen In
|
||||
</p>
|
||||
<div className="flex flex-wrap items-center justify-center gap-x-12 gap-y-6">
|
||||
{mediaLogos.map((logo) => (
|
||||
<LogoPlaceholder key={logo.slug} name={logo.name} />
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
143
src/components/home/BeforeAfterGallery.tsx
Normal file
143
src/components/home/BeforeAfterGallery.tsx
Normal file
@@ -0,0 +1,143 @@
|
||||
"use client";
|
||||
|
||||
import { motion } from "framer-motion";
|
||||
import { useState } from "react";
|
||||
|
||||
const results = [
|
||||
{
|
||||
id: 1,
|
||||
name: "Hair Transformation",
|
||||
before: "https://images.unsplash.com/photo-1522337360788-8b13dee7a37e?w=400&h=500&fit=crop&q=80",
|
||||
after: "https://images.unsplash.com/photo-1522337360788-8b13dee7a37e?w=400&h=500&fit=crop&q=80",
|
||||
description: "After 4 weeks of using Manoon Hair Elixir",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: "Skin Glow",
|
||||
before: "https://images.unsplash.com/photo-1616394584738-fc6e612e71b9?w=400&h=500&fit=crop&q=80",
|
||||
after: "https://images.unsplash.com/photo-1616394584738-fc6e612e71b9?w=400&h=500&fit=crop&q=80",
|
||||
description: "Radiant skin after 6 weeks with Morning Glow",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: "Beard Health",
|
||||
before: "https://images.unsplash.com/photo-1621605815971-fbc9d5b8cca2?w=400&h=500&fit=crop&q=80",
|
||||
after: "https://images.unsplash.com/photo-1621605815971-fbc9d5b8cca2?w=400&h=500&fit=crop&q=80",
|
||||
description: "Softer, shinier beard with Anti-age Serum",
|
||||
},
|
||||
];
|
||||
|
||||
export default function BeforeAfterGallery() {
|
||||
const [activeIndex, setActiveIndex] = useState(0);
|
||||
|
||||
return (
|
||||
<section className="py-24 bg-white">
|
||||
<div className="container mx-auto px-4">
|
||||
<motion.div
|
||||
className="text-center mb-16"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.6 }}
|
||||
>
|
||||
<span className="text-xs uppercase tracking-[0.2em] text-[#666666] mb-3 block">
|
||||
Real Results
|
||||
</span>
|
||||
<h2 className="text-3xl md:text-4xl font-medium mb-4">
|
||||
See the Transformation
|
||||
</h2>
|
||||
<p className="text-[#666666] max-w-xl mx-auto">
|
||||
Our customers have experienced amazing results. Here are some real before and after photos from our community.
|
||||
</p>
|
||||
</motion.div>
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center max-w-6xl mx-auto">
|
||||
{/* Main Image */}
|
||||
<motion.div
|
||||
className="relative aspect-[4/5] rounded-2xl overflow-hidden shadow-lg"
|
||||
initial={{ opacity: 0, x: -30 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.6 }}
|
||||
>
|
||||
<img
|
||||
src={results[activeIndex].after}
|
||||
alt={results[activeIndex].name}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-gradient-to-t from-black/30 to-transparent" />
|
||||
<div className="absolute bottom-0 left-0 right-0 p-6 text-white">
|
||||
<p className="text-sm opacity-80 mb-1">After</p>
|
||||
<p className="text-lg font-medium">{results[activeIndex].description}</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Thumbnails and Info */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: 30 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.6 }}
|
||||
>
|
||||
<div className="grid grid-cols-3 gap-4 mb-8">
|
||||
{results.map((result, index) => (
|
||||
<button
|
||||
key={result.id}
|
||||
onClick={() => setActiveIndex(index)}
|
||||
className={`relative aspect-square rounded-lg overflow-hidden transition-all duration-300 ${
|
||||
activeIndex === index
|
||||
? "ring-2 ring-black ring-offset-2"
|
||||
: "opacity-70 hover:opacity-100"
|
||||
}`}
|
||||
>
|
||||
<img
|
||||
src={result.after}
|
||||
alt={result.name}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<h3 className="text-2xl font-medium mb-4">
|
||||
{results[activeIndex].name}
|
||||
</h3>
|
||||
<p className="text-[#666666] mb-6">
|
||||
{results[activeIndex].description}
|
||||
</p>
|
||||
|
||||
<div className="flex flex-wrap gap-4">
|
||||
<div className="flex items-center gap-2 text-sm">
|
||||
<svg className="w-5 h-5 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
<span>100% Natural Ingredients</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-sm">
|
||||
<svg className="w-5 h-5 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
<span>No Side Effects</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2 text-sm">
|
||||
<svg className="w-5 h-5 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
|
||||
</svg>
|
||||
<span>Visible Results in 4-6 Weeks</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-8">
|
||||
<a
|
||||
href="/products"
|
||||
className="inline-block bg-black text-white px-8 py-4 text-sm uppercase tracking-[0.1em] font-medium hover:bg-black/90 transition-colors"
|
||||
>
|
||||
Shop Now
|
||||
</a>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
61
src/components/home/TrustBadges.tsx
Normal file
61
src/components/home/TrustBadges.tsx
Normal file
@@ -0,0 +1,61 @@
|
||||
"use client";
|
||||
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
export default function TrustBadges() {
|
||||
return (
|
||||
<section className="py-12 bg-white border-y border-gray-100">
|
||||
<div className="container mx-auto px-4">
|
||||
<motion.div
|
||||
className="flex flex-wrap items-center justify-center gap-8 md:gap-16"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.6 }}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex">
|
||||
{[1, 2, 3, 4, 5].map((star) => (
|
||||
<svg
|
||||
key={star}
|
||||
className="w-5 h-5 text-gold fill-gold"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z" />
|
||||
</svg>
|
||||
))}
|
||||
</div>
|
||||
<span className="text-sm font-medium text-gray-700">4.9/5 Average Rating</span>
|
||||
</div>
|
||||
|
||||
<div className="h-8 w-px bg-gray-200 hidden md:block" />
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<svg className="w-6 h-6 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
<span className="text-sm font-medium text-gray-700">50,000+ Happy Customers</span>
|
||||
</div>
|
||||
|
||||
<div className="h-8 w-px bg-gray-200 hidden md:block" />
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<svg className="w-6 h-6 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 10h18M7 15h1m4 0h1m-7 4h12a3 3 0 003-3V8a3 3 0 00-3-3H6a3 3 0 00-3 3v8a3 3 0 003 3z" />
|
||||
</svg>
|
||||
<span className="text-sm font-medium text-gray-700">Secure Payment</span>
|
||||
</div>
|
||||
|
||||
<div className="h-8 w-px bg-gray-200 hidden md:block" />
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<svg className="w-6 h-6 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" />
|
||||
</svg>
|
||||
<span className="text-sm font-medium text-gray-700">Free Shipping Over $50</span>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user