Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Homepage from "./pages/Homepage"
import Login from "./pages/Login";
import Navbar from "./components/Navbar";
import Dashboard from "./pages/Dashboard";
import PhotoGallery from "./pages/PhotoGallery";

import { devTesting } from "./config";

Expand Down Expand Up @@ -32,6 +33,7 @@ function AppRoutes({ user }: { user: any }) {
{!location.pathname.includes("/dashboard") && <Navbar />}
<Routes>
<Route path="/*" element={<Homepage />} />
<Route path="/gallery" element={<PhotoGallery />} />
{devTesting && (
<>
<Route path="/login" element={user ? <Navigate to="/dashboard/carpool" /> : <Login />} />
Expand Down
16 changes: 16 additions & 0 deletions src/components/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const navLinks = [
{ name: "Pricing", href: "#pricing" },
// { name: "History", href: "#history" },
{ name: "Contact", href: "#contact" },
{ name: "Gallery", href: "/gallery" },
];

const Navbar: React.FC = () => {
Expand Down Expand Up @@ -51,13 +52,28 @@ const Navbar: React.FC = () => {
</li>
{navLinks.map((link) => (
<li key={link.name} className="w-full md:w-auto">
{link.href.startsWith("/") ? (
<Link
to={link.href}
onClick={() => setOpen(false)}
className={`block px-6 py-3 rounded-full font-medium text-center transition-all duration-200 hover:cursor-pointer
${
link.name === "Gallery"
? "bg-white text-black hover:bg-gray-200"
: "text-white hover:bg-gradient-to-r hover:from-purple-600/30 hover:to-fuchsia-600/30 hover:text-purple-100"
}`}
>
{link.name}
</Link>
) : (
<a
href={link.href}
onClick={handleLinkClick}
className="block px-6 py-3 rounded-full text-white font-medium hover:bg-gradient-to-r hover:from-purple-600/30 hover:to-fuchsia-600/30 hover:text-purple-100 transition-all duration-200 text-center hover:cursor-pointer"
>
{link.name}
</a>
)}
</li>
))}
{devTesting && (
Expand Down
77 changes: 77 additions & 0 deletions src/components/ui/ParallaxScroll.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import React, { useRef } from "react";
import { motion, useScroll, useTransform, useSpring } from "framer-motion";

interface ParallaxScrollProps {
images: string[];
title?: string;
}

const ParallaxScroll: React.FC<ParallaxScrollProps> = ({ images, title }) => {
const ref = useRef<HTMLDivElement>(null);

// Track scroll progress relative to the section
const { scrollYProgress } = useScroll({
target: ref,
offset: ["start end", "end start"],
});

// Smooth the scroll value
const smoothProgress = useSpring(scrollYProgress, {
stiffness: 80,
damping: 20,
mass: 0.2,
});

// Parallax transform distances (smaller = smoother)
const moveUp = useTransform(smoothProgress, [0, 1], [0, -200]);
const moveDown = useTransform(smoothProgress, [0, 1], [0, 200]);

// Column
const columnCount = 5;
const chunkSize = Math.ceil(images.length / columnCount);
const columns = Array.from({ length: columnCount }, (_, i) =>
images.slice(i * chunkSize, (i + 1) * chunkSize)
);

return (
<section
ref={ref}
className="relative w-full overflow-visible bg-[#10091e] text-gray-200 py-20"
>
{title && (
<h1 className="text-center text-4xl md:text-5xl font-bold text-purple-300 mb-16">
{title}
</h1>
)}

<div className="mx-auto grid max-w-[1600px] grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-6 px-6">
{columns.map((col, colIndex) => (
<motion.div
key={colIndex}
style={{
y: colIndex % 2 === 0 ? moveUp : moveDown,
willChange: "transform",
}}
className="grid gap-6"
>
{col.map((img, i) => (
<div
key={`col-${colIndex}-img-${i}`}
className="rounded-2xl overflow-hidden shadow-lg shadow-purple-900/30 transition-transform duration-300 hover:scale-[1.02]"
>
<img
src={img}
alt={`parallax-${colIndex}-${i}`}
className="h-60 w-full object-cover object-center"
loading="lazy"
/>
</div>
))}
</motion.div>
))}
</div>
</section>
);
};

export default ParallaxScroll;
128 changes: 128 additions & 0 deletions src/pages/PhotoGallery.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import ParallaxScroll from "@/components/ui/ParallaxScroll";

export default function PhotoGallery() {
const images = [
"http://i.imgur.com/BivauDS.jpeg",
"http://i.imgur.com/OpmWzfm.jpeg",
"http://i.imgur.com/Lgwpif9.jpeg",
"http://i.imgur.com/jG8qPfo.jpeg",
"http://i.imgur.com/wLSxoKY.jpeg",
"http://i.imgur.com/zyPNRFN.jpeg",
"http://i.imgur.com/pg1nt93.jpeg",
"http://i.imgur.com/raGdhcp.jpeg",
"http://i.imgur.com/5METdMM.jpeg",
"http://i.imgur.com/QKSrFBu.jpeg",
"http://i.imgur.com/DR4kDzM.jpeg",
"http://i.imgur.com/wbMk4Nc.jpeg",
"http://i.imgur.com/02GvosS.jpeg",
"http://i.imgur.com/l5frs29.jpeg",
"http://i.imgur.com/q155QsR.jpeg",
"http://i.imgur.com/vAkVP4V.jpeg",
"http://i.imgur.com/eEbr83e.jpeg",
"http://i.imgur.com/BSp2i2g.jpeg",
"http://i.imgur.com/peR88Tx.jpeg",
"http://i.imgur.com/hvwUIsp.jpeg",
"http://i.imgur.com/qgILSqE.jpeg",
"http://i.imgur.com/wg3s65I.jpeg",
"http://i.imgur.com/qAOnCZj.jpeg",
"http://i.imgur.com/BkyWXsz.jpeg",
"http://i.imgur.com/fQwwWNu.jpeg",
"http://i.imgur.com/tMSZEit.jpeg",
"http://i.imgur.com/ENEq1DJ.jpeg",
"https://i.imgur.com/BivauDS.jpeg",
"https://i.imgur.com/OpmWzfm.jpeg",
"https://i.imgur.com/Lgwpif9.jpeg",
"https://i.imgur.com/jG8qPfo.jpeg",
"https://i.imgur.com/wLSxoKY.jpeg",
"https://i.imgur.com/zyPNRFN.jpeg",
"https://i.imgur.com/pg1nt93.jpeg",
"https://i.imgur.com/raGdhcp.jpeg",
"https://i.imgur.com/5METdMM.jpeg",
"https://i.imgur.com/QKSrFBu.jpeg",
"https://i.imgur.com/DR4kDzM.jpeg",
"https://i.imgur.com/wbMk4Nc.jpeg",
"https://i.imgur.com/02GvosS.jpeg",
"https://i.imgur.com/l5frs29.jpeg",
"https://i.imgur.com/q155QsR.jpeg",
"https://i.imgur.com/vAkVP4V.jpeg",
"https://i.imgur.com/eEbr83e.jpeg",
"https://i.imgur.com/BSp2i2g.jpeg",
"https://i.imgur.com/peR88Tx.jpeg",
"https://i.imgur.com/hvwUIsp.jpeg",
"https://i.imgur.com/qgILSqE.jpeg",
"https://i.imgur.com/wg3s65I.jpeg",
"https://i.imgur.com/qAOnCZj.jpeg",
"https://i.imgur.com/BkyWXsz.jpeg",
"https://i.imgur.com/fQwwWNu.jpeg",
"https://i.imgur.com/tMSZEit.jpeg",
"https://i.imgur.com/ENEq1DJ.jpeg",
"https://i.imgur.com/67IOvuV.jpeg",
"https://i.imgur.com/x38R9d5.jpeg",
"https://i.imgur.com/hf2HeGq.jpeg",
"https://i.imgur.com/IH9nuCW.jpeg",
"https://i.imgur.com/f3XvFk0.jpeg",
"https://i.imgur.com/uRaH337.jpeg",
"https://i.imgur.com/POLEJ2U.jpeg",
"https://i.imgur.com/ZnsDzZs.jpeg",
"https://i.imgur.com/MnKx6hO.jpeg",
"https://i.imgur.com/5tqW1Mo.jpeg",
"https://i.imgur.com/pCLQh4I.jpeg",
"https://i.imgur.com/MNewTK4.jpeg",
"https://i.imgur.com/uu1Vy2s.jpeg",
"https://i.imgur.com/cLab8NO.jpeg",
"https://i.imgur.com/thxxstg.jpeg",
"https://i.imgur.com/26DMJof.jpeg",
"https://i.imgur.com/HGrT4JB.jpeg",
"https://i.imgur.com/6sBgTZk.jpeg",
"https://i.imgur.com/48Adi4p.jpeg",
"https://i.imgur.com/ypWSz94.jpeg",
"https://i.imgur.com/39O4VYg.jpeg",
"https://i.imgur.com/jn2EtOI.jpeg",
"https://i.imgur.com/kBK7f5S.jpeg",
"https://i.imgur.com/vJh4CVu.jpeg",
"https://i.imgur.com/Tsf11Wm.jpeg",
"https://i.imgur.com/fDhEUmz.jpeg",
"https://i.imgur.com/HwX5O7M.jpeg",
"https://i.imgur.com/5R3WWsC.jpeg",
"https://i.imgur.com/bsBY5y9.jpeg",
"https://i.imgur.com/QAg69vh.jpeg",
"https://i.imgur.com/9EG51Rx.jpeg",
"https://i.imgur.com/EOkGkrZ.jpeg",
"https://i.imgur.com/OhRW8lE.jpeg",
"https://i.imgur.com/QqglvHE.jpeg",
"https://i.imgur.com/y7wND3y.jpeg",
"https://i.imgur.com/fNHf61u.jpeg",
"https://i.imgur.com/5eUMo3M.jpeg",
"https://i.imgur.com/PMzwFsY.jpeg",
"https://i.imgur.com/9ebNb6E.jpeg",
"https://i.imgur.com/GRnMLgQ.jpeg",
"https://i.imgur.com/vysJHHy.jpeg",
"https://i.imgur.com/yadMNcY.jpeg",
"https://i.imgur.com/KyOiRom.jpeg",
"https://i.imgur.com/l4LZ3Qd.jpeg",
"https://i.imgur.com/ZvPWNmM.jpeg",
"https://i.imgur.com/RgoCRor.jpeg",
"https://i.imgur.com/QQBUcOY.jpeg",
"https://i.imgur.com/ulm8bIh.jpeg",
"https://i.imgur.com/k9apoeN.jpeg",
"https://i.imgur.com/O9ipubk.jpeg",
"https://i.imgur.com/wbjXSnV.jpeg",
"https://i.imgur.com/3xJMRda.jpeg",
"https://i.imgur.com/JCooi6c.jpeg",
"https://i.imgur.com/LBUrlb6.jpeg",
"https://i.imgur.com/0DQWPT9.jpeg"
];

return (
<div
id="gallery"
className="bg-[#10091e] text-gray-200 min-h-screen pt-28 md:pt-32"
>
<h1 className="md:ms-4 text-3xl md:text-5xl font-bold mb-20 text-purple-300 text-center md:pt-24">
Our Adventures
</h1>

<ParallaxScroll images={images} />
</div>
);
}