animasi 90%
This commit is contained in:
@@ -113,4 +113,4 @@ function Banner() {
|
||||
)
|
||||
}
|
||||
|
||||
export default Banner
|
||||
export default Banner
|
||||
@@ -1,14 +1,49 @@
|
||||
import { homeLogo, waIcon, homeImg } from '../../assets';
|
||||
import { useNavigate, Link } from "react-router-dom"
|
||||
import { useNavigate, Link } from "react-router-dom";
|
||||
import { motion } from "framer-motion";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
function Hero() {
|
||||
const [inView, setInView] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
setInView(true);
|
||||
} else {
|
||||
setInView(false);
|
||||
}
|
||||
});
|
||||
},
|
||||
{ threshold: 0.2 }
|
||||
);
|
||||
|
||||
const target = document.querySelector("#hero-section");
|
||||
if (target) {
|
||||
observer.observe(target);
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (target) {
|
||||
observer.unobserve(target);
|
||||
}
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="w-full overflow-hidden" id="Home">
|
||||
<div className="container mx-auto px-4 lg:px-12">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 lg:gap-12 items-center py-12 lg:py-16">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 lg:gap-12 items-center py-12 lg:py-16" id="hero-section">
|
||||
{/* Left Section */}
|
||||
<div className="space-y-6 md:-mt-32 mt-10 text-center lg:text-left order-1 lg:order-none">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: -50 }}
|
||||
animate={{ opacity: inView ? 1 : 0, x: inView ? 0 : -50 }}
|
||||
transition={{ duration: 0.8 }}
|
||||
className="space-y-6 md:-mt-32 mt-10 text-center lg:text-left order-1 lg:order-none"
|
||||
>
|
||||
<img src={homeLogo} alt="Rekan AI Logo" className="h-12 w-auto lg:mx-0" />
|
||||
<h1 className="text-[24px] lg:text-[30px] font-semibold text-customBlack leading-tight">
|
||||
Ciptakan Pengalaman Pelanggan yang Tak Terlupakan dengan Solusi AI dari Rekan AI.
|
||||
@@ -17,27 +52,36 @@ function Hero() {
|
||||
Rekan AI menghadirkan teknologi kecerdasan buatan untuk membantu bisnis Anda beradaptasi dan tumbuh di era
|
||||
digital. Dari automasi hingga analisis data, kami membawa solusi cerdas yang mudah diimplementasikan.
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Right Section - Adjust order for mobile */}
|
||||
<div className="relative w-full aspect-square lg:aspect-auto md:w-[650px] md:h-[680px] lg:h-[600px] order-2 lg:order-none">
|
||||
{/* Right Section */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.8 }}
|
||||
animate={{ opacity: inView ? 1 : 0, scale: inView ? 1 : 0.8 }}
|
||||
transition={{ duration: 0.8, delay: 0.3 }}
|
||||
className="relative w-full aspect-square lg:aspect-auto md:w-[650px] md:h-[680px] lg:h-[600px] order-2 lg:order-none"
|
||||
>
|
||||
<img src={homeImg} alt="Rekan AI Illustration" className="object-contain" />
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Buttons - Ensure they come last on mobile */}
|
||||
<div className="flex flex-col sm:flex-row gap-4 md:-mt-96 order-3 lg:order-none">
|
||||
{/* Buttons */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 50 }}
|
||||
animate={{ opacity: inView ? 1 : 0, y: inView ? 0 : 50 }}
|
||||
transition={{ duration: 0.8, delay: 0.6 }}
|
||||
className="flex flex-col sm:flex-row gap-4 md:-mt-96 order-3 lg:order-none"
|
||||
id="button-section"
|
||||
>
|
||||
<button className="flex items-center justify-center px-6 py-3 border-2 md:w-[245px] md:h-[55px] border-customRed rounded-[14px] text-customRed font-medium text-base lg:text-lg hover:bg-pink-50 transition-colors">
|
||||
<img src={waIcon} alt="WhatsApp Icon" className="mr-2 h-7 w-7" />
|
||||
Konsultasi Gratis
|
||||
</button>
|
||||
<Link to={"/Contact#form"}>
|
||||
<button
|
||||
className="flex items-center justify-center px-6 py-3 rounded-[14px] w-[358px] h-[55px] md:w-[245px] md:h-[55px] bg-gradient-to-r from-[#DC0168] to-[#5B59E8] text-white font-medium text-base lg:text-lg hover:opacity-90 transition-opacity">
|
||||
<button className="flex items-center justify-center px-6 py-3 rounded-[14px] w-[358px] h-[55px] md:w-[245px] md:h-[55px] bg-gradient-to-r from-[#DC0168] to-[#5B59E8] text-white font-medium text-base lg:text-lg hover:opacity-90 transition-opacity">
|
||||
Coba Sekarang
|
||||
</button>
|
||||
</Link>
|
||||
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,67 +1,114 @@
|
||||
import { imgLeft, chek2, waIcon, circle1, circle2 } from '../../assets'
|
||||
import { Link } from "react-router-dom"
|
||||
import { imgLeft, chek2, waIcon, circle1, circle2 } from '../../assets';
|
||||
import { Link } from "react-router-dom";
|
||||
import { motion } from "framer-motion";
|
||||
import { useInView } from "react-intersection-observer";
|
||||
|
||||
function Kenapa() {
|
||||
const options = { triggerOnce: false, threshold: 0.2 };
|
||||
const { ref: sectionRef, inView: sectionInView } = useInView(options);
|
||||
const { ref: textRef, inView: textInView } = useInView(options);
|
||||
const { ref: listRef, inView: listInView } = useInView(options);
|
||||
const { ref: buttonRef, inView: buttonInView } = useInView(options);
|
||||
|
||||
return (
|
||||
<div className="container mx-auto flex justify-center items-center bg-customWhite mt-5 min-h-screen">
|
||||
<div className="flex flex-col md:flex-row bg-customWhite rounded-lg overflow-hidden relative pt-16 md:pt-52">
|
||||
<div ref={sectionRef} className="container mx-auto flex justify-center items-center bg-customWhite mt-5 min-h-screen">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 50 }}
|
||||
animate={sectionInView ? { opacity: 1, y: 0 } : {}}
|
||||
transition={{ duration: 0.8 }}
|
||||
className="flex flex-col md:flex-row bg-customWhite rounded-lg overflow-hidden relative pt-16 md:pt-52"
|
||||
>
|
||||
{/* Decorative Circles */}
|
||||
<div className="absolute hidden md:flex top-1 right-24 flex-col items-end space-y-4">
|
||||
<img src={circle1} alt="Circle 1" className="w-auto h-auto" />
|
||||
<img src={circle2} alt="Circle 2" className="w-auto h-auto" />
|
||||
<motion.img
|
||||
src={circle1} alt="Circle 1"
|
||||
className="w-auto h-auto"
|
||||
initial={{ opacity: 0, scale: 0.5 }}
|
||||
animate={sectionInView ? { opacity: 1, scale: 1 } : {}}
|
||||
transition={{ duration: 0.6, delay: 0.3 }}
|
||||
/>
|
||||
<motion.img
|
||||
src={circle2} alt="Circle 2"
|
||||
className="w-auto h-auto"
|
||||
initial={{ opacity: 0, scale: 0.5 }}
|
||||
animate={sectionInView ? { opacity: 1, scale: 1 } : {}}
|
||||
transition={{ duration: 0.6, delay: 0.5 }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Image Section */}
|
||||
<div className="relative w-full md:w-1/2 p-5 flex justify-center md:ml-14 md:justify-start">
|
||||
<motion.div
|
||||
ref={textRef}
|
||||
className="relative w-full md:w-1/2 p-5 flex justify-center md:ml-14 md:justify-start"
|
||||
initial={{ opacity: 0, x: -50 }}
|
||||
animate={textInView ? { opacity: 1, x: 0 } : {}}
|
||||
transition={{ duration: 0.8 }}
|
||||
>
|
||||
<img
|
||||
src={imgLeft}
|
||||
alt="Woman with Tablet"
|
||||
className="w-[300px] h-auto md:w-[654.5px] md:h-[609.67px]"
|
||||
/>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Text Section */}
|
||||
<div className="w-full md:w-1/2 p-6 md:p-10 flex flex-col items-center md:items-start md:mr-28 text-center md:text-left">
|
||||
<motion.div
|
||||
ref={listRef}
|
||||
className="w-full md:w-1/2 p-6 md:p-10 flex flex-col items-center md:items-start md:mr-28 text-center md:text-left"
|
||||
initial={{ opacity: 0, x: 50 }}
|
||||
animate={listInView ? { opacity: 1, x: 0 } : {}}
|
||||
transition={{ duration: 0.8, delay: 0.3 }}
|
||||
>
|
||||
<h2 className="text-2xl md:text-[28px] font-semibold text-customBlack">Kenapa Harus Rekan AI?</h2>
|
||||
<p className="text-customBlack mt-4 text-sm md:leading-7 md:text-[18px]">
|
||||
<p className="text-customBlack mt-4 text-sm md:leading-7 md:text-[18px]">
|
||||
Rekan AI adalah mitra inovasi bisnis Anda dalam menghadapi era
|
||||
digital. Kami menghadirkan teknologi kecerdasan buatan yang dirancang
|
||||
untuk meningkatkan efisiensi operasional, mempercepat proses, dan
|
||||
memberikan wawasan berbasis data yang akurat.
|
||||
</p>
|
||||
<ul className="mt-8 space-y-4 md:space-y-6 text-sm md:max-w-[90%] md:text-base text-customBlack font-medium">
|
||||
<li className="flex items-center">
|
||||
<img src={chek2} alt="Check" className="w-6 h-6 md:w-11 md:h-11 mr-3" />
|
||||
Automasi proses untuk mengurangi biaya dan meningkatkan produktivitas.
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<img src={chek2} alt="Check" className="w-6 h-6 md:w-11 md:h-11 mr-3" />
|
||||
Analisis data real-time untuk pengambilan keputusan yang lebih tepat.
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<img src={chek2} alt="Check" className="w-6 h-6 md:w-11 md:h-11 mr-3" />
|
||||
Menciptakan interaksi pelanggan yang lebih relevan dan berkesan.
|
||||
</li>
|
||||
<li className="flex items-center">
|
||||
<img src={chek2} alt="Check" className="w-6 h-6 md:w-11 md:h-11 mr-3" />
|
||||
Verifikasi dan autentikasi berbasis AI yang memperkuat keamanan data.
|
||||
</li>
|
||||
{[
|
||||
"Automasi proses untuk mengurangi biaya dan meningkatkan produktivitas.",
|
||||
"Analisis data real-time untuk pengambilan keputusan yang lebih tepat.",
|
||||
"Menciptakan interaksi pelanggan yang lebih relevan dan berkesan.",
|
||||
"Verifikasi dan autentikasi berbasis AI yang memperkuat keamanan data."
|
||||
].map((text, index) => (
|
||||
<motion.li
|
||||
key={index}
|
||||
className="flex items-center"
|
||||
initial={{ opacity: 0, x: -20 }}
|
||||
animate={listInView ? { opacity: 1, x: 0 } : {}}
|
||||
transition={{ duration: 0.6, delay: index * 0.2 }}
|
||||
>
|
||||
<img src={chek2} alt="Check" className="w-6 h-6 md:w-11 md:h-11 mr-3" />
|
||||
{text}
|
||||
</motion.li>
|
||||
))}
|
||||
</ul>
|
||||
|
||||
<div className="flex flex-col md:flex-row mt-8 md:mt-20 space-y-4 md:space-y-0 md:space-x-10 w-full">
|
||||
<button className="flex items-center justify-center w-full md:w-[270px] h-[50px] md:h-[70px] border-2 border-customRed text-customRed md:text-xl font-medium rounded-[14px] hover:bg-white hover:bg-opacity-10 transition">
|
||||
<div ref={buttonRef} className="flex flex-col md:flex-row mt-8 md:mt-20 space-y-4 md:space-y-0 md:space-x-10 w-full">
|
||||
<motion.button
|
||||
className="flex items-center justify-center w-full md:w-[270px] h-[50px] md:h-[70px] border-2 border-customRed text-customRed md:text-xl font-medium rounded-[14px] hover:bg-white hover:bg-opacity-10 transition"
|
||||
initial={{ opacity: 0, scale: 0.8 }}
|
||||
animate={buttonInView ? { opacity: 1, scale: 1 } : {}}
|
||||
transition={{ duration: 0.5, delay: 0.8 }}
|
||||
>
|
||||
<img src={waIcon} alt="WhatsApp Icon" className="mr-2 w-4 h-4 md:w-[30px] md:h-[30px]" />
|
||||
Konsultasi Gratis
|
||||
</button>
|
||||
</motion.button>
|
||||
<Link to={"/Contact#form"}>
|
||||
<button
|
||||
className="w-full md:w-[276px] h-[50px] md:h-[70px] bg-gradient-to-r from-pink-700 to-indigo-600 text-white md:text-xl font-medium rounded-[14px] hover:opacity-90 transition">
|
||||
<motion.button
|
||||
className="w-full md:w-[276px] h-[50px] md:h-[70px] bg-gradient-to-r from-pink-700 to-indigo-600 text-white md:text-xl font-medium rounded-[14px] hover:opacity-90 transition"
|
||||
initial={{ opacity: 0, scale: 0.8 }}
|
||||
animate={buttonInView ? { opacity: 1, scale: 1 } : {}}
|
||||
transition={{ duration: 0.5, delay: 1 }}
|
||||
>
|
||||
Coba Sekarang
|
||||
</button>
|
||||
</motion.button>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,46 +1,72 @@
|
||||
import React from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import { waIcon } from "../../assets";
|
||||
import { Link } from "react-router-dom"
|
||||
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
function MasaDepan() {
|
||||
return (
|
||||
<>
|
||||
<div className="flex flex-col items-center justify-center text-center w-full h-[65vh] -mt-3">
|
||||
{/* Tagline Section */}
|
||||
{/* Tagline Section */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 50 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 1.2, ease: "easeOut" }}
|
||||
className="flex flex-col items-center justify-center text-center w-full h-[65vh] -mt-3"
|
||||
>
|
||||
<div className="mb-5">
|
||||
<div className="flex flex-col sm:flex-row items-center justify-center gap-2 p-4">
|
||||
<span className="flex items-center justify-center bg-[#CA2B68] text-white font-semibold text-2xl rounded-2xl w-48 h-12">
|
||||
<motion.span
|
||||
initial={{ scale: 0.8, opacity: 0 }}
|
||||
animate={{ scale: 1, opacity: 1 }}
|
||||
transition={{ duration: 1.2, ease: "easeOut" }}
|
||||
className="flex items-center justify-center bg-[#CA2B68] text-white font-semibold text-2xl rounded-2xl w-48 h-12"
|
||||
>
|
||||
#Rekan AI
|
||||
</span>
|
||||
<h1 className="text-2xl sm:text-[32px] font-semibold text-[#212121]">
|
||||
</motion.span>
|
||||
<motion.h1
|
||||
initial={{ opacity: 0, x: -50 }}
|
||||
animate={{ opacity: 1, x: 0 }}
|
||||
transition={{ duration: 1.2, ease: "easeOut" }}
|
||||
className="text-2xl sm:text-[32px] font-semibold text-[#212121]"
|
||||
>
|
||||
Masa Depan Bisnis, Dimulai Hari Ini
|
||||
</h1>
|
||||
</motion.h1>
|
||||
</div>
|
||||
<p className="text-base sm:text-xl text-customBlack-600 md:max-w-[80%] md:ml-24 mt-2 leading-relaxed px-4 sm:px-0">
|
||||
<motion.p
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 1.2, ease: "easeOut", delay: 0.3 }}
|
||||
className="text-base sm:text-xl text-customBlack-600 md:max-w-[80%] md:ml-24 mt-2 leading-relaxed px-4 sm:px-0"
|
||||
>
|
||||
Bersama Rekan AI, bawa bisnis Anda menuju masa depan yang lebih
|
||||
cerdas, efisien, dan kompetitif.
|
||||
</p>
|
||||
</motion.p>
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
|
||||
</div>
|
||||
{/* Button Section */}
|
||||
<div className="flex flex-col justify-center md:-mt-32 md:mb-56 sm:flex-row gap-6 sm:gap-12 -mt-10 mb-20 px-4 sm:px-0">
|
||||
<button className="w-full lg:w-[270px] h-[70px] btn2 flex items-center justify-center py-3 border-2 border-[#DC0168] rounded-[14px] text-[#DC0168] font-medium text-[18px] lg:text-[20px] cursor-pointer transition-all ease-in-out hover:bg-[#ffffff1a]">
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 50 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 1.2, ease: "easeOut" }}
|
||||
viewport={{ once: false, amount: 0.2 }}
|
||||
className="flex flex-col justify-center md:-mt-32 md:mb-56 sm:flex-row gap-6 sm:gap-12 -mt-10 mb-20 px-4 sm:px-0"
|
||||
>
|
||||
<motion.button
|
||||
className="w-full lg:w-[270px] h-[70px] btn2 flex items-center justify-center py-3 border-2 border-[#DC0168] rounded-[14px] text-[#DC0168] font-medium text-[18px] lg:text-[20px] cursor-pointer transition-all ease-in-out hover:bg-[#ffffff1a]"
|
||||
>
|
||||
<img src={waIcon} alt="WhatsApp Icon" className="mr-4 w-5 h-5 md:w-[30px] md:h-[30px]" />
|
||||
Konsultasi Gratis
|
||||
</button>
|
||||
</motion.button>
|
||||
<Link to={"/Contact#form"}>
|
||||
<button
|
||||
className="w-full lg:w-[276px] h-[70px] btn2 flex items-center justify-center py-3 px-8 rounded-[14px] bg-gradient-to-r from-[#DC0168] to-[#5B59E8] text-white font-medium text-[18px] lg:text-[20px] cursor-pointer transition-all ease-in-out hover:opacity-90">
|
||||
<motion.button
|
||||
className="w-full lg:w-[276px] h-[70px] btn2 flex items-center justify-center py-3 px-8 rounded-[14px] bg-gradient-to-r from-[#DC0168] to-[#5B59E8] text-white font-medium text-[18px] lg:text-[20px] cursor-pointer transition-all ease-in-out hover:opacity-90"
|
||||
>
|
||||
Coba Sekarang
|
||||
</button>
|
||||
</motion.button>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
</motion.div>
|
||||
</>
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import React from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useInView } from 'react-intersection-observer';
|
||||
import { imgLeft1, imgLeft2, imgLeft3, imgRight } from '../../assets';
|
||||
|
||||
function Mendukung() {
|
||||
const { ref, inView } = useInView({ triggerOnce: false, threshold: 0.2 });
|
||||
|
||||
const items = [
|
||||
{ id: 1, image: imgLeft1, title: 'Personal' },
|
||||
{ id: 2, image: imgLeft2, title: 'UMKM' },
|
||||
@@ -9,9 +13,22 @@ function Mendukung() {
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="container mx-auto flex flex-col md:flex-row items-center justify-between gap-4 h-auto md:h-screen px-6 md:px-32 py-8 md:py-0" id="solusi2">
|
||||
<motion.div
|
||||
ref={ref}
|
||||
initial={{ opacity: 0 }}
|
||||
animate={inView ? { opacity: 1 } : { opacity: 0 }}
|
||||
transition={{ duration: 1 }}
|
||||
className="container mx-auto flex flex-col md:flex-row items-center justify-between gap-4 h-auto md:h-screen px-6 md:px-32 py-8 md:py-0"
|
||||
id="solusi2"
|
||||
>
|
||||
{/* Left Content */}
|
||||
<div className="flex flex-col justify-center w-full md:w-[45%] space-y-8 order-2 md:order-1">
|
||||
<motion.div
|
||||
ref={ref}
|
||||
initial={{ x: -50, opacity: 0 }}
|
||||
animate={inView ? { x: 0, opacity: 1 } : { x: -50, opacity: 0 }}
|
||||
transition={{ duration: 1 }}
|
||||
className="flex flex-col justify-center w-full md:w-[45%] space-y-8 order-2 md:order-1"
|
||||
>
|
||||
<p className="text-[24px] md:text-[32px] font-semibold text-customBlack text-left md:text-left">
|
||||
Solusi Mendukung Bisnis di Setiap
|
||||
<br />
|
||||
@@ -22,8 +39,15 @@ function Mendukung() {
|
||||
</p>
|
||||
|
||||
<div className="flex flex-col md:flex-row justify-center md:justify-between gap-6">
|
||||
{items.map((item) => (
|
||||
<div key={item.id} className="flex flex-col items-center w-full md:w-auto md:mt-5">
|
||||
{items.map((item, index) => (
|
||||
<motion.div
|
||||
key={item.id}
|
||||
ref={ref}
|
||||
initial={{ y: 50, opacity: 0 }}
|
||||
animate={inView ? { y: 0, opacity: 1 } : { y: 50, opacity: 0 }}
|
||||
transition={{ duration: 0.8, delay: index * 0.2 }}
|
||||
className="flex flex-col items-center w-full md:w-auto md:mt-5"
|
||||
>
|
||||
{/* Image */}
|
||||
<img
|
||||
src={item.image}
|
||||
@@ -34,19 +58,23 @@ function Mendukung() {
|
||||
<p className="bg-[#5B59E8] text-white text-center rounded-lg shadow-md w-[190px] sm:w-[150px] md:w-[190px] h-10 flex items-center justify-center text-sm font-bold mt-4">
|
||||
{item.title}
|
||||
</p>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Right Content */}
|
||||
<div className="w-full md:w-2/5 mt-8 md:mt-0 order-1 md:order-2">
|
||||
<motion.div
|
||||
ref={ref}
|
||||
initial={{ x: 50, opacity: 0 }}
|
||||
animate={inView ? { x: 0, opacity: 1 } : { x: 50, opacity: 0 }}
|
||||
transition={{ duration: 1 }}
|
||||
className="w-full md:w-2/5 mt-8 md:mt-0 order-1 md:order-2"
|
||||
>
|
||||
<img src={imgRight} alt="Image Right" className="w-auto h-auto" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Mendukung;
|
||||
export default Mendukung;
|
||||
@@ -1,4 +1,36 @@
|
||||
import { card1, card2, card3, card4, chek } from "../../assets"
|
||||
import { motion } from "framer-motion"
|
||||
import { useState, useEffect, useRef } from "react"
|
||||
|
||||
// Custom hook untuk menggunakan Intersection Observer
|
||||
const useIntersectionObserver = (options = {}) => {
|
||||
const [isIntersecting, setIsIntersecting] = useState(false)
|
||||
const ref = useRef(null)
|
||||
|
||||
useEffect(() => {
|
||||
const observer = new IntersectionObserver(
|
||||
([entry]) => {
|
||||
setIsIntersecting(entry.isIntersecting)
|
||||
},
|
||||
{
|
||||
threshold: 0.5, // Ketika 50% elemen terlihat
|
||||
...options,
|
||||
}
|
||||
)
|
||||
|
||||
if (ref.current) {
|
||||
observer.observe(ref.current)
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (ref.current) {
|
||||
observer.unobserve(ref.current)
|
||||
}
|
||||
}
|
||||
}, [options])
|
||||
|
||||
return [ref, isIntersecting]
|
||||
}
|
||||
|
||||
function Solusi() {
|
||||
const cards = [
|
||||
@@ -31,49 +63,67 @@ function Solusi() {
|
||||
return (
|
||||
<section className="min-h-screen flex flex-col items-center justify-center py-8 bg-customWhite mt-24" id="solusi">
|
||||
<div className="text-center mb-12 md:-mt-48 px-4">
|
||||
<div className="flex flex-col md:flex-row items-center justify-center gap-4">
|
||||
<motion.div
|
||||
className="flex flex-col md:flex-row items-center justify-center gap-4"
|
||||
initial={{ opacity: 0, y: -20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 1 }}
|
||||
>
|
||||
<h1 className="text-2xl md:text-[32px] font-semibold">Ragam Solusi Terbaik Dari</h1>
|
||||
<span className="flex items-center justify-center text-lg md:text-2xl text-customWhite bg-customRed rounded-[19px] font-bold w-[194px] h-[48px] text-center">
|
||||
#Rekan AI
|
||||
</span>
|
||||
</div>
|
||||
<p className="text-customBlack md:text-[20px] mt-4 md:max-w-[85%] mx-auto text-center">
|
||||
</motion.div>
|
||||
<motion.p
|
||||
className="text-customBlack md:text-[20px] mt-4 md:max-w-[85%] mx-auto text-center"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ delay: 0.5, duration: 1 }}
|
||||
>
|
||||
Kami menyediakan berbagai produk berbasis AI yang dirancang khusus untuk mendukung bisnis Anda dari berbagai
|
||||
aspek.
|
||||
</p>
|
||||
</motion.p>
|
||||
</div>
|
||||
|
||||
<div className="mt-24 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 md:gap-6 lg:gap-8 px-4 md:px-6 lg:px-8">
|
||||
{cards.map((card, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="bg-customWhite rounded-xl border p-4 md:p-6 flex flex-col items-center w-full max-w-[350px] mx-auto min-h-[500px]"
|
||||
>
|
||||
<img
|
||||
src={card.image || "/placeholder.svg"}
|
||||
alt={`Card ${index + 1}`}
|
||||
className="w-24 h-32 md:w-32 md:h-40 lg:w-40 lg:h-48 object-contain mb-4 md:mb-6"
|
||||
/>
|
||||
<p className="text-customBlack text-left mt-2 md:mt-4 flex-grow text-sm md:text-base">
|
||||
{card.description}
|
||||
</p>
|
||||
<ul className="text-left space-y-2 md:space-y-4 my-4 md:my-6 w-full min-h-[80px]">
|
||||
{card.features.map((feature, i) => (
|
||||
<li key={i} className="flex items-center gap-2 text-sm md:text-base">
|
||||
<img src={chek || "/placeholder.svg"} alt="Check" className="w-4 h-4 md:w-5 md:h-5" /> {feature}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<button className="w-full h-12 md:h-14 bg-white border border-blue-600 text-customBlue font-medium py-2 px-4 rounded-[18px] hover:bg-blue-600 hover:text-white transition duration-300 text-sm md:text-base">
|
||||
Selengkapnya <span>→</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
))}
|
||||
{cards.map((card, index) => {
|
||||
const [ref, isIntersecting] = useIntersectionObserver({
|
||||
threshold: 0.5, // Set threshold when 50% of the element is visible
|
||||
})
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
key={index}
|
||||
ref={ref}
|
||||
className="bg-customWhite rounded-xl border p-4 md:p-6 flex flex-col items-center w-full max-w-[350px] mx-auto min-h-[500px]"
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: isIntersecting ? 1 : 0, y: isIntersecting ? 0 : 20 }}
|
||||
transition={{ delay: index * 0.3 + 0.5, duration: 0.5 }}
|
||||
>
|
||||
<img
|
||||
src={card.image || "/placeholder.svg"}
|
||||
alt={`Card ${index + 1}`}
|
||||
className="w-24 h-32 md:w-32 md:h-40 lg:w-40 lg:h-48 object-contain mb-4 md:mb-6"
|
||||
/>
|
||||
<p className="text-customBlack text-left mt-2 md:mt-4 flex-grow text-sm md:text-base">
|
||||
{card.description}
|
||||
</p>
|
||||
<ul className="text-left space-y-2 md:space-y-4 my-4 md:my-6 w-full min-h-[80px]">
|
||||
{card.features.map((feature, i) => (
|
||||
<li key={i} className="flex items-center gap-2 text-sm md:text-base">
|
||||
<img src={chek || "/placeholder.svg"} alt="Check" className="w-4 h-4 md:w-5 md:h-5" /> {feature}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<button className="w-full h-12 md:h-14 bg-white border border-blue-600 text-customBlue font-medium py-2 px-4 rounded-[18px] hover:bg-blue-600 hover:text-white transition duration-300 text-sm md:text-base">
|
||||
Selengkapnya <span>→</span>
|
||||
</button>
|
||||
</motion.div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
export default Solusi
|
||||
|
||||
|
||||
Reference in New Issue
Block a user