Skip to content

Commit

Permalink
Update animation with framer motion side
Browse files Browse the repository at this point in the history
  • Loading branch information
wirapratamaz committed Jan 29, 2025
1 parent ecb1e24 commit 50116b9
Show file tree
Hide file tree
Showing 9 changed files with 643 additions and 146 deletions.
113 changes: 107 additions & 6 deletions components/sections/cta-section.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,117 @@
"use client";

import { Button } from "@/components/ui/button"
import Link from 'next/link';
import { StartFreeButton } from "@/components/ui/start-free-button"
import { motion } from "framer-motion";

const fadeInUpVariants = {
hidden: { opacity: 0, y: 30 },
visible: {
opacity: 1,
y: 0,
transition: {
duration: 0.6,
ease: "easeOut"
}
}
};

const highlightVariants = {
hidden: {
opacity: 0,
scale: 0.95
},
visible: {
opacity: 1,
scale: 1,
transition: {
delay: 0.3,
duration: 0.5,
ease: "easeOut"
}
}
};

const buttonContainerVariants = {
hidden: { opacity: 0, y: 20 },
visible: {
opacity: 1,
y: 0,
transition: {
delay: 0.5,
duration: 0.5,
ease: "easeOut"
}
},
hover: {
scale: 1.05,
transition: {
duration: 0.2,
ease: "easeInOut"
}
},
tap: {
scale: 0.98
}
};

export function CtaSection() {
return (
<section className="py-24 bg-gradient-to-b from-white to-pink-50">
<section className="py-24 bg-gradient-to-b from-white to-pink-50 overflow-hidden">
<div className="container mx-auto px-4 text-center">
<h2 className="text-4xl md:text-5xl font-bold mb-6">
Try it <span className="text-[#FF5C35]">free</span> for 7 days.{" "}
<span className="block">Subscribe if you love it.</span>
</h2>
<StartFreeButton />
<motion.div
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: "-100px" }}
variants={fadeInUpVariants}
className="mb-8"
>
<h2 className="text-4xl md:text-5xl font-bold mb-6">
Try it{" "}
<motion.span
variants={highlightVariants}
className="text-[#FF5C35] inline-block"
whileHover={{
scale: 1.1,
transition: { duration: 0.2 }
}}
>
free
</motion.span>
{" "}for 7 days.{" "}
<motion.span
className="block mt-2"
variants={highlightVariants}
>
Subscribe if you love it.
</motion.span>
</h2>
</motion.div>

<motion.div
variants={buttonContainerVariants}
initial="hidden"
whileInView="visible"
whileHover="hover"
whileTap="tap"
viewport={{ once: true }}
className="inline-block"
>
<StartFreeButton />
</motion.div>

<motion.div
initial={{ opacity: 0 }}
whileInView={{
opacity: 1,
transition: { delay: 0.7, duration: 0.5 }
}}
viewport={{ once: true }}
className="mt-6 text-gray-600 text-sm md:text-base"
>
No credit card required
</motion.div>
</div>
</section>
)
Expand Down
75 changes: 66 additions & 9 deletions components/sections/faq-section.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,41 @@
"use client";

import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion"
import { motion } from "framer-motion";

const fadeInUpVariants = {
hidden: { opacity: 0, y: 20 },
visible: { opacity: 1, y: 0, transition: { duration: 0.5 } }
};

const containerVariants = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.1,
delayChildren: 0.2
}
}
};

const accordionItemVariants = {
hidden: { opacity: 0, x: -20 },
visible: {
opacity: 1,
x: 0,
transition: {
type: "spring",
stiffness: 100,
damping: 12
}
}
};

const faqs = [
{
Expand Down Expand Up @@ -32,15 +64,40 @@ export function FaqSection() {
return (
<section className="py-24 bg-gray-50">
<div className="container mx-auto px-4 max-w-3xl">
<h2 className="text-4xl font-bold mb-12">FAQ</h2>
<Accordion type="single" collapsible className="w-full">
{faqs.map((faq, index) => (
<AccordionItem key={index} value={`item-${index}`}>
<AccordionTrigger className="text-left">{faq.question}</AccordionTrigger>
<AccordionContent>{faq.answer}</AccordionContent>
</AccordionItem>
))}
</Accordion>
<motion.div
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: "-100px" }}
variants={fadeInUpVariants}
>
<h2 className="text-4xl font-bold mb-12">FAQ</h2>
</motion.div>

<motion.div
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: "-100px" }}
variants={containerVariants}
>
<Accordion type="single" collapsible className="w-full">
{faqs.map((faq, index) => (
<motion.div
key={index}
variants={accordionItemVariants}
custom={index}
>
<AccordionItem value={`item-${index}`} className="border-b border-gray-200">
<AccordionTrigger className="text-left hover:text-blue-600 transition-colors duration-200">
{faq.question}
</AccordionTrigger>
<AccordionContent className="text-gray-600">
{faq.answer}
</AccordionContent>
</AccordionItem>
</motion.div>
))}
</Accordion>
</motion.div>
</div>
</section>
)
Expand Down
108 changes: 96 additions & 12 deletions components/sections/hero-section.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
import { Card } from "@/components/ui/card"
import { useState } from 'react'
import { HeroHeader } from "./hero/hero-header"
import SidebarNav from "@/components/sections/hero/sidebar-nav"
import SidebarNav from "@/components/sections/hero/sidebar-nav"
import { ChatPanel } from "./hero/chat-panel"
import { HomeView, GroupsView, ActionItemsView, AutomationsView, InsightsView } from "./hero/views"
import { motion, AnimatePresence } from "framer-motion";

const tabComponents = {
Home: HomeView,
Expand All @@ -17,35 +18,118 @@ const tabComponents = {

export type TabKey = keyof typeof tabComponents;

const containerVariants = {
hidden: { opacity: 0, y: 20 },
visible: {
opacity: 1,
y: 0,
transition: {
duration: 0.5,
ease: "easeOut"
}
}
};

const cardVariants = {
hidden: { opacity: 0, scale: 0.98 },
visible: {
opacity: 1,
scale: 1,
transition: {
duration: 0.4,
ease: "easeOut"
}
}
};

const contentVariants = {
enter: {
opacity: 0,
y: 10,
transition: {
duration: 0.3
}
},
center: {
opacity: 1,
y: 0,
transition: {
duration: 0.3
}
},
exit: {
opacity: 0,
y: -10,
transition: {
duration: 0.3
}
}
};

export function HeroSection() {
const [activeTab, setActiveTab] = useState<TabKey>('Home')

const ActiveComponent = tabComponents[activeTab]

return (
<section className="bg-gradient-to-b from-blue-50 to-white pt-24 md:pt-32 lg:pt-36">
<motion.section
className="bg-gradient-to-b from-blue-50 to-white pt-24 md:pt-32 lg:pt-36"
initial="hidden"
animate="visible"
variants={containerVariants}
>
<div className="container mx-auto px-2 md:px-4">
<HeroHeader />
<div className="flex flex-col lg:flex-row gap-3 border rounded-[24px] md:rounded-[44px] p-2 md:p-4 bg-white/40 backdrop-blur-sm shadow-lg lg:h-[600px] max-w-[1200px] mx-auto">
<motion.div
className="flex flex-col lg:flex-row gap-3 border rounded-[24px] md:rounded-[44px] p-2 md:p-4 bg-white/40 backdrop-blur-sm shadow-lg lg:h-[600px] max-w-[1200px] mx-auto"
variants={cardVariants}
>
{/* Left Sidebar */}
<div className="w-full lg:w-64 lg:shrink-0 min-h-[120px] lg:h-full mb-2 lg:mb-0">
<motion.div
className="w-full lg:w-64 lg:shrink-0 min-h-[120px] lg:h-full mb-2 lg:mb-0"
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: 0.2, duration: 0.4 }}
>
<div className="bg-white rounded-2xl md:rounded-3xl shadow-lg border border-gray-100 p-2 md:p-4 h-full">
<SidebarNav activeTab={activeTab} onTabChange={setActiveTab} />
</div>
</div>
</motion.div>

{/* Main Content */}
<div className="flex-1 min-h-[300px] lg:min-h-0">
<motion.div
className="flex-1 min-h-[300px] lg:min-h-0"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 0.3, duration: 0.4 }}
>
<Card className="p-2 md:p-4 bg-white rounded-[20px] md:rounded-[32px] shadow-[0_0_20px_0_rgb(236,236,241)] h-full overflow-auto">
<ActiveComponent />
<AnimatePresence mode="wait">
<motion.div
key={activeTab}
initial="enter"
animate="center"
exit="exit"
variants={contentVariants}
>
<ActiveComponent />
</motion.div>
</AnimatePresence>
</Card>
</div>
</motion.div>

{/* Right Chat Panel */}
<div className="w-full lg:w-64 lg:shrink-0 min-h-[300px] lg:h-full mt-2 lg:mt-0">
<motion.div
className="w-full lg:w-64 lg:shrink-0 min-h-[300px] lg:h-full mt-2 lg:mt-0"
initial={{ opacity: 0, x: 20 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: 0.4, duration: 0.4 }}
>
<ChatPanel />
</div>
</div>
</motion.div>
</motion.div>
</div>
</section>
</motion.section>
)
}

Loading

0 comments on commit 50116b9

Please sign in to comment.