diff --git a/package-lock.json b/package-lock.json index c037948..d0a2720 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,8 @@ "lucide-react": "^0.541.0", "react": "^19.1.1", "react-dom": "^19.1.1", - "react-router-dom": "^7.8.2" + "react-router-dom": "^7.8.2", + "react-router-hash-link": "^2.4.3" }, "devDependencies": { "@eslint/js": "^9.33.0", @@ -2690,7 +2691,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, "license": "MIT" }, "node_modules/js-yaml": { @@ -2820,6 +2820,18 @@ "dev": true, "license": "MIT" }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -2990,7 +3002,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -3327,6 +3338,17 @@ "node": ">= 0.8.0" } }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -3379,6 +3401,12 @@ "react": "^19.1.1" } }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, "node_modules/react-refresh": { "version": "0.17.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz", @@ -3427,6 +3455,19 @@ "react-dom": ">=18" } }, + "node_modules/react-router-hash-link": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/react-router-hash-link/-/react-router-hash-link-2.4.3.tgz", + "integrity": "sha512-NU7GWc265m92xh/aYD79Vr1W+zAIXDWp3L2YZOYP4rCqPnJ6LI6vh3+rKgkidtYijozHclaEQTAHaAaMWPVI4A==", + "license": "MIT", + "dependencies": { + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": ">=15", + "react-router-dom": ">=4" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", diff --git a/package.json b/package.json index 7fafcbd..01413f2 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,8 @@ "lucide-react": "^0.541.0", "react": "^19.1.1", "react-dom": "^19.1.1", - "react-router-dom": "^7.8.2" + "react-router-dom": "^7.8.2", + "react-router-hash-link": "^2.4.3" }, "devDependencies": { "@eslint/js": "^9.33.0", diff --git a/public/WTell.png b/public/WTell.png index db262e9..f57d06e 100644 Binary files a/public/WTell.png and b/public/WTell.png differ diff --git a/src/App.jsx b/src/App.jsx index fe85c61..5ef24dc 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,10 +1,26 @@ -import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; +import { BrowserRouter as Router, Routes, Route, useLocation } from "react-router-dom"; +import { useEffect } from "react"; +import Navbar from "./components/Navbar"; import Home from "./pages/Home"; import About from "./pages/About"; + +function ScrollHandler() { + const { pathname } = useLocation(); + + useEffect(() => { + // tiap kali route berubah, scroll ke atas + window.scrollTo(0, 0); + }, [pathname]); + + return null; +} + export default function App() { return ( + + } /> } /> diff --git a/src/components/Footer.jsx b/src/components/Footer.jsx new file mode 100644 index 0000000..7198f53 --- /dev/null +++ b/src/components/Footer.jsx @@ -0,0 +1,92 @@ +import { Phone, Mail, Earth, Link as LinkIcon } from "lucide-react"; +import { Link } from "react-router-dom"; // ini untuk routing + +export default function Footer({ footerRef }) { + return ( +
+ +
+ + {/* Logo + Deskripsi */} +
+ Walanja Logo +

+ PT. Jaringan Citra Mandiri adalah Perusahaan Swasta yang bergerak di bidang Penyedia + Layanan Teknologi Telekomunikasi Berbasis fiber optik. +

+
+ + {/* Explore */} +
+

+ Explore +

+
    +
  • + + Home +
  • +
  • + + Portofolio +
  • +
  • + + About Us +
  • +
  • + + Contact Us +
  • +
+
+ + {/* Newsletter */} +
+

+ Newsletter +

+

+ Subscribe untuk mendapatkan berita terbaru +

+
+ + +
+
+ + {/* Kontak Kami */} +
+

+ Kontak Kami +

+
    +
  • + 0821 2062 3712 +
  • +
  • + cs@wtell.id +
  • +
  • + https://www.wtell.id/ +
  • +
+
+
+ + {/* Copyright */} +
+ © 2025 Walanja Telekomunikasi. +
+
+ ); +} diff --git a/src/components/Navbar.jsx b/src/components/Navbar.jsx index 99641ce..b68a797 100644 --- a/src/components/Navbar.jsx +++ b/src/components/Navbar.jsx @@ -1,24 +1,23 @@ import { useState, useEffect } from "react"; -import { ChevronDown } from "lucide-react"; -import { Link } from "react-router-dom"; +import { ChevronDown, Menu, X } from "lucide-react"; +import { HashLink } from "react-router-hash-link"; export default function Navbar() { - const [isOpen, setIsOpen] = useState(false); + const [isOpen, setIsOpen] = useState(false); // dropdown portfolio + const [mobileMenu, setMobileMenu] = useState(false); // toggle mobile const [scrolled, setScrolled] = useState(false); // Deteksi scroll useEffect(() => { const handleScroll = () => { - if (window.scrollY > 50) { - setScrolled(true); - } else { - setScrolled(false); - } + setScrolled(window.scrollY > 50); }; window.addEventListener("scroll", handleScroll); return () => window.removeEventListener("scroll", handleScroll); }, []); + const linkClass = `block px-4 py-2 hover:text-yellow-400 transition-colors`; + return (
- WALANJA + WTell - {/* Menu */} + {/* Menu Desktop */}
    - {/* Home */}
  • - + Home - +
  • {/* Dropdown Portofolio */} -
  • +
  • - {/* About Us */}
  • - + About Us - +
  • - - {/* Contact Us */}
  • - + Contact Us - +
+ + {/* Hamburger Mobile */} + + + {/* Menu Mobile */} + {mobileMenu && ( +
+
+ +
+ +
    +
  • + setMobileMenu(false)} + className={linkClass} + > + Home + +
  • + + {/* Dropdown Portofolio di Mobile */} +
  • + + {isOpen && ( +
      +
    • + setMobileMenu(false)} + > + SDM + +
    • +
    • + setMobileMenu(false)} + > + Alat Kerja + +
    • +
    • + setMobileMenu(false)} + > + Produksi + +
    • +
    • + setMobileMenu(false)} + > + Pengalaman + +
    • +
    + )} +
  • + +
  • + setMobileMenu(false)} + className={linkClass} + > + About Us + +
  • +
  • + setMobileMenu(false)} + className={linkClass} + > + Contact Us + +
  • +
+
+ )}
); } diff --git a/src/pages/About.jsx b/src/pages/About.jsx index 5525392..0cf8bfc 100644 --- a/src/pages/About.jsx +++ b/src/pages/About.jsx @@ -1,4 +1,5 @@ import Navbar from "../components/Navbar"; +import Footer from "../components/Footer"; import { motion } from "framer-motion"; import { CheckCircle } from "lucide-react"; @@ -12,12 +13,11 @@ export default function About() {
{/* Logo & Deskripsi */} -

-
+ {/* Visi & Misi */}
{/* Visi */} - +

VISI

Menjadi Penyedia Jaringan Kabel Serat Optik Terbaik yang Menghubungkan Seluruh Wilayah di Indonesia.

-
+ {/* Misi */} -

MISI

    @@ -83,10 +82,13 @@ export default function About() { Fiber Optic.
-
+
+ + {/* Footer */} +