import React, { useState, useEffect, useRef, useCallback } from 'react'; import { CheckSquare, Square, CheckCircle2, Map, Info, Clock, ExternalLink, Settings, Navigation, ChevronRight, Star } from 'lucide-react'; /* Global API rate limiting and queue management */ let apiCallCount = 0; const MAX_API_CALLS = 25; const callQueue = []; let isProcessingQueue = false; const processQueue = () => { if (isProcessingQueue || callQueue.length === 0) return; if (apiCallCount >= MAX_API_CALLS) { console.warn(`Google Places API limit reached (${MAX_API_CALLS} requests). Stopping further requests.`); /* Trigger custom event to show UI warning */ window.dispatchEvent(new CustomEvent('api-limit-reached')); return; } isProcessingQueue = true; const task = callQueue.shift(); apiCallCount++; task.execute(); /* 250ms delay between API calls to prevent OVER_QUERY_LIMIT */ setTimeout(() => { isProcessingQueue = false; processQueue(); }, 250); }; const enqueueApiCall = (execute) => { callQueue.push({ execute }); processQueue(); }; const tripData = [ { day: 1, date: "23 มิถุนายน", title: "กรุงเทพฯ สู่ เขาใหญ่", drive: "ประมาณ 2.5 - 3 ชั่วโมง", options: [ { id: "1-1", title: "น้ำตกเหวนรก", desc: "น้ำตกสามชั้นที่น่าทึ่ง ทางเดินลาดยางไปยังจุดชมวิวนั้นค่อนข้างสั้นและอยู่ภายใต้ขีดจำกัด 1,000 เมตรของคุณ" }, { id: "1-2", title: "หอดูสัตว์หนองผักชี", desc: "ทางเดินเรียบและสั้นๆ จากถนนไปยังหอสังเกตการณ์ที่มองเห็นทุ่งหญ้าโล่งกว้างสุดสายตา" }, { id: "1-3", title: "พีบี วัลเล่ย์ เขาใหญ่ ไวเนอรี่", desc: "เพลิดเพลินกับการทัวร์ไร่องุ่นโดยรถราง (แทบไม่ต้องเดิน) พร้อมชมทิวทัศน์ที่สวยงามของภูเขาโดยรอบ" }, { id: "1-4", title: "จุดชมวิวผาเดียวดาย", desc: "ขับรถขึ้นไปจนสุด แล้วเดินบนทางเดินไม้สั้นๆ และเรียบ ไปยังจุดชมวิวหน้าผาสูงชันที่มองเห็นทิวทัศน์หุบเขาอันกว้างไกล" }, { id: "1-5", title: "เขาใหญ่ อาร์ต มิวเซียม", desc: "สวนประติมากรรมกลางแจ้งที่สวยงามและเรียบ ตั้งอยู่บนฉากหลังของภูเขาที่สวยงาม" } ] }, { day: 2, date: "24 มิถุนายน", title: "เขาใหญ่ สู่ นครนายก", drive: "ประมาณ 1.5 - 2 ชั่วโมง", confirmed: { id: "2-dam", title: "เขื่อนขุนด่านปราการชล", desc: "ขับรถไปยังเขื่อนคอนกรีตที่ใหญ่ที่สุดในประเทศไทยเพื่อชมวิวพาโนรามาขนาดใหญ่ จากนั้นล่องเรือหางยาวจากเขื่อนเข้าไปในอ่างเก็บน้ำและขึ้นไปตามแม่น้ำสู่น้ำตกที่ซ่อนอยู่" }, options: [ { id: "2-1", title: "น้ำตกนางรอง", desc: "หลังจากทัวร์เรือแล้ว ขับรถไปที่น้ำตกแห่งนี้ซึ่งคุณสามารถจอดรถได้ติดกับตัวน้ำตกเลย" }, { id: "2-2", title: "อุทยานธรรมชาติวังตะไคร้", desc: "ขับรถเข้าไป จอดรถ แล้วนั่งลงข้างลำธารที่สวยงามและเขียวชอุ่มได้ทันที" }, { id: "2-3", title: "น้ำตกสาริกา", desc: "น้ำตกอีกแห่งในบริเวณใกล้เคียงซึ่งชั้นล่างอยู่ใกล้กับลานจอดรถและเข้าถึงได้ง่าย" }, { id: "2-4", title: "ทุ่งบัวแดง", searchQuery: "ทุ่งบัวแดง นครนายก", desc: "ผ่อนคลายกับการล่องเรือระยะสั้นๆ หรือเดินเล่นบนสะพานสั้นๆ ที่ทอดข้ามบึงที่เต็มไปด้วยบัวแดงบานสะพรั่ง" }, { id: "2-5", title: "เอเดนฟาร์ม นครนายก", desc: "พื้นที่ฟาร์มที่สวยงามและเรียบมาก เดินง่าย มีสะพานไม้ไผ่ยาวข้ามน้ำและประดับด้วยร่มหลากสีสัน" } ] }, { day: 3, date: "25 มิถุนายน", title: "นครนายก สู่ จันทบุรี", drive: "ประมาณ 3.5 - 4 ชั่วโมง", options: [ { id: "3-1", title: "จุดชมวิวเนินนางพญา", desc: "แวะที่จุดชมวิวชายฝั่งที่มีชื่อเสียง จากนั้นเดินบนสะพานไม้ทางเดินศึกษาธรรมชาติอ่าวคุ้งกระเบน ซึ่งเป็นทางเดินไม้เรียบสนิทเหนือป่าชายเลน" }, { id: "3-2", title: "อุทยานแห่งชาติน้ำตกพลิ้ว", desc: "เยี่ยมชมน้ำตกพลิ้วที่มีชื่อเสียงจากปลาหลายพันตัวในแอ่งน้ำ ทางเดินเป็นทางลาดยาง เข้าถึงง่าย และระยะทางไม่ถึง 1,000 เมตร" }, { id: "3-3", title: "สะพานตากสินมหาราช (แหลมสิงห์)", desc: "ขับรถข้ามสะพานแขวนที่สวยงามทอดข้ามปากแม่น้ำ จากนั้นชมการแสดงโลมาที่โอเอซีส ซีเวิลด์ (ไม่ต้องเดินป่า)" }, { id: "3-4", title: "วนอุทยานเขาแหลมสิงห์", desc: "จอดรถใกล้ชายฝั่งเพื่อเดินเล่นระยะสั้นๆ และเรียบ ไปยังชายหาดที่เงียบสงบพร้อมทิวทัศน์มหาสมุทรที่ยอดเยี่ยม" }, { id: "3-5", title: "อาสนวิหารพระนางมารีอาปฏิสนธินิรมล", searchQuery: "อาสนวิหารพระนางมารีอาปฏิสนธินิรมล จันทบุรี", desc: "อาสนวิหารสไตล์ฝรั่งเศสที่สวยงามและสูงตระหง่าน ตั้งอยู่บนลานริมแม่น้ำที่เรียบ สามารถชมสถาปัตยกรรมที่ยอดเยี่ยมได้โดยไม่ต้องปีนเขา" } ] }, { day: 4, date: "26 มิถุนายน", title: "จันทบุรี (วันสำรอง)", drive: "สำรวจในพื้นที่", options: [ { id: "4-1", title: "ขับรถเลียบหาดอ่าวคุ้งวิมาน", desc: "ขับรถชมทิวทัศน์ที่งดงามเลียบชายฝั่ง แวะถ่ายรูปที่จุดชมวิวพระยืน แล้วจอดรถริมหาดได้เลย" }, { id: "4-2", title: "วัดปากน้ำแขมหนู", desc: "วัดเดียวที่คุณสามารถเลือกเที่ยวได้ในทริปนี้! เป็นวัดที่สวยงามน่าทึ่ง ปกคลุมด้วยเซรามิกสีน้ำเงินและสีขาวอย่างประณีต คุณสามารถจอดรถได้ที่ด้านหน้าเลย" }, { id: "4-3", title: "น้ำตกตรอกนอง", desc: "น้ำตกในภูมิภาคที่เข้าถึงได้ง่าย มีแอ่งน้ำธรรมชาติที่น่ารัก และเดินจากรถไม่ไกล" }, { id: "4-4", title: "ศูนย์สาธิตการเลี้ยงสัตว์น้ำ", desc: "ตั้งอยู่ในอ่าวคุ้งกระเบน คุณสามารถเดินไปตามแพไม้เรียบๆ เหนือน้ำเพื่อดูและให้อาหารสัตว์ทะเลได้" }, { id: "4-5", title: "หาดเจ้าหลาว", desc: "ขับรถขนานไปกับหาดทรายที่ยาวที่สุดในจันทบุรี จอดรถที่ใดก็ได้ริมถนนเพื่อลงชายหาดได้ทันที" } ] }, { day: 5, date: "27 มิถุนายน", title: "จันทบุรี สู่ เกาะช้าง", drive: "ขับรถประมาณ 1.5 ชม. + เรือเฟอร์รี่ 45 นาที", options: [ { id: "5-1", title: "จุดชมวิวไก่แบ้", desc: "จอดรถที่จุดชมวิวแห่งนี้บนชายฝั่งตะวันตก ใช้เวลาเดินจากรถเพียง 1 นาที และให้ทัศนียภาพพาโนรามาที่ดีที่สุด" }, { id: "5-2", title: "หาดทรายขาว", searchQuery: "หาดทรายขาว เกาะช้าง", desc: "จอดรถบนถนนสายหลักแล้วเดินลงหาดทรายได้เลย (ไม่ต้องเดินป่า) เพื่อชมวิวพระอาทิตย์ตกที่สวยงามริมชายหาด" }, { id: "5-3", title: "อ่าวสลักเพชร", desc: "ขับรถลงไปทางชายฝั่งตะวันออกที่เงียบสงบสู่สลักเพชร ถนนมีทิวทัศน์ที่สวยงามอย่างไม่น่าเชื่อ และคุณสามารถขับรถไปถึงท่าเรือที่ทอดยาวไปในทะเลได้เลย" }, { id: "5-4", title: "จุดชมวิวอุทยานแห่งชาติหมู่เกาะช้าง", desc: "ลานชมวิวขนาดใหญ่ที่สร้างขึ้นติดกับถนนสายหลัก เพียงจอดรถแล้วเดิน 20 เมตรเพื่อชมวิวมหาสมุทรที่ยิ่งใหญ่" }, { id: "5-5", title: "อ่าวคลองสน", searchQuery: "อ่าวคลองสน เกาะช้าง", desc: "มุ่งหน้าไปยังอ่าวทางตอนเหนือที่เงียบสงบหลังจากลงจากเรือเฟอร์รี่ ที่นี่สามารถเข้าถึงชายหาดได้ง่ายและเงียบสงบอย่างยิ่ง" } ] }, { day: 6, date: "28 มิถุนายน", title: "เกาะช้าง", drive: "สำรวจรอบเกาะ", options: [ { id: "6-1", title: "หมู่บ้านชาวประมงบางเบ้า", desc: "ขับรถไปทางใต้ของเกาะและเดินไปตามท่าเรือคอนกรีตที่เรียบ (รวมระยะทางไม่เกิน 1,000 เมตร) ซึ่งสร้างขึ้นเหนือน้ำทั้งหมด" }, { id: "6-2", title: "ทางเดินป่าชายเลนสลักคอก", desc: "ทางเดินคอนกรีตเรียบและสั้นๆ ผ่านป่าชายเลนที่เงียบสงบและสวยงามทางฝั่งตะวันออกของเกาะ" }, { id: "6-3", title: "ทัวร์เรือเกาะช้าง", desc: "เช่าเรือส่วนตัวลำเล็กจากชายหาดของคุณโดยตรงเพื่อล่องเรือรอบเกาะเล็กๆ ที่อยู่ใกล้เคียง ชมวิวทิวทัศน์ทั้งหมดโดยไม่ต้องเดินเลย" }, { id: "6-4", title: "น้ำตกคลองพลู", desc: "เส้นทางเดินได้รับการดูแลอย่างดีและส่วนใหญ่เป็นทางเรียบจนถึงช่วงสุดท้าย อยู่ในขีดจำกัด 1,000 เมตรของคุณและมีแอ่งน้ำให้ว่ายน้ำที่ยอดเยี่ยม" }, { id: "6-5", title: "น้ำตกธารมะยม", desc: "ตั้งอยู่บนชายฝั่งตะวันออก น้ำตกประวัติศาสตร์แห่งนี้ใช้เวลาเดินจากลานจอดรถสั้นกว่าและเรียบกว่าน้ำตกคลองพลูมาก" } ] }, { day: 7, date: "29 มิถุนายน", title: "เกาะช้าง", drive: "สำรวจรอบเกาะ", options: [ { id: "7-1", title: "ปากแม่น้ำคลองพร้าว", desc: "จอดรถใกล้ปากแม่น้ำที่แม่น้ำมาบรรจบกับทะเล เป็นพื้นที่ราบที่มีทิวทัศน์สวยงามของน้ำและภูเขา" }, { id: "7-2", title: "โลนลี่บีช (หาดท่าน้ำ)", desc: "ขับรถเลียบชายฝั่ง จอดรถ แล้วเดินไม่ไกลเพื่อไปยังหาดทรายเพื่อพักผ่อนที่บีชคลับ" }, { id: "7-3", title: "ทางเดินป่าชายเลนสลักเพชร", desc: "มีชื่อเสียงด้านการถ่ายภาพ ที่นี่เป็นทางเดินไม้สีแดงสดที่เรียบสนิททอดยาวผ่านป่าชายเลนไปจนถึงมหาสมุทร" }, { id: "7-4", title: "ราสต้าวิวพอยท์ เกาะช้าง", desc: "จุดชมวิวบรรยากาศสบายๆ สุดเจ๋งบนชายฝั่งทางใต้ ที่คุณสามารถจอดรถ นั่งจิบเครื่องดื่ม และมองออกไปเห็นอ่าวได้" }, { id: "7-5", title: "แหลมไชยเชษฐ์", desc: "จอดรถที่บริเวณไชยเชษฐ์รีสอร์ทและเดินเรียบๆ ออกไปยังแหลมหินเพื่อชมวิวพระอาทิตย์ตกที่ไม่มีอะไรบดบัง" } ] }, { day: 8, date: "30 มิถุนายน", title: "เกาะช้าง (วันสำรอง)", drive: "สำรวจรอบเกาะ", options: [ { id: "8-1", title: "น้ำตกคลองหนึ่ง", desc: "หนึ่งในน้ำตกที่สูงที่สุดบนเกาะ ตั้งอยู่ทางฝั่งตะวันออกที่เงียบสงบกว่า และสามารถเข้าถึงชั้นล่างได้ค่อนข้างง่าย" }, { id: "8-2", title: "อ่าวใบลาน", desc: "อ่าวหินและทรายที่เงียบสงบทางใต้ของโลนลี่บีช เหมาะสำหรับช่วงบ่ายที่สงบและไม่ต้องออกแรงมากนักริมทะเล" }, { id: "8-3", title: "หาดยาว เกาะช้าง", desc: "ขับรถไปยังมุมตะวันออกเฉียงใต้สุดของเกาะเพื่อพบกับชายหาดที่สวยงามและห่างไกลแห่งนี้ ซึ่งแทบไม่ต้องเดินเลย" }, { id: "8-4", title: "เกาะช้างน้อย", desc: "ชมเกาะเล็กๆ ทางตอนเหนือจากแนวชายฝั่ง มีจุดชมวิวเรียบๆ ที่เข้าถึงง่ายใกล้ท่าเรือเฟอร์รี่" }, { id: "8-5", title: "หาดไข่มุก เกาะช้าง", desc: "ชายหาดกรวดที่ไม่เหมือนใครบนชายฝั่งตะวันตก เหมาะสำหรับการแวะพักสั้นๆ และชมพระอาทิตย์ตกโดยไม่ต้องวุ่นวายกับทราย" } ] }, { day: 9, date: "1 กรกฎาคม", title: "เกาะช้าง สู่ ระยอง", drive: "เรือเฟอร์รี่ + ขับรถประมาณ 2 - 2.5 ชั่วโมง", options: [ { id: "9-1", title: "อุทยานแห่งชาติเขาแหลมหญ้า", desc: "ลานจอดรถอยู่ติดกับทางเดินไม้และจุดชมวิวโขดหินที่สวยงาม มองเห็นมหาสมุทรและเกาะเสม็ด เดินน้อยมาก" }, { id: "9-2", title: "สวนพฤกษศาสตร์ระยอง", desc: "เช่าเรือยนต์ขนาดเล็กเพื่อพาคุณล่องไปในป่าพรุน้ำท่วมและบึงบัวที่น่าทึ่ง ชมวิวธรรมชาติที่น่าตื่นตาตื่นใจโดยไม่ต้องเดิน" }, { id: "9-3", title: "หาดแม่พิมพ์", desc: "ขับรถไปตามถนนเลียบชายฝั่งที่สวยงามเลียบหาดแม่พิมพ์ จอดรถที่ใดก็ได้ตามแนวทรายหลายไมล์เพื่อลงชายหาดได้ทันที" }, { id: "9-4", title: "ทุ่งโปรงทอง", desc: "ทางเดินไม้ที่กว้างขวางและสวยงามผ่านป่าชายเลนสีทองขนาดใหญ่ เป็นทางเรียบสนิท และคุณสามารถเดินเข้าไปเพียง 500 เมตรแล้วกลับออกมาได้" }, { id: "9-5", title: "หาดสวนสน", desc: "ขับรถไปตามถนนเลียบชายฝั่งที่ไม่เหมือนใครซึ่งร่มรื่นไปด้วยต้นสนสูงตระหง่านติดกับชายหาด ทิวทัศน์สวยงามมากจากในรถ" } ] }, { day: 10, date: "2 กรกฎาคม", title: "ระยอง สู่ กรุงเทพฯ", drive: "ประมาณ 2.5 - 3 ชั่วโมง", options: [ { id: "10-1", title: "จุดชมวิวเขาสามมุข บางแสน", desc: "ระหว่างทางกลับ ขับรถขึ้นเนินเขาริมชายฝั่งนี้เพื่อดูลิงป่าและทิวทัศน์มหาสมุทรที่กว้างไกล" }, { id: "10-2", title: "แกรนด์แคนยอนชลบุรี", desc: "เหมืองหินเก่าที่กลายเป็นทะเลสาบที่มีทิวทัศน์สวยงามมาก ใช้เวลาเดินจากลานจอดรถไปยังขอบจุดชมวิวเพียงเล็กน้อย" }, { id: "10-3", title: "สถานตากอากาศบางปู", desc: "เดินออกไปบนสะพานที่ยาวและเรียบสนิทซึ่งทอดยาวออกไปในทะเล ที่ซึ่งคุณสามารถให้อาหารนกนางนวลอพยพหลายร้อยตัวได้" }, { id: "10-4", title: "เมืองโบราณ สมุทรปราการ", desc: "เช่ารถกอล์ฟและขับเที่ยวรอบๆ สวนกลางแจ้งขนาดใหญ่ที่มีสถาปัตยกรรมจำลองที่สวยงามจากทั่วประเทศไทย (ไม่ต้องเดิน)" }, { id: "10-5", title: "ริมน้ำบางกระเจ้า", desc: "ขับรถไปที่ร้านอาหารริมแม่น้ำเจ้าพระยาที่ขอบกรุงเทพฯ นั่งริมน้ำทันทีก่อนนำรถไปคืน" } ] } ]; const getRealisticImage = (title, id) => { const lower = title.toLowerCase(); let term = "nature,thailand"; if (lower.includes("beach") || lower.includes("bay") || lower.includes("cape")) term = "beach,thailand"; if (lower.includes("waterfall")) term = "waterfall,jungle"; if (lower.includes("viewpoint") || lower.includes("cliff")) term = "mountain,view,thailand"; if (lower.includes("mangrove") || lower.includes("garden")) term = "mangrove,forest"; if (lower.includes("dam") || lower.includes("lake")) term = "lake,reservoir"; return `https://loremflickr.com/400/250/${term}?lock=${id.replace('-', '')}`; }; const PlaceImage = ({ title, id, isSelected, isConfirmed, info, onSelect, searchQuery }) => { const defaultUrl = getRealisticImage(title, id); const displayUrl = info?.photoUrl || defaultUrl; const rating = info?.rating; const userRatingsTotal = info?.userRatingsTotal; const finalQuery = searchQuery || `${title} Thailand`; const mapLink = `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(finalQuery)}`; return (
); }; const MapView = ({ activeLocation, apiLoaded }) => { const mapRef = useRef(null); const mapInstance = useRef(null); const markerRef = useRef(null); useEffect(() => { if (!apiLoaded || !window.google || !mapRef.current) return; if (!mapInstance.current) { mapInstance.current = new window.google.maps.Map(mapRef.current, { center: { lat: 13.7563, lng: 100.5018 }, zoom: 6, styles: [ { featureType: "poi", stylers: [{ visibility: "off" }] }, { featureType: "transit", stylers: [{ visibility: "off" }] } ] }); } }, [apiLoaded]); useEffect(() => { if (!mapInstance.current || !window.google || !activeLocation || !activeLocation.location) return; /* Remove old marker */ if (markerRef.current) { markerRef.current.setMap(null); } /* Create new marker for just the single clicked location */ markerRef.current = new window.google.maps.Marker({ position: activeLocation.location, map: mapInstance.current, title: activeLocation.title, icon: { path: window.google.maps.SymbolPath.CIRCLE, fillColor: '#10b981', fillOpacity: 1, strokeColor: '#ffffff', strokeWeight: 2, scale: 14 }, animation: window.google.maps.Animation.DROP }); /* Smoothly pan and zoom to the single location */ mapInstance.current.panTo(activeLocation.location); mapInstance.current.setZoom(12); }, [activeLocation]); return (
{!apiLoaded && (
)} {!activeLocation && apiLoaded && (
แผนที่พร้อมใช้งาน
คลิกที่การ์ดใดก็ได้เพื่อดูบนแผนที่
)}
); }; export default function App() { const [selections, setSelections] = useState({}); const [placesInfo, setPlacesInfo] = useState({}); const [activeMapLocation, setActiveMapLocation] = useState(null); const [apiKey] = useState('AIzaSyCd9ILWS8BfAzMfh5ki0KTIypMRSWpDy7I'); const [apiLoaded, setApiLoaded] = useState(false); const [isMapOpen, setIsMapOpen] = useState(false); const [apiLimitReached, setApiLimitReached] = useState(false); /* Listen for the API limit event */ useEffect(() => { const handler = () => setApiLimitReached(true); window.addEventListener('api-limit-reached', handler); return () => window.removeEventListener('api-limit-reached', handler); }, []); useEffect(() => { if (apiKey && !window.google) { const script = document.createElement('script'); script.src = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places`; script.async = true; script.defer = true; script.onload = () => setApiLoaded(true); document.head.appendChild(script); } else if (window.google) { setApiLoaded(true); } }, [apiKey]); const handleActivatePlace = useCallback((id, title, dayIndex, isSelection, customQuery) => { /* 1. Set as selected if it's an option card */ if (isSelection) { setSelections(prev => ({ ...prev, [dayIndex]: id })); } /* 2. Open the map automatically if it's closed */ setIsMapOpen(true); /* 3. If we already fetched this place's API data before, just show it on the map and stop */ if (placesInfo[id]) { setActiveMapLocation(placesInfo[id]); return; } /* 4. Otherwise, queue EXACTLY ONE Google API call for this click */ if (!apiLoaded || !window.google) return; enqueueApiCall(() => { const finalSearchQuery = customQuery || `${title} Thailand`; const service = new window.google.maps.places.PlacesService(document.createElement('div')); service.findPlaceFromQuery({ query: finalSearchQuery, fields: ['photos', 'geometry', 'rating', 'user_ratings_total'] }, (results, status) => { if (status === window.google.maps.places.PlacesServiceStatus.OK && results && results[0]) { const newInfo = { location: results[0].geometry?.location, title: title, photoUrl: results[0].photos ? results[0].photos[0].getUrl({ maxWidth: 400 }) : null, rating: results[0].rating, userRatingsTotal: results[0].user_ratings_total }; setPlacesInfo(prev => ({ ...prev, [id]: newInfo })); setActiveMapLocation(newInfo); } }); }); }, [apiLoaded, placesInfo]); const scrollToBottom = () => { document.getElementById('final-itinerary')?.scrollIntoView({ behavior: 'smooth' }); }; const progress = Object.keys(selections).length; const totalDaysToSelect = tripData.length; return (
{/* Header */}
{/* Progress Bar */}
ความคืบหน้าในการเลือก: {progress} / {totalDaysToSelect} วัน
{/* API Limit Warning Banner */} {apiLimitReached && (
เกินขีดจำกัดการเรียกใช้ Google API แล้ว ({MAX_API_CALLS} ครั้ง) แอปได้หยุดการเชื่อมต่อเพื่อปกป้องขีดจำกัดการเรียกเก็บเงิน Google Cloud ของคุณ หมุดแผนที่และรูปภาพสำหรับตำแหน่งที่ยังไม่ได้โหลดจะไม่ปรากฏ รีเฟรชหน้าเพื่อรีเซ็ต
)} {/* Main Content Layout */}
{/* Left Column: Itinerary List */}
{} {tripData.map((day, dIdx) => ( {day.day} {day.title}
{day.date}
{/* Confirmed Activity Card */} {day.confirmed && (
กิจกรรมหลักที่ยืนยันแล้ว
handleActivatePlace(day.confirmed.id, day.confirmed.title, dIdx, false, day.confirmed.searchQuery)} >
{day.confirmed.title}
{day.confirmed.desc}
)}
เลือก 1 ตัวเลือกสำหรับวันนี้:
{day.options.map((opt) => { const isSelected = selections[dIdx] === opt.id; return (
handleActivatePlace(opt.id, opt.title, dIdx, true, opt.searchQuery)} /> handleActivatePlace(opt.id, opt.title, dIdx, true, opt.searchQuery)}>
{opt.title}
{opt.desc}
); })}
))} {/* Right Column: Sticky Map (Only visible if isMapOpen) */} {isMapOpen && (
)}
{}
แผนการเดินทางที่คุณเลือก
ตรวจสอบตัวเลือกของคุณสำหรับเส้นทาง กรุงเทพฯ - เกาะช้าง
{progress === 0 ? (
คุณยังไม่ได้เลือกตัวเลือกใดๆ
เลื่อนขึ้นไปและคลิกบนการ์ดเพื่อสร้างแผนการเดินทางของคุณ!
) : (
{tripData.map((day, idx) => { const selectedOptId = selections[idx]; const selectedOpt = day.options.find(o => o.id === selectedOptId); if (!day.confirmed && !selectedOpt) return null; /* Skip days with no selections */ return (
วันที่ {day.day} • {day.date} {day.title}
{day.confirmed && (
{day.confirmed.title}
{day.confirmed.desc}
)} {selectedOpt && (
{selectedOpt.title}
{selectedOpt.desc}
)}
); })}
)}
); }