Compare commits
2 Commits
version_1_
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| e2f19c4b04 | |||
|
|
c93395947d |
@@ -1,155 +1,27 @@
|
||||
import FaqTwoColumn from '@/components/sections/faq/FaqTwoColumn';
|
||||
import HeroBillboard from '@/components/sections/hero/HeroBillboard';
|
||||
import PricingCenteredCards from '@/components/sections/pricing/PricingCenteredCards';
|
||||
import SocialProofMarquee from '@/components/sections/social-proof/SocialProofMarquee';
|
||||
import TestimonialOverlayCards from '@/components/sections/testimonial/TestimonialOverlayCards';
|
||||
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 TestimonialsSection from './HomePage/sections/Testimonials';
|
||||
import SocialProofSection from './HomePage/sections/SocialProof';
|
||||
import PricingSection from './HomePage/sections/Pricing';
|
||||
import FaqSection from './HomePage/sections/Faq';
|
||||
|
||||
export default function HomePage(): React.JSX.Element {
|
||||
return (
|
||||
<>
|
||||
<div id="hero" data-section="hero">
|
||||
<SectionErrorBoundary name="hero">
|
||||
<HeroBillboard
|
||||
tag="Software Engineer"
|
||||
title="Hi, I'm Mehak Bhutto"
|
||||
description="Building scalable, high-performance software solutions for complex problems. Passionate about cloud-native technologies and clean architecture."
|
||||
primaryButton={{
|
||||
text: "View Projects",
|
||||
href: "/projects",
|
||||
}}
|
||||
secondaryButton={{
|
||||
text: "About Me",
|
||||
href: "/about",
|
||||
}}
|
||||
imageSrc="http://img.b2bpic.net/free-photo/smiling-mechanic-standing-repair-shop_1170-1349.jpg"
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<>
|
||||
<HeroSection />
|
||||
|
||||
<div id="testimonials" data-section="testimonials">
|
||||
<SectionErrorBoundary name="testimonials">
|
||||
<TestimonialOverlayCards
|
||||
tag="Reviews"
|
||||
title="What Partners Say"
|
||||
description="Collaborative success stories from clients and teammates."
|
||||
testimonials={[
|
||||
{
|
||||
name: "Alice Wang",
|
||||
role: "PM",
|
||||
company: "TechInnovate",
|
||||
rating: 5,
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/3d-portrait-businessman_23-2150793883.jpg",
|
||||
},
|
||||
{
|
||||
name: "Bob Smith",
|
||||
role: "CTO",
|
||||
company: "CloudReady",
|
||||
rating: 5,
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/young-blonde-charming-female-isolated_176474-79133.jpg",
|
||||
},
|
||||
{
|
||||
name: "Charlie Davis",
|
||||
role: "Dev",
|
||||
company: "StartupX",
|
||||
rating: 5,
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/portrait-confident-black-businesswoman-office_637285-9877.jpg",
|
||||
},
|
||||
{
|
||||
name: "Dana White",
|
||||
role: "CEO",
|
||||
company: "GrowthApp",
|
||||
rating: 5,
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/close-up-businessman-with-tie_1098-2867.jpg",
|
||||
},
|
||||
{
|
||||
name: "Eve Miller",
|
||||
role: "Designer",
|
||||
company: "CreativeHub",
|
||||
rating: 5,
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/girl-trying-look-like-grown-up_23-2148244890.jpg",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<TestimonialsSection />
|
||||
|
||||
<div id="social-proof" data-section="social-proof">
|
||||
<SectionErrorBoundary name="social-proof">
|
||||
<SocialProofMarquee
|
||||
tag="Experience"
|
||||
title="Trusted By Industry Leaders"
|
||||
description="Collaborated with forward-thinking teams across multiple domains."
|
||||
names={[
|
||||
"TechCloud",
|
||||
"DataFlow Systems",
|
||||
"Innovate Apps",
|
||||
"SecureBridge",
|
||||
"NextGen Labs",
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<SocialProofSection />
|
||||
|
||||
<div id="pricing" data-section="pricing">
|
||||
<SectionErrorBoundary name="pricing">
|
||||
<PricingCenteredCards
|
||||
tag="Consulting"
|
||||
title="Engagement Models"
|
||||
description="Flexible collaboration options to meet your project goals."
|
||||
plans={[
|
||||
{
|
||||
tag: "Freelance",
|
||||
price: "Project Based",
|
||||
description: "Ideal for specific deliverables and feature development.",
|
||||
features: [
|
||||
"Requirements gathering",
|
||||
"Architectural design",
|
||||
"Implementation & testing",
|
||||
],
|
||||
primaryButton: {
|
||||
text: "Inquire",
|
||||
href: "/contact",
|
||||
},
|
||||
},
|
||||
{
|
||||
tag: "Contractor",
|
||||
price: "Hourly/Retainer",
|
||||
description: "Best for long-term integration and team support.",
|
||||
features: [
|
||||
"Daily standups",
|
||||
"Full-stack development",
|
||||
"Code reviews & mentorship",
|
||||
],
|
||||
primaryButton: {
|
||||
text: "Discuss",
|
||||
href: "/contact",
|
||||
},
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<PricingSection />
|
||||
|
||||
<div id="faq" data-section="faq">
|
||||
<SectionErrorBoundary name="faq">
|
||||
<FaqTwoColumn
|
||||
tag="Support"
|
||||
title="Frequently Asked Questions"
|
||||
description="Common inquiries about my development process and services."
|
||||
items={[
|
||||
{
|
||||
question: "What is your primary technology stack?",
|
||||
answer: "I specialize in modern JavaScript/TypeScript, React, Node.js, and cloud-native services like AWS and Kubernetes.",
|
||||
},
|
||||
{
|
||||
question: "Do you work remotely?",
|
||||
answer: "Yes, I am fully equipped for remote collaboration and effective asynchronous communication.",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
<FaqSection />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
30
src/pages/HomePage/sections/Faq.tsx
Normal file
30
src/pages/HomePage/sections/Faq.tsx
Normal file
@@ -0,0 +1,30 @@
|
||||
// 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 FaqTwoColumn from '@/components/sections/faq/FaqTwoColumn';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function FaqSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="faq" data-section="faq">
|
||||
<SectionErrorBoundary name="faq">
|
||||
<FaqTwoColumn
|
||||
tag="Support"
|
||||
title="Frequently Asked Questions"
|
||||
description="Common inquiries about my development process and services."
|
||||
items={[
|
||||
{
|
||||
question: "What is your primary technology stack?",
|
||||
answer: "I specialize in modern JavaScript/TypeScript, React, Node.js, and cloud-native services like AWS and Kubernetes.",
|
||||
},
|
||||
{
|
||||
question: "Do you work remotely?",
|
||||
answer: "Yes, I am fully equipped for remote collaboration and effective asynchronous communication.",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
162
src/pages/HomePage/sections/Hero.tsx
Normal file
162
src/pages/HomePage/sections/Hero.tsx
Normal file
@@ -0,0 +1,162 @@
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck — generated by catalog-eject; runtime-correct but TS strict-mode false-positives on inlined catalog body
|
||||
import Button from "@/components/ui/Button";
|
||||
import HeroBackgroundSlot from "@/components/ui/HeroBackgroundSlot";
|
||||
import TextAnimation from "@/components/ui/TextAnimation";
|
||||
import ImageOrVideo from "@/components/ui/ImageOrVideo";
|
||||
import ScrollReveal from "@/components/ui/ScrollReveal";
|
||||
import AvatarGroup from "@/components/ui/AvatarGroup";
|
||||
|
||||
const primaryButton = {
|
||||
text: "View Projects",
|
||||
href: "/projects"
|
||||
};
|
||||
const secondaryButton = {
|
||||
text: "About Me",
|
||||
href: "/about"
|
||||
};
|
||||
|
||||
type HeroBillboardProps = {
|
||||
tag?: string;
|
||||
title: string;
|
||||
description: string;
|
||||
primaryButton: { text: string; href: string };
|
||||
secondaryButton: { text: string; href: string };
|
||||
avatarsSrc?: string[];
|
||||
avatarsLabel?: string;
|
||||
} & ({ imageSrc: string; videoSrc?: never } | { videoSrc: string; imageSrc?: never });
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { BookOpen, Award, FileText, Github, Terminal } from 'lucide-react';
|
||||
import { motion } from 'motion/react';
|
||||
|
||||
const HeroInline = () => {
|
||||
const [isNight, setIsNight] = useState(false);
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
const hour = new Date().getHours();
|
||||
setIsNight(hour < 6 || hour >= 18);
|
||||
}, []);
|
||||
|
||||
if (!mounted) return null;
|
||||
|
||||
return (
|
||||
<section aria-label="Hero section" className={`relative min-h-[90vh] w-full overflow-hidden transition-colors duration-1000 ${isNight ? 'bg-slate-900 text-slate-200' : 'bg-slate-50 text-slate-800'}`}>
|
||||
{/* Background Window */}
|
||||
<a href="https://github.com" target="_blank" rel="noopener noreferrer" className="absolute top-12 right-12 md:top-24 md:right-24 w-48 h-64 md:w-64 md:h-80 rounded-t-full border-8 border-slate-800 bg-gradient-to-b overflow-hidden shadow-2xl cursor-pointer group z-0 transition-transform hover:scale-105">
|
||||
<div className={`w-full h-full transition-colors duration-1000 relative ${isNight ? 'from-indigo-950 to-purple-900' : 'from-sky-300 to-blue-400'}`}>
|
||||
{isNight ? (
|
||||
<motion.div animate={{ y: [0, -10, 0] }} transition={{ repeat: Infinity, duration: 6, ease: "easeInOut" }} className="absolute top-10 right-10 w-12 h-12 bg-yellow-100 rounded-full shadow-[0_0_20px_rgba(255,255,255,0.8)]" />
|
||||
) : (
|
||||
<motion.div animate={{ y: [0, -10, 0] }} transition={{ repeat: Infinity, duration: 6, ease: "easeInOut" }} className="absolute top-10 right-10 w-16 h-16 bg-yellow-400 rounded-full shadow-[0_0_40px_rgba(255,215,0,0.8)]" />
|
||||
)}
|
||||
<div className="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity bg-black/40 backdrop-blur-sm">
|
||||
<Github className="w-12 h-12 text-white" />
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
|
||||
<div className="relative z-10 max-w-7xl mx-auto px-6 pt-24 pb-0 flex flex-col h-full min-h-[90vh] justify-between">
|
||||
|
||||
{/* Wall Items */}
|
||||
<div className="flex flex-col md:flex-row justify-between items-start w-full mb-12 gap-8">
|
||||
|
||||
{/* Intro Text & Certificates */}
|
||||
<div className="flex flex-col gap-8 max-w-lg">
|
||||
<div>
|
||||
<TextAnimation text="Mehak Bhutto" variant="fade-blur" tag="h1" className="text-5xl md:text-7xl font-bold mb-4" />
|
||||
<TextAnimation text="Software Engineer & Full Stack Developer" variant="fade-blur" tag="p" className="text-xl md:text-2xl opacity-80" />
|
||||
</div>
|
||||
|
||||
<motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} transition={{ delay: 0.3 }} className="flex gap-4">
|
||||
<div className={`p-4 rounded-lg border shadow-lg transform -rotate-3 hover:rotate-0 transition-all cursor-pointer ${isNight ? 'bg-slate-800 border-slate-700' : 'bg-white border-slate-200'}`}>
|
||||
<Award className="w-8 h-8 mb-2 text-yellow-500" />
|
||||
<p className="text-sm font-bold">AWS Certified</p>
|
||||
</div>
|
||||
<div className={`p-4 rounded-lg border shadow-lg transform rotate-2 hover:rotate-0 transition-all cursor-pointer ${isNight ? 'bg-slate-800 border-slate-700' : 'bg-white border-slate-200'}`}>
|
||||
<Award className="w-8 h-8 mb-2 text-blue-500" />
|
||||
<p className="text-sm font-bold">React Expert</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
{/* Bookshelf */}
|
||||
<motion.div initial={{ opacity: 0, x: 50 }} animate={{ opacity: 1, x: 0 }} transition={{ delay: 0.5 }} className={`p-6 rounded-xl shadow-xl w-full md:w-72 ${isNight ? 'bg-slate-800/90' : 'bg-white/90'} backdrop-blur-md border ${isNight ? 'border-slate-700' : 'border-slate-200'}`}>
|
||||
<h3 className="font-bold mb-4 flex items-center gap-2 text-lg"><BookOpen className="w-5 h-5" /> Tech Stack</h3>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{['React', 'TypeScript', 'Node.js', 'Next.js', 'Tailwind CSS', 'GraphQL', 'PostgreSQL', 'Docker'].map(tech => (
|
||||
<span key={tech} className={`text-xs px-3 py-1.5 rounded-full font-medium ${isNight ? 'bg-slate-700 text-slate-300' : 'bg-slate-100 text-slate-700'}`}>{tech}</span>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
{/* Desk Area */}
|
||||
<div className="relative mt-auto pt-20">
|
||||
{/* Desk Surface */}
|
||||
<div className={`absolute bottom-0 left-1/2 -translate-x-1/2 w-[150vw] h-64 -z-10 ${isNight ? 'bg-slate-800' : 'bg-slate-200'} shadow-[inset_0_20px_50px_rgba(0,0,0,0.1)]`} style={{ transform: 'perspective(1000px) rotateX(70deg) translateY(100px)' }}></div>
|
||||
|
||||
<div className="flex flex-col md:flex-row justify-center items-end gap-8 md:gap-16 pb-8 relative z-20">
|
||||
|
||||
{/* Resume */}
|
||||
<motion.a whileHover={{ y: -15, rotate: -2 }} href="/resume.pdf" className={`hidden md:flex p-6 rounded-lg shadow-2xl transform -rotate-6 w-48 h-64 flex-col items-center justify-center gap-4 transition-colors ${isNight ? 'bg-slate-700 hover:bg-slate-600' : 'bg-white hover:bg-slate-50'}`}>
|
||||
<FileText className="w-16 h-16 text-blue-500" />
|
||||
<span className="font-bold text-center">Download Résumé</span>
|
||||
<div className="w-full h-2 bg-slate-200 rounded mt-auto"></div>
|
||||
<div className="w-3/4 h-2 bg-slate-200 rounded"></div>
|
||||
<div className="w-full h-2 bg-slate-200 rounded"></div>
|
||||
</motion.a>
|
||||
|
||||
{/* Laptop */}
|
||||
<motion.a whileHover={{ y: -5 }} href="#projects" className="relative group cursor-pointer z-30">
|
||||
<div className={`w-[300px] md:w-[500px] h-[200px] md:h-[320px] rounded-t-2xl border-[12px] border-b-0 p-2 flex flex-col shadow-2xl ${isNight ? 'bg-slate-900 border-slate-700' : 'bg-slate-800 border-slate-900'}`}>
|
||||
<div className="w-full h-full bg-slate-950 rounded-sm overflow-hidden relative flex flex-col">
|
||||
{/* Screen Content */}
|
||||
<div className="bg-slate-900 p-2 flex gap-2 border-b border-slate-800">
|
||||
<div className="w-3 h-3 rounded-full bg-red-500"></div>
|
||||
<div className="w-3 h-3 rounded-full bg-yellow-500"></div>
|
||||
<div className="w-3 h-3 rounded-full bg-green-500"></div>
|
||||
</div>
|
||||
<div className="flex-1 p-6 flex flex-col items-center justify-center text-center relative overflow-hidden">
|
||||
<Terminal className="w-12 h-12 text-green-400 mb-4 opacity-50 absolute top-4 right-4" />
|
||||
<h2 className="text-2xl md:text-3xl font-bold text-white mb-2">Live Projects</h2>
|
||||
<p className="text-green-400 font-mono text-sm md:text-base mb-6">{">"} ./view_portfolio.sh</p>
|
||||
<Button text="Explore Work" variant="primary" className="shadow-lg shadow-primary-cta/20" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className={`w-[340px] md:w-[560px] h-4 md:h-6 rounded-b-2xl -ml-[20px] md:-ml-[30px] shadow-xl ${isNight ? 'bg-slate-600' : 'bg-slate-400'}`}></div>
|
||||
<div className={`w-32 md:w-48 h-1 md:h-2 mx-auto rounded-b-md ${isNight ? 'bg-slate-500' : 'bg-slate-300'}`}></div>
|
||||
</motion.a>
|
||||
|
||||
{/* Coffee Mug */}
|
||||
<motion.div whileHover={{ y: -10, rotate: 5 }} className="hidden md:block relative w-24 h-28 cursor-pointer group">
|
||||
<div className={`absolute bottom-0 w-full h-24 rounded-xl ${isNight ? 'bg-slate-700' : 'bg-white'} shadow-xl flex items-center justify-center border-2 ${isNight ? 'border-slate-600' : 'border-slate-200'}`}>
|
||||
<span className="text-3xl">☕</span>
|
||||
</div>
|
||||
<div className={`absolute top-4 -right-4 w-8 h-12 border-4 rounded-r-xl ${isNight ? 'border-slate-700' : 'border-white'}`}></div>
|
||||
<motion.div animate={{ y: [-5, -20], opacity: [0, 0.8, 0] }} transition={{ repeat: Infinity, duration: 2.5, ease: "easeOut" }} className="absolute -top-4 left-1/2 w-3 h-12 bg-white/40 blur-md rounded-full"></motion.div>
|
||||
<motion.div animate={{ y: [-5, -20], opacity: [0, 0.6, 0] }} transition={{ repeat: Infinity, duration: 2, delay: 0.5, ease: "easeOut" }} className="absolute -top-2 left-1/3 w-2 h-10 bg-white/40 blur-md rounded-full"></motion.div>
|
||||
|
||||
{/* Tooltip on hover */}
|
||||
<div className="absolute -top-12 left-1/2 -translate-x-1/2 bg-black text-white text-xs px-3 py-1 rounded opacity-0 group-hover:opacity-100 transition-opacity whitespace-nowrap pointer-events-none">
|
||||
Fueled by Coffee
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default function HeroSection() {
|
||||
return (
|
||||
<div data-webild-section="hero" id="hero">
|
||||
<HeroInline />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
50
src/pages/HomePage/sections/Pricing.tsx
Normal file
50
src/pages/HomePage/sections/Pricing.tsx
Normal file
@@ -0,0 +1,50 @@
|
||||
// AUTO-GENERATED by per-section-migrate. Edit freely — Bob will treat this
|
||||
// file as the canonical source for the "pricing" section.
|
||||
|
||||
import React from 'react';
|
||||
import PricingCenteredCards from '@/components/sections/pricing/PricingCenteredCards';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function PricingSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="pricing" data-section="pricing">
|
||||
<SectionErrorBoundary name="pricing">
|
||||
<PricingCenteredCards
|
||||
tag="Consulting"
|
||||
title="Engagement Models"
|
||||
description="Flexible collaboration options to meet your project goals."
|
||||
plans={[
|
||||
{
|
||||
tag: "Freelance",
|
||||
price: "Project Based",
|
||||
description: "Ideal for specific deliverables and feature development.",
|
||||
features: [
|
||||
"Requirements gathering",
|
||||
"Architectural design",
|
||||
"Implementation & testing",
|
||||
],
|
||||
primaryButton: {
|
||||
text: "Inquire",
|
||||
href: "/contact",
|
||||
},
|
||||
},
|
||||
{
|
||||
tag: "Contractor",
|
||||
price: "Hourly/Retainer",
|
||||
description: "Best for long-term integration and team support.",
|
||||
features: [
|
||||
"Daily standups",
|
||||
"Full-stack development",
|
||||
"Code reviews & mentorship",
|
||||
],
|
||||
primaryButton: {
|
||||
text: "Discuss",
|
||||
href: "/contact",
|
||||
},
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
27
src/pages/HomePage/sections/SocialProof.tsx
Normal file
27
src/pages/HomePage/sections/SocialProof.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 "social-proof" section.
|
||||
|
||||
import React from 'react';
|
||||
import SocialProofMarquee from '@/components/sections/social-proof/SocialProofMarquee';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function SocialProofSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="social-proof" data-section="social-proof">
|
||||
<SectionErrorBoundary name="social-proof">
|
||||
<SocialProofMarquee
|
||||
tag="Experience"
|
||||
title="Trusted By Industry Leaders"
|
||||
description="Collaborated with forward-thinking teams across multiple domains."
|
||||
names={[
|
||||
"TechCloud",
|
||||
"DataFlow Systems",
|
||||
"Innovate Apps",
|
||||
"SecureBridge",
|
||||
"NextGen Labs",
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
57
src/pages/HomePage/sections/Testimonials.tsx
Normal file
57
src/pages/HomePage/sections/Testimonials.tsx
Normal file
@@ -0,0 +1,57 @@
|
||||
// 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 TestimonialOverlayCards from '@/components/sections/testimonial/TestimonialOverlayCards';
|
||||
import SectionErrorBoundary from "@/components/ui/SectionErrorBoundary";
|
||||
|
||||
export default function TestimonialsSection(): React.JSX.Element {
|
||||
return (
|
||||
<div id="testimonials" data-section="testimonials">
|
||||
<SectionErrorBoundary name="testimonials">
|
||||
<TestimonialOverlayCards
|
||||
tag="Reviews"
|
||||
title="What Partners Say"
|
||||
description="Collaborative success stories from clients and teammates."
|
||||
testimonials={[
|
||||
{
|
||||
name: "Alice Wang",
|
||||
role: "PM",
|
||||
company: "TechInnovate",
|
||||
rating: 5,
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/3d-portrait-businessman_23-2150793883.jpg",
|
||||
},
|
||||
{
|
||||
name: "Bob Smith",
|
||||
role: "CTO",
|
||||
company: "CloudReady",
|
||||
rating: 5,
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/young-blonde-charming-female-isolated_176474-79133.jpg",
|
||||
},
|
||||
{
|
||||
name: "Charlie Davis",
|
||||
role: "Dev",
|
||||
company: "StartupX",
|
||||
rating: 5,
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/portrait-confident-black-businesswoman-office_637285-9877.jpg",
|
||||
},
|
||||
{
|
||||
name: "Dana White",
|
||||
role: "CEO",
|
||||
company: "GrowthApp",
|
||||
rating: 5,
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/close-up-businessman-with-tie_1098-2867.jpg",
|
||||
},
|
||||
{
|
||||
name: "Eve Miller",
|
||||
role: "Designer",
|
||||
company: "CreativeHub",
|
||||
rating: 5,
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/girl-trying-look-like-grown-up_23-2148244890.jpg",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</SectionErrorBoundary>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user