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 */}
image 1 @@ -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 */} -
+ Customer Service -
+ ); }; 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 (
{ backgroundRepeat: "no-repeat", }} > -
- {/* Bagian Kiri */} -
-

+
+ {/* Left Section */} +
+

Isi formulir di samping ini dan kami akan menghubungi Anda secepat mungkin

-

- Kami percaya bahwa kolaborasi adalah kunci kesuksesan. Hubungi kami hari ini, dan mari wujudkan masa depan bisnis Anda bersama Rekan AI! +

+ Kami percaya bahwa kolaborasi adalah kunci kesuksesan. Hubungi kami hari ini, dan mari wujudkan masa depan + bisnis Anda bersama Rekan AI!

- {/* Bagian Form */} -
-

- Hubungi Tim Terbaik Kami -

-

- Silakan isi data diri Anda pada formulir di bawah ini -

+ {/* Form Section */} +
+
+

+ Hubungi Tim Terbaik Kami +

+

Silakan isi data diri Anda pada formulir di bawah ini

-
-
- - -
-
- - { - e.target.value = e.target.value.replace(/[^0-9]/g, ""); - }} - /> -
-
- - -
-
- - -
-
- - -
- - - + +
+ + +
+
+ + { + e.target.value = e.target.value.replace(/[^0-9]/g, "") + }} + /> +
+
+ + +
+
+ + +
+
+ + +
+ + + +
-
- {/* ReCAPTCHA */} -
- -
+
+ +
- - + + +
- ); -}; + ) +} + +export default ContactForm -export default ContactForm; diff --git a/src/components/solusi/HeadCorporate/HeadCorporate.jsx b/src/components/solusi/HeadCorporate/HeadCorporate.jsx index fdcb9b5..b1a966b 100644 --- a/src/components/solusi/HeadCorporate/HeadCorporate.jsx +++ b/src/components/solusi/HeadCorporate/HeadCorporate.jsx @@ -44,11 +44,12 @@ export default function HeadCorporate() { WhatsApp Icon Konsultasi Gratis - - - + + +

diff --git a/src/components/solusi/HeadPersonal/HeadPersonal.jsx b/src/components/solusi/HeadPersonal/HeadPersonal.jsx index 76bced6..40f2a55 100644 --- a/src/components/solusi/HeadPersonal/HeadPersonal.jsx +++ b/src/components/solusi/HeadPersonal/HeadPersonal.jsx @@ -47,11 +47,12 @@ export default function HeadPersonal() { WhatsApp Icon Konsultasi Gratis - - - + + +
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) => (