// --- API KEYS AND CONFIG --- const TRAVELPAYOUTS_MARKER = '634425'; const AMADEUS_API_KEY = 'wnxdD8f2YGFwGBNqA7hXafKbIL4gsojf'; // 🔒 IMPORTANT: The Amadeus API Secret should NOT be stored here in production. // See the security note at the end of this guide. const AMADEUS_API_SECRET = 'NafcUGE85nx0RPVO'; let amadeusAccessToken = null; // --- 1. GOOGLE PLACES AUTOCOMPLETE --- function initAutocomplete() { const autocompleteOptions = { types: ['(cities)', 'airport'] }; // Hero Search new google.maps.places.Autocomplete(document.getElementById('from-input'), autocompleteOptions); new google.maps.places.Autocomplete(document.getElementById('to-input'), autocompleteOptions); // Tracker Search new google.maps.places.Autocomplete(document.getElementById('tracker-from-input'), autocompleteOptions); new google.maps.places.Autocomplete(document.getElementById('tracker-to-input'), autocompleteOptions); // Predictor Search new google.maps.places.Autocomplete(document.getElementById('predictor-from-input'), autocompleteOptions); new google.maps.places.Autocomplete(document.getElementById('predictor-to-input'), autocompleteOptions); // Other Searches new google.maps.places.Autocomplete(document.getElementById('hotel-location-input'), { types: ['(cities)'] }); new google.maps.places.Autocomplete(document.getElementById('hostel-location-input'), { types: ['(cities)'] }); new google.maps.places.Autocomplete(document.getElementById('car-pickup-location-input'), { types: ['(cities)', 'airport'] }); } // --- 2. AMADEUS API FLIGHT LOGIC --- async function getAmadeusToken() { // Note: This is a client-side token request for demonstration. // In production, this should be handled server-side to protect your API Secret. if (amadeusAccessToken) return amadeusAccessToken; try { const response = await fetch('https://test.api.amadeus.com/v1/security/oauth2/token', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: `grant_type=client_credentials&client_id=${AMADEUS_API_KEY}&client_secret=${AMADEUS_API_SECRET}` }); const data = await response.json(); amadeusAccessToken = data.access_token; setTimeout(() => { amadeusAccessToken = null; }, (data.expires_in - 300) * 1000); return amadeusAccessToken; } catch (error) { console.error("Amadeus Auth Error:", error); return null; } } async function getIataCode(place) { // This is a simplified function. A real implementation would use Google's Geocoding API // or a dedicated IATA code lookup service to convert the place name to a code. // For now, we will return a placeholder or extract from input if possible. console.warn("getIataCode is a placeholder. You need to implement a real IATA lookup."); return "LHR"; // Placeholder } // --- 3. DYNAMIC SEARCH FUNCTIONS --- async function searchDeals() { // This function will now power the main hero search showAudienceTab('all-travel', document.getElementById('all-travel-btn')); const fromInput = document.getElementById('from-input').value; const toInput = document.getElementById('to-input').value; const dateInput = document.getElementById('date-input').value; const dealsGrid = document.getElementById('deals-grid'); if (!fromInput || !toInput || !dateInput) { alert("Please provide an origin, destination, and departure date."); return; } dealsGrid.innerHTML = '

✈️ Searching for flights...

'; // In a real application, you would convert user-friendly names to IATA codes here. const originIata = await getIataCode(fromInput); const destinationIata = await getIataCode(toInput); const token = await getAmadeusToken(); if (!token) { dealsGrid.innerHTML = '

Could not connect to flight service. Please try again later.

'; return; } try { const url = `https://test.api.amadeus.com/v2/shopping/flight-offers?originLocationCode=${originIata}&destinationLocationCode=${destinationIata}&departureDate=${dateInput}&adults=1&nonStop=false&max=6`; const response = await fetch(url, { headers: { 'Authorization': `Bearer ${token}` }}); if (!response.ok) throw new Error(`API Error: ${response.statusText}`); const data = await response.json(); if (data.data.length === 0) { dealsGrid.innerHTML = '

No flights found for this route. Please try another search.

'; return; } // Generate dynamic Travelpayout affiliate links const aviasalesLink = `https://www.travelpayouts.com/click?shmarker=${TRAVELPAYOUTS_MARKER}&promo_id=4047&origin_iata=${originIata}&destination_iata=${destinationIata}&trip_class=0&adults=1&with_request=true`; grid.innerHTML = data.data.map(deal => `

${deal.itineraries[0].segments[0].departure.iataCode} → ${deal.itineraries[0].segments.slice(-1)[0].arrival.iataCode}

${deal.itineraries[0].segments.length - 1} stop(s) via ${deal.validatingAirlineCodes[0]}

$${deal.price.total}

View Deal →
`).join(''); } catch (error) { console.error("Flight Search Error:", error); dealsGrid.innerHTML = '

An error occurred while searching for flights.

'; } } function searchHotels() { const location = document.getElementById('hotel-location-input').value; if (!location) { alert("Please enter a city or hotel name."); return; } const url = `https://search.hotellook.com/?marker=${TRAVELPAYOUTS_MARKER}&destination=${encodeURIComponent(location)}&language=en`; window.open(url, '_blank'); } function searchHostels() { const location = document.getElementById('hostel-location-input').value; if (!location) { alert("Please enter a city."); return; } // Hotellook is also used for hostels const url = `https://search.hotellook.com/?marker=${TRAVELPAYOUTS_MARKER}&destination=${encodeURIComponent(location)}&language=en`; window.open(url, '_blank'); } function searchCars() { const location = document.getElementById('car-pickup-location-input').value; if (!location) { alert("Please enter a pick-up location."); return; } // Using EconomyBookings.com link from Travelpayout const url = `https://www.travelpayouts.com/click?shmarker=${TRAVELPAYOUTS_MARKER}&promo_id=1415&source_type=link&type=click&trs=201555`; window.open(url, '_blank'); // Note: For a better user experience, you'd find a way to pass the 'location' to the partner site. } function setPriceAlert() { const from = document.getElementById('tracker-from-input').value; const to = document.getElementById('tracker-to-input').value; if (!from || !to) { alert("Please enter an origin and destination for the price alert."); return; } alert(`Price alert for ${from} to ${to} has been set! (This is a demo).`); // Here you would integrate with Amadeus's Flight Price Analysis API or a similar service. } function getPricePrediction() { const from = document.getElementById('predictor-from-input').value; const to = document.getElementById('predictor-to-input').value; const date = document.getElementById('predictor-date-input').value; const container = document.getElementById('prediction-result-container'); if (!from || !to || !date) { alert("Please enter all fields for a prediction."); return; } container.innerHTML = `

🔮 Analyzing historical data for ${from} to ${to}...

`; // This is where you would call your historical data API (e.g., Tefaa or Amadeus). // For this demo, we'll simulate a result. setTimeout(() => { const shouldBuy = Math.random() > 0.5; const confidence = Math.floor(Math.random() * (95 - 75 + 1) + 75); if (shouldBuy) { container.innerHTML = `

Good time to Buy!

Our analysis of historical data suggests prices are lower than average. We are ${confidence}% confident in this prediction.

`; } else { container.innerHTML = `

Consider Waiting.

Prices are currently higher than usual for this route. It may be better to track prices. We are ${confidence}% confident in this prediction.

`; } }, 2000); }

Homepage

Endless Travel Plans – Your Expert Travel Guides

Travel Smarter, Not Harder.

We research, test, and review everything travel-related, so you can book with confidence. Your adventure starts with our expert advice.

Explore Our Expert Guides

Your Most Trusted Travel Resource

We’re obsessed with finding the best value and experiences. Here’s our promise to you:

Unbiased & Independent

Our recommendations are based on hands-on testing and data, not sponsorships. We only succeed when you’re happy.

Expert-Led Teams

Our guides are crafted by seasoned travelers who specialize in everything from budget backpacking to luxury family vacations.

Data-Driven Insights

We analyze thousands of data points—from flight costs to hotel reviews—to ensure you get the best possible value.

Find Your Perfect Travel Style

Our experts live and breathe travel. They create in-depth guides, gear reviews, and travel tips tailored to your specific needs.

Portrait of Jake Martinez

Jake Martinez

The Budget Optimizer

Data-driven travel strategies that maximize value without sacrificing experiences. 47 countries of ROI optimization.

47

Countries

342%

Avg. ROI

$2.3K

Saved

Read Jake’s Guides
Portrait of Sarah Chen-Anderson

Sarah Chen-Anderson

The Family Travel Expert

Multi-generational travel planning that creates magical memories for every family member, from toddlers to grandparents.

500+

Families

98%

Satisfaction

0-85

Ages

See Sarah’s Family Trips
Portrait of Alex Rivera

Alex Rivera

The Cultural Immersion Guide

Transformative journeys that connect you with authentic local cultures and create life-changing experiences.

200+

Experiences

31

Cultures

7

Languages

Explore Alex’s Journeys
Team of travel experts collaborating

Our Mission: Empowering Your Wanderlust

Endless Travel Plans was founded by a team of obsessive travelers who believe that the right information can turn a good trip into a life-changing one. We were tired of generic advice and biased reviews.

So we created the resource we always wanted: a trusted hub of expert-written guides, honest gear reviews, and data-backed tips to help you explore the world with confidence. Your adventure is our passion.

From Our Travel Journal

The latest tips, stories, and in-depth reviews from our team of experts.

Blog post image
BUDGET TRAVEL

The Top 5 Travel Credit Cards of 2025

We compared the points, perks, and fees so you don’t have to…

Read Jake’s Review →
Blog post image
FAMILY TRAVEL

Is All-Inclusive Worth It For Families?

A complete cost breakdown for a family of four in the Caribbean…

Read Sarah’s Analysis →
Blog post image
CULTURAL IMMERSION

5 Apps for Learning a Language on the Go

We tested the most popular language apps for real-world travel…

Read Alex’s Top Picks →

Get the Best Travel Deals & Tips

Join our free newsletter for expert advice, exclusive deals, and travel inspiration delivered straight to your inbox.

EndlessTravel

Your expert guides to smarter travel.

Newsletter

Get the best deals and tips. Subscribe now.

Affiliate Disclosure: This site contains affiliate links, which means we may receive a commission if you click a link and purchase something that we have recommended. While clicking these links won’t cost you any extra money, they will help us keep this site up and running! Thank you for your support!

© 2024 Endless Travel Plans. All Rights Reserved.