Compare commits

...

10 Commits

Author SHA1 Message Date
adelyaou 1a31d8dd76 Fortiva Landing Page 2025-09-15 23:58:45 +07:00
Syifa ee7540a820 Revisi 3 Title WTell 2025-08-27 12:11:53 +07:00
Syifa 27a91c1840 Revisi 2 Title WTell 2025-08-27 12:05:46 +07:00
Syifa 92705cb78b Revisi Title WTell 2025-08-27 11:46:28 +07:00
Syifa 2b1586d919 Revisi Navbar 2025-08-27 08:27:32 +07:00
Syifa 4406dad9f8 Revisi Hero 2025-08-27 08:24:35 +07:00
Syifa 3d4709493b Walanja landing-page revisi 2025-08-26 22:10:17 +07:00
Syifa e8d33cb0bd membuat portfolio, home, about, dan footer 2025-08-26 21:12:25 +07:00
syifa 9f9c2ec14c Merge pull request 'adel' (#1) from adel into main
Reviewed-on: internship/landingpage-wtell#1
2025-08-26 14:03:49 +00:00
adelyaou 1309840e6f Revisi about, footer, hero 2025-08-26 20:12:42 +07:00
38 changed files with 926 additions and 610 deletions

View File

@ -2,9 +2,9 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link rel="icon" type="image/png" href="/Finals_Icon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React</title>
<title>FortivaNet</title>
</head>
<body>
<div id="root"></div>

572
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
{
"name": "walanja-landing",
"name": "FortivaNet-landing",
"private": true,
"version": "0.0.0",
"type": "module",

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
public/Finals_Icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
public/Finals_Profile.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
public/SDM.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
public/WTell_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 917 KiB

BIN
public/Wtell2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

BIN
public/Wtell2r.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

BIN
public/about.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 KiB

BIN
public/alat-kerja.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
public/alat2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
public/bandungraya.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

BIN
public/ciamis.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

BIN
public/exfo.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

BIN
public/fujikura.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
public/garut.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
public/map1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

BIN
public/pangandaran.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

BIN
public/port.mp4 Normal file

Binary file not shown.

BIN
public/sdm2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

BIN
public/subang.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
public/tasik.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

BIN
public/tiang.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
public/tiang1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

BIN
public/tiang2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

BIN
public/yokogwa.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -3,6 +3,7 @@ import { useEffect } from "react";
import Navbar from "./components/Navbar";
import Home from "./pages/Home";
import About from "./pages/About";
import Portfolio from "./pages/Portfolio";
function ScrollHandler() {
@ -24,6 +25,7 @@ export default function App() {
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/portofolio" element={<Portfolio />} />
</Routes>
</Router>
);

View File

@ -0,0 +1,54 @@
import { motion } from "framer-motion";
export default function Cakupan() {
return (
<section id="cakupan" className="relative py-20 bg-gray-50 overflow-hidden">
{/* Animated Overlay */}
<div className="absolute inset-0 bg-gradient-to-r from-blue-50 via-white to-blue-50 animate-gradient bg-[length:300%_300%]"></div>
<div className="relative z-10">
{/* Title */}
<div className="text-center mb-12">
<h2 className="text-3xl md:text-4xl font-bold flex items-center justify-center gap-2 text-blue-900">
Cakupan Area
</h2>
<p className="mt-3 text-gray-600 max-w-2xl mx-auto">
Saat ini jaringan dan layanan{" "}
<span className="font-semibold">FortivaNet</span> telah berhasil
menghadirkan internet di berbagai daerah di Kota Bandung hingga
Desa 3T (Tertinggal, Terdepan, Terluar).
</p>
</div>
{/* Content */}
<div className="max-w-6xl mx-auto flex flex-col md:flex-row items-stretch gap-12 px-6">
{/* Map */}
<motion.div
whileHover={{ scale: 1.05 }}
className="flex-1 flex justify-center"
>
<img
src="/map-bandung.jpg"
alt="Map Bandung"
className="w-full max-w-md rounded-2xl shadow-xl border-4 border-blue-100 object-cover"
/>
</motion.div>
{/* List Area */}
<div className="flex-1 bg-white/70 p-12 rounded-2xl shadow-lg flex flex-col justify-center">
<h3 className="text-2xl text-center font-semibold mb-6 text-blue-600">
Fokus Layanan
</h3>
<ul className="space-y-3 text-gray-700">
<li>📍 Bandung Kota</li>
<li>📍 Cimahi</li>
<li>📍 Cileunyi</li>
<li>📍 Ngamprah</li>
<li>📍 Desa 3T sekitar Bandung</li>
</ul>
</div>
</div>
</div>
</section>
);
}

View File

@ -8,20 +8,41 @@ export default function Footer({ footerRef }) {
ref={footerRef}
className="bg-[#5C739B] text-white py-10 px-6">
<div className="max-w-7xl mx-auto grid grid-cols-1 md:grid-cols-4 gap-8">
<div className="max-w-7xl mx-auto grid grid-cols-1 md:grid-cols-12 gap-8">
{/* Logo + Deskripsi */}
<div>
<img src="/WTell.png" alt="Walanja Logo" className="w-32 mb-4" />
<div className="md:col-span-4">
<img src="/Finals_Profile.png" alt="FortivaNet Logo" className="w-32 mb-4" />
<p className="text-sm leading-relaxed">
PT. Jaringan Citra Mandiri adalah Perusahaan Swasta yang bergerak di bidang Penyedia
Layanan Teknologi Telekomunikasi Berbasis fiber optik.
</p>
</div>
{/* Explore */}
<div>
{/* Alamat */}
<div className="md:col-span-4">
<h3 className="font-bold text-lg mb-4 relative inline-block">
Alamat
</h3>
<p className="text-sm leading-relaxed">
Kantor Administrasi:
<br />
Jl. Paledang No. 236, Kec. Campaka, Kel. Andir Bandung 40184
</p>
<br />
<p className="text-sm leading-relaxed">
Kantor Teknis:
<br />
Parahyangan Business Park, The Suites Blok E5-E7
Jl. Soekarno Hatta No. 693, Bandung,
Jawa Barat 40286, Indonesia
</p>
</div>
{/* Explore */}
<div className="md:col-span-2">
<h3 className="font-bold text-lg mb-2 relative inline-block">
Explore
</h3>
<ul className="space-y-3 text-sm">
@ -31,7 +52,7 @@ export default function Footer({ footerRef }) {
</li>
<li className="flex items-center gap-2">
<LinkIcon className="w-4 h-4" />
<Link to="/portfolio">Portofolio</Link>
<Link to="/portofolio">Portofolio</Link>
</li>
<li className="flex items-center gap-2">
<LinkIcon className="w-4 h-4" />
@ -44,29 +65,10 @@ export default function Footer({ footerRef }) {
</ul>
</div>
{/* Newsletter */}
<div>
<h3 className="font-bold text-lg mb-4 relative inline-block">
Newsletter
</h3>
<p className="text-sm mb-3">
Subscribe untuk mendapatkan berita terbaru
</p>
<div className="flex flex-col sm:flex-row gap-2">
<input
type="email"
placeholder="Masukkan Email"
className="px-3 py-2 rounded-md border border-gray-300 text-black text-sm focus:outline-none"
/>
<button className="px-4 py-2 bg-gradient-to-r from-green-400 to-blue-400 text-white rounded-md text-sm hover:opacity-90">
Subscribe
</button>
</div>
</div>
{/* Kontak Kami */}
<div>
<h3 className="font-bold text-lg mb-4 relative inline-block">
<div className="md:col-span-2">
<h3 className="font-bold text-lg mb-2 relative inline-block">
Kontak Kami
</h3>
<ul className="space-y-2 text-sm">
@ -74,10 +76,10 @@ export default function Footer({ footerRef }) {
<Phone className="w-4 h-4"/> 0821 2062 3712
</li>
<li className="flex items-center gap-2">
<Mail className="w-4 h-4"/> cs@wtell.id
<Mail className="w-4 h-4"/> cs@fnet.id
</li>
<li className="flex items-center gap-2">
<Earth className="w-4 h-4"/> https://www.wtell.id/
<Earth className="w-4 h-4"/> https://www.fnet.id/
</li>
</ul>
</div>
@ -85,7 +87,7 @@ export default function Footer({ footerRef }) {
{/* Copyright */}
<div className="border-t border-gray-400 mt-8 pt-4 text-center text-sm">
© 2025 Walanja Telekomunikasi.
© 2025 Fortiva Networking.
</div>
</footer>
);

25
src/components/Hero.jsx Normal file
View File

@ -0,0 +1,25 @@
export default function Hero() {
return (
<section className="relative h-screen w-full overflow-hidden">
<video
autoPlay
loop
muted
playsInline
className="absolute inset-0 w-full h-full object-cover"
>
<source src="/bg-video.mp4" type="video/mp4" />
</video>
<div className="absolute inset-0 bg-black/50"></div>
<div className="relative z-10 flex flex-col justify-center h-full px-6 lg:px-20 text-white max-w-3xl">
<header className="text-4xl md:text-6xl font-bold leading-tight mt-2">
FORTIVA <br /> NETWORKING
</header>
<h1 className="mt-4 text-2xl md:text-3xl>">
Connected Everywhere
</h1>
</div>
</section>
);
}

View File

@ -1,13 +1,15 @@
import { useState, useEffect } from "react";
import { ChevronDown, Menu, X } from "lucide-react";
import { Menu, X } from "lucide-react";
import { NavLink, useLocation, useNavigate } from "react-router-dom";
import { HashLink } from "react-router-hash-link";
export default function Navbar() {
const [isOpen, setIsOpen] = useState(false); // dropdown portfolio
const [mobileMenu, setMobileMenu] = useState(false); // toggle mobile
const [scrolled, setScrolled] = useState(false);
const location = useLocation();
const navigate = useNavigate();
// Deteksi scroll
// Deteksi scroll untuk ubah background navbar
useEffect(() => {
const handleScroll = () => {
setScrolled(window.scrollY > 50);
@ -16,8 +18,31 @@ export default function Navbar() {
return () => window.removeEventListener("scroll", handleScroll);
}, []);
// Scroll otomatis kalau ada hash (#footer, dll)
useEffect(() => {
if (location.hash) {
const id = location.hash.replace("#", "");
const el = document.getElementById(id);
if (el) {
setTimeout(() => {
el.scrollIntoView({ behavior: "smooth" });
}, 100);
}
}
}, [location]);
const linkClass = `block px-4 py-2 hover:text-yellow-400 transition-colors`;
// Klik About Us scroll atau pindah halaman
const handleAboutClick = (e) => {
if (location.pathname === "/about") {
e.preventDefault();
window.scrollTo({ top: 0, behavior: "smooth" });
} else {
navigate("/about");
}
};
return (
<header
className={`fixed w-full top-0 z-20 transition-all duration-300 ${
@ -27,13 +52,13 @@ export default function Navbar() {
<nav className="max-w-7xl mx-auto flex items-center justify-between px-6 lg:px-12 py-4 relative">
{/* Logo */}
<div className="flex items-center space-x-2">
<img src="/WTell.png" alt="logo" className="h-8" />
<img src="/Finals_Icon.png" alt="logo" className="h-7 w-auto object-contain" />
<span
className={`text-lg font-bold transition-colors duration-300 ${
scrolled ? "text-black" : "text-white"
}`}
>
WTell
FortivaNet
</span>
</div>
@ -44,59 +69,29 @@ export default function Navbar() {
}`}
>
<li>
<HashLink smooth to="/#" className="hover:text-yellow-400">
<HashLink smooth to="/#" className={linkClass}>
Home
</HashLink>
</li>
{/* Dropdown Portofolio */}
<li className="relative group">
<button
onClick={() => setIsOpen(!isOpen)}
className="hover:text-yellow-400 flex items-center gap-1"
>
{/* Portofolio link biasa */}
<li>
<NavLink to="/portofolio" className={linkClass}>
Portofolio
<ChevronDown
size={18}
className={`transition-transform duration-200 ${
isOpen ? "rotate-180" : ""
}`}
/>
</button>
{isOpen && (
<ul className="absolute left-0 mt-2 w-48 bg-white rounded-lg shadow-lg text-black">
<li>
<HashLink to="/sdm" className={linkClass}>
SDM
</HashLink>
</li>
<li>
<HashLink to="/alat-kerja" className={linkClass}>
Alat Kerja
</HashLink>
</li>
<li>
<HashLink to="/produksi" className={linkClass}>
Produksi
</HashLink>
</li>
<li>
<HashLink to="/pengalaman" className={linkClass}>
Pengalaman
</HashLink>
</li>
</ul>
)}
</NavLink>
</li>
<li>
<HashLink to="/about" className="hover:text-yellow-400">
<NavLink
to="/about"
className={linkClass}
onClick={handleAboutClick}
>
About Us
</HashLink>
</NavLink>
</li>
<li>
<HashLink smooth to="/#footer" className="hover:text-yellow-400">
<HashLink smooth to="/#footer" className={linkClass}>
Contact Us
</HashLink>
</li>
@ -138,70 +133,25 @@ export default function Navbar() {
</HashLink>
</li>
{/* Dropdown Portofolio di Mobile */}
{/* Portofolio link biasa mobile */}
<li>
<button
onClick={() => setIsOpen(!isOpen)}
className="w-full flex justify-between items-center px-4 py-2 hover:bg-gray-100 rounded-lg"
>
Portofolio
<ChevronDown
size={18}
className={`transition-transform ${
isOpen ? "rotate-180" : ""
}`}
/>
</button>
{isOpen && (
<ul className="ml-4 mt-2 space-y-2 text-sm">
<li>
<HashLink
to="/sdm"
className="block px-4 py-2 hover:text-yellow-400 rounded"
onClick={() => setMobileMenu(false)}
>
SDM
</HashLink>
</li>
<li>
<HashLink
to="/alat-kerja"
className="block px-4 py-2 hover:text-yellow-400 rounded"
onClick={() => setMobileMenu(false)}
>
Alat Kerja
</HashLink>
</li>
<li>
<HashLink
to="/produksi"
className="block px-4 py-2 hover:text-yellow-400 rounded"
onClick={() => setMobileMenu(false)}
>
Produksi
</HashLink>
</li>
<li>
<HashLink
to="/pengalaman"
className="block px-4 py-2 hover:text-yellow-400 rounded"
onClick={() => setMobileMenu(false)}
>
Pengalaman
</HashLink>
</li>
</ul>
)}
</li>
<li>
<HashLink
to="/about"
<NavLink
to="/portofolio"
onClick={() => setMobileMenu(false)}
className={linkClass}
>
Portofolio
</NavLink>
</li>
<li>
<NavLink
to="/about"
onClick={handleAboutClick}
className={linkClass}
>
About Us
</HashLink>
</NavLink>
</li>
<li>
<HashLink

73
src/components/Produk.jsx Normal file
View File

@ -0,0 +1,73 @@
import { Wifi, Network, Cog } from "lucide-react";
import { motion } from "framer-motion";
export default function Produk() {
const products = [
{
icon: <Wifi className="w-8 h-8 text-blue-600" />,
title: "FNET LastMile Connection",
desc: "Solusi bagi penyedia layanan internet untuk melayani pelanggan Last Mile tanpa harus membangun jaringan fiber optic sendiri.",
gradient: "from-blue-500/20 to-blue-100/40"
},
{
icon: <Network className="w-8 h-8 text-yellow-500" />,
title: "FNET Metro Link",
desc: "Layanan jaringan serat optik Point to Point dan Point to Multi Point dengan kapasitas tinggi dan infrastruktur handal.",
gradient: "from-yellow-400/30 to-yellow-100/40"
},
{
icon: <Cog className="w-8 h-8 text-blue-700" />,
title: "FNET EPC Solution",
desc: "Menyediakan layanan Engineering, Procurement, Construction: Survey, Design, Deployment, Operation & Maintenance, FTIX.",
gradient: "from-blue-300/40 to-blue-100/30"
}
];
return (
<section id="produk" className="relative py-20 overflow-hidden text-center">
{/* Animated Background Gradient */}
<motion.div
className="absolute inset-0 bg-gradient-to-r from-blue-900 via-blue-700 to-blue-900 bg-[length:400%_400%]"
animate={{ backgroundPosition: ["0% 50%", "100% 50%", "0% 50%"] }}
transition={{ duration: 20, repeat: Infinity, ease: "linear" }}
></motion.div>
{/* Overlay biar teks tetap jelas */}
<div className="absolute inset-0 bg-white/95"></div>
<div className="relative z-10">
<h2 className="text-3xl md:text-4xl font-bold mb-4 text-color-rgb(20,91,181)">
Produk
</h2>
<p className="text-gray-700 max-w-3xl mx-auto mb-12 px-4">
Solusi layanan jaringan kabel serat optik Point to Point dan Point to
Multi Point dengan kapasitas tinggi, didukung infrastruktur yang
handal melalui jaringan kabel serat optik kami.
</p>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 max-w-6xl mx-auto px-6">
{products.map((item, i) => (
<motion.div
key={i}
whileHover={{ y: -8, scale: 1.03 }}
transition={{ duration: 0.4, ease: "easeOut" }}
className={`bg-white text-blue-900 rounded-2xl shadow-lg relative overflow-hidden p-8 border border-gray-100 hover:border-blue-300`}
>
{/* Gradient overlay per-card */}
<div
className={`absolute inset-0 bg-gradient-to-br ${item.gradient} opacity-30`}
></div>
{/* Icon Circle */}
<div className="relative z-10 w-16 h-16 mx-auto mb-5 rounded-full flex items-center justify-center bg-white shadow-md">
{item.icon}
</div>
<h3 className="text-xl font-semibold mb-3 relative z-10">
{item.title}
</h3>
<p className="relative z-10 text-gray-700">{item.desc}</p>
</motion.div>
))}
</div>
</div>
</section>
);
}

View File

@ -1,55 +1,85 @@
"use client";
import Navbar from "../components/Navbar";
import Hero from "../components/Hero";
import Footer from "../components/Footer";
import { motion } from "framer-motion";
import { CheckCircle } from "lucide-react";
export default function About() {
const cardHover = {
scale: 1.03,
y: -4,
boxShadow: "0 15px 25px rgba(0,0,0,0.1)",
transition: { type: "spring", stiffness: 200, damping: 20 },
};
return (
<div className="font-sans">
{/* Navbar */}
<Navbar />
{/* Hero Section */}
<Hero
title="Tentang Kami"
subtitle="Kenali lebih dekat siapa kami dan visi misi kami"
background="/bg-video.mp4"
/>
{/* About Section */}
<section className="py-20 bg-gray-50 min-h-screen">
<div className="max-w-6xl mx-auto px-6 lg:px-20">
{/* Logo & Deskripsi */}
<motion.section className="text-center"
initial={{ opacity: 0, y: 40 }}
<div className="max-w-6xl mx-auto px-6 lg:px-20 space-y-16">
{/* Card Deskripsi Perusahaan dengan Logo */}
<motion.div
className="bg-white/80 backdrop-blur-lg rounded-3xl shadow-xl border border-gray-200 p-10 flex flex-col md:flex-row items-center gap-8"
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.7 }}
viewport={{ once: true }}
whileHover={{
scale: 1.02,
y: -3,
boxShadow: "0 20px 30px rgba(0,0,0,0.08)",
transition: { type: "spring", stiffness: 200, damping: 20 },
}}
>
{/* Logo di kiri */}
<div className="flex justify-center md:justify-start flex-shrink-0">
<img
src="/WTell.png"
alt="Logo Walanja"
className="mx-auto w-32 mb-6"
src="/Finals_Profile.png"
alt="Logo WTELL"
className="w-44 md:w-56"
/>
<p className="text-gray-700 max-w-3xl mx-auto leading-relaxed">
<span className="font-semibold">PT. Jaringan Citra Mandiri</span>{" "}
adalah Perusahaan Swasta yang bergerak di bidang Penyedia Layanan
</div>
{/* Deskripsi di kanan */}
<div className="text-center md:text-left">
<h2 className="text-3xl font-bold text-color-rgb(20,91,181)">
PT. Jaringan Citra Mandiri
</h2>
<p className="text-gray-700 leading-relaxed mb-4">
Adalah Perusahaan Swasta yang bergerak di bidang Penyedia Layanan
Teknologi Telekomunikasi Berbasis Fiber Optic.
</p>
<p className="mt-4 text-gray-700 max-w-3xl mx-auto leading-relaxed">
Berdiri sejak tahun 2018,{" "}
<span className="font-semibold text-blue-700">WTELL</span>{" "}
berkomitmen menjadi{" "}
<span className="font-bold">
Penyedia Layanan Teknologi Telekomunikasi Berbasis Fiber Optic
yang Handal dan Profesional.
</span>
<p className="text-gray-700 leading-relaxed">
Berdiri sejak tahun 2018, <span className="font-semibold text-color-rgb(20,91,181)">Fortiva Networking</span>{" "}
berkomitmen menjadi Penyedia Layanan Teknologi Telekomunikasi
Berbasis Fiber Optic yang Handal dan Profesional.
</p>
</motion.section>
</div>
</motion.div>
{/* Visi & Misi */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-10 mt-16">
<div className="grid grid-cols-1 md:grid-cols-2 gap-10">
{/* Visi */}
<motion.section className="bg-white shadow-lg rounded-2xl p-8"
initial={{ opacity: 0, x: -50 }}
<motion.section
className="bg-white rounded-2xl p-8 cursor-pointer"
whileHover={cardHover}
initial={{ opacity: 0, x: -30 }}
whileInView={{ opacity: 1, x: 0 }}
transition={{ duration: 0.7 }}
viewport={{ once: true }}
>
<h3 className="text-2xl font-bold text-center mb-6">VISI</h3>
<p className="text-gray-700 text-center leading-relaxed">
Menjadi Penyedia Jaringan Kabel Serat Optik Terbaik yang
@ -58,8 +88,10 @@ export default function About() {
</motion.section>
{/* Misi */}
<motion.section className="bg-white shadow-lg rounded-2xl p-8"
initial={{ opacity: 0, x: 50 }}
<motion.section
className="bg-white rounded-2xl p-8 cursor-pointer"
whileHover={cardHover}
initial={{ opacity: 0, x: 30 }}
whileInView={{ opacity: 1, x: 0 }}
transition={{ duration: 0.7 }}
viewport={{ once: true }}

View File

@ -1,9 +1,25 @@
import Navbar from "../components/Navbar";
import Hero from "../components/Hero";
import Produk from "../components/Produk";
import Cakupan from "../components/Cakupan";
import Footer from "../components/Footer";
import { useEffect, useRef } from "react";
import { useLocation } from "react-router-dom";
import { MapPin, Wifi, Network, Cog } from "lucide-react";
import { motion } from "framer-motion";
import { MapPin, Wifi, Network, Cog } from "lucide-react";
const sectionVariant = {
hidden: { opacity: 0, y: 40 },
visible: (delay = 0) => ({
opacity: 1,
y: 0,
transition: {
duration: 0.8,
delay,
ease: "easeOut",
},
}),
};
export default function Home() {
const footerRef = useRef(null);
@ -21,163 +37,37 @@ export default function Home() {
<Navbar />
{/* Hero Section */}
<section className="relative h-screen w-full overflow-hidden">
<video
autoPlay
loop
muted
playsInline
className="absolute inset-0 w-full h-full object-cover"
<motion.section
variants={sectionVariant}
initial="hidden"
animate="visible"
custom={0.1}
>
<source src="/bg-video.mp4" type="video/mp4" />
</video>
<div className="absolute inset-0 bg-black/50"></div>
<div className="relative z-10 flex flex-col justify-center h-full px-6 lg:px-20 text-white max-w-3xl">
<p className="text-lg">Mari menjadi bagian dari kami</p>
<h1 className="text-4xl md:text-6xl font-bold leading-tight mt-2">
WALANJA <br /> TELEKOMUNIKASI
</h1>
<p className="mt-4 text-lg">
Bergabung bersama kami untuk mewujudkan Indonesia Emas 2045
</p>
</div>
</section>
<Hero />
</motion.section>
{/* Produk Section */}
<section
id="produk"
className="relative py-20 overflow-hidden text-center"
<motion.section
variants={sectionVariant}
initial="hidden"
animate="visible"
custom={0.3}
>
{/* Animated Background */}
<div className="absolute inset-0 bg-gradient-to-r from-blue-900 via-blue-700 to-blue-900 animate-gradient bg-[length:400%_400%]"></div>
<div className="absolute inset-0 bg-white/90"></div>
<Produk />
</motion.section>
<div className="relative z-10">
<h2 className="text-3xl font-bold mb-3 text-blue-900">Produk</h2>
<p className="text-gray-700 max-w-3xl mx-auto mb-12">
Solusi layanan jaringan kabel serat optik Point to Point dan Point
to Multi Point dengan kapasitas tinggi, didukung infrastruktur yang
handal melalui jaringan kabel serat optik kami.
</p>
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 max-w-6xl mx-auto px-6">
{/* Card 1 */}
<motion.div
whileHover={{ scale: 1.05 }}
initial={{ opacity: 0, y: 40 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
viewport={{ once: true }}
className="bg-white text-blue-900 rounded-2xl shadow-xl p-6 relative overflow-hidden"
{/* Cakupan Section */}
<motion.section
variants={sectionVariant}
initial="hidden"
animate="visible"
custom={0.6}
>
<div className="absolute inset-0 bg-gradient-to-br from-blue-900/10 to-transparent"></div>
<Wifi className="w-12 h-12 mb-4 text-blue-600 mx-auto relative z-10" />
<h3 className="text-xl font-bold mb-3 relative z-10">
WTELL LastMile Connection
</h3>
<p className="relative z-10">
Solusi bagi penyedia layanan internet untuk melayani pelanggan
Last Mile tanpa harus membangun jaringan fiber optic sendiri.
</p>
</motion.div>
{/* Card 2 */}
<motion.div
whileHover={{ scale: 1.05 }}
initial={{ opacity: 0, y: 40 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.7 }}
viewport={{ once: true }}
className="bg-white text-blue-900 rounded-2xl shadow-xl p-6 relative overflow-hidden"
>
<div className="absolute inset-0 bg-gradient-to-br from-yellow-200/40 to-transparent"></div>
<Network className="w-12 h-12 mb-4 text-yellow-500 mx-auto relative z-10" />
<h3 className="text-xl font-bold mb-3 relative z-10">
WTELL Metro Link
</h3>
<p className="relative z-10">
Layanan jaringan serat optik Point to Point dan Point to Multi
Point dengan kapasitas tinggi dan infrastruktur handal.
</p>
</motion.div>
{/* Card 3 */}
<motion.div
whileHover={{ scale: 1.05 }}
initial={{ opacity: 0, y: 40 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
viewport={{ once: true }}
className="bg-white text-blue-900 rounded-2xl shadow-xl p-6 relative overflow-hidden"
>
<div className="absolute inset-0 bg-gradient-to-br from-blue-300/30 to-transparent"></div>
<Cog className="w-12 h-12 mb-4 text-blue-600 mx-auto relative z-10" />
<h3 className="text-xl font-bold mb-3 relative z-10">
WTELL EPC Solution
</h3>
<p className="relative z-10">
Menyediakan layanan Engineering, Procurement, Construction:
Survey, Design, Deployment, Operation & Maintenance, FTIX.
</p>
</motion.div>
</div>
</div>
</section>
{/* Cakupan Area Section */}
<section id="cakupan" className="relative py-20 bg-gray-50 overflow-hidden">
{/* Animated Overlay */}
<div className="absolute inset-0 bg-gradient-to-r from-blue-50 via-white to-blue-50 animate-gradient bg-[length:300%_300%]"></div>
<div className="relative z-10">
{/* Title */}
<div className="text-center mb-12">
<h2 className="text-3xl md:text-4xl font-bold flex items-center justify-center gap-2 text-blue-900">
<MapPin className="w-8 h-8 text-blue-600" />
Cakupan Area
</h2>
<p className="mt-3 text-gray-600 max-w-2xl mx-auto">
Saat ini jaringan dan layanan{" "}
<span className="font-semibold">WTELL</span> telah berhasil
menghadirkan internet di berbagai daerah di Kota Bandung hingga
Desa 3T (Tertinggal, Terdepan, Terluar).
</p>
</div>
{/* Content */}
<div className="max-w-6xl mx-auto flex flex-col md:flex-row items-center gap-12 px-6">
{/* Map with hover animation */}
<motion.div
whileHover={{ scale: 1.05 }}
className="flex-1 flex justify-center"
>
<img
src="/map-bandung.jpg"
alt="Map Bandung"
className="w-full max-w-md rounded-2xl shadow-xl border-4 border-blue-100"
/>
</motion.div>
{/* List Area */}
<div className="flex-1 bg-white/70 p-6 rounded-2xl shadow-lg">
<h3 className="text-xl font-semibold mb-4 text-blue-600">
Fokus Layanan
</h3>
<ul className="space-y-3 text-gray-700">
<li>📍 Bandung Kota</li>
<li>📍 Cimahi</li>
<li>📍 Cileunyi</li>
<li>📍 Ngamprah</li>
<li>📍 Desa 3T sekitar Bandung</li>
</ul>
</div>
</div>
</div>
</section>
<Cakupan />
</motion.section>
{/* Footer */}
<Footer footerRef={footerRef} />
<Footer ref={footerRef} />
</div>
);
}

274
src/pages/Portfolio.jsx Normal file
View File

@ -0,0 +1,274 @@
import Navbar from "../components/Navbar";
import Footer from "../components/Footer";
import { motion } from "framer-motion";
import { useState } from "react";
export default function Portfolio() {
const [selectedPortfolio, setSelectedPortfolio] = useState(null);
const portfolioData = [
{
id: 1,
image: "/sdm2.jpg",
title: "Didukung Tenaga Kerja Profesional & Bersertifikasi BNSP",
shortDesc:
"PT. Jaringan Citra Mandiri memiliki tenaga kerja bersertifikasi BNSP dan tenaga ahli berpengalaman.",
detail: (
<>
<h2 className="text-xl font-bold mb-2">
Didukung Tenaga Kerja Profesional & Bersertifikasi BNSP Untuk Layanan Terbaik
</h2>
<p className="text-sm leading-relaxed mb-2">
PT. Jaringan Citra Mandiri memiliki tenaga kerja dengan kualifikasi tinggi dan telah
mendapatkan sertifikasi dari BNSP. Tenaga kerja kami memiliki pengetahuan, keterampilan,
dan pemahaman yang mendalam dalam berbagai bidang pekerjaan.
</p>
<p className="text-sm leading-relaxed">
Lebih dari 200 tenaga kerja siap mendukung semua layanan dengan standar terbaik,
termasuk tenaga ahli di dalamnya yang siap memaksimalkan layanan yang kami sediakan.
</p>
</>
),
},
{
id: 2,
image: "/alat2.jpg",
title: "Peralatan Fiber Optik",
shortDesc:
"PT. Jaringan Citra Mandiri memiliki alat kerja yang lengkap dan tersertifikasi.",
detail: (
<>
<h2 className="text-xl font-bold mb-2">Peralatan Fiber Optik</h2>
<p className="text-sm leading-relaxed mb-2">
Kami menggunakan peralatan fiber optik seperti Fujikura, Yokogawa, dan Exfo untuk
memastikan hasil kerja berkualitas tinggi.
</p>
<p className="text-sm leading-relaxed">
Semua alat kerja sudah sesuai standar industri jaringan serat optik.
</p>
</>
),
extraImages: ["/fujikura.jpg", "/yokogwa.jpg", "/exfo.jpg"],
},
{
id: 3,
image: "/tiang.jpg",
title: "Produksi / Pabrikasi Tiang",
shortDesc: "Pabrikasi tiang telco berkualitas dengan standar industri terbaik.",
detail: (
<div className="space-y-10">
<div className="grid md:grid-cols-2 gap-6 items-center">
<img
src="/tiang1.jpg"
alt="Pabrikasi Berkualitas"
className="w-full h-56 object-cover rounded-lg border shadow"
/>
<div>
<h3 className="font-semibold text-gray-800 mb-2">
Pabrikasi Berkualitas dengan Standar Industri Terbaik
</h3>
<p className="text-sm leading-relaxed">
Selain dari pekerjaan jaringan, PT. Jaringan Citra Mandiri mempunyai Pabrikasi Tiang Telco,
guna menunjang kebutuhan perusahaan maupun kebutuhan dari luar perusahaan.
</p>
</div>
</div>
<div className="grid md:grid-cols-2 gap-6 items-center">
<div className="order-2 md:order-1">
<h3 className="font-semibold text-gray-800 mb-2">
Efisiensi Tinggi untuk Memenuhi Permintaan Pelanggan
</h3>
<p className="text-sm leading-relaxed">
Kami dapat memproduksi tiang sebanyak 50 batang per hari. Dengan peralatan dan fasilitas
yang mumpuni, tenaga kerja yang berkualitas serta sistem manajemen yang efisien, membuat
kami dapat memenuhi permintaan pelanggan dengan baik.
</p>
</div>
<img
src="/tiang2.jpg"
alt="Efisiensi Tinggi"
className="w-full h-56 object-cover rounded-lg border shadow order-1 md:order-2"
/>
</div>
</div>
),
},
{
id: 4,
image: "/map1.jpg",
title: "Pembangunan & Pemeliharaan Jaringan Serat Optik Antar Kota",
shortDesc:
"Pembangunan dan pemeliharaan jaringan serat optik skala besar di berbagai wilayah Jawa Barat.",
detail: (
<div className="space-y-4">
<h2 className="text-xl font-bold mb-2">
Pembangunan & Pemeliharaan Jaringan Serat Optik Antar Kota
</h2>
<p className="text-sm leading-relaxed mb-2">
PT. Jaringan Citra Mandiri telah menyelesaikan berbagai proyek pembangunan
dan pemeliharaan jaringan serat optik antar kota.
Beberapa proyek utama mencakup wilayah strategis di Jawa Barat.
</p>
<div className="grid grid-cols-2 gap-4 mt-4">
<div>
<img src="/subang.jpg" alt="Subang" className="w-full h-36 object-cover rounded-lg border" />
<p className="text-xs mt-1 text-center font-semibold">Subang 50 Km</p>
</div>
<div>
<img src="/pangandaran.jpg" alt="Pangandaran" className="w-full h-36 object-cover rounded-lg border" />
<p className="text-xs mt-1 text-center font-semibold">Pangandaran 225 Km</p>
</div>
<div>
<img src="/bandungraya.jpg" alt="Bandung Raya" className="w-full h-36 object-cover rounded-lg border" />
<p className="text-xs mt-1 text-center font-semibold">Bandung Raya 800 Km</p>
</div>
<div>
<img src="/garut.jpg" alt="Garut" className="w-full h-36 object-cover rounded-lg border" />
<p className="text-xs mt-1 text-center font-semibold">Garut 1000 Km</p>
</div>
<div>
<img src="/ciamis.jpg" alt="Ciamis" className="w-full h-36 object-cover rounded-lg border" />
<p className="text-xs mt-1 text-center font-semibold">Ciamis 100 Km</p>
</div>
<div>
<img src="/tasik.jpg" alt="Tasik" className="w-full h-36 object-cover rounded-lg border" />
<p className="text-xs mt-1 text-center font-semibold">Tasik 100 Km</p>
</div>
</div>
</div>
),
},
];
return (
<div className="font-sans">
<Navbar />
<section className="relative w-full h-[400px] flex items-center justify-center text-center text-white overflow-hidden">
<video
className="absolute inset-0 w-full h-full object-cover"
src="/port.mp4"
autoPlay
loop
muted
playsInline
/>
<div className="absolute inset-0 bg-black/50"></div>
<div className="relative z-10 px-4">
<h1 className="text-4xl font-bold mb-8">Portofolio Kami</h1>
<p className="text-lg opacity-90">
Lihat karya dan layanan terbaik yang sudah kami bangun
</p>
</div>
</section>
<section className="relative py-20 bg-gradient-to-br from-indigo-50 via-white to-pink-50 min-h-screen overflow-hidden">
<div className="relative max-w-6xl mx-auto px-6 lg:px-20">
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 relative z-10">
{portfolioData.map((item) => (
<PortfolioCard
key={item.id}
image={item.image}
title={item.title}
shortDesc={item.shortDesc}
onClick={() => setSelectedPortfolio(item)}
/>
))}
</div>
</div>
</section>
{selectedPortfolio && (
<div className="fixed inset-0 bg-black/70 flex items-center justify-center z-50 px-4">
<motion.div
initial={{ opacity: 0, y: 50, scale: 0.95 }}
animate={{ opacity: 1, y: 0, scale: 1 }}
exit={{ opacity: 0, y: 50, scale: 0.95 }}
transition={{ duration: 0.4, ease: "easeOut" }}
className="relative bg-white/90 backdrop-blur-xl rounded-3xl max-w-5xl w-full h-[85vh] flex flex-col shadow-2xl overflow-hidden"
>
<button
onClick={() => setSelectedPortfolio(null)}
className="absolute top-4 right-4 z-50 bg-white/80 hover:bg-red-500 hover:text-white rounded-full shadow-md p-2 transition"
>
</button>
<div className="relative">
<img
src={selectedPortfolio.image}
alt={selectedPortfolio.title}
className="w-full h-72 object-cover rounded-t-3xl"
/>
<div className="absolute inset-0 bg-gradient-to-t from-black/70 via-black/20 to-transparent rounded-t-3xl"></div>
<div className="absolute bottom-6 left-6">
<h2 className="text-2xl md:text-3xl font-bold text-white drop-shadow-lg">
{selectedPortfolio.title}
</h2>
</div>
</div>
<div className="p-6 overflow-y-auto flex-1 text-gray-800 space-y-4 text-sm leading-relaxed custom-scrollbar">
{selectedPortfolio.detail}
{selectedPortfolio.extraImages && (
<div className="grid grid-cols-2 md:grid-cols-3 gap-4 mt-6">
{selectedPortfolio.extraImages.map((img, idx) => (
<motion.img
key={idx}
src={img}
alt={`extra-${idx}`}
whileHover={{ scale: 1.05 }}
className="w-full h-40 object-cover rounded-xl border shadow-sm transition"
/>
))}
</div>
)}
</div>
</motion.div>
</div>
)}
{/* Tambahkan Footer */}
<Footer />
</div>
);
}
/* Komponen Card */
function PortfolioCard({ image, title, shortDesc, onClick }) {
return (
<motion.div
whileHover={{ scale: 1.02 }}
initial={{ opacity: 0, y: 40 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
viewport={{ once: true }}
className="rounded-2xl overflow-hidden bg-white/90 backdrop-blur-md shadow-md hover:shadow-xl hover:-translate-y-1 transition-all duration-300 flex flex-col"
>
<div className="relative">
<img src={image} alt={title} className="w-full h-48 object-cover" />
<div className="absolute inset-0 bg-gradient-to-t from-black/30 via-transparent to-transparent"></div>
</div>
<div className="p-6 flex flex-col flex-grow">
<h3 className="text-lg font-bold bg-gradient-to-r from-indigo-600 to-blue-500 bg-clip-text text-transparent">
{title}
</h3>
<p className="mt-2 text-gray-700 text-sm leading-relaxed flex-grow">
{shortDesc}
</p>
<button
onClick={onClick}
className="mt-4 inline-block text-blue-600 font-semibold hover:underline text-sm text-left"
>
Lihat Selengkapnya
</button>
</div>
</motion.div>
);
}