add animation
This commit is contained in:
parent
a032738c3c
commit
b0217d0a3a
5 changed files with 258 additions and 73 deletions
43
package-lock.json
generated
43
package-lock.json
generated
|
|
@ -15,6 +15,7 @@
|
|||
"aos": "^2.3.4",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"framer-motion": "^12.4.7",
|
||||
"lucide-react": "^0.476.0",
|
||||
"next": "15.1.7",
|
||||
"react": "^19.0.0",
|
||||
|
|
@ -3228,6 +3229,33 @@
|
|||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/framer-motion": {
|
||||
"version": "12.4.7",
|
||||
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.4.7.tgz",
|
||||
"integrity": "sha512-VhrcbtcAMXfxlrjeHPpWVu2+mkcoR31e02aNSR7OUS/hZAciKa8q6o3YN2mA1h+jjscRsSyKvX6E1CiY/7OLMw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"motion-dom": "^12.4.5",
|
||||
"motion-utils": "^12.0.0",
|
||||
"tslib": "^2.4.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@emotion/is-prop-valid": "*",
|
||||
"react": "^18.0.0 || ^19.0.0",
|
||||
"react-dom": "^18.0.0 || ^19.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@emotion/is-prop-valid": {
|
||||
"optional": true
|
||||
},
|
||||
"react": {
|
||||
"optional": true
|
||||
},
|
||||
"react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
|
|
@ -4345,6 +4373,21 @@
|
|||
"node": ">=16 || 14 >=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/motion-dom": {
|
||||
"version": "12.4.5",
|
||||
"resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.4.5.tgz",
|
||||
"integrity": "sha512-Q2xmhuyYug1CGTo0jdsL05EQ4RhIYXlggFS/yPhQQRNzbrhjKQ1tbjThx5Plv68aX31LsUQRq4uIkuDxdO5vRQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"motion-utils": "^12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/motion-utils": {
|
||||
"version": "12.0.0",
|
||||
"resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.0.0.tgz",
|
||||
"integrity": "sha512-MNFiBKbbqnmvOjkPyOKgHUp3Q6oiokLkI1bEwm5QA28cxMZrv0CbbBGDNmhF6DIXsi1pCQBSs0dX8xjeER1tmA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
"aos": "^2.3.4",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"framer-motion": "^12.4.7",
|
||||
"lucide-react": "^0.476.0",
|
||||
"next": "15.1.7",
|
||||
"react": "^19.0.0",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
"use client";
|
||||
import { X, Plus } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
|
||||
import { Plus } from "lucide-react";
|
||||
import * as React from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
|
||||
interface FAQItem {
|
||||
id: string;
|
||||
|
|
@ -36,7 +38,7 @@ const faqs: FAQItem[] = [
|
|||
];
|
||||
|
||||
export default function FAQSection() {
|
||||
const [openItems, setOpenItems] = useState<Set<string>>(new Set());
|
||||
const [openItems, setOpenItems] = React.useState<Set<string>>(new Set());
|
||||
|
||||
const handleItemClick = (itemId: string) => {
|
||||
const newOpenItems = new Set(openItems);
|
||||
|
|
@ -57,27 +59,86 @@ export default function FAQSection() {
|
|||
|
||||
<div className="space-y-4">
|
||||
{faqs.map((faq) => (
|
||||
<div key={faq.id} className="bg-white rounded-lg overflow-hidden">
|
||||
<button
|
||||
<motion.div
|
||||
key={faq.id}
|
||||
initial={false}
|
||||
animate={openItems.has(faq.id) ? "open" : "closed"}
|
||||
className="bg-white rounded-lg overflow-hidden"
|
||||
>
|
||||
<motion.button
|
||||
onClick={() => handleItemClick(faq.id)}
|
||||
className="w-full text-left p-6 flex items-center justify-between hover:bg-gray-50"
|
||||
whileHover={{ backgroundColor: "rgba(0, 0, 0, 0.02)" }}
|
||||
transition={{ duration: 0.2 }}
|
||||
>
|
||||
<span className="text-lg text-[#7c3aed] font-medium">
|
||||
{faq.question}
|
||||
</span>
|
||||
{openItems.has(faq.id) ? (
|
||||
<X className="h-5 w-5 text-[#7c3aed]" />
|
||||
) : (
|
||||
<Plus className="h-5 w-5 text-[#7c3aed]" />
|
||||
)}
|
||||
</button>
|
||||
<motion.div
|
||||
variants={{
|
||||
open: { rotate: 45 },
|
||||
closed: { rotate: 0 },
|
||||
}}
|
||||
transition={{ duration: 0.2 }}
|
||||
className="relative w-6 h-6 flex items-center justify-center"
|
||||
>
|
||||
<Plus className="h-5 w-5 text-[#7c3aed] absolute" />
|
||||
</motion.div>
|
||||
</motion.button>
|
||||
|
||||
{openItems.has(faq.id) && (
|
||||
<div className="px-6 pb-6">
|
||||
<p className="text-gray-600">{faq.answer}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<AnimatePresence initial={false}>
|
||||
{openItems.has(faq.id) && (
|
||||
<motion.div
|
||||
initial="collapsed"
|
||||
animate="open"
|
||||
exit="collapsed"
|
||||
variants={{
|
||||
open: {
|
||||
opacity: 1,
|
||||
height: "auto",
|
||||
transition: {
|
||||
duration: 0.3,
|
||||
ease: [0.4, 0, 0.2, 1],
|
||||
},
|
||||
},
|
||||
collapsed: {
|
||||
opacity: 0,
|
||||
height: 0,
|
||||
transition: {
|
||||
duration: 0.3,
|
||||
ease: [0.4, 0, 0.2, 1],
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
||||
<motion.div
|
||||
variants={{
|
||||
open: {
|
||||
y: 0,
|
||||
opacity: 1,
|
||||
transition: {
|
||||
duration: 0.3,
|
||||
ease: [0.4, 0, 0.2, 1],
|
||||
delay: 0.1,
|
||||
},
|
||||
},
|
||||
collapsed: {
|
||||
y: 20,
|
||||
opacity: 0,
|
||||
transition: {
|
||||
duration: 0.3,
|
||||
ease: [0.4, 0, 0.2, 1],
|
||||
},
|
||||
},
|
||||
}}
|
||||
className="px-6 pb-6"
|
||||
>
|
||||
<p className="text-gray-600">{faq.answer}</p>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
"use client";
|
||||
|
||||
import React from "react";
|
||||
import styles from "./HeroSection.module.css";
|
||||
import Link from "next/link";
|
||||
import Image from "next/image";
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
const HeroSection: React.FC = () => {
|
||||
return (
|
||||
<section className="header">
|
||||
|
|
@ -9,34 +13,53 @@ const HeroSection: React.FC = () => {
|
|||
<div className="absolute w-full flex flex-col md:flex-row">
|
||||
{/* Left Background */}
|
||||
<div
|
||||
className={`${styles.bgLeft} w-full md:w-1/2 h-[500px] md:h-[1075px]`}
|
||||
className={`${styles.bgLeft} w-full md:w-1/2 h-[410px] md:h-[1075px]`}
|
||||
></div>
|
||||
|
||||
{/* Right Background */}
|
||||
<div className="relative w-full md:w-1/2 bg-[#F9F1FF] h-[400px] md:h-[1075px]">
|
||||
<div
|
||||
<motion.div
|
||||
initial={{ x: 100, opacity: 0 }}
|
||||
animate={{ x: 0, opacity: 1 }}
|
||||
transition={{
|
||||
duration: 0.8,
|
||||
ease: "easeOut",
|
||||
delay: 0.2,
|
||||
}}
|
||||
className="absolute top-0 -left-[150px] mt-0 md:mt-40 ml-16 h-[542px] flex flex-col justify-start items-start gap-2.5 z-50"
|
||||
data-aos="fade-left"
|
||||
data-aos-duration="2000"
|
||||
>
|
||||
<Image
|
||||
src="/assets/images/hero-temp-slider.png"
|
||||
alt="Hero Slider"
|
||||
width={750}
|
||||
height={542}
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
<motion.div
|
||||
whileHover={{
|
||||
scale: 1.02,
|
||||
transition: { duration: 0.3 },
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
src="/assets/images/hero-temp-slider.png"
|
||||
alt="Hero Slider"
|
||||
width={750}
|
||||
height={542}
|
||||
priority
|
||||
className="drop-shadow-2xl"
|
||||
/>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
{/* Main Content */}
|
||||
<div
|
||||
<motion.div
|
||||
initial={{ y: 50, opacity: 0 }}
|
||||
animate={{ y: 0, opacity: 1 }}
|
||||
transition={{
|
||||
duration: 0.6,
|
||||
ease: "easeOut",
|
||||
}}
|
||||
className={`${styles.glass} absolute my-20 md:my-40 w-full md:w-7/12 z-10`}
|
||||
>
|
||||
<div className="p-8 md:p-16">
|
||||
<div className="text-2xl md:text-4xl lg:text-6xl leading-5xl font-normal font-['Gendy'] ">
|
||||
<span className="text-[#ff256d] md:text-white ">R</span>
|
||||
<span className="text-[#252525] ">
|
||||
<div className="text-2xl md:text-4xl lg:text-6xl leading-5xl font-normal font-['Gendy']">
|
||||
<span className="text-[#ff256d] md:text-white">R</span>
|
||||
<span className="text-[#252525]">
|
||||
evolutionize Your Social Media Strategy with a Personalized
|
||||
</span>
|
||||
<br />
|
||||
|
|
@ -49,7 +72,12 @@ const HeroSection: React.FC = () => {
|
|||
</p>
|
||||
|
||||
<div className="flex">
|
||||
<div className="flex mt-5 items-center">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: -20 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ delay: 0.4, duration: 0.6 }}
|
||||
className="flex mt-5 items-center"
|
||||
>
|
||||
<div>
|
||||
<p className="text-[#252525] text-[10px] md:text-xs font-normal">
|
||||
Customers Rating
|
||||
|
|
@ -61,37 +89,63 @@ const HeroSection: React.FC = () => {
|
|||
(8,279 reviews)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* CTA Button */}
|
||||
<Link
|
||||
href="https://dashboard.planpostai.com/"
|
||||
className="ml-5 mt-5 px-7 py-3.5 bg-[#ff2b85] rounded-xl shadow-md border border-white flex items-center gap-2.5 text-white text-xl font-bold"
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: 20 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ delay: 0.6, duration: 0.6 }}
|
||||
>
|
||||
Generate
|
||||
<Image
|
||||
src="/assets/svg/generate-icon.svg"
|
||||
alt="Generate Icon"
|
||||
className="w-6 h-6"
|
||||
height={24}
|
||||
width={24}
|
||||
/>
|
||||
</Link>
|
||||
<Link
|
||||
href="https://dashboard.planpostai.com/"
|
||||
className="ml-5 mt-5 px-7 py-3.5 bg-[#ff2b85] rounded-xl shadow-md border border-white flex items-center gap-2.5 text-white text-xl font-bold"
|
||||
>
|
||||
Generate
|
||||
<Image
|
||||
src="/assets/svg/generate-icon.svg"
|
||||
alt="Generate Icon"
|
||||
className="w-6 h-6"
|
||||
height={24}
|
||||
width={24}
|
||||
/>
|
||||
</Link>
|
||||
</motion.div>
|
||||
</div>
|
||||
{/* Customer Reviews */}
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
{/* Social Icons */}
|
||||
<div className="absolute top-[142px] left-[77px] social-icons-pp z-20">
|
||||
<Image
|
||||
src="/assets/images/social-icons.png"
|
||||
alt="Social Icons"
|
||||
height={500}
|
||||
width={500}
|
||||
/>
|
||||
</div>
|
||||
<motion.div
|
||||
initial={{ scale: 0.8, opacity: 0 }}
|
||||
animate={{ scale: 1, opacity: 1 }}
|
||||
transition={{
|
||||
duration: 0.8,
|
||||
ease: [0.4, 0, 0.2, 1],
|
||||
delay: 0.4,
|
||||
}}
|
||||
className="absolute top-[142px] left-[77px] social-icons-pp z-20"
|
||||
>
|
||||
<motion.div
|
||||
animate={{
|
||||
y: [0, -10, 0],
|
||||
}}
|
||||
transition={{
|
||||
duration: 4,
|
||||
repeat: Infinity,
|
||||
repeatType: "reverse",
|
||||
ease: "easeInOut",
|
||||
}}
|
||||
>
|
||||
<Image
|
||||
src="/assets/images/social-icons.png"
|
||||
alt="Social Icons"
|
||||
height={500}
|
||||
width={500}
|
||||
/>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,24 +1,50 @@
|
|||
"use client";
|
||||
import React, { useRef } from "react";
|
||||
import Image from "next/image";
|
||||
import React from "react";
|
||||
import { motion, useInView } from "framer-motion";
|
||||
|
||||
const SocialSection: React.FC = () => {
|
||||
const sectionRef = useRef<HTMLDivElement>(null);
|
||||
const isInView = useInView(sectionRef, {
|
||||
once: false,
|
||||
amount: 0.3,
|
||||
});
|
||||
|
||||
const fadeInUp = {
|
||||
hidden: {
|
||||
opacity: 0,
|
||||
y: 60,
|
||||
},
|
||||
visible: {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
transition: {
|
||||
duration: 0.8,
|
||||
ease: "easeOut",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<section
|
||||
id="feature"
|
||||
className="social"
|
||||
data-aos="fade-up"
|
||||
data-aos-duration="1500"
|
||||
>
|
||||
<section ref={sectionRef} id="feature" className="social">
|
||||
<div className="h-0 md:h-[180px] lg:h-[250px] flex justify-center relative">
|
||||
<div className="absolute -top-[200px]">
|
||||
<Image
|
||||
src="/assets/images/temp-example.png"
|
||||
alt="Example Image"
|
||||
width={1200}
|
||||
height={300}
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
<motion.div
|
||||
className="absolute -top-[200px]"
|
||||
variants={fadeInUp}
|
||||
initial="hidden"
|
||||
animate={isInView ? "visible" : "hidden"}
|
||||
>
|
||||
<div className="relative rounded-lg overflow-hidden">
|
||||
<Image
|
||||
src="/assets/images/temp-example.png"
|
||||
alt="Example Image"
|
||||
width={1200}
|
||||
height={300}
|
||||
priority
|
||||
className="transform transition duration-700 hover:scale-105"
|
||||
/>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue