diff --git a/package-lock.json b/package-lock.json index 4bdce81..656803f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,8 @@ "name": "future_website", "version": "0.0.0", "dependencies": { + "@fortawesome/free-solid-svg-icons": "^6.7.2", + "@fortawesome/react-fontawesome": "^0.2.2", "@react-three/drei": "^10.4.2", "@react-three/fiber": "^9.1.4", "@tailwindcss/vite": "^4.1.11", @@ -910,6 +912,53 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@fortawesome/fontawesome-common-types": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.7.2.tgz", + "integrity": "sha512-Zs+YeHUC5fkt7Mg1l6XTniei3k4bwG/yo3iFUtZWd/pMx9g3fdvkSK9E0FOC+++phXOka78uJcYb8JaFkW52Xg==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/fontawesome-svg-core": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.7.2.tgz", + "integrity": "sha512-yxtOBWDrdi5DD5o1pmVdq3WMCvnobT0LU6R8RyyVXPvFRd2o79/0NCuQoCjNTeZz9EzA9xS3JxNWfv54RIHFEA==", + "license": "MIT", + "peer": true, + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.7.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/free-solid-svg-icons": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.7.2.tgz", + "integrity": "sha512-GsBrnOzU8uj0LECDfD5zomZJIjrPhIlWU82AHwa2s40FKH+kcxQaBvBo3Z4TxyZHIyX8XTDxsyA33/Vx9eFuQA==", + "license": "(CC-BY-4.0 AND MIT)", + "dependencies": { + "@fortawesome/fontawesome-common-types": "6.7.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@fortawesome/react-fontawesome": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz", + "integrity": "sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==", + "license": "MIT", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "@fortawesome/fontawesome-svg-core": "~1 || ~6", + "react": ">=16.3" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -2806,7 +2855,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, "license": "MIT" }, "node_modules/js-yaml": { @@ -3159,6 +3207,18 @@ "dev": true, "license": "MIT" }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", @@ -3291,6 +3351,15 @@ "dev": true, "license": "MIT" }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -3445,6 +3514,17 @@ "lie": "^3.0.2" } }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -3476,6 +3556,12 @@ "react": "^19.1.0" } }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" + }, "node_modules/react-leaflet": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/react-leaflet/-/react-leaflet-5.0.0.tgz", diff --git a/package.json b/package.json index 5371653..1b8af89 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,8 @@ "preview": "vite preview" }, "dependencies": { + "@fortawesome/free-solid-svg-icons": "^6.7.2", + "@fortawesome/react-fontawesome": "^0.2.2", "@react-three/drei": "^10.4.2", "@react-three/fiber": "^9.1.4", "@tailwindcss/vite": "^4.1.11", diff --git a/src/App.jsx b/src/App.jsx index 0e87781..ec022a4 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,11 +1,11 @@ // src/App.jsx -import React, { useState, useCallback, useEffect, useMemo } from 'react'; +import { useState, useCallback, useEffect, useMemo } from 'react'; import GlobeCanvas from './components/GlobeCanvas'; import NewsPanel from './components/NewsPanel'; import StatsPanel from './components/StatsPanel'; import GlobalNav from './components/GlobalNav'; import PopUpDetail from './components/PopUpDetail'; -import LocalMap from './components/LocalMap'; // ต้องสร้างไฟล์นี้ด้วย (จากคำตอบก่อนหน้า) +import LocalMap from './components/LocalMap'; function App() { const [isNewsMode, setIsNewsMode] = useState(true); @@ -18,13 +18,13 @@ function App() { const [localViewCenter, setLocalViewCenter] = useState({ lat: 0, lon: 0 }); const [localViewZoom, setLocalViewZoom] = useState(10); // ซูมเริ่มต้นสำหรับ Leaflet - // Data สำหรับ Panel ต่างๆ - เหมือนเดิม + // Data สำหรับ Panel ต่างๆ const panelData = { 'world_news': { title: 'WORLD NEWS', type: 'news', content: 'Global events unfold across continents, shaping economies and societies.', youtubeVideoId: 'dQw4w9WgXcQ' }, 'euro_news': { title: 'EURO NEWS', type: 'news', content: 'Key developments in European politics and markets are impacting global trends.', youtubeVideoId: '1' }, 'america_news': { title: 'AMERICA NEWS', type: 'news', content: 'Breaking news from North and South America, focusing on economic shifts.', youtubeVideoId: '6' }, 'china_japan_news': { title: 'CHINA / JAPAN NEWS', type: 'news', content: 'Latest economic and cultural updates from China and Japan, shaping regional dynamics.', youtubeVideoId: '11' }, - 'asia_news': { title: 'ASIA NEWS', type: 'news', content: 'Emerging tech and market news from Asia, driving innovation forward.', youtubeVideoId: 'k4F9c40tWnQ' }, + 'asean_news': { title: 'ASEAN NEWS', type: 'news', content: 'Emerging tech and market news from Asean, driving innovation forward.', youtubeVideoId: 'k4F9c40tWnQ', lat: 13.7563, lon: 105.00 }, 'market_review': { title: 'MARKET REVIEW', type: 'stats', data: [ @@ -66,7 +66,17 @@ function App() { { label: 'MICEX Index', value: '3,200', trend: 'up' }, { label: 'Oil Production', value: '10.5 M bbl/d', trend: 'same' }, ], - youtubeVideoId: 'your-russia-video-id' + youtubeVideoId: 'your-russia-video-id', + // เพิ่ม news_content สำหรับ Pop-up โดยเฉพาะ + news_content: { + title: 'Key Russian Economic Updates', + text: 'Recent reports indicate a steady increase in the BIX and MICEX indices, reflecting a resilient domestic market. Oil production maintains consistent levels, impacting global energy prices.', + image: 'https://via.placeholder.com/400x200?text=Russia+News+Image', // ตัวอย่างรูปภาพ + links: [ + { label: 'Read more on BIX Index', url: 'https://example.com/bix' }, + { label: 'MICEX Market Analysis', url: 'https://example.com/micex' }, + ] + } }, }; @@ -76,20 +86,33 @@ function App() { { id: 'germany', name: 'Germany', lat: 51.1657, lon: 10.4515, type: 'news', panel: 'euro_news', news: ['German economy outlook.', 'Renewable energy growth.'] }, { id: 'china', name: 'China', lat: 35.8617, lon: 104.1954, type: 'news', panel: 'china_japan_news', news: ['China trade balance.', 'Digital currency trials.'] }, { id: 'japan', name: 'Japan', lat: 36.2048, lon: 138.2529, type: 'news', panel: 'china_japan_news', news: ['Japan tech advancements.', 'Olympic preparations.'] }, - { id: 'russia', name: 'Russia', lat: 61.5240, lon: 105.3188, type: 'stats', panel: 'russia_news_stats', news: ['Russia energy exports.', 'Geopolitical developments.'] }, + // อัปเดตจุด Russia เพื่อให้สามารถแสดง Pop-up ได้ด้วย + { id: 'russia', name: 'Russia', lat: 61.5240, lon: 105.3188, type: 'stats', panel: 'russia_news_stats', news: ['Russia energy exports.', 'Geopolitical developments.'], isClickableForPopUp: true }, { id: 'brazil', name: 'Brazil', lat: -14.2350, lon: -51.9253, type: 'stats', panel: 'next_dollar_currencies', news: ['Brazilian Real fluctuation.', 'Agricultural exports outlook.'] }, { id: 'india', name: 'India', lat: 20.5937, lon: 78.9629, type: 'stats', panel: 'market_review', news: ['Indian market growth.', 'Startup ecosystem booming.'] }, { id: 'australia', name: 'Australia', lat: -25.2744, lon: 133.7751, type: 'news', panel: 'world_news', news: ['Australia bushfire recovery.', 'Mining sector update.'] }, + // เพิ่มจุดสำหรับ ASEAN News ที่เป็น generic ถ้ายังไม่มีจุดเฉพาะ + { id: 'thailand', name: 'Thailand', lat: 13.7563, lon: 100.5018, type: 'news', panel: 'asean_news', news: ['Thai tourism booming.', 'Digital economy initiatives.'] }, + { id: 'singapore', name: 'Singapore', lat: 1.3521, lon: 103.8198, type: 'news', panel: 'asean_news', news: ['Singapore tech hub.', 'Fintech innovations.'] }, ]; const globePointsWithRussia = useMemo(() => { - const existingRussiaPoint = globePoints.find(p => p.id === 'russia'); - if (!existingRussiaPoint) { - return [...globePoints, { id: 'russia', name: 'Russia', lat: 61.5240, lon: 105.3188, type: 'stats', panel: 'russia_news_stats', news: ['Russia energy exports.', 'Geopolitical developments.'] }]; + // ตรวจสอบและเพิ่ม/อัปเดตจุด Russia ตามเดิม + const existingRussiaPointIndex = globePoints.findIndex(p => p.id === 'russia'); + if (existingRussiaPointIndex === -1) { + return [...globePoints, { id: 'russia', name: 'Russia', lat: 61.5240, lon: 105.3188, type: 'stats', panel: 'russia_news_stats', news: ['Russia energy exports.', 'Geopolitical developments.'], isClickableForPopUp: true }]; + } else { + // อัปเดตจุด Russia เดิมด้วย isClickableForPopUp + const updatedGlobePoints = [...globePoints]; + updatedGlobePoints[existingRussiaPointIndex] = { + ...updatedGlobePoints[existingRussiaPointIndex], + isClickableForPopUp: true + }; + return updatedGlobePoints; } - return globePoints; }, [globePoints]); + const globeConnections = [ { id: 'us-uk', startLat: 39.8283, startLon: -98.5795, endLat: 51.5074, endLon: -0.1278 }, { id: 'uk-germany', startLat: 51.5074, startLon: -0.1278, endLat: 51.1657, endLon: 10.4515 }, @@ -97,6 +120,37 @@ function App() { { id: 'us-china', startLat: 39.8283, startLon: -98.5795, endLat: 35.8617, endLon: 104.1954 }, ]; + // Mock data for satellites + const satelliteData = [ + { + id: 'napa1', + name: 'NAPA-1', // <<< เปลี่ยนชื่อ + description: 'Thai Earth Observation Satellite 1', + orbitRadius: 1.05, + orbitSpeed: 0.15, // <<< ปรับความเร็ว: 0.000145 คือ 2 รอบต่อ 24 ชม. จริงๆ (ประมาณ) ลองเพิ่มเล็กน้อยเพื่อชดเชย delta + orbitTiltDeg: 45, // <<< Polar Orbit + color: '#ff00ff' + }, + { + id: 'napa2', + name: 'NAPA-2', // <<< เปลี่ยนชื่อ + description: 'Thai Earth Observation Satellite 2', + orbitRadius: 1.07, + orbitSpeed: 0.05, // <<< ปรับความเร็วเล็กน้อย + orbitTiltDeg: 180, // <<< Polar Orbit + color: '#00ffff' + }, + { + id: 'napa3', + name: 'NAPA-3', // <<< เปลี่ยนชื่อ + description: 'Thai Earth Observation Satellite 3', + orbitRadius: 1.10, + orbitSpeed: 0.08, // <<< ปรับความเร็วเล็กน้อย + orbitTiltDeg: -45, // <<< Polar Orbit + color: '#00ff00' + } + ]; + const panelLocations = useMemo(() => { const locations = {}; for (const panelId in panelData) { @@ -110,28 +164,85 @@ function App() { } }); + // เพิ่มการตรวจสอบความปลอดภัยก่อนเข้าถึง .lat และ .lon + // สำหรับ 'world_news' + if (!locations['world_news']) locations['world_news'] = {}; // ตรวจสอบและสร้าง object ว่างๆ ถ้าไม่มี if (!locations['world_news'].lat && !locations['world_news'].lon) { locations['world_news'].lat = -25.2744; locations['world_news'].lon = 133.7751; } - if (!locations['asia_news'].lat && !locations['asia_news'].lon) { locations['asia_news'].lat = 30; locations['asia_news'].lon = 90; } + + // สำหรับ 'asean_news' + if (!locations['asean_news']) locations['asean_news'] = {}; + if (!locations['asean_news'].lat && !locations['asean_news'].lon) { locations['asean_news'].lat = 13.7563; locations['asean_news'].lon = 105.1954; } + + // สำหรับ 'euro_news' + if (!locations['euro_news']) locations['euro_news'] = {}; if (!locations['euro_news'].lat && !locations['euro_news'].lon) { locations['euro_news'].lat = 50; locations['euro_news'].lon = 10; } + + // สำหรับ 'america_news' + if (!locations['america_news']) locations['america_news'] = {}; if (!locations['america_news'].lat && !locations['america_news'].lon) { locations['america_news'].lat = 35; locations['america_news'].lon = -100; } + + // สำหรับ 'global_population' + if (!locations['global_population']) locations['global_population'] = {}; if (!locations['global_population'].lat && !locations['global_population'].lon) { locations['global_population'].lat = 0; locations['global_population'].lon = 0; } + + // สำหรับ 'energy_consumption' + if (!locations['energy_consumption']) locations['energy_consumption'] = {}; if (!locations['energy_consumption'].lat && !locations['energy_consumption'].lon) { locations['energy_consumption'].lat = 0; locations['energy_consumption'].lon = 0; } + + // สำหรับ 'russia_news_stats' + if (!locations['russia_news_stats']) locations['russia_news_stats'] = {}; if (!locations['russia_news_stats'].lat && !locations['russia_news_stats'].lon) { locations['russia_news_stats'].lat = 61.5240; locations['russia_news_stats'].lon = 105.3188; } return locations; }, [panelData, globePointsWithRussia]); + // แก้ไข handlePointClick เพื่อรองรับ Pop-up จากจุดบนโลก const handlePointClick = useCallback((point) => { - setSelectedPoint(point); - if (point.panel) { + if (point.isClickableForPopUp) { + // ถ้าจุดนั้นตั้งค่าให้คลิกแล้วแสดง Pop-up + setSelectedPoint(point); + } else if (point.panel) { + // โหมดปกติ: แสดง Panel setActivePanel(point.panel); if (point.type === 'news') setIsNewsMode(true); else if (point.type === 'stats') setIsNewsMode(false); setIsPanelVisible(true); - // ไม่ต้องเปลี่ยนเป็น Local View ที่นี่ ให้ GlobeCanvas จัดการเมื่อซูมเข้า } }, []); + // ฟังก์ชันใหม่สำหรับจัดการการคลิกเมนูใน GlobalNav + const handleMenuClick = useCallback((panelId) => { + setActivePanel(panelId); // ตั้งค่า panel ที่ใช้งานอยู่ + setIsPanelVisible(true); // แสดง Panel + + const panelInfo = panelData[panelId]; + if (panelInfo) { + if (panelInfo.type === 'news') { + setIsNewsMode(true); + } else if (panelInfo.type === 'stats') { + setIsNewsMode(false); + } + + // ตรวจสอบว่าเมนูที่คลิกมีข้อมูล news_content สำหรับ Pop-up หรือไม่ + if (panelInfo.news_content) { + // สร้าง object point จำลองสำหรับ PopUpDetail + const dummyPoint = { + id: panelId, + name: panelInfo.title, // ใช้ชื่อ panel เป็นชื่อจุด + // กำหนดตำแหน่งกลางๆ หรือตำแหน่งที่เกี่ยวข้อง หากไม่มีใน globePoints + lat: panelLocations[panelId]?.lat || 0, + lon: panelLocations[panelId]?.lon || 0, + // ใส่ข้อมูล news_content ที่สร้างขึ้นมา + news_content: panelInfo.news_content + }; + setSelectedPoint(dummyPoint); + } else { + setSelectedPoint(null); // ปิด Pop-up หากไม่มีข้อมูล Pop-up สำหรับเมนูนั้น + } + } + }, [panelData, panelLocations]); + + const closePopUp = useCallback(() => { setSelectedPoint(null); }, []); @@ -147,7 +258,7 @@ function App() { }, [isLocalView]); const handleExitLocalView = useCallback(() => { - if (isLocalView) { // ตรวจสอบเพื่อไม่ให้เปลี่ยนโหมดซ้ำซ้อน + if (isLocalView) { setIsLocalView(false); console.log("App.jsx: Exiting Local View"); } @@ -157,7 +268,7 @@ function App() { const currentPanel = panelData[activePanel]; const [currentTime, setCurrentTime] = useState(''); - const [population, setPopulation] = useState('7.42 Billion People'); + const [population] = useState('7.42 Billion People'); useEffect(() => { const timer = setInterval(() => { @@ -179,16 +290,17 @@ function App() { globePoints={globePointsWithRussia} globeConnections={globeConnections} onPointClick={handlePointClick} - onZoomToLocal={handleZoomToLocal} // ส่ง callback ไปยัง GlobeCanvas - isLocalView={isLocalView} // ส่ง state ไปยัง GlobeCanvas เพื่อควบคุม OrbitControls + onZoomToLocal={handleZoomToLocal} + isLocalView={isLocalView} + satelliteData={satelliteData} // ตรวจสอบว่าส่ง prop นี้ไปแล้ว /> ) : (
{/* ปุ่มสำหรับออกจาก Local View */}
@@ -246,8 +359,6 @@ function App() { {/* Top Right - Time Display & Population */}
- {/* เปลี่ยน text-base-content เป็น text-white เพื่อสีที่สว่างขึ้น */} - {/* เพิ่ม text-shadow เพื่อให้ข้อความมีมิติและอ่านง่ายขึ้นบนพื้นหลังมืด */}
{currentTime}
{population}
diff --git a/src/components/ConnectionLines.jsx b/src/components/ConnectionLines.jsx index a2e52e4..6a14fd8 100644 --- a/src/components/ConnectionLines.jsx +++ b/src/components/ConnectionLines.jsx @@ -1,5 +1,5 @@ // src/components/ConnectionLines.jsx -import React, { useMemo } from 'react'; +import { useMemo } from 'react'; import { Line } from '@react-three/drei'; import { Vector3, CatmullRomCurve3 } from 'three'; import { latLonToCartesian } from '../utils/threeHelpers'; diff --git a/src/components/EarthBody.jsx b/src/components/EarthBody.jsx index eb8724a..25f7d99 100644 --- a/src/components/EarthBody.jsx +++ b/src/components/EarthBody.jsx @@ -8,7 +8,7 @@ import { gsap } from 'gsap'; import atmosphereVertexShader from "../shaders/atmosphereVertex.glsl"; import atmosphereFragmentShader from "../shaders/atmosphereFragment.glsl"; -// Clouds และ AtmosphereGlow components เหมือนเดิม (ไม่มีการเปลี่ยนแปลง) +// Clouds และ AtmosphereGlow components function Clouds() { const cloudsRef = useRef(); const cloudMap = useLoader(TextureLoader, '/textures/05_earthcloudmaptrans.jpg'); diff --git a/src/components/GlobalNav.jsx b/src/components/GlobalNav.jsx index 2b17246..fcd399d 100644 --- a/src/components/GlobalNav.jsx +++ b/src/components/GlobalNav.jsx @@ -1,28 +1,53 @@ // src/components/GlobalNav.jsx -import React from 'react'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +// เพิ่ม faChartLine เข้ามาในการ import +import { faNewspaper, faChartBar, faGlobeAsia, faDollarSign, faUsers, faFire, faChartLine } from '@fortawesome/free-solid-svg-icons'; +import { useCallback } from 'react'; -export default function GlobalNav({ activePanel, setActivePanel, isNewsMode, setIsNewsMode }) { - const newsItems = [ - { id: 'world_news', label: 'WORLD NEWS', number: '01' }, - { id: 'euro_news', label: 'EURO NEWS', number: '02' }, - { id: 'america_news', label: 'AMERICA NEWS', number: '03' }, - { id: 'china_japan_news', label: 'CHINA / JAPAN NEWS', number: '04' }, - { id: 'russia_news', label: 'RUSSIA NEWS', number: '05' }, +export default function GlobalNav({ activePanel, setActivePanel, isNewsMode, setIsNewsMode, onMenuClick }) { + + // รวมรายการเมนูทั้งหมดไว้ใน Array เดียว + // ใช้ 'panelId' ในการอ้างอิงถึง key ใน panelData ของ App.jsx + const navItems = [ + // --- News Section --- + { id: 'world_news', label: 'WORLD NEWS', type: 'news', icon: faNewspaper }, + { id: 'euro_news', label: 'EURO NEWS', type: 'news', icon: faNewspaper }, + { id: 'america_news', label: 'AMERICA NEWS', type: 'news', icon: faNewspaper }, + { id: 'china_japan_news', label: 'CHINA / JAPAN NEWS', type: 'news', icon: faNewspaper }, + { id: 'asean_news', label: 'ASEAN NEWS', type: 'news', icon: faGlobeAsia }, + // --- Stats Section --- + { id: 'market_review', label: 'MARKET REVIEW', type: 'stats', icon: faChartBar }, + { id: 'next_dollar_currencies', label: 'CURRENCIES', type: 'stats', icon: faDollarSign }, + { id: 'global_population', label: 'POPULATION', type: 'stats', icon: faUsers }, + { id: 'energy_consumption', label: 'ENERGY', type: 'stats', icon: faFire }, + // **นี่คือส่วนที่ต้องแก้ไข:** + // ลบบรรทัดเก่าของ 'RUSSIA NEWS' ที่ซ้ำออก + // { id: 'russia_news_stats', label: 'RUSSIA NEWS', type: 'stats', icon: faNewspaper }, // <-- ลบบรรทัดนี้! + // เก็บไว้เฉพาะรายการที่ต้องการ: 'RUSSIAN ECONOMY' + { id: 'russia_news_stats', label: 'RUSSIAN ECONOMY', type: 'stats', icon: faChartLine }, ]; - const statsItems = [ - { id: 'market_review', label: 'MARKET REVIEW', number: '01' }, - { id: 'next_dollar_currencies', label: 'CURRENCIES', number: '02' }, - { id: 'global_population', label: 'POPULATION', number: '03' }, - { id: 'energy_consumption', label: 'ENERGY', number: '04' }, - { id: 'bix_micex_index', label: 'BIX INDEX / MICEX INDEX', number: '05' }, - ]; + // Filter รายการที่จะแสดงตาม isNewsMode + const currentItems = navItems.filter(item => + isNewsMode ? item.type === 'news' : item.type === 'stats' + ); - const currentItems = isNewsMode ? newsItems : statsItems; + const handleNavClick = useCallback((panelId, type) => { + // อัปเดต activePanel และ isNewsMode เสมอเมื่อมีการคลิกเมนู + setActivePanel(panelId); + if (type === 'news') { + setIsNewsMode(true); + } else { + setIsNewsMode(false); + } + + // เรียกใช้ onMenuClick ที่รับมาจาก App.jsx + // App.jsx จะเป็นผู้ตัดสินใจว่าควรแสดง NewsPanel/StatsPanel หรือ PopUpDetail + if (onMenuClick) { + onMenuClick(panelId); + } + }, [setActivePanel, setIsNewsMode, onMenuClick]); - const handlePanelClick = (id) => { - setActivePanel(id); - }; return (
@@ -33,11 +58,11 @@ export default function GlobalNav({ activePanel, setActivePanel, isNewsMode, set