diff --git a/package-lock.json b/package-lock.json
index 96f23bb..3dfee1a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,9 +8,11 @@
"name": "rekan-ai-tailwind",
"version": "0.0.0",
"dependencies": {
+ "framer-motion": "^12.4.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-google-recaptcha": "^3.1.0",
+ "react-intersection-observer": "^9.15.1",
"react-router-dom": "^7.1.3"
},
"devDependencies": {
@@ -2863,6 +2865,33 @@
"url": "https://github.com/sponsors/rawify"
}
},
+ "node_modules/framer-motion": {
+ "version": "12.4.3",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.4.3.tgz",
+ "integrity": "sha512-rsMeO7w3dKyNG09o3cGwSH49iHU+VgDmfSSfsX+wfkO3zDA6WWkh4sUsMXd155YROjZP+7FTIhDrBYfgZeHjKQ==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-dom": "^12.0.0",
+ "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",
@@ -3930,6 +3959,21 @@
"node": ">=16 || 14 >=14.17"
}
},
+ "node_modules/motion-dom": {
+ "version": "12.0.0",
+ "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.0.0.tgz",
+ "integrity": "sha512-CvYd15OeIR6kHgMdonCc1ihsaUG4MYh/wrkz8gZ3hBX/uamyZCXN9S9qJoYF03GqfTt7thTV/dxnHYX4+55vDg==",
+ "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",
@@ -4581,6 +4625,21 @@
"react": ">=16.4.1"
}
},
+ "node_modules/react-intersection-observer": {
+ "version": "9.15.1",
+ "resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.15.1.tgz",
+ "integrity": "sha512-vGrqYEVWXfH+AGu241uzfUpNK4HAdhCkSAyFdkMb9VWWXs6mxzBLpWCxEy9YcnDNY2g9eO6z7qUtTBdA9hc8pA==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^17.0.0 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/react-is": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
@@ -5423,6 +5482,12 @@
"dev": true,
"license": "Apache-2.0"
},
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "license": "0BSD"
+ },
"node_modules/turbo-stream": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz",
diff --git a/package.json b/package.json
index 76cf9f4..6e6a469 100644
--- a/package.json
+++ b/package.json
@@ -10,9 +10,11 @@
"preview": "vite preview"
},
"dependencies": {
+ "framer-motion": "^12.4.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-google-recaptcha": "^3.1.0",
+ "react-intersection-observer": "^9.15.1",
"react-router-dom": "^7.1.3"
},
"devDependencies": {
diff --git a/src/components/beranda/Banner.jsx b/src/components/beranda/Banner.jsx
index 608a469..f87256f 100644
--- a/src/components/beranda/Banner.jsx
+++ b/src/components/beranda/Banner.jsx
@@ -5,7 +5,7 @@ function Banner() {
return (
+ >
+
+
{/* Gambar L1-L4 untuk mobile */}

@@ -23,7 +25,7 @@ function Banner() {
{/* Teks dan tombol */}
-
+
Bersama Rekan AI, Wujudkan Masa Depan Bisnis yang Lebih Inovatif dan Kompetitif.
@@ -48,7 +50,6 @@ function Banner() {
Coba Sekarang
-
@@ -113,4 +114,3 @@ function Banner() {
}
export default Banner
-
diff --git a/src/components/beranda/Footer.jsx b/src/components/beranda/Footer.jsx
index dab4ae7..7649a93 100644
--- a/src/components/beranda/Footer.jsx
+++ b/src/components/beranda/Footer.jsx
@@ -27,7 +27,7 @@ function Footer() {
{/* Kolom 2: Deskripsi singkat perusahaan */}
-
+
Rekan AI{" "}
@@ -145,7 +145,7 @@ function Footer() {
{/* Bagian hak cipta */}
-
+
© Copyright 2025 Rekan AI. Seluruh hak cipta dilindungi undang-undang
diff --git a/src/components/beranda/Hero.jsx b/src/components/beranda/Hero.jsx
index 2d5b2bb..c933578 100644
--- a/src/components/beranda/Hero.jsx
+++ b/src/components/beranda/Hero.jsx
@@ -32,7 +32,7 @@ function Hero() {
diff --git a/src/components/beranda/Kenapa.jsx b/src/components/beranda/Kenapa.jsx
index ccb35c0..9514bbe 100644
--- a/src/components/beranda/Kenapa.jsx
+++ b/src/components/beranda/Kenapa.jsx
@@ -3,7 +3,7 @@ import { Link } from "react-router-dom"
function Kenapa() {
return (
-
+
{/* Decorative Circles */}
diff --git a/src/components/beranda/Mendukung.jsx b/src/components/beranda/Mendukung.jsx
index b0eee04..f66cee6 100644
--- a/src/components/beranda/Mendukung.jsx
+++ b/src/components/beranda/Mendukung.jsx
@@ -9,7 +9,7 @@ function Mendukung() {
];
return (
-
+
{/* Left Content */}
diff --git a/src/components/contact/CustomerService.jsx b/src/components/contact/CustomerService.jsx
index 9d6c9b9..a9f307e 100644
--- a/src/components/contact/CustomerService.jsx
+++ b/src/components/contact/CustomerService.jsx
@@ -1,13 +1,37 @@
import { email, phone, customer } from "./asset";
+import { motion } from "framer-motion";
+import { useEffect } from "react";
+import { useInView } from "react-intersection-observer";
const CustomerService = () => {
+ const { ref: leftRef, inView: leftInView } = useInView({ triggerOnce: false, threshold: 0.2 });
+ const { ref: rightRef, inView: rightInView } = useInView({ triggerOnce: false, threshold: 0.2 });
+
+ const fadeInLeft = {
+ hidden: { opacity: 0, x: -100 },
+ visible: { opacity: 1, x: 0, transition: { duration: 0.8 } },
+ };
+
+ const fadeInRight = {
+ hidden: { opacity: 0, x: 100 },
+ visible: { opacity: 1, x: 0, transition: { duration: 0.8 } },
+ };
+
return (
-
+
{/* LEFT SECTION - Informasi */}
-
+
+
- Kami Siap Membantu Bisnis Anda
+ Kami Siap Membantu Bisnis Anda
Lebih Maju!
@@ -50,16 +74,23 @@ const CustomerService = () => {
-
+
{/* RIGHT SECTION - Gambar */}
-
+
-
+
);
};
diff --git a/src/components/contact/FormSection.jsx b/src/components/contact/FormSection.jsx
index 9122826..7fdd515 100644
--- a/src/components/contact/FormSection.jsx
+++ b/src/components/contact/FormSection.jsx
@@ -1,26 +1,26 @@
-import { img10 } from "./asset"; // Pastikan img10 ada dan benar path-nya
-import ReCAPTCHA from "react-google-recaptcha"; // Pastikan penulisan benar (ReCAPTCHA)
-import useRecaptcha from './Recaptcha/useRecaptcha';
-import { useLocation } from "react-router-dom";
-import { useEffect } from "react";
+
+import { img10 } from "./asset"
+import ReCAPTCHA from "react-google-recaptcha"
+import useRecaptcha from "./Recaptcha/useRecaptcha"
+import { useLocation } from "react-router-dom"
+import { useEffect } from "react"
const ContactForm = () => {
- const { capchaToken, handleRecaptcha } = useRecaptcha();
-
- const location = useLocation();
+ const { capchaToken, handleRecaptcha } = useRecaptcha()
+ const location = useLocation()
useEffect(() => {
if (location.hash) {
- const element = document.querySelector(location.hash);
+ const element = document.querySelector(location.hash)
if (element) {
- element.scrollIntoView({ behavior: "smooth" });
+ element.scrollIntoView({ behavior: "smooth" })
}
}
- }, [location]);
+ }, [location])
return (
diff --git a/src/components/solusi/HeadStartup/HeadStartup.jsx b/src/components/solusi/HeadStartup/HeadStartup.jsx
index 91ca8f2..ec42ec6 100644
--- a/src/components/solusi/HeadStartup/HeadStartup.jsx
+++ b/src/components/solusi/HeadStartup/HeadStartup.jsx
@@ -45,10 +45,11 @@ export default function HeadPersonal() {
Konsultasi Gratis
-
-
+
+
diff --git a/src/components/solusi/SolusiCorporate/SolusiCorporate.jsx b/src/components/solusi/SolusiCorporate/SolusiCorporate.jsx
index b241592..ba6cda8 100644
--- a/src/components/solusi/SolusiCorporate/SolusiCorporate.jsx
+++ b/src/components/solusi/SolusiCorporate/SolusiCorporate.jsx
@@ -1,12 +1,25 @@
-import { useState } from "react";
+import { useState, useEffect } from "react";
import { data } from "./data";
export default function BusinessSolution() {
const [activeTab, setActiveTab] = useState("hr");
const activeContent = data.content[activeTab];
+ const [isMobile, setIsMobile] = useState(false);
+
+ // Detect mobile screen size
+ useEffect(() => {
+ const handleResize = () => {
+ setIsMobile(window.innerWidth < 768); // Set true jika lebar layar < 768px
+ };
+
+ window.addEventListener("resize", handleResize);
+ handleResize(); // Inisialisasi state saat pertama kali mount
+
+ return () => window.removeEventListener("resize", handleResize);
+ }, []);
return (
-
+
{/* Header */}
{data.title}
@@ -14,8 +27,8 @@ export default function BusinessSolution() {
{/* Navigation Buttons */}
-
-
+
+
{data.tabs.map((button) => (