forked from UKSOURCE/ipv6
Merge pull request 'feat: agenda, filter, event location' (#22) from feat/toan-04082026-agenda into main
Reviewed-on: UKSOURCE/ipv6#22
This commit is contained in:
@@ -25,3 +25,4 @@
|
||||
| 3168 | — | Task | Home | Agenda Section | Cập nhật thông tin agenda, speaker | Cập nhật đúng thời gian biểu, bổ sung các bài phát biểu mới và hình ảnh đại diện của diễn giả (cả Anh/Việt) | 18/7/2026 | `[x]` | — | Toàn |
|
||||
| 3168 | — | Task | Home | Agenda Section | Khôi phục cấu trúc Agenda cũ (loại bỏ IEAS) | Gỡ bỏ các bài phát biểu của đối tác IEAS và đưa khung giờ sự kiện về 8:30 AM | 18/7/2026 | `[x]` | — | Toàn |
|
||||
| 3168 | — | Task | Home | Partners Carousel | Tạm ẩn logo đối tác IEAS khỏi carousel | Comment out logo IEAS, không hiển thị trên trang chủ | 18/7/2026 | `[x]` | — | Toàn |
|
||||
| 3210 | — | Task | Home | Agenda Section | Nâng cấp Agenda 21 phiên, Timeline gốc, Table View rút gọn kèm Modal, Múi giờ & Maps Direct | Hiển thị 21 phiên chuẩn, Timeline gốc so le, Table View rút gọn line-clamp kèm Modal chi tiết, Timezone ICT/UTC/Local, Print PDF, Google Maps | 04/8/2026 | `[x]` | Hoàn thành | Toàn |
|
||||
|
||||
@@ -0,0 +1,310 @@
|
||||
# IPv6 Enhanced for AI & Cloud Summit 2026 - Website Requirements & Agenda Data
|
||||
|
||||
Tài liệu này tổng hợp toàn bộ cấu trúc Filter/UI và danh sách chi tiết các phiên (Agenda) trích xuất từ tài liệu PDF để làm dữ liệu đầu vào cho việc cập nhật/phát triển Website và tích hợp AI.
|
||||
|
||||
---
|
||||
|
||||
## 1. Cấu Trúc Bộ Lọc & Giao Diện (Filter & UI Features)
|
||||
|
||||
### 1.1. Thanh Tìm Kiếm (Search Bar)
|
||||
* **Placeholder:** `Search sessions, speaker`
|
||||
* **Chức năng:** Cho phép người dùng tìm kiếm theo từ khóa trong tên phiên (Session Title), nội dung mô tả (Description), hoặc tên diễn giả (Speaker/Presenter).
|
||||
|
||||
### 1.2. Thẻ Lọc Theo Chủ Đề (Filter Tracks / Categories)
|
||||
Các Tag filter hỗ trợ chọn theo từng danh mục:
|
||||
* **All Sessions** (Tất cả các phiên)
|
||||
* **Ceremonies** (Lễ / Khai mạc - Bế mạc)
|
||||
* **Keynotes & Address** (Bài phát biểu chính & Toạ đàm)
|
||||
* **Technical & Infrastructure** (Kỹ thuật & Hạ tầng)
|
||||
* **Forums & Panels** (Diễn đàn & Thảo luận bàn tròn)
|
||||
* **Breaks & Networking** (Nghỉ giải lao & Kết nối)
|
||||
|
||||
### 1.3. Chế Độ Hiển Thị (View Modes)
|
||||
* **Table View:** Hiển thị danh sách Agenda dưới dạng bảng chi tiết.
|
||||
* **Card View:** Hiển thị danh sách Agenda dưới dạng thẻ (Card UI).
|
||||
|
||||
### 1.4. Quản Lý Lịch Cá Nhân (My Schedule)
|
||||
* **Nút bấm My Schedule:** Hiển thị số lượng phiên đã chọn, ví dụ: `My Schedule (0)`.
|
||||
* **Hành động Lưu (Action Save):** Mỗi phiên trong danh sách có biểu tượng `Star` (☆ / ★) ở cột Action để người dùng click thêm/xóa phiên vào lịch trình cá nhân (`My Schedule`).
|
||||
|
||||
---
|
||||
|
||||
## 2. Cấu Trúc Bảng Agenda (Agenda Table Structure)
|
||||
|
||||
Bảng dữ liệu Agenda bao gồm các thuộc tính chính:
|
||||
1. **Time (ICT / UTC):** Thời gian diễn ra theo giờ ICT và giờ UTC.
|
||||
2. **Category:** Phân loại chủ đề của phiên.
|
||||
3. **Session Title & Description:** Tên phiên chủ đề và nội dung chi tiết.
|
||||
4. **Speaker / Presenter:** Tên, chức danh và đơn vị công tác của diễn giả/người trình bày.
|
||||
5. **Location:** Địa điểm diễn ra (VD: Main Stage).
|
||||
6. **Action:** Biểu tượng đánh dấu lưu vào lịch cá nhân (Bookmark / Star).
|
||||
|
||||
---
|
||||
|
||||
## 3. Danh Sách Chi Tiết Toàn Bộ Agenda (Full Event Schedule)
|
||||
|
||||
| Time (ICT / UTC) | Category | Session Title & Description | Speaker / Presenter | Location | Action |
|
||||
| :--- | :--- | :--- | :--- | :--- | :---: |
|
||||
| **9.00 am - 9.15 am ICT**<br>2.00 am - 2.15 am UTC | NETWORKING & BREAK | **Registration & Networking**<br>Welcome to APAC IPv6, AI & Cloud Summit 2026. Collect your badge. | *(N/A)* | Main Stage | ☆ |
|
||||
| **9.15 am - 9.30 am ICT**<br>2.15 am - 2.30 am UTC | CEREMONIES | **Arrival of VIPs**<br>Reception of government dignitaries, international delegates, and VIPs. | *(N/A)* | Main Stage | ☆ |
|
||||
| **9.30 am - 9.50 am ICT**<br>2.30 am - 2.50 am UTC | KEYNOTE | **Welcome Address & Keynote Address: National Sovereign Cloud in the Intelligent Era: Shaping Independent and Resilient Digital Infrastructure**<br>Opening greeting and keynote address detailing national sovereign cloud... | **Prof Emeritus Dr Sureswaran Ramadass**<br>Chairman, APAC IPv6 Council | Main Stage | ☆ |
|
||||
| **9.50 am - 10.00 am ICT**<br>2.50 am - 3.00 am UTC | KEYNOTE | **Keynote Address: Viet Nam's IPv6 Journey: Bridging the Gaps, Accelerating IPv6-Only, and Driving Robust and Intelligent Network Evolution**<br>Keynote detailing Viet Nam's strategic progress, bridging technical gaps, accelerating IPv6-Only... | **Mr. Nguyen Truong Giang**<br>Acting Director General, VNNIC | Main Stage | ☆ |
|
||||
| **10.00 am - 10.10 am ICT**<br>3.00 am - 3.10 am UTC | KEYNOTE | **Keynote Address: Navigating the Global Digital Landscape: European-American Practices and Strategic Insights for Viet Nam in Intelligent Era**<br>Keynote insights comparing European and American digital infrastructure practices... | **Nguyen Chien Thang**<br>Director General, Institute for European and American Studies | Main Stage | ☆ |
|
||||
| **10.10 am - 10.20 am ICT**<br>3.10 am - 3.20 am UTC | CEREMONIES | **Launch Ceremony "IPv6-First & IPv6 Enhanced National Implementation Strategy Guideline"**<br>Inaugural launch ceremony of the National Implementation Strategy Guidelines. | *(N/A)* | Main Stage | ☆ |
|
||||
| **10.20 am - 10.40 am ICT**<br>3.20 am - 3.40 am UTC | KEYNOTE | **Keynote Address: AI WAN: Empowering Carriers into the New Era of Token Monetization**<br>Keynote presentation detailing AI WAN architectures, network transformation, and tokenization. | **Mr. Jun Cai**<br>Vice President, Data Communication Product Line | Main Stage | ☆ |
|
||||
| **10.40 am - 11.00 am ICT**<br>3.40 am - 4.00 am UTC | NETWORKING & BREAK | **Morning Coffee Break / Press Conference + Photos**<br>Morning refreshment break. VIPs and media gather for press briefings and photo opportunities. | *(N/A)* | Main Stage | ☆ |
|
||||
| **11.00 am - 11.20 am ICT**<br>4.00 am - 4.20 am UTC | TECHNICAL | **Carrier Perspectives: IPv6-Driven Robust Infrastructure Fueling Enterprise Cloud and Computing Networks**<br>Carrier presentation analyzing how IPv6-driven robust infrastructure fuels enterprise cloud... | **Speaker from Vietnam ISP / Data Centre Operator**<br>Technical Representative | Main Stage | ☆ |
|
||||
| **11.20 am - 11.40 am ICT**<br>4.20 am - 4.40 am UTC | TECHNICAL | **Pioneering the AI Era: Building Secure and Smart Digital Ecosystems with IPv6 and AI**<br>Technical presentation on cybersecurity vulnerabilities, digital readiness, and smart ecosystems. | **Dr. Navaneethan C Arjuman**<br>Chair of IPv6 and SG Working Group | Main Stage | ☆ |
|
||||
| **11.40 am - 12.00 pm ICT**<br>4.40 am - 5.00 am UTC | TECHNICAL | **Building AI-Ready Network Infrastructure**<br>Case studies and structural designs for building AI-ready network infrastructure. | **Mr. Bayu Hanantasena**<br>Strategic Advisor to CEO, Indosat | Main Stage | ☆ |
|
||||
| **12.00 pm - 12.20 pm ICT**<br>5.00 am - 5.20 am UTC | TECHNICAL | **Navigating ASEAN's Digital Future: Aligning Next-Gen Networking, AI, and Cloud Strategy**<br>Strategic sharing on policy frameworks, digital economy, and cloud strategy alignment. | **Mr. Sivaram Superamanian**<br>Assistant Director, Digital Economy | Main Stage | ☆ |
|
||||
| **12.20 pm - 12.40 pm ICT**<br>5.20 am - 5.40 am UTC | TECHNICAL | **Insights and Operational Perspectives from Local Network Operators**<br>Operational perspectives and network deployment insights from local network operators. | **Speaker from Vietnam ISP / Network Operator**<br>Network Operator Representative | Main Stage | ☆ |
|
||||
| **12.40 pm - 1.30 pm ICT**<br>5.40 am - 6.30 am UTC | NETWORKING & BREAK | **Lunch**<br>Lunch and networking recess for all registered delegates and speakers. | *(N/A)* | Main Stage | ☆ |
|
||||
| **1.30 pm - 2.30 pm ICT**<br>6.30 am - 7.30 am UTC | FORUM & PANEL | **Forum: AI Regulation & Data Sovereignty**<br>A high-level panel discussion on policy frameworks governing data sovereignty and AI regulation. | **Moderator from Council / Panellists from Gov Officials or ISPs** | Main Stage | ☆ |
|
||||
| **2.30 pm - 2.50 pm ICT**<br>7.30 am - 7.50 am UTC | TECHNICAL | **AI & Cloud (IPv6) - Developments in China**<br>A technical overview of global IPv6 adoption patterns, protocol implementations, and AI-cloud integration. | **Mr. Liu Shuai**<br>Vice President, MII, China | Main Stage | ☆ |
|
||||
| **2.50 pm - 3.10 pm ICT**<br>7.50 am - 8.10 am UTC | TECHNICAL | **Technical Presentation (TBD)**<br>Technical presentation session slot. Specific presentation topic and details to be announced. | **TBD**<br>Speaker To Be Announced | Main Stage | ☆ |
|
||||
| **3.10 pm - 3.30 pm ICT**<br>8.10 am - 8.30 am UTC | NETWORKING & BREAK | **Afternoon Coffee Break**<br>Afternoon tea and coffee, networking with cloud partners, and exhibition viewing. | *(N/A)* | Main Stage | ☆ |
|
||||
| **3.30 pm - 4.00 pm ICT**<br>8.30 am - 9.00 am UTC | TECHNICAL | **IEC Standards Between Powermeter and Distributed Energy Resource**<br>Technical presentation on IEC standards between powermeters and distributed energy resources. | **Dr. Masaki Umejima**<br>Convener of Energy Resource Aggregation | Main Stage | ☆ |
|
||||
| **4.00 pm - 5.30 pm ICT**<br>9.00 am - 10.30 am UTC | TECHNICAL | **Technical Sharing & Demo (TBD by Local Partner - SIMS)**<br>Hands-on lab showcase and technical integration demo led by local partner SIMS. | **TBD by Local Partner (SIMS)**<br>Technical Lead Specialists | Main Stage | ☆ |
|
||||
| **5.30 pm - 6.00 pm ICT**<br>10.30 am - 11.00 am UTC | CEREMONIES | **Conference Adjourns**<br>Final wrap-up, thanks to hosts and sponsors, and distribution of event closing remarks. | *(N/A)* | Main Stage | ☆ |
|
||||
|
||||
---
|
||||
|
||||
## 4. Dữ Liệu JSON Thô (JSON Data Format)
|
||||
|
||||
Dành cho AI/Developer dễ dàng import trực tiếp vào database hoặc làm Mock Data:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"time_ict": "9.00 am - 9.15 am",
|
||||
"time_utc": "2.00 am - 2.15 am",
|
||||
"category": "Breaks & Networking",
|
||||
"title": "Registration & Networking",
|
||||
"description": "Welcome to APAC IPv6, AI & Cloud Summit 2026. Collect your badge.",
|
||||
"speaker": "",
|
||||
"speaker_title": "",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"time_ict": "9.15 am - 9.30 am",
|
||||
"time_utc": "2.15 am - 2.30 am",
|
||||
"category": "Ceremonies",
|
||||
"title": "Arrival of VIPs",
|
||||
"description": "Reception of government dignitaries, international delegates, and VIPs.",
|
||||
"speaker": "",
|
||||
"speaker_title": "",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"time_ict": "9.30 am - 9.50 am",
|
||||
"time_utc": "2.30 am - 2.50 am",
|
||||
"category": "Keynotes & Address",
|
||||
"title": "Welcome Address & Keynote Address: National Sovereign Cloud in the Intelligent Era: Shaping Independent and Resilient Digital Infrastructure",
|
||||
"description": "Opening greeting and keynote address detailing national sovereign cloud in the intelligent era.",
|
||||
"speaker": "Prof Emeritus Dr Sureswaran Ramadass",
|
||||
"speaker_title": "Chairman, APAC IPv6 Council",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"time_ict": "9.50 am - 10.00 am",
|
||||
"time_utc": "2.50 am - 3.00 am",
|
||||
"category": "Keynotes & Address",
|
||||
"title": "Keynote Address: Viet Nam's IPv6 Journey: Bridging the Gaps, Accelerating IPv6-Only, and Driving Robust and Intelligent Network Evolution",
|
||||
"description": "Keynote detailing Viet Nam's strategic progress, bridging technical gaps, accelerating IPv6-Only...",
|
||||
"speaker": "Mr. Nguyen Truong Giang",
|
||||
"speaker_title": "Acting Director General, VNNIC",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"time_ict": "10.00 am - 10.10 am",
|
||||
"time_utc": "3.00 am - 3.10 am",
|
||||
"category": "Keynotes & Address",
|
||||
"title": "Keynote Address: Navigating the Global Digital Landscape: European-American Practices and Strategic Insights for Viet Nam in Intelligent Era",
|
||||
"description": "Keynote insights comparing European and American digital infrastructure practices...",
|
||||
"speaker": "Nguyen Chien Thang",
|
||||
"speaker_title": "Director General, Institute for European and American Studies",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"time_ict": "10.10 am - 10.20 am",
|
||||
"time_utc": "3.10 am - 3.20 am",
|
||||
"category": "Ceremonies",
|
||||
"title": "Launch Ceremony "IPv6-First & IPv6 Enhanced National Implementation Strategy Guideline"",
|
||||
"description": "Inaugural launch ceremony of the National Implementation Strategy Guidelines.",
|
||||
"speaker": "",
|
||||
"speaker_title": "",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"time_ict": "10.20 am - 10.40 am",
|
||||
"time_utc": "3.20 am - 3.40 am",
|
||||
"category": "Keynotes & Address",
|
||||
"title": "Keynote Address: AI WAN: Empowering Carriers into the New Era of Token Monetization",
|
||||
"description": "Keynote presentation detailing AI WAN architectures, network transformation, and tokenization.",
|
||||
"speaker": "Mr. Jun Cai",
|
||||
"speaker_title": "Vice President, Data Communication Product Line",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"time_ict": "10.40 am - 11.00 am",
|
||||
"time_utc": "3.40 am - 4.00 am",
|
||||
"category": "Breaks & Networking",
|
||||
"title": "Morning Coffee Break / Press Conference + Photos",
|
||||
"description": "Morning refreshment break. VIPs and media gather for press briefings and photo opportunities.",
|
||||
"speaker": "",
|
||||
"speaker_title": "",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"time_ict": "11.00 am - 11.20 am",
|
||||
"time_utc": "4.00 am - 4.20 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "Carrier Perspectives: IPv6-Driven Robust Infrastructure Fueling Enterprise Cloud and Computing Networks",
|
||||
"description": "Carrier presentation analyzing how IPv6-driven robust infrastructure fuels enterprise cloud...",
|
||||
"speaker": "Speaker from Vietnam ISP / Data Centre Operator",
|
||||
"speaker_title": "Technical Representative",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"time_ict": "11.20 am - 11.40 am",
|
||||
"time_utc": "4.20 am - 4.40 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "Pioneering the AI Era: Building Secure and Smart Digital Ecosystems with IPv6 and AI",
|
||||
"description": "Technical presentation on cybersecurity vulnerabilities, digital readiness, and smart ecosystems.",
|
||||
"speaker": "Dr. Navaneethan C Arjuman",
|
||||
"speaker_title": "Chair of IPv6 and SG Working Group",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"time_ict": "11.40 am - 12.00 pm",
|
||||
"time_utc": "4.40 am - 5.00 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "Building AI-Ready Network Infrastructure",
|
||||
"description": "Case studies and structural designs for building AI-ready network infrastructure.",
|
||||
"speaker": "Mr. Bayu Hanantasena",
|
||||
"speaker_title": "Strategic Advisor to CEO, Indosat",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"time_ict": "12.00 pm - 12.20 pm",
|
||||
"time_utc": "5.00 am - 5.20 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "Navigating ASEAN's Digital Future: Aligning Next-Gen Networking, AI, and Cloud Strategy",
|
||||
"description": "Strategic sharing on policy frameworks, digital economy, and cloud strategy alignment.",
|
||||
"speaker": "Mr. Sivaram Superamanian",
|
||||
"speaker_title": "Assistant Director, Digital Economy",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"time_ict": "12.20 pm - 12.40 pm",
|
||||
"time_utc": "5.20 am - 5.40 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "Insights and Operational Perspectives from Local Network Operators",
|
||||
"description": "Operational perspectives and network deployment insights from local network operators.",
|
||||
"speaker": "Speaker from Vietnam ISP / Network Operator",
|
||||
"speaker_title": "Network Operator Representative",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"time_ict": "12.40 pm - 1.30 pm",
|
||||
"time_utc": "5.40 am - 6.30 am",
|
||||
"category": "Breaks & Networking",
|
||||
"title": "Lunch",
|
||||
"description": "Lunch and networking recess for all registered delegates and speakers.",
|
||||
"speaker": "",
|
||||
"speaker_title": "",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"time_ict": "1.30 pm - 2.30 pm",
|
||||
"time_utc": "6.30 am - 7.30 am",
|
||||
"category": "Forums & Panels",
|
||||
"title": "Forum: AI Regulation & Data Sovereignty",
|
||||
"description": "A high-level panel discussion on policy frameworks governing data sovereignty and AI regulation.",
|
||||
"speaker": "Moderator from Council / Panellists from Gov Officials or ISPs",
|
||||
"speaker_title": "",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"time_ict": "2.30 pm - 2.50 pm",
|
||||
"time_utc": "7.30 am - 7.50 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "AI & Cloud (IPv6) - Developments in China",
|
||||
"description": "A technical overview of global IPv6 adoption patterns, protocol implementations, and AI-cloud integration.",
|
||||
"speaker": "Mr. Liu Shuai",
|
||||
"speaker_title": "Vice President, MII, China",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"time_ict": "2.50 pm - 3.10 pm",
|
||||
"time_utc": "7.50 am - 8.10 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "Technical Presentation (TBD)",
|
||||
"description": "Technical presentation session slot. Specific presentation topic and details to be announced.",
|
||||
"speaker": "TBD",
|
||||
"speaker_title": "Speaker To Be Announced",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"time_ict": "3.10 pm - 3.30 pm",
|
||||
"time_utc": "8.10 am - 8.30 am",
|
||||
"category": "Breaks & Networking",
|
||||
"title": "Afternoon Coffee Break",
|
||||
"description": "Afternoon tea and coffee, networking with cloud partners, and exhibition viewing.",
|
||||
"speaker": "",
|
||||
"speaker_title": "",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"time_ict": "3.30 pm - 4.00 pm",
|
||||
"time_utc": "8.30 am - 9.00 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "IEC Standards Between Powermeter and Distributed Energy Resource",
|
||||
"description": "Technical presentation on IEC standards between powermeters and distributed energy resources.",
|
||||
"speaker": "Dr. Masaki Umejima",
|
||||
"speaker_title": "Convener of Energy Resource Aggregation",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"time_ict": "4.00 pm - 5.30 pm",
|
||||
"time_utc": "9.00 am - 10.30 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "Technical Sharing & Demo (TBD by Local Partner - SIMS)",
|
||||
"description": "Hands-on lab showcase and technical integration demo led by local partner SIMS.",
|
||||
"speaker": "TBD by Local Partner (SIMS)",
|
||||
"speaker_title": "Technical Lead Specialists",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"time_ict": "5.30 pm - 6.00 pm",
|
||||
"time_utc": "10.30 am - 11.00 am",
|
||||
"category": "Ceremonies",
|
||||
"title": "Conference Adjourns",
|
||||
"description": "Final wrap-up, thanks to hosts and sponsors, and distribution of event closing remarks.",
|
||||
"speaker": "",
|
||||
"speaker_title": "",
|
||||
"location": "Main Stage"
|
||||
}
|
||||
]
|
||||
```
|
||||
@@ -1,10 +1,17 @@
|
||||
"use client";
|
||||
|
||||
type AgendaItem = {
|
||||
order: string;
|
||||
time: string;
|
||||
import { useState, useEffect, useMemo } from "react";
|
||||
|
||||
export type AgendaItem = {
|
||||
id: number;
|
||||
time_ict: string;
|
||||
time_utc: string;
|
||||
category: string;
|
||||
title: string;
|
||||
description: string;
|
||||
speaker: string;
|
||||
speaker_title: string;
|
||||
location: string;
|
||||
avatar?: string;
|
||||
};
|
||||
|
||||
@@ -18,15 +25,20 @@ type Props = {
|
||||
};
|
||||
};
|
||||
|
||||
const CATEGORIES = [
|
||||
"All Sessions",
|
||||
"Ceremonies",
|
||||
"Keynotes & Address",
|
||||
"Technical & Infrastructure",
|
||||
"Forums & Panels",
|
||||
"Breaks & Networking",
|
||||
];
|
||||
|
||||
const renderFormattedText = (text: string) => {
|
||||
if (!text) return "";
|
||||
|
||||
if (!text) return null;
|
||||
const lines = text.split("\n");
|
||||
|
||||
return lines.map((line, lineIndex) => {
|
||||
// Split the line by markdown bold (**bold**) and italic (*italic*)
|
||||
const parts = line.split(/(\*\*.*?\*\*|\*.*?\*)/g);
|
||||
|
||||
const renderedLine = parts.map((part, partIndex) => {
|
||||
if (part.startsWith("**") && part.endsWith("**")) {
|
||||
return (
|
||||
@@ -55,30 +67,197 @@ const renderFormattedText = (text: string) => {
|
||||
|
||||
export default function AgendaSection({ data }: Props) {
|
||||
const base = process.env.NEXT_PUBLIC_BASE_PATH || "";
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
const [selectedCategory, setSelectedCategory] = useState("All Sessions");
|
||||
const [viewMode, setViewMode] = useState<"table" | "card">("card");
|
||||
const [timezoneMode, setTimezoneMode] = useState<"ICT" | "UTC" | "Local">("ICT");
|
||||
const [bookmarkedIds, setBookmarkedIds] = useState<number[]>([]);
|
||||
const [showOnlyBookmarks, setShowOnlyBookmarks] = useState(false);
|
||||
const [selectedModalItem, setSelectedModalItem] = useState<AgendaItem | null>(null);
|
||||
|
||||
const renderAvatar = (avatarUrl: string, sizeClass: string) => (
|
||||
<div className={`${sizeClass} rounded-full overflow-hidden border border-primary/20 bg-white/5 flex items-center justify-center backdrop-blur-sm shadow-inner shrink-0`}>
|
||||
{avatarUrl.includes("placeholder") ? (
|
||||
<svg className="w-1/2 h-1/2 text-primary/60" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={1.5}>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z" />
|
||||
</svg>
|
||||
) : (
|
||||
// Load bookmarks from localStorage
|
||||
useEffect(() => {
|
||||
try {
|
||||
const saved = localStorage.getItem("ipv6_agenda_bookmarks");
|
||||
if (saved) {
|
||||
setBookmarkedIds(JSON.parse(saved));
|
||||
}
|
||||
} catch {
|
||||
// Ignore localStorage errors
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Keyboard shortcut to close modal
|
||||
useEffect(() => {
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
if (e.key === "Escape") {
|
||||
setSelectedModalItem(null);
|
||||
}
|
||||
};
|
||||
window.addEventListener("keydown", handleKeyDown);
|
||||
return () => window.removeEventListener("keydown", handleKeyDown);
|
||||
}, []);
|
||||
|
||||
// Save bookmarks to localStorage
|
||||
const toggleBookmark = (id: number) => {
|
||||
setBookmarkedIds((prev) => {
|
||||
const next = prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id];
|
||||
try {
|
||||
localStorage.setItem("ipv6_agenda_bookmarks", JSON.stringify(next));
|
||||
} catch {
|
||||
// Ignore localStorage errors
|
||||
}
|
||||
return next;
|
||||
});
|
||||
};
|
||||
|
||||
// Convert time display based on selected timezone mode
|
||||
const getTimeDisplay = (item: AgendaItem) => {
|
||||
if (timezoneMode === "UTC") {
|
||||
return item.time_utc ? `${item.time_utc} UTC` : item.time_ict;
|
||||
}
|
||||
if (timezoneMode === "ICT") {
|
||||
return item.time_ict ? `${item.time_ict} ICT` : item.time_utc;
|
||||
}
|
||||
// Local Time mode
|
||||
try {
|
||||
const timeStr = item.time_utc;
|
||||
if (!timeStr) return item.time_ict;
|
||||
const parts = timeStr.split(" - ");
|
||||
if (parts.length < 1) return item.time_ict;
|
||||
|
||||
const parseUtcHourMin = (s: string) => {
|
||||
const m = s.trim().match(/(\d+)[\.:](\d+)\s*(am|pm)/i);
|
||||
if (!m) return null;
|
||||
let h = parseInt(m[1], 10);
|
||||
const min = parseInt(m[2], 10);
|
||||
const period = m[3].toLowerCase();
|
||||
if (period === "pm" && h < 12) h += 12;
|
||||
if (period === "am" && h === 12) h = 0;
|
||||
const d = new Date();
|
||||
d.setUTCHours(h, min, 0, 0);
|
||||
return d.toLocaleTimeString([], { hour: "numeric", minute: "2-digit", hour12: true });
|
||||
};
|
||||
|
||||
const startLocal = parseUtcHourMin(parts[0]);
|
||||
const endLocal = parts[1] ? parseUtcHourMin(parts[1]) : null;
|
||||
|
||||
if (startLocal && endLocal) return `${startLocal} - ${endLocal} (Local)`;
|
||||
if (startLocal) return `${startLocal} (Local)`;
|
||||
return item.time_ict;
|
||||
} catch {
|
||||
return item.time_ict;
|
||||
}
|
||||
};
|
||||
|
||||
// Filter items
|
||||
const filteredItems = useMemo(() => {
|
||||
return (data.items || []).filter((item) => {
|
||||
// Category filter
|
||||
if (selectedCategory !== "All Sessions" && item.category !== selectedCategory) {
|
||||
const categoryMatch =
|
||||
selectedCategory === "Breaks & Networking" && (item.category?.includes("Breaks") || item.category?.includes("Nghỉ"));
|
||||
const ceremonyMatch =
|
||||
selectedCategory === "Ceremonies" && (item.category?.includes("Ceremony") || item.category?.includes("Lễ"));
|
||||
const keynoteMatch =
|
||||
selectedCategory === "Keynotes & Address" && (item.category?.includes("Keynote") || item.category?.includes("Bài phát biểu"));
|
||||
const techMatch =
|
||||
selectedCategory === "Technical & Infrastructure" && (item.category?.includes("Technical") || item.category?.includes("Kỹ thuật"));
|
||||
const forumMatch =
|
||||
selectedCategory === "Forums & Panels" && (item.category?.includes("Forum") || item.category?.includes("Tọa đàm"));
|
||||
|
||||
if (!categoryMatch && !ceremonyMatch && !keynoteMatch && !techMatch && !forumMatch) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Bookmark filter
|
||||
if (showOnlyBookmarks && !bookmarkedIds.includes(item.id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Search query
|
||||
if (searchQuery.trim()) {
|
||||
const q = searchQuery.toLowerCase();
|
||||
const matchTitle = item.title?.toLowerCase().includes(q);
|
||||
const matchDesc = item.description?.toLowerCase().includes(q);
|
||||
const matchSpeaker = item.speaker?.toLowerCase().includes(q) || item.speaker_title?.toLowerCase().includes(q);
|
||||
const matchCategory = item.category?.toLowerCase().includes(q);
|
||||
if (!matchTitle && !matchDesc && !matchSpeaker && !matchCategory) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
}, [data.items, selectedCategory, showOnlyBookmarks, bookmarkedIds, searchQuery]);
|
||||
|
||||
const handlePrint = () => {
|
||||
window.print();
|
||||
};
|
||||
|
||||
const renderAvatar = (avatarUrl?: string, sizeClass: string = "w-9 h-9 lg:w-10 lg:h-10") => {
|
||||
return (
|
||||
<div className={`${sizeClass} rounded-full overflow-hidden border border-primary/30 bg-primary/10 flex items-center justify-center backdrop-blur-sm shadow-sm shrink-0`}>
|
||||
{avatarUrl ? (
|
||||
// eslint-disable-next-line @next/next/no-img-element
|
||||
<img
|
||||
src={`${base}${avatarUrl}`}
|
||||
src={`${base}${avatarUrl.startsWith("/") ? avatarUrl : `/${avatarUrl}`}`}
|
||||
alt="Speaker"
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
) : (
|
||||
<svg className="w-1/2 h-1/2 text-primary" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={1.5}>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M15.75 6a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0ZM4.501 20.118a7.5 7.5 0 0 1 14.998 0A17.933 17.933 0 0 1 12 21.75c-2.676 0-5.216-.584-7.499-1.632Z" />
|
||||
</svg>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<section className="py-16 lg:py-24 max-w-hd mx-auto px-[var(--spacing-gutter)]" id={data.id}>
|
||||
{/* Section Header */}
|
||||
<div className="flex flex-col lg:flex-row justify-between lg:items-end mb-16 lg:mb-28 gap-8">
|
||||
<section className="py-12 lg:py-20 max-w-hd mx-auto px-[var(--spacing-gutter)]" id={data.id}>
|
||||
{/* Printable CSS style overlay for clean PDF / Print export */}
|
||||
<style jsx global>{`
|
||||
@media print {
|
||||
body * {
|
||||
visibility: hidden;
|
||||
}
|
||||
#printable-agenda-area,
|
||||
#printable-agenda-area * {
|
||||
visibility: visible;
|
||||
}
|
||||
#printable-agenda-area {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
color: #000 !important;
|
||||
background: #fff !important;
|
||||
}
|
||||
.no-print {
|
||||
display: none !important;
|
||||
}
|
||||
.glass-panel {
|
||||
background: #fff !important;
|
||||
border: 1px solid #ddd !important;
|
||||
color: #000 !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
.text-primary {
|
||||
color: #1a56db !important;
|
||||
}
|
||||
.text-on-surface,
|
||||
.text-on-surface-variant {
|
||||
color: #111 !important;
|
||||
}
|
||||
}
|
||||
`}</style>
|
||||
|
||||
{/* Header */}
|
||||
<div className="flex flex-col lg:flex-row justify-between lg:items-end mb-8 gap-4 no-print">
|
||||
<div className="max-w-3xl">
|
||||
<span className="font-[var(--font-label-caps)] text-xs lg:text-sm text-primary block mb-4 lg:mb-6 tracking-[0.25em] uppercase">
|
||||
<span className="font-[var(--font-label-caps)] text-xs lg:text-sm text-primary block mb-2 tracking-[0.25em] uppercase">
|
||||
{data.eyebrow}
|
||||
</span>
|
||||
<h2 className="font-[var(--font-display-lg)] text-on-surface uppercase tracking-tight text-[clamp(1.75rem,3vw+1rem,3.5rem)]">
|
||||
@@ -90,9 +269,192 @@ export default function AgendaSection({ data }: Props) {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Timeline Container */}
|
||||
<div className="relative w-full max-w-5xl mx-auto pl-10 lg:pl-0">
|
||||
{/* Main Container */}
|
||||
<div id="printable-agenda-area" className="w-full">
|
||||
{/* Printable Header (Visible only when printing) */}
|
||||
<div className="hidden print:block mb-8 border-b pb-4">
|
||||
<h1 className="text-2xl font-bold text-gray-900">APAC IPv6, AI & Cloud Summit 2026 - Agenda</h1>
|
||||
<p className="text-sm text-gray-600">Keangnam Landmark Tower, Hanoi, Vietnam</p>
|
||||
</div>
|
||||
|
||||
{/* Event Venue Banner with Direct Google Maps Button */}
|
||||
<div className="glass-panel p-4 rounded-2xl mb-6 border border-primary/30 bg-surface/50 flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 no-print">
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-10 h-10 rounded-full bg-primary/10 border border-primary/30 flex items-center justify-center text-primary shrink-0">
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={2}>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M15 10.5a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M19.5 10.5c0 7.142-7.5 11.25-7.5 11.25S4.5 17.642 4.5 10.5a7.5 7.5 0 1 1 15 0Z" />
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-[11px] uppercase tracking-wider text-primary font-bold">Event Venue / Địa điểm tổ chức</div>
|
||||
<div className="text-sm font-semibold text-on-surface">Keangnam Landmark Tower, Hanoi, Vietnam</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<a
|
||||
href="https://www.google.com/maps?q=InterContinental+Hanoi+Landmark72"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="px-4 py-2 rounded-full gold-gradient-bg text-on-primary font-bold text-xs uppercase tracking-wider hover:shadow-[0_0_15px_rgba(197,160,89,0.4)] transition-all flex items-center gap-1.5 shrink-0"
|
||||
>
|
||||
<span>📍 Google Maps Direct</span>
|
||||
<svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={2}>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25" />
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{/* Control Toolbar */}
|
||||
<div className="glass-panel p-3.5 lg:p-5 rounded-3xl mb-6 space-y-3 no-print border border-primary/20 bg-surface/40 backdrop-blur-md">
|
||||
{/* Row 1: Search & My Schedule & Print & View Modes */}
|
||||
<div className="flex flex-col md:flex-row gap-3 justify-between items-center">
|
||||
{/* Search Input */}
|
||||
<div className="relative w-full md:w-80">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search sessions, speaker..."
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
className="w-full pl-9 pr-3 py-2 rounded-full bg-background/80 border border-primary/20 text-on-surface text-xs lg:text-sm focus:outline-none focus:border-primary transition-colors placeholder:text-on-surface-variant/50"
|
||||
/>
|
||||
<svg
|
||||
className="w-4 h-4 text-primary absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
strokeWidth={2}
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d="m21 21-5.197-5.197m0 0A7.5 7.5 0 1 0 5.196 5.196a7.5 7.5 0 0 0 10.607 10.607Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
{/* Right Action Controls */}
|
||||
<div className="flex flex-wrap items-center gap-2.5 w-full md:w-auto justify-end">
|
||||
{/* My Schedule Filter Button */}
|
||||
<button
|
||||
onClick={() => setShowOnlyBookmarks(!showOnlyBookmarks)}
|
||||
className={`px-3.5 py-1.5 rounded-full text-xs font-semibold uppercase tracking-wider transition-all duration-300 flex items-center gap-1.5 border ${
|
||||
showOnlyBookmarks
|
||||
? "bg-primary text-background border-primary shadow-[0_0_15px_rgba(197,160,89,0.4)]"
|
||||
: "bg-surface/60 text-on-surface border-primary/30 hover:border-primary"
|
||||
}`}
|
||||
>
|
||||
<span>★ My Schedule ({bookmarkedIds.length})</span>
|
||||
</button>
|
||||
|
||||
{/* Print / Export PDF Button */}
|
||||
<button
|
||||
onClick={handlePrint}
|
||||
className="px-3.5 py-1.5 rounded-full text-xs font-semibold uppercase tracking-wider border border-primary/30 bg-surface/60 text-primary hover:bg-primary/10 transition-colors flex items-center gap-1.5"
|
||||
title="Print or Save as PDF"
|
||||
>
|
||||
<svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={2}>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M6.72 13.829c-.24.03-.48.062-.72.096m.72-.096a42.415 42.415 0 0 1 10.56 0m-10.56 0L6.34 18m10.94-4.171c.24.03.48.062.72.096m-.72-.096L17.66 18m0 0 .229 2.523a1.125 1.125 0 0 1-1.12 1.227H7.231c-.6 0-1.1-.47-1.12-1.07L6.34 18m11.318 0h1.091A2.25 2.25 0 0 0 21 15.75V9.456c0-1.081-.768-2.015-1.837-2.175a48.055 48.055 0 0 0-1.913-.247M6.34 18H5.25A2.25 2.25 0 0 1 3 15.75V9.456c0-1.081.768-2.015 1.837-2.175a48.041 48.041 0 0 1 1.913-.247m10.5 0a48.536 48.536 0 0 0-10.5 0m10.5 0V3.375c0-.621-.504-1.125-1.125-1.125h-8.25c-.621 0-1.125.504-1.125 1.125v3.656" />
|
||||
</svg>
|
||||
<span>Print / PDF</span>
|
||||
</button>
|
||||
|
||||
{/* Timezone Switcher */}
|
||||
<div className="flex items-center bg-background/80 rounded-full border border-primary/20 p-1 text-xs">
|
||||
{(["ICT", "UTC", "Local"] as const).map((tz) => (
|
||||
<button
|
||||
key={tz}
|
||||
onClick={() => setTimezoneMode(tz)}
|
||||
className={`px-2 py-0.5 rounded-full transition-colors ${
|
||||
timezoneMode === tz ? "bg-primary text-background font-bold" : "text-on-surface-variant/70 hover:text-on-surface"
|
||||
}`}
|
||||
>
|
||||
{tz}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* View Mode Toggle */}
|
||||
<div className="flex items-center bg-background/80 rounded-full border border-primary/20 p-1 text-xs">
|
||||
<button
|
||||
onClick={() => setViewMode("card")}
|
||||
className={`px-2.5 py-0.5 rounded-full transition-colors flex items-center gap-1 ${
|
||||
viewMode === "card" ? "bg-primary text-background font-bold" : "text-on-surface-variant/70 hover:text-on-surface"
|
||||
}`}
|
||||
>
|
||||
<svg className="w-3.5 h-3.5" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M4 4h7v16H4V4zm9 0h7v7h-7V4zm0 9h7v7h-7v-7z" />
|
||||
</svg>
|
||||
<span>Timeline</span>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setViewMode("table")}
|
||||
className={`px-2.5 py-0.5 rounded-full transition-colors flex items-center gap-1 ${
|
||||
viewMode === "table" ? "bg-primary text-background font-bold" : "text-on-surface-variant/70 hover:text-on-surface"
|
||||
}`}
|
||||
>
|
||||
<svg className="w-3.5 h-3.5" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M4 4h16v16H4V4zm2 4v4h12V8H6zm0 6v4h12v-4H6z" />
|
||||
</svg>
|
||||
<span>Table</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Row 2: Category Filter Tags */}
|
||||
<div className="flex items-center gap-1.5 overflow-x-auto pb-1 scrollbar-none border-t border-primary/10 pt-3">
|
||||
{CATEGORIES.map((category) => (
|
||||
<button
|
||||
key={category}
|
||||
onClick={() => setSelectedCategory(category)}
|
||||
className={`px-3 py-1 rounded-full text-xs whitespace-nowrap transition-all duration-300 font-medium ${
|
||||
selectedCategory === category
|
||||
? "bg-primary/20 text-primary border border-primary/50 font-semibold"
|
||||
: "bg-surface/40 text-on-surface-variant/80 border border-transparent hover:border-primary/20 hover:text-on-surface"
|
||||
}`}
|
||||
>
|
||||
{category}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Results Counter Bar */}
|
||||
<div className="flex justify-between items-center mb-6 text-xs text-on-surface-variant/70 px-2 no-print">
|
||||
<div>
|
||||
Showing <span className="text-primary font-bold">{filteredItems.length}</span> of {(data.items || []).length} sessions
|
||||
{showOnlyBookmarks && " (My Schedule)"}
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="relative flex h-2.5 w-2.5">
|
||||
<span className="animate-ping absolute inline-flex h-full w-full rounded-full bg-emerald-400 opacity-75"></span>
|
||||
<span className="relative inline-flex rounded-full h-2.5 w-2.5 bg-emerald-500"></span>
|
||||
</span>
|
||||
<span className="text-emerald-400 font-medium uppercase tracking-wider text-[11px]">Event Date: Aug 4, 2026</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* No Results Fallback */}
|
||||
{filteredItems.length === 0 && (
|
||||
<div className="text-center py-12 glass-panel rounded-3xl">
|
||||
<p className="text-on-surface-variant/60 text-base mb-2">No matching sessions found.</p>
|
||||
<button
|
||||
onClick={() => {
|
||||
setSearchQuery("");
|
||||
setSelectedCategory("All Sessions");
|
||||
setShowOnlyBookmarks(false);
|
||||
}}
|
||||
className="text-primary hover:underline text-xs font-semibold"
|
||||
>
|
||||
Reset all filters
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* CARD VIEW: Wider Max Width + Reduced Gaps for Natural Text Flow */}
|
||||
{viewMode === "card" && filteredItems.length > 0 && (
|
||||
<div className="relative w-full max-w-6xl mx-auto pl-8 lg:pl-0">
|
||||
{/* Central vertical line */}
|
||||
<div
|
||||
className="absolute left-4 lg:left-1/2 top-4 bottom-4 w-[2px] bg-gradient-to-b from-primary via-primary/45 to-primary/5 -translate-x-1/2 pointer-events-none"
|
||||
@@ -100,116 +462,444 @@ export default function AgendaSection({ data }: Props) {
|
||||
/>
|
||||
|
||||
{/* Timeline Items */}
|
||||
<div className="space-y-12 lg:space-y-16">
|
||||
{data.items.map((item, index) => {
|
||||
<div className="space-y-6 lg:space-y-8">
|
||||
{filteredItems.map((item, index) => {
|
||||
const isEven = index % 2 === 0;
|
||||
return (
|
||||
<div key={item.order} className="relative w-full group">
|
||||
const isBookmarked = bookmarkedIds.includes(item.id);
|
||||
const orderNum = String(index + 1).padStart(2, "0");
|
||||
const timeText = getTimeDisplay(item);
|
||||
const hasSpeaker = Boolean(item.speaker && item.speaker.trim() !== "");
|
||||
|
||||
return (
|
||||
<div key={item.id || index} className="relative w-full group">
|
||||
{/* Timeline Dot (glowing on hover) */}
|
||||
<div
|
||||
className="absolute left-[-24px] lg:left-1/2 top-6 lg:top-8 -translate-x-1/2 w-4 h-4 rounded-full bg-background border-2 border-primary z-20 group-hover:scale-125 group-hover:bg-primary group-hover:shadow-[0_0_10px_#c5a059] transition-all duration-300 status-led"
|
||||
/>
|
||||
<div className="absolute left-[-24px] lg:left-1/2 top-5 lg:top-6 -translate-x-1/2 w-4 h-4 rounded-full bg-background border-2 border-primary z-20 group-hover:scale-125 group-hover:bg-primary group-hover:shadow-[0_0_10px_#c5a059] transition-all duration-300 status-led" />
|
||||
|
||||
{/* Left/Right alternating grid layout */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4 lg:gap-16 w-full">
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-3 lg:gap-8 w-full">
|
||||
{isEven ? (
|
||||
<>
|
||||
{/* Left: Card (Desktop) / Full content (Mobile) */}
|
||||
<div className="order-1 lg:order-1">
|
||||
<div className="glass-panel p-6 lg:p-8 rounded-3xl relative overflow-hidden hover:border-primary/50 transition-colors duration-300">
|
||||
<span className="absolute top-6 right-6 lg:right-auto lg:left-6 text-xs lg:text-sm font-[var(--font-display-lg)] text-primary/30 group-hover:text-primary transition-colors duration-300">
|
||||
{item.order}
|
||||
<div className="glass-panel p-4 lg:p-6 rounded-3xl relative overflow-hidden hover:border-primary/50 transition-all duration-300">
|
||||
{/* Top Bar inside Card: Category badge + Order + Star */}
|
||||
<div className="flex justify-between items-center mb-3 gap-2">
|
||||
<span className="px-2.5 py-0.5 rounded-full text-[11px] font-medium bg-primary/10 text-primary border border-primary/20">
|
||||
{item.category}
|
||||
</span>
|
||||
<div className="flex items-center gap-2.5">
|
||||
<span className="text-xs font-[var(--font-display-lg)] text-primary/40 group-hover:text-primary transition-colors duration-300">
|
||||
{orderNum}
|
||||
</span>
|
||||
<button
|
||||
onClick={() => toggleBookmark(item.id)}
|
||||
className="text-lg no-print hover:scale-110 transition-transform leading-none"
|
||||
title={isBookmarked ? "Remove from My Schedule" : "Add to My Schedule"}
|
||||
>
|
||||
<span className={isBookmarked ? "text-amber-400" : "text-on-surface-variant/30 hover:text-amber-400"}>
|
||||
{isBookmarked ? "★" : "☆"}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Mobile-only time badge */}
|
||||
<div className="lg:hidden mb-3">
|
||||
<span className="font-[var(--font-display-lg)] text-base text-primary">
|
||||
{item.time}
|
||||
<div className="lg:hidden mb-2">
|
||||
<span className="font-[var(--font-display-lg)] text-sm text-primary">
|
||||
{timeText}
|
||||
</span>
|
||||
</div>
|
||||
<h3 className="font-[var(--font-display-lg)] text-base lg:text-lg text-on-surface mb-3 leading-snug text-balance pr-8 lg:pr-0 lg:pl-8 lg:text-right">
|
||||
|
||||
{/* Session Title */}
|
||||
<h3 className="font-[var(--font-display-lg)] text-base lg:text-lg text-on-surface mb-2 leading-snug lg:text-right">
|
||||
{renderFormattedText(item.title)}
|
||||
</h3>
|
||||
{!item.description && item.avatar && (
|
||||
<div className="flex lg:justify-end justify-start mb-3">
|
||||
{renderAvatar(item.avatar, "w-10 h-10 lg:w-12 lg:h-12")}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Description & Speaker Info */}
|
||||
<div className="text-xs lg:text-sm text-on-surface-variant/75 leading-relaxed border-t border-primary/10 pt-2.5 mt-2.5 flex flex-col gap-2.5">
|
||||
{item.description && (
|
||||
<div className="text-xs lg:text-sm text-on-surface-variant/75 leading-relaxed border-t border-primary/10 pt-3 mt-3 flex flex-row lg:flex-row-reverse items-center gap-4">
|
||||
{item.avatar && (
|
||||
<div className="shrink-0">
|
||||
{renderAvatar(item.avatar, "w-10 h-10 lg:w-12 lg:h-12")}
|
||||
</div>
|
||||
)}
|
||||
<div className="flex-1 lg:text-right">
|
||||
<div className="lg:text-right">
|
||||
{renderFormattedText(item.description)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Speaker info with avatar */}
|
||||
<div className="flex flex-row lg:flex-row-reverse items-center gap-2.5 border-t border-primary/5 pt-2">
|
||||
{hasSpeaker ? (
|
||||
<>
|
||||
{renderAvatar(item.avatar)}
|
||||
<div className="lg:text-right">
|
||||
<div className="font-semibold text-on-surface text-xs lg:text-sm">
|
||||
{item.speaker}
|
||||
</div>
|
||||
{item.speaker_title && (
|
||||
<div className="text-[11px] text-on-surface-variant/60">
|
||||
{item.speaker_title}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<div className="text-on-surface-variant/40 font-bold lg:text-right w-full text-base">
|
||||
—
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Location Badge */}
|
||||
<div className="flex items-center lg:justify-end gap-1 text-[11px] text-on-surface-variant/60">
|
||||
<svg className="w-3 h-3 text-primary shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
|
||||
</svg>
|
||||
<span>{item.location || "Main Stage"}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Right: Time badge (Desktop-only) */}
|
||||
<div className="order-2 lg:order-2 hidden lg:flex items-center justify-start pl-4">
|
||||
<span className="font-[var(--font-display-lg)] text-xl lg:text-[22px] text-primary group-hover:text-on-surface transition-colors duration-300">
|
||||
{item.time}
|
||||
<div className="order-2 lg:order-2 hidden lg:flex flex-col items-start justify-center pl-2">
|
||||
<span className="font-[var(--font-display-lg)] text-lg lg:text-xl text-primary group-hover:text-on-surface transition-colors duration-300">
|
||||
{timeText}
|
||||
</span>
|
||||
{timezoneMode !== "UTC" && item.time_utc && (
|
||||
<span className="text-xs text-on-surface-variant/50">
|
||||
{item.time_utc} UTC
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
{/* Left: Time badge (Desktop-only) */}
|
||||
<div className="order-2 lg:order-1 hidden lg:flex items-center justify-end pr-4 text-right">
|
||||
<span className="font-[var(--font-display-lg)] text-xl lg:text-[22px] text-primary group-hover:text-on-surface transition-colors duration-300">
|
||||
{item.time}
|
||||
<div className="order-2 lg:order-1 hidden lg:flex flex-col items-end justify-center pr-2 text-right">
|
||||
<span className="font-[var(--font-display-lg)] text-lg lg:text-xl text-primary group-hover:text-on-surface transition-colors duration-300">
|
||||
{timeText}
|
||||
</span>
|
||||
{timezoneMode !== "UTC" && item.time_utc && (
|
||||
<span className="text-xs text-on-surface-variant/50">
|
||||
{item.time_utc} UTC
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Right: Card (Desktop) / Full content (Mobile) */}
|
||||
<div className="order-1 lg:order-2">
|
||||
<div className="glass-panel p-6 lg:p-8 rounded-3xl relative overflow-hidden hover:border-primary/50 transition-colors duration-300">
|
||||
<span className="absolute top-6 right-6 text-xs lg:text-sm font-[var(--font-display-lg)] text-primary/30 group-hover:text-primary transition-colors duration-300">
|
||||
{item.order}
|
||||
<div className="glass-panel p-4 lg:p-6 rounded-3xl relative overflow-hidden hover:border-primary/50 transition-all duration-300">
|
||||
{/* Top Bar inside Card: Category badge + Order + Star */}
|
||||
<div className="flex justify-between items-center mb-3 gap-2">
|
||||
<span className="px-2.5 py-0.5 rounded-full text-[11px] font-medium bg-primary/10 text-primary border border-primary/20">
|
||||
{item.category}
|
||||
</span>
|
||||
<div className="flex items-center gap-2.5">
|
||||
<span className="text-xs font-[var(--font-display-lg)] text-primary/40 group-hover:text-primary transition-colors duration-300">
|
||||
{orderNum}
|
||||
</span>
|
||||
<button
|
||||
onClick={() => toggleBookmark(item.id)}
|
||||
className="text-lg no-print hover:scale-110 transition-transform leading-none"
|
||||
title={isBookmarked ? "Remove from My Schedule" : "Add to My Schedule"}
|
||||
>
|
||||
<span className={isBookmarked ? "text-amber-400" : "text-on-surface-variant/30 hover:text-amber-400"}>
|
||||
{isBookmarked ? "★" : "☆"}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Mobile-only time badge */}
|
||||
<div className="lg:hidden mb-3">
|
||||
<span className="font-[var(--font-display-lg)] text-base text-primary">
|
||||
{item.time}
|
||||
<div className="lg:hidden mb-2">
|
||||
<span className="font-[var(--font-display-lg)] text-sm text-primary">
|
||||
{timeText}
|
||||
</span>
|
||||
</div>
|
||||
<h3 className="font-[var(--font-display-lg)] text-base lg:text-lg text-on-surface mb-3 leading-snug text-balance pr-8">
|
||||
|
||||
{/* Session Title */}
|
||||
<h3 className="font-[var(--font-display-lg)] text-base lg:text-lg text-on-surface mb-2 leading-snug">
|
||||
{renderFormattedText(item.title)}
|
||||
</h3>
|
||||
{!item.description && item.avatar && (
|
||||
<div className="flex justify-start mb-3">
|
||||
{renderAvatar(item.avatar, "w-10 h-10 lg:w-12 lg:h-12")}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Description & Speaker Info */}
|
||||
<div className="text-xs lg:text-sm text-on-surface-variant/75 leading-relaxed border-t border-primary/10 pt-2.5 mt-2.5 flex flex-col gap-2.5">
|
||||
{item.description && (
|
||||
<div className="text-xs lg:text-sm text-on-surface-variant/75 leading-relaxed border-t border-primary/10 pt-3 mt-3 flex flex-row items-center gap-4">
|
||||
{item.avatar && (
|
||||
<div className="shrink-0">
|
||||
{renderAvatar(item.avatar, "w-10 h-10 lg:w-12 lg:h-12")}
|
||||
<div>{renderFormattedText(item.description)}</div>
|
||||
)}
|
||||
|
||||
{/* Speaker info with avatar */}
|
||||
<div className="flex flex-row items-center gap-2.5 border-t border-primary/5 pt-2">
|
||||
{hasSpeaker ? (
|
||||
<>
|
||||
{renderAvatar(item.avatar)}
|
||||
<div>
|
||||
<div className="font-semibold text-on-surface text-xs lg:text-sm">
|
||||
{item.speaker}
|
||||
</div>
|
||||
{item.speaker_title && (
|
||||
<div className="text-[11px] text-on-surface-variant/60">
|
||||
{item.speaker_title}
|
||||
</div>
|
||||
)}
|
||||
<div className="flex-1">
|
||||
{renderFormattedText(item.description)}
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<div className="text-on-surface-variant/40 font-bold text-base">
|
||||
—
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Location Badge */}
|
||||
<div className="flex items-center gap-1 text-[11px] text-on-surface-variant/60">
|
||||
<svg className="w-3 h-3 text-primary shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
|
||||
</svg>
|
||||
<span>{item.location || "Main Stage"}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* TABLE VIEW: Responsive Truncated Rows + Click Row to Open Detail Modal */}
|
||||
{viewMode === "table" && filteredItems.length > 0 && (
|
||||
<div className="glass-panel rounded-3xl overflow-hidden border border-primary/20 shadow-2xl">
|
||||
<div className="overflow-x-auto">
|
||||
<table className="w-full text-left text-xs lg:text-sm text-on-surface border-collapse">
|
||||
<thead className="bg-primary/10 uppercase tracking-wider text-[11px] font-bold text-primary border-b border-primary/20">
|
||||
<tr>
|
||||
<th className="py-3 px-3 lg:px-4 w-36 shrink-0">Time</th>
|
||||
<th className="py-3 px-3 w-32 shrink-0">Category</th>
|
||||
<th className="py-3 px-4 min-w-[240px]">Session Title & Description</th>
|
||||
<th className="py-3 px-3 lg:px-4 w-48 shrink-0">Speaker / Presenter</th>
|
||||
<th className="py-3 px-3 w-28 shrink-0">Location</th>
|
||||
<th className="py-3 px-2 w-16 text-center no-print shrink-0">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody className="divide-y divide-primary/10">
|
||||
{filteredItems.map((item, idx) => {
|
||||
const isBookmarked = bookmarkedIds.includes(item.id);
|
||||
const isEven = idx % 2 === 0;
|
||||
const hasSpeaker = Boolean(item.speaker && item.speaker.trim() !== "");
|
||||
|
||||
return (
|
||||
<tr
|
||||
key={item.id || idx}
|
||||
onClick={() => setSelectedModalItem(item)}
|
||||
className={`hover:bg-primary/10 transition-colors group cursor-pointer ${
|
||||
isEven ? "bg-surface/20" : "bg-transparent"
|
||||
}`}
|
||||
title="Click to view full session details"
|
||||
>
|
||||
{/* Time */}
|
||||
<td className="py-3 px-3 lg:px-4 align-top">
|
||||
<div className="font-bold text-primary whitespace-nowrap text-xs lg:text-sm">
|
||||
{getTimeDisplay(item)}
|
||||
</div>
|
||||
{timezoneMode !== "UTC" && item.time_utc && (
|
||||
<div className="text-[11px] text-on-surface-variant/50 mt-0.5 whitespace-nowrap">
|
||||
{item.time_utc} UTC
|
||||
</div>
|
||||
)}
|
||||
</td>
|
||||
|
||||
{/* Category */}
|
||||
<td className="py-3 px-3 align-top">
|
||||
<span className="inline-block px-2.5 py-0.5 rounded-full text-[11px] font-medium bg-primary/10 text-primary border border-primary/20 whitespace-nowrap">
|
||||
{item.category}
|
||||
</span>
|
||||
</td>
|
||||
|
||||
{/* Title & Description (Truncated for clean responsive table layout) */}
|
||||
<td className="py-3 px-4 align-top max-w-md">
|
||||
<h4 className="font-semibold text-on-surface text-xs lg:text-sm mb-1 leading-snug line-clamp-2 group-hover:text-primary transition-colors">
|
||||
{item.title}
|
||||
</h4>
|
||||
{item.description && (
|
||||
<p className="text-[11px] lg:text-xs text-on-surface-variant/75 leading-relaxed line-clamp-1">
|
||||
{item.description}
|
||||
</p>
|
||||
)}
|
||||
</td>
|
||||
|
||||
{/* Speaker */}
|
||||
<td className="py-3 px-3 lg:px-4 align-top">
|
||||
{hasSpeaker ? (
|
||||
<div className="flex items-center gap-2">
|
||||
{renderAvatar(item.avatar, "w-7 h-7 lg:w-8 lg:h-8")}
|
||||
<div className="min-w-0">
|
||||
<div className="font-semibold text-on-surface text-xs truncate">
|
||||
{item.speaker}
|
||||
</div>
|
||||
{item.speaker_title && (
|
||||
<div className="text-[10px] text-on-surface-variant/60 truncate">
|
||||
{item.speaker_title}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<span className="text-on-surface-variant/40 font-bold text-base">—</span>
|
||||
)}
|
||||
</td>
|
||||
|
||||
{/* Location */}
|
||||
<td className="py-3 px-3 align-top">
|
||||
<div className="flex items-center gap-1 text-xs text-on-surface-variant/80 whitespace-nowrap">
|
||||
<svg className="w-3.5 h-3.5 text-primary shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||
</svg>
|
||||
<span>{item.location || "Main Stage"}</span>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
{/* Actions: Save Star + Expand indicator */}
|
||||
<td className="py-3 px-2 align-top text-center no-print" onClick={(e) => e.stopPropagation()}>
|
||||
<div className="flex items-center justify-center gap-1">
|
||||
<button
|
||||
onClick={() => toggleBookmark(item.id)}
|
||||
className="p-1 rounded-full hover:bg-primary/20 transition-all text-base"
|
||||
title={isBookmarked ? "Remove from My Schedule" : "Add to My Schedule"}
|
||||
>
|
||||
<span className={isBookmarked ? "text-amber-400" : "text-on-surface-variant/30 hover:text-amber-400"}>
|
||||
{isBookmarked ? "★" : "☆"}
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setSelectedModalItem(item)}
|
||||
className="p-1 rounded-full text-on-surface-variant/40 hover:text-primary transition-colors"
|
||||
title="Expand details"
|
||||
>
|
||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={2}>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M3.75 3.75v4.5m0-4.5h4.5m-4.5 0L9 9M20.25 3.75h-4.5m4.5 0v4.5m0-4.5L15 9m5.25 11.25v-4.5m0 4.5h-4.5m4.5 0L15 15m-11.25 5.25h4.5m-4.5 0v-4.5m0 4.5L9 15" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* SESSION DETAIL MODAL (Opens on Row Click in Table View or Detail Click) */}
|
||||
{selectedModalItem && (
|
||||
<div
|
||||
className="fixed inset-0 z-50 bg-black/75 backdrop-blur-md flex items-center justify-center p-4 no-print animate-in fade-in duration-200"
|
||||
onClick={() => setSelectedModalItem(null)}
|
||||
>
|
||||
<div
|
||||
className="glass-panel p-6 lg:p-8 rounded-3xl max-w-2xl w-full relative max-h-[90vh] overflow-y-auto border border-primary/30 shadow-2xl bg-surface/95 text-on-surface"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{/* Modal Header Bar */}
|
||||
<div className="flex items-center justify-between gap-4 mb-4 pb-4 border-b border-primary/20">
|
||||
<span className="px-3 py-1 rounded-full text-xs font-semibold bg-primary/20 text-primary border border-primary/40">
|
||||
{selectedModalItem.category}
|
||||
</span>
|
||||
<div className="flex items-center gap-3">
|
||||
<button
|
||||
onClick={() => toggleBookmark(selectedModalItem.id)}
|
||||
className="px-3 py-1 rounded-full text-xs font-semibold uppercase tracking-wider border border-primary/40 bg-surface/60 text-primary hover:bg-primary/20 transition-colors flex items-center gap-1.5"
|
||||
>
|
||||
<span className={bookmarkedIds.includes(selectedModalItem.id) ? "text-amber-400" : "text-on-surface-variant/40"}>
|
||||
{bookmarkedIds.includes(selectedModalItem.id) ? "★ Saved" : "☆ Save to Schedule"}
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setSelectedModalItem(null)}
|
||||
className="p-1.5 rounded-full hover:bg-primary/20 text-on-surface-variant/70 hover:text-on-surface transition-colors"
|
||||
title="Close Modal (Esc)"
|
||||
>
|
||||
<svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={2}>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Session Time & Location Badges */}
|
||||
<div className="flex flex-wrap items-center gap-3 text-xs text-on-surface-variant/80 mb-4">
|
||||
<div className="flex items-center gap-1.5 bg-primary/10 px-3 py-1 rounded-full text-primary font-bold">
|
||||
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={2}>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||
</svg>
|
||||
<span>{getTimeDisplay(selectedModalItem)}</span>
|
||||
</div>
|
||||
|
||||
{selectedModalItem.time_utc && (
|
||||
<span className="text-on-surface-variant/60 text-[11px]">
|
||||
({selectedModalItem.time_utc} UTC)
|
||||
</span>
|
||||
)}
|
||||
|
||||
<div className="flex items-center gap-1 text-on-surface-variant/80 bg-surface/80 px-3 py-1 rounded-full border border-primary/20">
|
||||
<svg className="w-3.5 h-3.5 text-primary" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={2}>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
|
||||
</svg>
|
||||
<span>{selectedModalItem.location || "Main Stage"}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Full Title (Untruncated) */}
|
||||
<h2 className="font-[var(--font-display-lg)] text-xl lg:text-2xl text-on-surface font-bold mb-4 leading-snug">
|
||||
{renderFormattedText(selectedModalItem.title)}
|
||||
</h2>
|
||||
|
||||
{/* Full Description (Untruncated) */}
|
||||
{selectedModalItem.description && (
|
||||
<div className="text-sm text-on-surface-variant/85 leading-relaxed bg-surface/40 p-4 rounded-2xl border border-primary/10 mb-6">
|
||||
<div className="text-xs uppercase font-bold text-primary mb-1 tracking-wider">Description</div>
|
||||
{renderFormattedText(selectedModalItem.description)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Speaker Information */}
|
||||
<div className="border-t border-primary/20 pt-4">
|
||||
<div className="text-xs uppercase font-bold text-primary mb-2 tracking-wider">Speaker / Presenter</div>
|
||||
{selectedModalItem.speaker && selectedModalItem.speaker.trim() !== "" ? (
|
||||
<div className="flex items-center gap-4 bg-primary/5 p-3.5 rounded-2xl border border-primary/15">
|
||||
{renderAvatar(selectedModalItem.avatar, "w-12 h-12")}
|
||||
<div>
|
||||
<div className="font-bold text-on-surface text-base">
|
||||
{selectedModalItem.speaker}
|
||||
</div>
|
||||
{selectedModalItem.speaker_title && (
|
||||
<div className="text-xs text-on-surface-variant/70 mt-0.5">
|
||||
{selectedModalItem.speaker_title}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-on-surface-variant/40 font-bold text-lg">—</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Modal Footer */}
|
||||
<div className="mt-6 pt-4 border-t border-primary/10 flex justify-end">
|
||||
<button
|
||||
onClick={() => setSelectedModalItem(null)}
|
||||
className="px-6 py-2.5 rounded-full gold-gradient-bg text-on-primary font-bold text-xs uppercase tracking-wider hover:shadow-lg transition-all"
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -16,13 +16,25 @@ export default function HeroSection({
|
||||
<section className="relative min-h-[80vh] lg:min-h-[90vh] flex items-center overflow-hidden bg-background hero-glow px-[var(--spacing-gutter)]">
|
||||
<div className="relative z-10 max-w-hd mx-auto w-full">
|
||||
<div className="max-w-7xl">
|
||||
<div className="inline-flex items-center gap-3 lg:gap-4 px-4 lg:px-8 py-2 lg:py-3 rounded-full bg-surface-container-high border border-primary/30 mb-8 lg:mb-16">
|
||||
<div className="inline-flex flex-wrap items-center gap-3 lg:gap-4 px-4 lg:px-8 py-2.5 lg:py-3.5 rounded-full bg-surface-container-high border border-primary/30 mb-8 lg:mb-16">
|
||||
<span className="material-symbols-outlined text-primary text-[20px] lg:text-[26px]">
|
||||
{data.badgeIcon}
|
||||
</span>
|
||||
<span className="font-[var(--font-label-caps)] text-xs lg:text-[14px] text-on-surface">
|
||||
{data.badgeText}
|
||||
</span>
|
||||
<a
|
||||
href="https://www.google.com/maps?q=InterContinental+Hanoi+Landmark72"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="ml-1 lg:ml-2 px-3 py-1 rounded-full bg-primary/20 text-primary hover:bg-primary hover:text-background text-xs font-semibold uppercase tracking-wider transition-colors inline-flex items-center gap-1.5 border border-primary/40"
|
||||
title="Open Google Maps"
|
||||
>
|
||||
<span>📍 Google Maps</span>
|
||||
<svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24" strokeWidth={2}>
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25" />
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
<h1 className="font-[var(--font-display-lg)] text-on-surface mb-6 lg:mb-8 leading-[1.1] text-[clamp(1.75rem,3.5vw+1rem,4.25rem)]">
|
||||
{data.title.includes(" AI") ? (
|
||||
@@ -57,4 +69,3 @@ export default function HeroSection({
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+198
-57
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"hero": {
|
||||
"badgeIcon": "calendar_today",
|
||||
"badgeText": "27 August 2026 | Hanoi, Vietnam",
|
||||
"badgeText": "27 August 2026 | Keangnam Landmark Tower, Hanoi, Vietnam",
|
||||
"title": "IPv6 - Enhanced for AI & Data Centre Summit 2026",
|
||||
"subtitle": "Unlocking the Potential of Next-Gen Infrastructure. Join global leaders in redefining ASEAN's digital connectivity for the age of AI.",
|
||||
"primaryCta": { "label": "Register", "href": "/registration" },
|
||||
@@ -138,98 +138,239 @@
|
||||
"description": "A strategic overview of the technical and strategic sessions.",
|
||||
"items": [
|
||||
{
|
||||
"order": "01",
|
||||
"time": "8.30 am – 9.00 am",
|
||||
"id": 1,
|
||||
"time_ict": "9.00 am - 9.15 am",
|
||||
"time_utc": "2.00 am - 2.15 am",
|
||||
"category": "Breaks & Networking",
|
||||
"title": "Registration & Networking",
|
||||
"description": ""
|
||||
"description": "Welcome to APAC IPv6, AI & Cloud Summit 2026. Collect your badge.",
|
||||
"speaker": "",
|
||||
"speaker_title": "",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"order": "02",
|
||||
"time": "9.00 am – 9.15 am",
|
||||
"id": 2,
|
||||
"time_ict": "9.15 am - 9.30 am",
|
||||
"time_utc": "2.15 am - 2.30 am",
|
||||
"category": "Ceremonies",
|
||||
"title": "Arrival of VIPs",
|
||||
"description": ""
|
||||
"description": "Reception of government dignitaries, international delegates, and VIPs.",
|
||||
"speaker": "",
|
||||
"speaker_title": "",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"order": "03",
|
||||
"time": "9.15 am – 9.25 am",
|
||||
"title": "Welcome Address by **Prof Emeritus Dr Sureswaran Ramadass**",
|
||||
"description": "*Chairman, IPv6 Forum Malaysia*\n*Chairman, APAC IPv6 Council*",
|
||||
"id": 3,
|
||||
"time_ict": "9.30 am - 9.50 am",
|
||||
"time_utc": "2.30 am - 2.50 am",
|
||||
"category": "Keynotes & Address",
|
||||
"title": "Welcome Address & Keynote Address: National Sovereign Cloud in the Intelligent Era: Shaping Independent and Resilient Digital Infrastructure",
|
||||
"description": "Opening greeting and keynote address detailing national sovereign cloud in the intelligent era.",
|
||||
"speaker": "Prof Emeritus Dr Sureswaran Ramadass",
|
||||
"speaker_title": "Chairman, APAC IPv6 Council",
|
||||
"location": "Main Stage",
|
||||
"avatar": "/assets/img/speakers/speaker.png"
|
||||
},
|
||||
{
|
||||
"order": "04",
|
||||
"time": "9.25 am – 9.35 am",
|
||||
"title": "Officiating Address by **Vietnam Government Official**",
|
||||
"description": "Opening Ceremony"
|
||||
"id": 4,
|
||||
"time_ict": "9.50 am - 10.00 am",
|
||||
"time_utc": "2.50 am - 3.00 am",
|
||||
"category": "Keynotes & Address",
|
||||
"title": "Keynote Address: Viet Nam's IPv6 Journey: Bridging the Gaps, Accelerating IPv6-Only, and Driving Robust and Intelligent Network Evolution",
|
||||
"description": "Keynote detailing Viet Nam's strategic progress, bridging technical gaps, accelerating IPv6-Only...",
|
||||
"speaker": "Mr. Nguyen Truong Giang",
|
||||
"speaker_title": "Acting Director General, VNNIC",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"order": "05",
|
||||
"time": "9.35 am – 9.45 am",
|
||||
"title": "Launch Ceremony **\"ASEAN IPv6-First & IPv6 Enhanced National Implementation Guideline\"**",
|
||||
"description": ""
|
||||
"id": 5,
|
||||
"time_ict": "10.00 am - 10.10 am",
|
||||
"time_utc": "3.00 am - 3.10 am",
|
||||
"category": "Keynotes & Address",
|
||||
"title": "Keynote Address: Navigating the Global Digital Landscape: European-American Practices and Strategic Insights for Viet Nam in Intelligent Era",
|
||||
"description": "Keynote insights comparing European and American digital infrastructure practices...",
|
||||
"speaker": "Nguyen Chien Thang",
|
||||
"speaker_title": "Director General, Institute for European and American Studies",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"order": "06",
|
||||
"time": "9.45 am – 10.00 am",
|
||||
"title": "Morning Coffee Break",
|
||||
"description": "Press Conference + Photos"
|
||||
"id": 6,
|
||||
"time_ict": "10.10 am - 10.20 am",
|
||||
"time_utc": "3.10 am - 3.20 am",
|
||||
"category": "Ceremonies",
|
||||
"title": "Launch Ceremony \"IPv6-First & IPv6 Enhanced National Implementation Strategy Guideline\"",
|
||||
"description": "Inaugural launch ceremony of the National Implementation Strategy Guidelines.",
|
||||
"speaker": "",
|
||||
"speaker_title": "",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"order": "07",
|
||||
"time": "10.00 am – 10.40 am",
|
||||
"title": "Keynote Address: **\"IPv6 Enhanced, SRv6 & Net5.5G for AI-Native Data Centres\"**",
|
||||
"description": "Speaker: Dr. Will Liu, Huawei, China",
|
||||
"id": 7,
|
||||
"time_ict": "10.20 am - 10.40 am",
|
||||
"time_utc": "3.20 am - 3.40 am",
|
||||
"category": "Keynotes & Address",
|
||||
"title": "Keynote Address: AI WAN: Empowering Carriers into the New Era of Token Monetization",
|
||||
"description": "Keynote presentation detailing AI WAN architectures, network transformation, and tokenization.",
|
||||
"speaker": "Mr. Jun Cai",
|
||||
"speaker_title": "Vice President, Data Communication Product Line",
|
||||
"location": "Main Stage",
|
||||
"avatar": "/assets/img/speakers/dr.liushucheng.jpg"
|
||||
},
|
||||
{
|
||||
"order": "08",
|
||||
"time": "10.40 am – 11.10 am",
|
||||
"title": "**AI, Cybersecurity & Smart Digital Ecosystems**",
|
||||
"description": "Speaker: Prof. Sureswaran Ramadass, Malaysia\nChairman, IPv6 Forum Malaysia",
|
||||
"avatar": "/assets/img/speakers/speaker.png"
|
||||
"id": 8,
|
||||
"time_ict": "10.40 am - 11.00 am",
|
||||
"time_utc": "3.40 am - 4.00 am",
|
||||
"category": "Breaks & Networking",
|
||||
"title": "Morning Coffee Break / Press Conference + Photos",
|
||||
"description": "Morning refreshment break. VIPs and media gather for press briefings and photo opportunities.",
|
||||
"speaker": "",
|
||||
"speaker_title": "",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"order": "09",
|
||||
"time": "11.10 am – 11.50 am",
|
||||
"title": "**Building AI-Ready Data Centre Infrastructure in ASEAN**",
|
||||
"description": "Speaker: Mr. Bayu Hanantasena, Strategic Advisor to CEO, Indosat, Indonesia",
|
||||
"id": 9,
|
||||
"time_ict": "11.00 am - 11.20 am",
|
||||
"time_utc": "4.00 am - 4.20 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "Carrier Perspectives: IPv6-Driven Robust Infrastructure Fueling Enterprise Cloud and Computing Networks",
|
||||
"description": "Carrier presentation analyzing how IPv6-driven robust infrastructure fuels enterprise cloud...",
|
||||
"speaker": "Speaker from Vietnam ISP / Data Centre Operator",
|
||||
"speaker_title": "Technical Representative",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"time_ict": "11.20 am - 11.40 am",
|
||||
"time_utc": "4.20 am - 4.40 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "Pioneering the AI Era: Building Secure and Smart Digital Ecosystems with IPv6 and AI",
|
||||
"description": "Technical presentation on cybersecurity vulnerabilities, digital readiness, and smart ecosystems.",
|
||||
"speaker": "Dr. Navaneethan C Arjuman",
|
||||
"speaker_title": "Chair of IPv6 and SG Working Group",
|
||||
"location": "Main Stage",
|
||||
"avatar": "/assets/img/speakers/dr.navaneethan-c-arjuman.png"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"time_ict": "11.40 am - 12.00 pm",
|
||||
"time_utc": "4.40 am - 5.00 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "Building AI-Ready Network Infrastructure",
|
||||
"description": "Case studies and structural designs for building AI-ready network infrastructure.",
|
||||
"speaker": "Mr. Bayu Hanantasena",
|
||||
"speaker_title": "Strategic Advisor to CEO, Indosat",
|
||||
"location": "Main Stage",
|
||||
"avatar": "/assets/img/speakers/bayu-hanatasena.jpg"
|
||||
},
|
||||
{
|
||||
"order": "10",
|
||||
"time": "11.50 am – 12.30 pm",
|
||||
"title": "Cybersecurity in AI & Cloud Environments: Safeguarding the Digital Future",
|
||||
"description": "**Speaker from Vietnam ISP/Regulators**"
|
||||
"id": 12,
|
||||
"time_ict": "12.00 pm - 12.20 pm",
|
||||
"time_utc": "5.00 am - 5.20 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "Navigating ASEAN's Digital Future: Aligning Next-Gen Networking, AI, and Cloud Strategy",
|
||||
"description": "Strategic sharing on policy frameworks, digital economy, and cloud strategy alignment.",
|
||||
"speaker": "Mr. Sivaram Superamanian",
|
||||
"speaker_title": "Assistant Director, Digital Economy",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"order": "11",
|
||||
"time": "12.30 pm – 2.00 pm",
|
||||
"id": 13,
|
||||
"time_ict": "12.20 pm - 12.40 pm",
|
||||
"time_utc": "5.20 am - 5.40 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "Insights and Operational Perspectives from Local Network Operators",
|
||||
"description": "Operational perspectives and network deployment insights from local network operators.",
|
||||
"speaker": "Speaker from Vietnam ISP / Network Operator",
|
||||
"speaker_title": "Network Operator Representative",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"time_ict": "12.40 pm - 1.30 pm",
|
||||
"time_utc": "5.40 am - 6.30 am",
|
||||
"category": "Breaks & Networking",
|
||||
"title": "Lunch",
|
||||
"description": ""
|
||||
"description": "Lunch and networking recess for all registered delegates and speakers.",
|
||||
"speaker": "",
|
||||
"speaker_title": "",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"order": "12",
|
||||
"time": "2.00 pm – 3.00 pm",
|
||||
"title": "**Forum**\nAI Regulation & Data Sovereignty",
|
||||
"description": "**Moderator from Council**\n**Panellists from Gov Officials or ISPs of Indonesia, Malaysia, Vietnam**"
|
||||
"id": 15,
|
||||
"time_ict": "1.30 pm - 2.30 pm",
|
||||
"time_utc": "6.30 am - 7.30 am",
|
||||
"category": "Forums & Panels",
|
||||
"title": "Forum: AI Regulation & Data Sovereignty",
|
||||
"description": "A high-level panel discussion on policy frameworks governing data sovereignty and AI regulation.",
|
||||
"speaker": "Moderator from Council / Panellists from Gov Officials or ISPs",
|
||||
"speaker_title": "",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"order": "13",
|
||||
"time": "3.00 pm – 3.15 pm",
|
||||
"id": 16,
|
||||
"time_ict": "2.30 pm - 2.50 pm",
|
||||
"time_utc": "7.30 am - 7.50 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "AI & Cloud (IPv6) - Developments in China",
|
||||
"description": "A technical overview of global IPv6 adoption patterns, protocol implementations, and AI-cloud integration.",
|
||||
"speaker": "Mr. Liu Shuai",
|
||||
"speaker_title": "Vice President, MII, China",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"time_ict": "2.50 pm - 3.10 pm",
|
||||
"time_utc": "7.50 am - 8.10 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "Technical Presentation (TBD)",
|
||||
"description": "Technical presentation session slot. Specific presentation topic and details to be announced.",
|
||||
"speaker": "TBD",
|
||||
"speaker_title": "Speaker To Be Announced",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"time_ict": "3.10 pm - 3.30 pm",
|
||||
"time_utc": "8.10 am - 8.30 am",
|
||||
"category": "Breaks & Networking",
|
||||
"title": "Afternoon Coffee Break",
|
||||
"description": ""
|
||||
"description": "Afternoon tea and coffee, networking with cloud partners, and exhibition viewing.",
|
||||
"speaker": "",
|
||||
"speaker_title": "",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"order": "14",
|
||||
"time": "3.15 pm – 5.30 pm",
|
||||
"title": "**TBD by Local partner(SIMS)**",
|
||||
"description": ""
|
||||
"id": 19,
|
||||
"time_ict": "3.30 pm - 4.00 pm",
|
||||
"time_utc": "8.30 am - 9.00 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "IEC Standards Between Powermeter and Distributed Energy Resource",
|
||||
"description": "Technical presentation on IEC standards between powermeters and distributed energy resources.",
|
||||
"speaker": "Dr. Masaki Umejima",
|
||||
"speaker_title": "Convener of Energy Resource Aggregation",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"order": "15",
|
||||
"time": "5.30 pm",
|
||||
"id": 20,
|
||||
"time_ict": "4.00 pm - 5.30 pm",
|
||||
"time_utc": "9.00 am - 10.30 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "Technical Sharing & Demo (TBD by Local Partner - SIMS)",
|
||||
"description": "Hands-on lab showcase and technical integration demo led by local partner SIMS.",
|
||||
"speaker": "TBD by Local Partner (SIMS)",
|
||||
"speaker_title": "Technical Lead Specialists",
|
||||
"location": "Main Stage"
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"time_ict": "5.30 pm - 6.00 pm",
|
||||
"time_utc": "10.30 am - 11.00 am",
|
||||
"category": "Ceremonies",
|
||||
"title": "Conference Adjourns",
|
||||
"description": ""
|
||||
"description": "Final wrap-up, thanks to hosts and sponsors, and distribution of event closing remarks.",
|
||||
"speaker": "",
|
||||
"speaker_title": "",
|
||||
"location": "Main Stage"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
+202
-61
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"hero": {
|
||||
"badgeIcon": "calendar_today",
|
||||
"badgeText": "27 Tháng 8/2026 | Hà Nội, Việt Nam",
|
||||
"badgeText": "27 Tháng 8 2026 | Keangnam Landmark Tower, Hà Nội, Việt Nam",
|
||||
"title": "IPv6 - Enhanced for AI & Data Centre Summit 2026",
|
||||
"subtitle": "Khám phá tiềm năng Hạ tầng thế hệ mới. Chung sức định hình kỷ nguyên kết nối số tại ASEAN cùng doanh nghiệp hàng đầu quốc tế.",
|
||||
"primaryCta": { "label": "Đăng Ký", "href": "/registration" },
|
||||
@@ -138,98 +138,239 @@
|
||||
"description": "Tổng quan chiến lược về các phiên kỹ thuật và chiến lược.",
|
||||
"items": [
|
||||
{
|
||||
"order": "01",
|
||||
"time": "8.30 am – 9.00 am",
|
||||
"id": 1,
|
||||
"time_ict": "9.00 am - 9.15 am",
|
||||
"time_utc": "2.00 am - 2.15 am",
|
||||
"category": "Breaks & Networking",
|
||||
"title": "Đăng ký & Kết nối",
|
||||
"description": ""
|
||||
"description": "Chào mừng quý đại biểu đến với APAC IPv6, AI & Cloud Summit 2026. Nhận thẻ tham dự.",
|
||||
"speaker": "",
|
||||
"speaker_title": "",
|
||||
"location": "Sân khấu chính"
|
||||
},
|
||||
{
|
||||
"order": "02",
|
||||
"time": "9.00 am – 9.15 am",
|
||||
"title": "Đón tiếp đại biểu VIP",
|
||||
"description": ""
|
||||
"id": 2,
|
||||
"time_ict": "9.15 am - 9.30 am",
|
||||
"time_utc": "2.15 am - 2.30 am",
|
||||
"category": "Ceremonies",
|
||||
"title": "Đón tiếp VIP & Đại biểu",
|
||||
"description": "Đón tiếp các quan chức chính phủ, đại biểu quốc tế và khách mời VIP.",
|
||||
"speaker": "",
|
||||
"speaker_title": "",
|
||||
"location": "Sân khấu chính"
|
||||
},
|
||||
{
|
||||
"order": "03",
|
||||
"time": "9.15 am – 9.25 am",
|
||||
"title": "Phát biểu chào mừng bởi **Prof Emeritus Dr Sureswaran Ramadass**",
|
||||
"description": "*Chairman, IPv6 Forum Malaysia*\n*Chairman, APAC IPv6 Council*",
|
||||
"id": 3,
|
||||
"time_ict": "9.30 am - 9.50 am",
|
||||
"time_utc": "2.30 am - 2.50 am",
|
||||
"category": "Keynotes & Address",
|
||||
"title": "Bài phát biểu Khai mạc & Keynote: Điện toán Đám mây Chủ quyền Quốc gia trong Kỷ nguyên Thông minh: Định hình Hạ tầng Số Độc lập & Tự cường",
|
||||
"description": "Bài phát biểu chào mừng và báo cáo chính về chiến lược đám mây chủ quyền quốc gia...",
|
||||
"speaker": "Prof Emeritus Dr Sureswaran Ramadass",
|
||||
"speaker_title": "Chủ tịch Hội đồng APAC IPv6",
|
||||
"location": "Sân khấu chính",
|
||||
"avatar": "/assets/img/speakers/speaker.png"
|
||||
},
|
||||
{
|
||||
"order": "04",
|
||||
"time": "9.25 am – 9.35 am",
|
||||
"title": "Phát biểu khai mạc bởi **Vietnam Government Official**",
|
||||
"description": "Opening Ceremony"
|
||||
"id": 4,
|
||||
"time_ict": "9.50 am - 10.00 am",
|
||||
"time_utc": "2.50 am - 3.00 am",
|
||||
"category": "Keynotes & Address",
|
||||
"title": "Bài phát biểu Keynote: Hành trình IPv6 của Việt Nam: Thu hẹp Khoảng cách, Thúc đẩy IPv6-Only và Phát triển Mạng lưới Thông minh",
|
||||
"description": "Báo cáo chiến lược của Việt Nam về tiến trình chuyển đổi IPv6, IPv6-Only...",
|
||||
"speaker": "Mr. Nguyễn Trường Giang",
|
||||
"speaker_title": "Quyền Giám đốc VNNIC",
|
||||
"location": "Sân khấu chính"
|
||||
},
|
||||
{
|
||||
"order": "05",
|
||||
"time": "9.35 am – 9.45 am",
|
||||
"title": "Lễ công bố **\"ASEAN IPv6-First & IPv6 Enhanced National Implementation Guideline\"**",
|
||||
"description": ""
|
||||
"id": 5,
|
||||
"time_ict": "10.00 am - 10.10 am",
|
||||
"time_utc": "3.00 am - 3.10 am",
|
||||
"category": "Keynotes & Address",
|
||||
"title": "Bài phát biểu Keynote: Định hướng Bối cảnh Số Toàn cầu: Thực tiễn Âu - Mỹ & Bài học Chiến lược cho Việt Nam",
|
||||
"description": "Kinh nghiệm quốc tế từ Âu - Mỹ và góc nhìn chiến lược cho hạ tầng số Việt Nam...",
|
||||
"speaker": "Nguyễn Chiến Thắng",
|
||||
"speaker_title": "Viện trưởng Viện Nghiên cứu Châu Âu và Châu Mỹ",
|
||||
"location": "Sân khấu chính"
|
||||
},
|
||||
{
|
||||
"order": "06",
|
||||
"time": "9.45 am – 10.00 am",
|
||||
"title": "Nghỉ giải lao sáng",
|
||||
"description": "Họp báo + Chụp ảnh lưu niệm"
|
||||
"id": 6,
|
||||
"time_ict": "10.10 am - 10.20 am",
|
||||
"time_utc": "3.10 am - 3.20 am",
|
||||
"category": "Ceremonies",
|
||||
"title": "Lễ công bố \"Khung Chiến lược Quốc gia về Triển khai IPv6-First & IPv6 Nâng cao\"",
|
||||
"description": "Lễ ra mắt chính thức Khung hướng dẫn chiến lược triển khai IPv6 quốc gia.",
|
||||
"speaker": "",
|
||||
"speaker_title": "",
|
||||
"location": "Sân khấu chính"
|
||||
},
|
||||
{
|
||||
"order": "07",
|
||||
"time": "10.00 am – 10.40 am",
|
||||
"title": "Bài phát biểu Keynote: **\"Tối ưu hóa IPv6, SRv6 & Net5.5G cho Trung tâm Dữ liệu tích hợp AI\"**",
|
||||
"description": "Speaker: Dr. Will Liu, Huawei, China",
|
||||
"id": 7,
|
||||
"time_ict": "10.20 am - 10.40 am",
|
||||
"time_utc": "3.20 am - 3.40 am",
|
||||
"category": "Keynotes & Address",
|
||||
"title": "Bài phát biểu Keynote: AI WAN: Mở ra Kỷ nguyên Mới về Thương mại hóa Token cho các Nhà mạng",
|
||||
"description": "Kiến trúc AI WAN, chuyển đổi hạ tầng mạng và mô hình monetizing mới.",
|
||||
"speaker": "Mr. Jun Cai",
|
||||
"speaker_title": "Phó Chủ tịch, Dòng sản phẩm Truyền thông Dữ liệu",
|
||||
"location": "Sân khấu chính",
|
||||
"avatar": "/assets/img/speakers/dr.liushucheng.jpg"
|
||||
},
|
||||
{
|
||||
"order": "08",
|
||||
"time": "10.40 am – 11.10 am",
|
||||
"title": "**AI, An ninh mạng & Hệ sinh thái số thông minh**",
|
||||
"description": "Speaker: Prof. Sureswaran Ramadass, Malaysia\nChairman, IPv6 Forum Malaysia",
|
||||
"avatar": "/assets/img/speakers/speaker.png"
|
||||
"id": 8,
|
||||
"time_ict": "10.40 am - 11.00 am",
|
||||
"time_utc": "3.40 am - 4.00 am",
|
||||
"category": "Breaks & Networking",
|
||||
"title": "Nghỉ giải lao sáng / Họp báo & Chụp ảnh lưu niệm",
|
||||
"description": "Nghỉ giải lao, dùng trà chiều. Đại biểu VIP và báo chí chụp ảnh lưu niệm.",
|
||||
"speaker": "",
|
||||
"speaker_title": "",
|
||||
"location": "Sân khấu chính"
|
||||
},
|
||||
{
|
||||
"order": "09",
|
||||
"time": "11.10 am – 11.50 am",
|
||||
"title": "**Xây dựng hạ tầng Trung tâm dữ liệu sẵn sàng cho AI tại ASEAN**",
|
||||
"description": "Speaker: Mr. Bayu Hanantasena, Strategic Advisor to CEO, Indosat, Indonesia",
|
||||
"id": 9,
|
||||
"time_ict": "11.00 am - 11.20 am",
|
||||
"time_utc": "4.00 am - 4.20 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "Góc nhìn Nhà mạng: Hạ tầng IPv6 Nâng cao Thúc đẩy Điện toán Đám mây Doanh nghiệp",
|
||||
"description": "Phân tích vai trò của IPv6 nâng cao trong việc tiếp sức cho điện toán doanh nghiệp...",
|
||||
"speaker": "Đại diện Kỹ thuật",
|
||||
"speaker_title": "Nhà mạng / Trung tâm Dữ liệu Việt Nam",
|
||||
"location": "Sân khấu chính"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"time_ict": "11.20 am - 11.40 am",
|
||||
"time_utc": "4.20 am - 4.40 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "Tiên phong Kỷ nguyên AI: Xây dựng Hệ sinh thái Số An toàn & Thông minh với IPv6 & AI",
|
||||
"description": "Giải pháp an ninh mạng, sẵn sàng hạ tầng và hệ sinh thái số thông minh.",
|
||||
"speaker": "Dr. Navaneethan C Arjuman",
|
||||
"speaker_title": "Chủ tịch Nhóm làm việc IPv6 & SG",
|
||||
"location": "Sân khấu chính",
|
||||
"avatar": "/assets/img/speakers/dr.navaneethan-c-arjuman.png"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"time_ict": "11.40 am - 12.00 pm",
|
||||
"time_utc": "4.40 am - 5.00 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "Xây dựng Hạ tầng Mạng Sẵn sàng cho Kỷ nguyên AI",
|
||||
"description": "Case study thực tế và thiết kế kiến trúc mạng sẵn sàng đáp ứng AI.",
|
||||
"speaker": "Mr. Bayu Hanantasena",
|
||||
"speaker_title": "Cố vấn Chiến lược CEO, Indosat",
|
||||
"location": "Sân khấu chính",
|
||||
"avatar": "/assets/img/speakers/bayu-hanatasena.jpg"
|
||||
},
|
||||
{
|
||||
"order": "10",
|
||||
"time": "11.50 am – 12.30 pm",
|
||||
"title": "An ninh mạng trong môi trường AI & Điện toán đám mây: Bảo vệ tương lai số",
|
||||
"description": "**Speaker from Vietnam ISP/Regulators**"
|
||||
"id": 12,
|
||||
"time_ict": "12.00 pm - 12.20 pm",
|
||||
"time_utc": "5.00 am - 5.20 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "Định hình Tương lai Số ASEAN: Đồng bộ Hạ tầng Mạng Thế hệ mới, AI & Chiến lược Cloud",
|
||||
"description": "Khung chính sách, kinh tế số và chiến lược phát triển mạng đám mây tại ASEAN.",
|
||||
"speaker": "Mr. Sivaram Superamanian",
|
||||
"speaker_title": "Phó Giám đốc, Kinh tế Số",
|
||||
"location": "Sân khấu chính"
|
||||
},
|
||||
{
|
||||
"order": "11",
|
||||
"time": "12.30 pm – 2.00 pm",
|
||||
"title": "Nghỉ trưa",
|
||||
"description": ""
|
||||
"id": 13,
|
||||
"time_ict": "12.20 pm - 12.40 pm",
|
||||
"time_utc": "5.20 am - 5.40 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "Góc nhìn Vận hành và Thực tiễn từ các Nhà mạng Trong nước",
|
||||
"description": "Kinh nghiệm thực tiễn triển khai hạ tầng từ các doanh nghiệp viễn thông Việt Nam.",
|
||||
"speaker": "Đại diện Nhà mạng",
|
||||
"speaker_title": "Doanh nghiệp Viễn thông Việt Nam",
|
||||
"location": "Sân khấu chính"
|
||||
},
|
||||
{
|
||||
"order": "12",
|
||||
"time": "2.00 pm – 3.00 pm",
|
||||
"title": "**Tọa đàm**\nQuản lý AI & Chủ quyền dữ liệu",
|
||||
"description": "**Moderator from Council**\n**Panellists from Gov Officials or ISPs of Indonesia, Malaysia, Vietnam**"
|
||||
"id": 14,
|
||||
"time_ict": "12.40 pm - 1.30 pm",
|
||||
"time_utc": "5.40 am - 6.30 am",
|
||||
"category": "Breaks & Networking",
|
||||
"title": "Tiệc Trưa & Kết Nối",
|
||||
"description": "Tiệc trưa và giao lưu kết nối dành cho toàn thể đại biểu và diễn giả.",
|
||||
"speaker": "",
|
||||
"speaker_title": "",
|
||||
"location": "Sân khấu chính"
|
||||
},
|
||||
{
|
||||
"order": "13",
|
||||
"time": "3.00 pm – 3.15 pm",
|
||||
"title": "Nghỉ giải lao chiều",
|
||||
"description": ""
|
||||
"id": 15,
|
||||
"time_ict": "1.30 pm - 2.30 pm",
|
||||
"time_utc": "6.30 am - 7.30 am",
|
||||
"category": "Forums & Panels",
|
||||
"title": "Tọa đàm: Quản trị AI & Chủ quyền Dữ liệu",
|
||||
"description": "Thảo luận bàn tròn cấp cao về chính sách quản trị dữ liệu và quy định pháp lý cho AI.",
|
||||
"speaker": "Chủ tọa & Diễn giả Tọa đàm",
|
||||
"speaker_title": "Đại diện Cơ quan Quản lý & Nhà mạng",
|
||||
"location": "Sân khấu chính"
|
||||
},
|
||||
{
|
||||
"order": "14",
|
||||
"time": "3.15 pm – 5.30 pm",
|
||||
"title": "**Nội dung do đối tác địa phương quyết định (SIMS)**",
|
||||
"description": ""
|
||||
"id": 16,
|
||||
"time_ict": "2.30 pm - 2.50 pm",
|
||||
"time_utc": "7.30 am - 7.50 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "AI & Cloud (IPv6) - Xu hướng và Phát triển tại Trung Quốc",
|
||||
"description": "Tổng quan kỹ thuật về mô hình triển khai IPv6, giao thức mới và tích hợp AI-Cloud.",
|
||||
"speaker": "Mr. Liu Shuai",
|
||||
"speaker_title": "Phó Chủ tịch, MII Trung Quốc",
|
||||
"location": "Sân khấu chính"
|
||||
},
|
||||
{
|
||||
"order": "15",
|
||||
"time": "5.30 pm",
|
||||
"title": "Bế mạc hội thảo",
|
||||
"description": ""
|
||||
"id": 17,
|
||||
"time_ict": "2.50 pm - 3.10 pm",
|
||||
"time_utc": "7.50 am - 8.10 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "Báo cáo Kỹ thuật Chuyên đề",
|
||||
"description": "Phiên trình bày báo cáo chuyên sâu. Thông tin chi tiết sẽ được công bố sớm.",
|
||||
"speaker": "Diễn giả Chuyên đề",
|
||||
"speaker_title": "Chuyên gia Kỹ thuật",
|
||||
"location": "Sân khấu chính"
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"time_ict": "3.10 pm - 3.30 pm",
|
||||
"time_utc": "8.10 am - 8.30 am",
|
||||
"category": "Breaks & Networking",
|
||||
"title": "Nghỉ giải lao chiều & Thăm quan Triển lãm",
|
||||
"description": "Dùng trà chiều, kết nối cùng các đối tác đám mây và tham quan triển lãm công nghệ.",
|
||||
"speaker": "",
|
||||
"speaker_title": "",
|
||||
"location": "Sân khấu chính"
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"time_ict": "3.30 pm - 4.00 pm",
|
||||
"time_utc": "8.30 am - 9.00 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "Tiêu chuẩn IEC giữa Thiết bị Đo đạc và Nguồn Năng lượng Phân tán",
|
||||
"description": "Báo cáo kỹ thuật về chuẩn IEC áp dụng trong đo đạc và tích hợp năng lượng phân tán.",
|
||||
"speaker": "Dr. Masaki Umejima",
|
||||
"speaker_title": "Trưởng nhóm Tích hợp Nguồn Năng lượng",
|
||||
"location": "Sân khấu chính"
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"time_ict": "4.00 pm - 5.30 pm",
|
||||
"time_utc": "9.00 am - 10.30 am",
|
||||
"category": "Technical & Infrastructure",
|
||||
"title": "Chia sẻ Kỹ thuật & Demo Trực tiếp (Đối tác SIMS)",
|
||||
"description": "Trình diễn giải pháp kỹ thuật và thử nghiệm thực tế do đối tác SIMS chủ trì.",
|
||||
"speaker": "Đội ngũ Chuyên gia Kỹ thuật",
|
||||
"speaker_title": "Đối tác Địa phương (SIMS)",
|
||||
"location": "Sân khấu chính"
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"time_ict": "5.30 pm - 6.00 pm",
|
||||
"time_utc": "10.30 am - 11.00 am",
|
||||
"category": "Ceremonies",
|
||||
"title": "Bế mạc Hội thảo",
|
||||
"description": "Tổng kết hội thảo, tri ân đơn vị đồng hành & tài trợ, phát biểu bế mạc.",
|
||||
"speaker": "",
|
||||
"speaker_title": "",
|
||||
"location": "Sân khấu chính"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user