From e152bfcde1b864b648c77b24705b3b0637184b10 Mon Sep 17 00:00:00 2001 From: nthanhtoan61 Date: Thu, 28 May 2026 19:37:12 +0700 Subject: [PATCH] 1 --- app/(site)/gallery/page.tsx | 12 + app/components/gallery/GalleryPageClient.tsx | 247 +++++++++++++++++++ app/components/gallery/ReadyToJoin.tsx | 57 +++++ app/components/home/GallerySection.tsx | 20 +- app/data/gallery.json | 111 +++++++++ app/data/gallery.vi.json | 111 +++++++++ app/data/site.json | 1 + app/data/site.vi.json | 1 + app/hooks/useTranslation.ts | 3 + 9 files changed, 562 insertions(+), 1 deletion(-) create mode 100644 app/(site)/gallery/page.tsx create mode 100644 app/components/gallery/GalleryPageClient.tsx create mode 100644 app/components/gallery/ReadyToJoin.tsx create mode 100644 app/data/gallery.json create mode 100644 app/data/gallery.vi.json diff --git a/app/(site)/gallery/page.tsx b/app/(site)/gallery/page.tsx new file mode 100644 index 0000000..d3f8a04 --- /dev/null +++ b/app/(site)/gallery/page.tsx @@ -0,0 +1,12 @@ +import type { Metadata } from "next"; +import GalleryPageClient from "@/app/components/gallery/GalleryPageClient"; + +export const metadata: Metadata = { + title: "Event Gallery | IPv6 Enhanced 2026", + description: + "Experience the journey of IPv6 adoption through our event highlights and join the Council today.", +}; + +export default function GalleryPage() { + return ; +} diff --git a/app/components/gallery/GalleryPageClient.tsx b/app/components/gallery/GalleryPageClient.tsx new file mode 100644 index 0000000..9d18172 --- /dev/null +++ b/app/components/gallery/GalleryPageClient.tsx @@ -0,0 +1,247 @@ +"use client"; + +import { useState, useEffect } from "react"; +import { useTranslation } from "@/app/hooks/useTranslation"; +import ReadyToJoin from "./ReadyToJoin"; + +const BASE = process.env.NEXT_PUBLIC_BASE_PATH || ""; + +type EventItem = { + id: number; + title: string; + location: string; + date: string; + description: string; + images: string[]; +}; + +export default function GalleryPageClient() { + const { gallery } = useTranslation(); + + // Lightbox State + const [lightboxEventId, setLightboxEventId] = useState(null); + const [lightboxImageIndex, setLightboxImageIndex] = useState(null); + + // Helper to format image source path + const getImgSrc = (src: string) => { + if (src.startsWith("http")) return src; + return `${BASE}${src}`; + }; + + // Keyboard navigation for Lightbox + useEffect(() => { + if (lightboxEventId === null || lightboxImageIndex === null) return; + + const activeEvent = gallery.events.find((e: EventItem) => e.id === lightboxEventId); + if (!activeEvent) return; + + const handleKeyDown = (e: KeyboardEvent) => { + if (e.key === "Escape") { + closeLightbox(); + } else if (e.key === "ArrowRight") { + setLightboxImageIndex((prev) => (prev! + 1) % activeEvent.images.length); + } else if (e.key === "ArrowLeft") { + setLightboxImageIndex((prev) => (prev! - 1 + activeEvent.images.length) % activeEvent.images.length); + } + }; + + window.addEventListener("keydown", handleKeyDown); + return () => { + window.removeEventListener("keydown", handleKeyDown); + }; + }, [lightboxEventId, lightboxImageIndex, gallery.events]); + + const openLightbox = (eventId: number, imgIndex: number) => { + setLightboxEventId(eventId); + setLightboxImageIndex(imgIndex); + document.body.style.overflow = "hidden"; + }; + + const closeLightbox = () => { + setLightboxEventId(null); + setLightboxImageIndex(null); + document.body.style.overflow = ""; + }; + + // Find active lightbox image and event + const activeEvent = lightboxEventId !== null + ? gallery.events.find((e: EventItem) => e.id === lightboxEventId) + : null; + const activeImage = activeEvent && lightboxImageIndex !== null + ? activeEvent.images[lightboxImageIndex] + : null; + + return ( +
+ {/* Hero Header */} +
+
+ + {gallery.hero.eyebrow} + +

+ {gallery.hero.title} +

+

+ {gallery.hero.description} +

+
+
+ + {/* Visual Gallery section */} +
+
+ {gallery.events.map((event: EventItem) => ( +
+ {/* Event details */} +
+
+

+ {event.title} +

+

+ {event.description} +

+
+ + {/* Meta details */} +
+
+ location_on + {event.location} +
+
+ calendar_today + {event.date} +
+
+
+ + {/* Collage gallery grid */} +
+ {/* Large image (left) */} +
openLightbox(event.id, 0)} + > + {/* eslint-disable-next-line @next/next/no-img-element */} + {`${event.title} +
+
+ zoom_in +
+
+
+ + {/* Stacked images (right) */} +
+ {event.images.slice(1, 3).map((imgUrl, i) => ( +
openLightbox(event.id, i + 1)} + > + {/* eslint-disable-next-line @next/next/no-img-element */} + {`${event.title} +
+
+ zoom_in +
+
+
+ ))} +
+
+
+ ))} +
+
+ + {/* Invitation Section */} + + + {/* Lightbox Overlay */} + {lightboxEventId !== null && lightboxImageIndex !== null && activeEvent && activeImage && ( +
+ {/* Close button */} + + + {/* Lightbox content container */} +
e.stopPropagation()} + > + {/* Prev arrow */} + + + {/* Active Image */} +
+ {/* eslint-disable-next-line @next/next/no-img-element */} + {`${activeEvent.title} +
+ + {/* Next arrow */} + +
+ + {/* Info bar below image */} +
e.stopPropagation()} + > +

+ {activeEvent.title} +

+

+ {useTranslation().lang === "vi" + ? `Hình ảnh ${lightboxImageIndex + 1} trên ${activeEvent.images.length}` + : `Image ${lightboxImageIndex + 1} of ${activeEvent.images.length}` + } +

+
+
+ )} +
+ ); +} diff --git a/app/components/gallery/ReadyToJoin.tsx b/app/components/gallery/ReadyToJoin.tsx new file mode 100644 index 0000000..259f47f --- /dev/null +++ b/app/components/gallery/ReadyToJoin.tsx @@ -0,0 +1,57 @@ +"use client"; + +import Link from "next/link"; + +type Props = { + data: { + title: string; + description: string; + registerBtn: string; + viewMembersBtn: string; + }; +}; + +export default function ReadyToJoin({ data }: Props) { + return ( +
+
+ {/* Background Decor */} +
+
+
+ +
+ {/* Title */} +

+ {data.title} +

+ + {/* Description */} +

+ {data.description} +

+ + {/* Call-to-Action Buttons */} +
+ + {data.registerBtn} + + arrow_forward + + + + + {data.viewMembersBtn} + +
+
+
+
+ ); +} diff --git a/app/components/home/GallerySection.tsx b/app/components/home/GallerySection.tsx index 88de053..7471fc9 100644 --- a/app/components/home/GallerySection.tsx +++ b/app/components/home/GallerySection.tsx @@ -1,5 +1,8 @@ "use client"; +import Link from "next/link"; +import { useTranslation } from "@/app/hooks/useTranslation"; + const BASE = process.env.NEXT_PUBLIC_BASE_PATH || ""; type GalleryItem = { @@ -32,6 +35,10 @@ const heightClass: Record = { }; export default function GallerySection({ data }: Props) { + const { lang } = useTranslation(); + const isVi = lang === "vi"; + const btnLabel = isVi ? "Xem Toàn Bộ Thư Viện" : "View Full Event Gallery"; + return (
- {data.items.map((item, i) => ( + {data.items.slice(0, 6).map((item, i) => (
))}
+ + {/* Button to full gallery */} +
+ + {btnLabel} + arrow_forward + +
); } diff --git a/app/data/gallery.json b/app/data/gallery.json new file mode 100644 index 0000000..63a103b --- /dev/null +++ b/app/data/gallery.json @@ -0,0 +1,111 @@ +{ + "hero": { + "eyebrow": "Visual Journey", + "title": "Visual Gallery", + "description": "Experience the journey of IPv6 adoption through our event highlights." + }, + "events": [ + { + "id": 1, + "title": "IPv6 Enhanced AI Summit 2025", + "location": "Singapore", + "date": "Nov 14, 2025", + "description": "Exploring the intersection of IPv6 next-gen routing and large-scale AI cluster networks.", + "images": [ + "/assets/img/gallery/ipv6_new1.jpg", + "https://images.unsplash.com/photo-1540575467063-178a50c2df87?auto=format&fit=crop&w=800&q=80", + "https://images.unsplash.com/photo-1515187029135-18ee286d815b?auto=format&fit=crop&w=800&q=80" + ] + }, + { + "id": 2, + "title": "ASEAN Next-Gen Internet Forum 2025", + "location": "Bangkok, Thailand", + "date": "Sep 08, 2025", + "description": "Driving the adoption of IPv6 across ASEAN telecommunications networks for regional integration.", + "images": [ + "/assets/img/gallery/ipv6_new2.JPG", + "https://images.unsplash.com/photo-1528605248644-14dd04022da1?auto=format&fit=crop&w=800&q=80", + "https://images.unsplash.com/photo-1558494949-ef010cbdcc31?auto=format&fit=crop&w=800&q=80" + ] + }, + { + "id": 3, + "title": "Global IPv6 Innovation Summit 2024", + "location": "Tokyo, Japan", + "date": "Dec 05, 2024", + "description": "Celebrating pioneers in IPv6 deployment and next-generation internet protocols.", + "images": [ + "/assets/img/gallery/ipv6_new3.JPG", + "https://images.unsplash.com/photo-1475721027785-f74eccf877e2?auto=format&fit=crop&w=800&q=80", + "https://images.unsplash.com/photo-1511578314322-379afb476865?auto=format&fit=crop&w=800&q=80" + ] + }, + { + "id": 4, + "title": "ASEAN AI & Cloud Networking Conference 2024", + "location": "Kuala Lumpur, Malaysia", + "date": "Oct 22, 2024", + "description": "Discussing the role of IPv6 in building AI-ready, scalable multi-cloud architectures.", + "images": [ + "/assets/img/gallery/ipv6_new4.jpg", + "https://images.unsplash.com/photo-1597852074816-d933c7d2b988?auto=format&fit=crop&w=800&q=80", + "https://images.unsplash.com/photo-1511795409834-ef04bbd61622?auto=format&fit=crop&w=800&q=80" + ] + }, + { + "id": 5, + "title": "APAC IPv6 Council Regional Assembly 2024", + "location": "Kathmandu, Nepal", + "date": "Apr 18, 2024", + "description": "Regional coordinators aligning policies, routing standards, and government initiatives.", + "images": [ + "/assets/img/gallery/ipv6_new5.jpg", + "https://images.unsplash.com/photo-1531482615713-2afd69097998?auto=format&fit=crop&w=800&q=80", + "https://images.unsplash.com/photo-1542744173-8e0ee26cf195?auto=format&fit=crop&w=800&q=80" + ] + }, + { + "id": 6, + "title": "Vietnam IPv6 Transition Workshop 2023", + "location": "Hanoi, Vietnam", + "date": "Nov 10, 2023", + "description": "Guiding local enterprises and ISPs in the seamless migration from IPv4 to IPv6.", + "images": [ + "/assets/img/gallery/ipv6_new6.jpg", + "https://images.unsplash.com/photo-1517245386807-bb43f82c33c4?auto=format&fit=crop&w=800&q=80", + "https://images.unsplash.com/photo-1454165804606-c3d57bc86b40?auto=format&fit=crop&w=800&q=80" + ] + }, + { + "id": 7, + "title": "ASEAN Cloud & Datacenter Forum 2023", + "location": "Jakarta, Indonesia", + "date": "Aug 15, 2023", + "description": "Optimizing server hardware and network topology using IPv6 features for enterprise scale.", + "images": [ + "/assets/img/gallery/ipv6_new7.jpg", + "https://images.unsplash.com/photo-1600132806370-bf17e65e942f?auto=format&fit=crop&w=800&q=80", + "https://images.unsplash.com/photo-1505373877841-8d25f7d46678?auto=format&fit=crop&w=800&q=80" + ] + }, + { + "id": 8, + "title": "5G & IPv6 Enhanced Summit 2023", + "location": "Manila, Philippines", + "date": "May 24, 2023", + "description": "Catalyzing mobile broadband innovation and IoT connectivity through IPv6-based 5G network slicing.", + "images": [ + "/assets/img/gallery/ipv6_new8.jpg", + "https://images.unsplash.com/photo-1519389950473-47ba0277781c?auto=format&fit=crop&w=800&q=80", + "https://images.unsplash.com/photo-1522071820081-009f0129c71c?auto=format&fit=crop&w=800&q=80" + ] + } + ], + "join": { + "title": "Ready to Join the Council?", + "description": "Become a member today and collaborate with regional leaders to shape the future of the Internet in the Asia-Pacific region.", + "registerBtn": "Member Registration", + "viewMembersBtn": "View Current Members" + } +} diff --git a/app/data/gallery.vi.json b/app/data/gallery.vi.json new file mode 100644 index 0000000..71a4973 --- /dev/null +++ b/app/data/gallery.vi.json @@ -0,0 +1,111 @@ +{ + "hero": { + "eyebrow": "Hành Trình Hình Ảnh", + "title": "Thư Viện Ảnh", + "description": "Trải nghiệm hành trình chuyển đổi IPv6 thông qua các khoảnh khắc nổi bật của sự kiện." + }, + "events": [ + { + "id": 1, + "title": "Hội Nghị Thượng Đỉnh IPv6 Enhanced Cho AI 2025", + "location": "Singapore", + "date": "14/11/2025", + "description": "Khám phá sự giao thoa giữa định tuyến thế hệ mới IPv6 và mạng lưới cụm máy chủ AI quy mô lớn.", + "images": [ + "/assets/img/gallery/ipv6_new1.jpg", + "https://images.unsplash.com/photo-1540575467063-178a50c2df87?auto=format&fit=crop&w=800&q=80", + "https://images.unsplash.com/photo-1515187029135-18ee286d815b?auto=format&fit=crop&w=800&q=80" + ] + }, + { + "id": 2, + "title": "Diễn Đàn Internet Thế Hệ Mới ASEAN 2025", + "location": "Bangkok, Thái Lan", + "date": "08/09/2025", + "description": "Thúc đẩy chuyển đổi sang IPv6 trên các mạng viễn thông ASEAN nhằm tích hợp khu vực số.", + "images": [ + "/assets/img/gallery/ipv6_new2.JPG", + "https://images.unsplash.com/photo-1528605248644-14dd04022da1?auto=format&fit=crop&w=800&q=80", + "https://images.unsplash.com/photo-1558494949-ef010cbdcc31?auto=format&fit=crop&w=800&q=80" + ] + }, + { + "id": 3, + "title": "Hội Nghị Thượng Đỉnh Sáng Tạo IPv6 Toàn Cầu 2024", + "location": "Tokyo, Nhật Bản", + "date": "05/12/2024", + "description": "Vinh danh những đơn vị tiên phong trong triển khai IPv6 và các giao thức internet thế hệ tiếp theo.", + "images": [ + "/assets/img/gallery/ipv6_new3.JPG", + "https://images.unsplash.com/photo-1475721027785-f74eccf877e2?auto=format&fit=crop&w=800&q=80", + "https://images.unsplash.com/photo-1511578314322-379afb476865?auto=format&fit=crop&w=800&q=80" + ] + }, + { + "id": 4, + "title": "Hội Nghị Mạng Đám Mây & AI ASEAN 2024", + "location": "Kuala Lumpur, Malaysia", + "date": "22/10/2024", + "description": "Thảo luận về vai trò của IPv6 trong việc xây dựng kiến trúc đa đám mây có khả năng mở rộng cho AI.", + "images": [ + "/assets/img/gallery/ipv6_new4.jpg", + "https://images.unsplash.com/photo-1597852074816-d933c7d2b988?auto=format&fit=crop&w=800&q=80", + "https://images.unsplash.com/photo-1511795409834-ef04bbd61622?auto=format&fit=crop&w=800&q=80" + ] + }, + { + "id": 5, + "title": "Đại Hội Đồng Khu Vực Hội Đồng IPv6 APAC 2024", + "location": "Kathmandu, Nepal", + "date": "18/04/2024", + "description": "Các điều phối viên khu vực thống nhất về chính sách mạng, tiêu chuẩn định tuyến và các sáng kiến quốc gia.", + "images": [ + "/assets/img/gallery/ipv6_new5.jpg", + "https://images.unsplash.com/photo-1531482615713-2afd69097998?auto=format&fit=crop&w=800&q=80", + "https://images.unsplash.com/photo-1542744173-8e0ee26cf195?auto=format&fit=crop&w=800&q=80" + ] + }, + { + "id": 6, + "title": "Hội Thảo Chuyển Đổi IPv6 Việt Nam 2023", + "location": "Hà Nội, Việt Nam", + "date": "10/11/2023", + "description": "Hướng dẫn các doanh nghiệp và nhà cung cấp dịch vụ Internet (ISP) trong nước chuyển đổi suôn sẻ từ IPv4 sang IPv6.", + "images": [ + "/assets/img/gallery/ipv6_new6.jpg", + "https://images.unsplash.com/photo-1517245386807-bb43f82c33c4?auto=format&fit=crop&w=800&q=80", + "https://images.unsplash.com/photo-1454165804606-c3d57bc86b40?auto=format&fit=crop&w=800&q=80" + ] + }, + { + "id": 7, + "title": "Diễn Đàn Điện Toán Đám Mây & Trung Tâm Dữ Liệu ASEAN 2023", + "location": "Jakarta, Indonesia", + "date": "15/08/2023", + "description": "Tối ưu hóa phần cứng máy chủ và cấu trúc liên kết mạng dựa trên các tính năng của IPv6 cho quy mô doanh nghiệp.", + "images": [ + "/assets/img/gallery/ipv6_new7.jpg", + "https://images.unsplash.com/photo-1600132806370-bf17e65e942f?auto=format&fit=crop&w=800&q=80", + "https://images.unsplash.com/photo-1505373877841-8d25f7d46678?auto=format&fit=crop&w=800&q=80" + ] + }, + { + "id": 8, + "title": "Hội Nghị Thượng Đỉnh 5G & IPv6 Enhanced 2023", + "location": "Manila, Philippines", + "date": "24/05/2023", + "description": "Thúc đẩy đổi mới băng thông rộng di động và kết nối IoT thông qua kỹ thuật chia tách mạng 5G dựa trên IPv6.", + "images": [ + "/assets/img/gallery/ipv6_new8.jpg", + "https://images.unsplash.com/photo-1519389950473-47ba0277781c?auto=format&fit=crop&w=800&q=80", + "https://images.unsplash.com/photo-1522071820081-009f0129c71c?auto=format&fit=crop&w=800&q=80" + ] + } + ], + "join": { + "title": "Sẵn Sàng Tham Gia Hội Đồng?", + "description": "Trở thành thành viên ngay hôm nay và hợp tác với các nhà lãnh đạo khu vực để định hình tương lai của Internet tại khu vực Châu Á - Thái Bình Dương.", + "registerBtn": "Đăng Ký Thành Viên", + "viewMembersBtn": "Xem Các Thành Viên Hiện Tại" + } +} diff --git a/app/data/site.json b/app/data/site.json index ee8b235..0230562 100644 --- a/app/data/site.json +++ b/app/data/site.json @@ -4,6 +4,7 @@ }, "nav": [ { "label": "Home", "href": "/" }, + { "label": "Gallery", "href": "/gallery" }, { "label": "Registration", "href": "/registration" }, { "label": "Feedback", "href": "/feedback" }, { "label": "Sponsor", "href": "/sponsor" } diff --git a/app/data/site.vi.json b/app/data/site.vi.json index fb7c6c8..0894014 100644 --- a/app/data/site.vi.json +++ b/app/data/site.vi.json @@ -4,6 +4,7 @@ }, "nav": [ { "label": "Trang Chủ", "href": "/" }, + { "label": "Thư Viện Ảnh", "href": "/gallery" }, { "label": "Đăng Ký", "href": "/registration" }, { "label": "Phản Hồi", "href": "/feedback" }, { "label": "Nhà Tài Trợ", "href": "/sponsor" } diff --git a/app/hooks/useTranslation.ts b/app/hooks/useTranslation.ts index 56df185..2e3450d 100644 --- a/app/hooks/useTranslation.ts +++ b/app/hooks/useTranslation.ts @@ -12,6 +12,8 @@ import sponsorEn from "@/app/data/sponsor.json"; import sponsorVi from "@/app/data/sponsor.vi.json"; import adminEn from "@/app/data/admin.json"; import adminVi from "@/app/data/admin.vi.json"; +import galleryEn from "@/app/data/gallery.json"; +import galleryVi from "@/app/data/gallery.vi.json"; export function useTranslation() { const { lang } = useLanguage(); @@ -25,5 +27,6 @@ export function useTranslation() { feedback: isVi ? feedbackVi : feedbackEn, sponsor: isVi ? sponsorVi : sponsorEn, admin: isVi ? adminVi : adminEn, + gallery: isVi ? galleryVi : galleryEn, }; }