Skip to content
Merged
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
41 changes: 41 additions & 0 deletions src/components/playground/GalarySection.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import TButton from "../shared/TertiaryButton";
import images from "../../config/galary";

export default function GalarySection() {
const getRandomImages = () => {
const shuffled = [...images].sort(() => 0.5 - Math.random());
return shuffled.slice(0, 5);
};

const randomImages = getRandomImages();

return (
<div className="w-full max-w-7xl mx-auto px-4 py-8">
{/* Header Section */}
<div className="text-center mb-8">
<h2 className="text-4xl font-bold text-gray-800 mb-4">Image Gallery</h2>
<p className="text-black-600 mb-6">
Explore our vibrant moments captured in stunning visuals.
</p>
<TButton>Go to Gallery &gt;</TButton>
</div>

{/* Gallery Grid */}
<div className="columns-1 sm:columns-2 lg:columns-3 gap-6 space-y-6">
{randomImages.map((image) => (
<div
key={image.id}
className="group cursor-pointer overflow-hidden rounded-lg shadow-md hover:shadow-xl transition-all duration-300 break-inside-avoid"
>
<img
src={image.src}
alt={image.alt}
className="w-full object-cover group-hover:scale-105 transition-transform duration-300"
loading="lazy"
/>
</div>
))}
</div>
</div>
);
}
9 changes: 9 additions & 0 deletions src/components/shared/TertiaryButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const TButton = ({ children }) => {
return (
<div className="bg-[#3773EC] px-3 py-2 inline-block text-white text-base rounded-lg cursor-pointer hover:scale-110 transition-all duration-100 ease-out delay-50">
{children}
</div>
);
};

export default TButton;
40 changes: 40 additions & 0 deletions src/config/galary.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const images = [
{
id: 1,
src: "https://res.cloudinary.com/dsjxx976j/image/upload/v1752424604/image-2_yjyxwo.png",
alt: "Gallery Image 1",
year: 2025,
},
{
id: 2,
src: "https://res.cloudinary.com/dsjxx976j/image/upload/v1752424605/image_r6mlez.png",
alt: "Gallery Image 2",
year: 2025,
},
{
id: 3,
src: "https://res.cloudinary.com/dsjxx976j/image/upload/v1752424604/image-3_yezplq.png",
alt: "Gallery Image 3",
year: 2025,
},
{
id: 4,
src: "https://res.cloudinary.com/dsjxx976j/image/upload/v1752424604/image-4_lwzmbl.png",
alt: "Gallery Image 4",
year: 2024,
},
{
id: 5,
src: "https://res.cloudinary.com/dsjxx976j/image/upload/v1752424604/image-1_ruw6yy.png",
alt: "Gallery Image 5",
year: 2024,
},
{
id: 6,
src: "https://res.cloudinary.com/dsjxx976j/image/upload/v1752425766/e8d1afdb4d097b5c14935394e296d28109b650e4_fominv.png",
alt: "Gallery Image 6",
year: 2024,
},
];

export default images;
16 changes: 16 additions & 0 deletions src/config/galaryPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const heroImages = [
{
id: 1,
src: "https://res.cloudinary.com/dsjxx976j/image/upload/v1752424604/image-2_yjyxwo.png",
alt: "Gallery Image 1",
year: 2025,
},
{
id: 2,
src: "https://res.cloudinary.com/dsjxx976j/image/upload/v1752425766/e8d1afdb4d097b5c14935394e296d28109b650e4_fominv.png",
alt: "Gallery Image 1",
year: 2025,
},
];

export default heroImages;
4 changes: 4 additions & 0 deletions src/main.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import Footer from "./components/playground/Footer.jsx";
import Playground from "./Playground.jsx";
import Test from "./components/playground/Test.jsx";
import Home from "./pages/playground/landing-page/Home.jsx";
import GalarySection from "./components/playground/GalarySection.jsx";
import GallaryPage from "./pages/gallary/Gallary.jsx";
import Achievements from "./pages/playground/Achievements.jsx";
import AchievementPage from "./pages/playground/AchievementPage.jsx";
import Events from "./pages/playground/landing-page/Events.jsx";
Expand All @@ -19,6 +21,8 @@ createRoot(document.getElementById("root")).render(
<Route path="playground" element={<Playground />}>
<Route index element={<Home />} />
<Route path="test" element={<Test />} />
<Route path="galary" element={<GalarySection />} />
<Route path="galaryPage" element={<GallaryPage />} />
<Route path="events" element={<Events />} />
<Route path="achievement" element={<Achievements />} />
<Route path="achievementpage" element={<AchievementPage />} />
Expand Down
178 changes: 178 additions & 0 deletions src/pages/gallary/Gallary.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
import { useState, useEffect } from "react";
import images from "../../config/galary";
import heroImages from "../../config/galaryPage";

const NavButton = ({ direction, onClick }) => {
const isNext = direction === "next";
return (
<button
className="absolute top-1/2 -translate-y-1/2 z-30 bg-black/30 hover:bg-black/50 text-white w-10 h-10 rounded-full flex items-center justify-center"
style={{ [isNext ? "right" : "left"]: "1rem" }}
onClick={onClick}
aria-label={`${isNext ? "Next" : "Previous"} slide`}
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
strokeWidth={2}
stroke="currentColor"
className="w-6 h-6"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d={
isNext ? "M8.25 4.5l7.5 7.5-7.5 7.5" : "M15.75 19.5L8.25 12l7.5-7.5"
}
/>
</svg>
</button>
);
};

const YearButton = ({ year, isSelected, onClick }) => (
<button
onClick={onClick}
className={`px-4 py-1 rounded-full text-sm md:text-base transition-all ${
isSelected
? "bg-blue-600 text-white font-medium"
: "bg-gray-100 text-gray-700 hover:bg-gray-200"
}`}
>
{year === "all" ? "All Years" : year}
</button>
);

const GalleryItem = ({ image }) => (
<div className="group cursor-pointer overflow-hidden rounded-lg shadow-md hover:shadow-xl transition-all duration-300 break-inside-avoid mb-6">
<img
src={image.src}
alt={image.alt}
className="w-full object-cover group-hover:scale-105 transition-transform duration-300"
loading="lazy"
/>
</div>
);

export default function GallaryPage() {
const [selectedYear, setSelectedYear] = useState("all");
const [currentSlide, setCurrentSlide] = useState(0);

useEffect(() => {
const interval = setInterval(() => {
setCurrentSlide((prev) => (prev + 1) % heroImages.length);
}, 5000);
return () => clearInterval(interval);
}, []);

const years = ["all", ...new Set(images.map((image) => image.year))].sort();

const galleryImages =
selectedYear === "all"
? images
: images.filter((image) => image.year === Number(selectedYear));

return (
<div className="w-full">
{/* Hero Banner Carousel */}
<div className="relative h-[280px] sm:h-[320px] md:h-[400px] lg:h-[480px] w-full overflow-hidden">
{/* Carousel Slides */}
<div className="relative h-full w-full">
{heroImages.map((image, index) => (
<div
key={image.id}
className={`absolute inset-0 transition-opacity duration-1000 ease-in-out ${
index === currentSlide ? "opacity-100 z-10" : "opacity-0 z-0"
}`}
>
<img
src={image.src}
alt={image.alt}
className="w-full h-full object-cover brightness-75"
/>
</div>
))}

{/* Carousel Controls */}
<div className="absolute bottom-4 left-0 right-0 z-30 flex justify-center gap-2">
{heroImages.map((_, index) => (
<button
key={index}
onClick={() => setCurrentSlide(index)}
className={`w-2 h-2 rounded-full transition-all ${index === currentSlide ? "bg-white w-4" : "bg-white/50"}`}
aria-label={`Go to slide ${index + 1}`}
/>
))}
</div>

{/* Next/Prev Buttons */}
{heroImages.length > 1 && (
<>
<NavButton
direction="prev"
onClick={() =>
setCurrentSlide((prev) =>
prev === 0 ? heroImages.length - 1 : prev - 1,
)
}
/>
<NavButton
direction="next"
onClick={() =>
setCurrentSlide((prev) => (prev + 1) % heroImages.length)
}
/>
</>
)}
</div>
</div>

{/* Gallery Content */}
<div className="container mx-auto px-4 py-8 md:py-12">
{/* Year Filters and Description Section */}
<div className="mb-12">
<div className="flex flex-col md:flex-row md:items-end md:justify-between gap-6 mb-6">
<div>
<h2 className="text-black text-2xl md:text-[48px] font-bold leading-tight mb-2">
Gallery
</h2>
<div className="flex flex-wrap gap-3 mt-4">
{years.map((year) => (
<YearButton
key={year}
year={year}
isSelected={selectedYear === year}
onClick={() => setSelectedYear(year)}
/>
))}
</div>
</div>
<p className="text-black-600 md:max-w-xl text-sm md:text-base">
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Suspendisse varius enim in eros elementum tristique. Duis cursus,
mi quis viverra ornare, eros dolor interdum nulla, ut commodo diam
libero vitae erat.
</p>
</div>
</div>

{/* Gallery Grid */}
<div className="columns-1 sm:columns-2 lg:columns-3 gap-6 space-y-6">
{galleryImages.map((image) => (
<GalleryItem key={image.id} image={image} />
))}
</div>

{/* No Images Message */}
{galleryImages.length === 0 && (
<div className="text-center py-16">
<p className="text-gray-500 text-lg">
No images found for selected year.
</p>
</div>
)}
</div>
</div>
);
}
Loading