В этой статье я расскажу о веб-сайте панели мониторинга погоды, который использует API OpenWeatherApp для отображения текущих погодных условий в определенном месте. Кроме того, в нем также есть еще один раздел, в котором отображаются случаи Covid-19 по всему миру с использованием Highcharts. Этот веб-сайт является отличным инструментом для людей, которым нужен быстрый доступ к точной и актуальной информации о местных и глобальных условиях.

Первая часть этого веб-сайта — это его способность предоставлять пользователям актуальную информацию о текущих погодных условиях в их регионе с помощью API OpenWeatherApp. Данные, предоставляемые этой службой, включают в себя, среди прочего, показания температуры, а также скорость и направление ветра; все в режиме реального времени, чтобы пользователи могли быть в курсе того, чего им следует ожидать, выходя на улицу или заранее планируя определенные мероприятия, такие как мероприятия на открытом воздухе или планы поездок и т. д. Кроме того, поскольку он использует внешний API, можно не беспокоиться о точности данных — используются только надежные источники, гарантирующие, что все, что вы видите на экране, действительно верно в любой момент времени!

Наконец, у нас есть вторая часть: отображение случаев Covid 19 со всего мира с помощью графиков/диаграмм HighCharts (которые можно найти здесь). Эти диаграммы предоставляют подробные визуальные представления, показывающие количество подтвержденных случаев в каждой стране, а также другие соответствующие статистические данные, такие как количество новых случаев заражения в день и т. д.; что делает их очень полезными инструментами для того, чтобы быть в курсе событий, связанных с пандемией во всем мире, и позволяет нам всем отслеживать их без необходимости читать страницы за страницами, достойными текста каждый день! Все вместе эти две функции составляют один комплексный пакет, идеально подходящий для тех, кто хочет лучше понять нашу постоянно меняющуюся среду как рядом с домом, так и за границей, что дает нам спокойствие, зная, что именно происходит там, не беспокоясь о себе.

Давайте перейдем к части кода

<!DOCTYPE html>
<html lang="en">
 <head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta property="og:title" content="Weather Dashboard" />
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/5.2.0/css/bootstrap.min.css">
  <link rel="stylesheet" href="https://cdn.datatables.net/1.13.1/css/dataTables.bootstrap5.min.css">
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-qKXV1j0HvMUeCBQ+QVp7JcfGl760yU08IQ+GpUo5hlbpg51QRiuqHAJz8+BrxE/N" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js" integrity="sha384-oBqDVmMz9ATKxIep9tiCxS/Z9fNfEXiDAYTujMAeBAsjFuCZSmKbSSUnQlmh/jp3" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-heAjqF+bCxXpCWLa6Zhcp4fu20XoNIA98ecBC1YkdXhszjoejr5y9Q77hIrv8R9i" crossorigin="anonymous"></script>
  <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous"/>
  <link rel="preconnect" href="https://fonts.googleapis.com" />
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
  <link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght@400;500;700&display=swap" rel="stylesheet"/>
  <link href="styles.css" rel="stylesheet" type="text/css" />
  <script src="https://kit.fontawesome.com/50cde61edc.js" crossorigin="anonymous"></script>
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
  <title>Weather Dashboard</title>
 </head>
 <style>
  #chart{
   width:30%;
  }
 </style>
 <script src="covid-script.js"></script>
 <body onload="getData()">
  <div class="container">
   <header class="container text-md-start my-2 mt-3">
    <div class="row align-items-center">
     <h1 class="col-md-6">Weather Dashboard</h1>
     <div class="w-100 d-md-none d-block"></div>
     <form class="input-group col p-1 search-form">
      <button class="btn btn-outline-primary" id="geolocation-btn" type="button">
       <i class="fa-solid fa-location-arrow"></i>
      </button>
      <input type="search"placeholder="Search City..."class="form-control"id="search-input"autocapitalize="on"autocomplete="address-level2"/> 
      <button type="submit"class="btn btn-outline-primary me-2 search-btn">
       <i class="fa-solid fa-magnifying-glass-location"></i>
      </button>
     </form>
     <div class="form-check form-switch ps-2 align-self-center col-1 me-4 me-md-1">
      <input class="form-check-input"type="checkbox"id="flexSwitchCheckChecked"role="switch"/>
     </div>
    </div>
   </header>
   <div class="row d-flex">
    <div class="local-overview col ms-lg-4 mt-4">
     <div class="mx-3 my-4">
      <h2>Forecast in <span id="location"></span></h2>
      <h3 id="today"></h3>
     </div>
     <div class="container flex-md-row flex-column">
      <div class="row">
       <section class="temp-overview col-lg-5">
        <div class="current-weather card">
         <div class="card-body">
          <div class="d-flex">
           <h1 class="flex-grow-1">
            <span id="temp-now"></span>°<span class="fahrenheit">F</span>
            <span class="toggle-temps">/ <a href="#" class="celsius">C</a></span>
           </h1>
           <h3 class="text-end pt-2"><small>High</small><span class="temps" id="high-temp"></span>°<span class="fahrenheit">F</span><br />
            <small>Low </small>
            <span class="temps" id="low-temp">30</span>°<span class="fahrenheit">F</span>
           </h3>
          </div>
          <br /><br />
          <div class="d-flex">
           <div class="flex-grow-1">
            <p>
             <span id="description-temp">Mostly Sunny</span><br />
             Feels like
             <span class="temps" id="feels-like"></span>°<span
              class="fahrenheit"
              >F</span><br />
             <small id="condition-msg"></small>
            </p>
           </div>
           <div>
            <img
             src=""
             width="85px"
             class="weather-icon default-main-icon"/>
           </div>
          </div>
         </div>
        </div>
       </section>
       <div class="w-100 d-lg-none d-block"></div>
       <section class="temp-details col-lg-4 col-md-5 mt-3 mt-md-2 mt-lg-0">
        <div class="card p-1 initial">
         <ul class="list-group list-group-flush">
          <li class="list-group-item d-flex">
           <strong class="flex-grow-1">Visibility </strong>
           <span id="visibility">0</span>km
           <i class="fa-solid fa-eye-slash align-self-center"></i>
          </li>
          <li class="list-group-item d-flex">
           <strong class="flex-grow-1">Dew Point </strong><span id="dew-point" class="temps"></span>°<span
            class="fahrenheit">F</span>
           <i class="fa-solid fa-droplet align-self-center"></i>
          </li>
          <li class="list-group-item d-flex">
           <strong class="flex-grow-1">Wind </strong>
           <span id="wind">0</span>
           <span id="wind-unit">mph</span>
           <i class="fa-solid fa-wind align-self-center"></i>
          </li>

          <li class="list-group-item d-flex">
           <strong class="flex-grow-1"> Humidity</strong>
           <span id="humidity">0</span>%
           <i class="fa-solid fa-water align-self-center"></i>
          </li>

          <li class="list-group-item d-flex">
           <strong class="flex-grow-1">Cloudiness </strong>
           <span id="clouds"></span>%
           <i class="fa-solid fa-cloud align-self-center"></i>
          </li>
         </ul>
        </div>
       </section>
       <div class="w-100 d-md-none d-block"></div>
       <section class="sun-time col-md mt-3 mt-md-2 mt-lg-0">
        <div class="card">
         <img
          src="./assets/day-landscape.png"
          class="card-img w-100"
          id="scenery"
         />
         <div class="card-img-overlay text-center">
          <i class="fa-solid fa-sun"></i>
          <h3 lass="fw-light">Sunrise</h3>
          <h2 id="sunrise-time"></h2>
          <br />
          <i class="fa-solid fa-moon"></i>
          <h3 lass="fw-lighter">Sunset</h3>
          <h2 id="sunset-time"></h2>
         </div>
        </div>
       </section>
      </div>
     </div>
     <section class="full-forecast d-flex justify-content-md-around my-4"></section>
    </div>
    <div class="w-100 d-lg-none d-block mb-2"></div>
    <section
     class="global-overview mx-lg-4 col-xl-3 mt-4 flex-lg-shrink-1 me-lg-0 pb-1">
     <div class="p-1 mt-3">
      <h2 class="mx-1 mb-3">Forecast in Other <strong>Cities</strong></h2>
      <hr/>
      <div class="d-flex flex-column">
       <div class="container global-item align-items-center">
        <div
         class="row align-items-center flex-nowrap justify-content-center">
         <p class="col">
          <b class="global-name"></b><br /><small class="country-name"></small>
         </p>
         <img
          src="./assets/loading.svg"
          height="50px"
          class="col-3 weather-icon global-icon"/>
         <p class="text-end col">
          <strong
           ><span class="temps global-temps"></span>°<span
            class="fahrenheit">F</span></strong><br /><small class="global-descriptions"></small>
         </p>
        </div>
       </div>
       <hr />
       <div class="container global-item align-items-center">
        <div
         class="row align-items-center flex-nowrap justify-content-center">
         <p class="col">
          <b class="global-name"></b><br /><small
           class="country-name"></small>
         </p>
         <img
          src="./assets/loading.svg"
          height="50px"
          class="col-3 weather-icon global-icon"/>
         <p class="text-end col">
          <strong><span class="temps global-temps"></span>°<span class="fahrenheit">F</span></strong><br /><small class="global-descriptions"></small>
         </p>
        </div>
       </div>
       <hr />
       <div class="container global-item align-items-center">
        <div
         class="row align-items-center flex-nowrap justify-content-center">
         <p class="col">
          <b class="global-name"></b><br /><small class="country-name"></small>
         </p>
         <img
          src="./assets/loading.svg"
          height="50px"
          class="col-3 weather-icon global-icon"/>
         <p class="text-end col">
          <strong><span class="temps global-temps"></span>°<span class="fahrenheit">F</span></strong><br /><small class="global-descriptions"></small>
         </p>
        </div>
       </div>
       <hr />
       <div class="container global-item align-items-center">
        <div class="row align-items-center flex-nowrap justify-content-center">
         <p class="col">
          <b class="global-name"></b><br /><small
           class="country-name"></small>
         </p>
         <img
          src="./assets/loading.svg"
          height="50px"
          class="col-3 weather-icon global-icon"/>
         <p class="text-end col">
          <strong><span class="temps global-temps"></span>°<span class="fahrenheit">F</span></strong><br /><small class="global-descriptions"></small>
         </p>
        </div>
       </div>
       <hr/>
       <div class="container global-item align-items-center">
        <div class="row align-items-center flex-nowrap justify-content-center">
         <p class="col">
          <b class="global-name"></b><br /><small class="country-name"></small>
         </p>
         <img
          src="./assets/loading.svg"
          height="50px"
          class="col-3 weather-icon global-icon"/>
         <p class="text-end col">
          <strong
           ><span class="temps global-temps"></span>°<span class="fahrenheit">F</span></strong><br /><small class="global-descriptions"></small>
         </p>
        </div>
       </div>
      </div>
     </div>
    </section>
   </div>
  </div>
  
  <div class="row d-flex m-5">
   <div class="local-overview col ms-lg-4 mt-4">
    <div class="mx-3 my-4">
     <h2>Covid-19 Dashboard</h2>
     <h3>Charts on Covid-19 Data</h3>
    </div>
    <div class="container flex-md-row flex-column">
     <div class="row d-flex">
      <div id="mychart2" class="col-lg-12 col-md-6"></div>
      <div id="mychart5" class="col-md-6 col-lg-12"></div>
     </div>
     <div id="mychart7"></div>
     <div class="row">
      <div id="mychart6" class="col-md-6"></div>
      <div id="mychart8" class="col-md-6"></div>
     </div>
    </div>
   </div>
  </div>
 
 
 
 
 <script src="https://code.highcharts.com/highcharts.js"></script>
 <script src="https://code.highcharts.com/modules/variable-pie.js"></script>
 <script src="https://code.highcharts.com/modules/exporting.js"></script>
 <script src="https://code.highcharts.com/modules/export-data.js"></script>
 <script src="https://code.highcharts.com/modules/accessibility.js"></script>
 
 
 <script src="https://code.highcharts.com/highcharts.js"></script>
 <script src="https://code.highcharts.com/modules/exporting.js"></script>
 <script src="https://code.highcharts.com/modules/export-data.js"></script>
 <script src="https://code.highcharts.com/modules/accessibility.js"></script>   
 
 
   <script>
  fetch('https://api.covid19api.com/summary')
  .then(response => response.json())
  .then(data => {
    // Format the data as needed
    const countries = data.Countries.map(country => country.Country);
    const cases = data.Countries.map(country => country.TotalConfirmed);
    
    // Create a Chart.js chart
    const ctx = document.getElementById('myChart').getContext('2d');
    const myChart = new Chart(ctx, {
   type: 'bar',
   data: {
     labels: countries,
     datasets: [{
    label: 'Cases',
    data: cases,
    backgroundColor: 'yellow',
    borderColor: 'red',
    borderWidth: 1
     }]
   },
   options: {
     scales: {
    yAxes: [{
      ticks: {
     beginAtZero: true
      }
    }]
     }
   }
    });
  })
  .catch(error => console.error(error));
  var ctx = document.getElementById('chart').getContext('2d');
  var chart = new Chart(ctx, {
   type: 'bar',
   data: {
    labels: [],
    datasets: [{
     label: 'total Confirmed Cases',
     data: [],
     backgroundColor: 'red'
    }, {
     label: 'total Recovered',
     data: [],
     backgroundColor: 'black'
    }, {
     label: 'total Deaths',
     data: [],
     backgroundColor: 'purple'
    }]
   },
   options: {
    title: {
     display: true,
     text: 'Covid19API Chart'
    }
   }
  });
 
  function getData() {
   var country = $('#country').val();
   $.ajax({
    url: 'https://api.covid19api.com/total/country/' + country,
    success: function(data) {
     chart.data.labels = [];
     chart.data.datasets[0].data = [];
     chart.data.datasets[1].data = [];
     chart.data.datasets[2].data = [];
 
     data.forEach(function(d) {
      chart.data.labels.push(d.Date);
      chart.data.datasets[0].data.push(d.Confirmed);
      chart.data.datasets[1].data.push(d.Recovered);
      chart.data.datasets[2].data.push(d.Deaths);
     });
 
     chart.update();
    }
   });
  }
 
 </script>
  
 <script>
 
  var N = [];
  var datas =[];
  fetch('https://api.covid19api.com/world/total')
  
  .then (response =>response.json())
  .then ( data =>{
   // data=JSON.stringify(data.Countries)
    // data=JSON.parse(data);
 
  //console.log(data);
  draw1(data);
  //console.log(data.Countries);
  /*data.Countries.forEach(naems =>{
   //output+=Country.Country;
   if(naems.TotalConfirmed > 20000000){
     N.push(naems.Country);
     datas.push(naems.TotalConfirmed);
   }
  });*/
   
   //var total_case=comfirmedcase[0]
 })
 let chartDiv2 = `
 
 <figure class="highcharts-figure" style="border-radius: 25px;">
  <div id="containe"></div>
  <p class="highcharts-description">
   
  </p>
 </figure>`;
 document.getElementById("mychart2").innerHTML = chartDiv2;
 
 async function draw1(info){
  Highcharts.chart('containe', {
   chart: {
    type: 'column'
   },
   title: {
    text: 'ALL TOTAL'
   },
   subtitle: {
    text: ''
   },
   xAxis: {
    type: 'category',
    labels: {
     rotation: -45,
     style: {
      fontSize: '13px',
      fontFamily: 'Verdana, sans-serif'
     }
    }
   },
   yAxis: {
    min: 0,
    title: {
     text: 'Population (millions)'
    }
   },
   legend: {
    enabled: false
   },
   tooltip: {
    pointFormat: 'Population in 2021: <b>{point.y:.1f} millions</b>'
   },
   series: [{
    name: 'Population',
    data: [
     ['Total Confirmed', parseFloat(info.TotalConfirmed)],
     ['dEATH', parseFloat(info.TotalDeaths)],
     ['NewConfirmed', parseFloat(info.NewConfirmed)],
     
    ],
    dataLabels: {
     enabled: true,
     rotation: -90,
     color: '#FFFFFF',
     align: 'right',
     format: '{point.y:.1f}', // one decimal
     y: 10, // 10 pixels down from the top
     style: {
      fontSize: '13px',
      fontFamily: 'Verdana, sans-serif'
     }
    }
   }]
  });
 }
 </script>
 
 
 
 <script src="https://code.highcharts.com/highcharts.js"></script>
 <script src="https://code.highcharts.com/highcharts-3d.js"></script>
 <script src="https://code.highcharts.com/modules/exporting.js"></script>
 <script src="https://code.highcharts.com/modules/export-data.js"></script>
 <script src="https://code.highcharts.com/modules/accessibility.js"></script>
 
 <script>
  fetch('https://disease.sh/v3/covid-19/countries')
 .then(response => response.json())
 .then(data => {
  console.log(data)
  draw3(data);
 })
  let chartDiv6 = `
 
 <figure class="highcharts-figure" style="border-radius: 25px;">
  <div id="containeru"></div>
  <p class="highcharts-description">
   
  </p>
 </figure>`;
 document.getElementById("mychart6").innerHTML = chartDiv6;
 async function draw3(info3){
  Highcharts.chart('containeru', {
   chart: {
    type: 'column',
    options3d: {
     enabled: true,
     alpha: 10,
     beta: 25,
     depth: 70
    }
   },
   title: {
    text: 'Cases Per One Million',
    align: 'center'
   },
   subtitle: {
    text: '',
    align: 'left'
   },
   plotOptions: {
    column: {
     depth: 25
    }
   },
   xAxis: {
    categories: [info3[0].country, info3[1].country, info3[2].country, info3[4].country,info3[9].country,info3[20].country, info3[10].country,
    info3[15].country, info3[28].country, info3[60].country, info3[61].country, info3[40].country],
    labels: {
     skew3d: true,
     style: {
      fontSize: '16px'
     }
    }
   },
   yAxis: {
    title: {
     text: '(million)',
     margin: 20
    }
   },
   tooltip: {
    valueSuffix: ' '
   },
   series: [{
    name: 'CASES PER MILLION',
    data: [info3[0].casesPerOneMillion, info3[1].casesPerOneMillion, info3[2].casesPerOneMillion, info3[4].casesPerOneMillion, info3[9].casesPerOneMillion,
    info3[20].casesPerOneMillion,info3[10].casesPerOneMillion,info3[15].casesPerOneMillion, info3[28].casesPerOneMillion, info3[60].casesPerOneMillion, info3[61].casesPerOneMillion, info3[40].casesPerOneMillion]
   }]
  });
 }
 </script>
 <script src="https://code.highcharts.com/highcharts.js"></script>
 <script src="https://code.highcharts.com/maps/modules/map.js"></script>
 <script src="https://code.highcharts.com/maps/modules/accessibility.js"></script>
 
 <!-- Flag sprites service provided by Martijn Lafeber, https://github.com/lafeber/world-flags-sprite/blob/master/LICENSE -->
 <link rel="stylesheet" type="text/css" href="https://github.com/downloads/lafeber/world-flags-sprite/flags32.css" />
 <script>
 
 </script>
 <script src="https://code.highcharts.com/highcharts.js"></script>
 <script src="https://code.highcharts.com/highcharts-3d.js"></script>
 <script src="https://code.highcharts.com/modules/cylinder.js"></script>
 <script src="https://code.highcharts.com/modules/exporting.js"></script>
 <script src="https://code.highcharts.com/modules/export-data.js"></script>
 <script src="https://code.highcharts.com/modules/accessibility.js"></script>
 <script>
  fetch('https://disease.sh/v3/covid-19/countries')
  .then(response => response.json())
  .then(data => {
   console.log(data)
   draw5(data);
  })
  let chartDiv8 = `
  
  <figure class="highcharts-figure" style="border-radius: 25px;">
   <div id="container4"></div>
   <p class="highcharts-description">
    
   </p>
  </figure>`;
  document.getElementById("mychart8").innerHTML = chartDiv8;
  async function draw5(info3){
  Highcharts.chart('container4', {
   chart: {
    type: 'cylinder',
    options3d: {
     enabled: true,
     alpha: 15,
     beta: 15,
     depth: 50,
     viewDistance: 25
    }
   },
   title: {
    text: 'Number of confirmed COVID-19'
   },
   subtitle: {
    text: ''
   },
   xAxis: {
    categories: [info3[8].country, info3[90].country, info3[20].country, info3[4].country,info3[9].country,info3[20].country, info3[19].country,
    info3[15].country, info3[28].country, info3[50].country, info3[51].country, info3[30].country],
    title: {
     text: 'country'
    }
   },
   yAxis: {
    title: {
     margin: 20,
     text: 'Reported cases'
    }
   },
   tooltip: {
    headerFormat: '<b></b><br>'
   },
   plotOptions: {
    series: {
     depth: 25,
     colorByPoint: true
    }
   },
   series: [{
    data: [info3[8].casesPerOneMillion, info3[90].casesPerOneMillion, info3[20].casesPerOneMillion, info3[4].casesPerOneMillion, info3[9].casesPerOneMillion,
    info3[20].casesPerOneMillion,info3[19].casesPerOneMillion,info3[15].casesPerOneMillion, info3[28].casesPerOneMillion, info3[50].casesPerOneMillion, info3[51].casesPerOneMillion, info3[30].casesPerOneMillion],
    name: 'Cases',
    showInLegend: false
   }]
  });
 }
 </script>
 <div class="row d-flex m-5">
  <div class="local-overview col ms-lg-4 mt-4">
   <div class="container " >
     <table class="table" id="userTable">
     <thead>
    
      <th >country</th>
      <th >continent</th>
      <th >cases</th>
      <th >death</th>
      <th >active</th>
      <th >recovered</th>
     
     </thead>
     <tbody id="table">
    
   
     </tbody>
   </table>
    </div>
  </div>
 </div>
  <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
  <script src="https://cdn.datatables.net/1.13.1/js/jquery.dataTables.min.js"></script>
  <script src="https://cdn.datatables.net/1.13.1/js/dataTables.bootstrap5.min.js"></script>  
  <script src="covid-script.js"></script>
  <script src="main.js"></script>
  <div id="load"></div>
 </body>
</html>

Следующая часть — это код JavaScript для панели мониторинга погоды, который использует API openweatherapp для получения данных.

// Dark Mode Triggered by Click
const themeToggle = document.querySelector('#flexSwitchCheckChecked');
themeToggle.addEventListener('click', changeTheme);

// User Theme Preference
const userTheme = localStorage.getItem('theme');
if (userTheme === 'dark') {
 themeToggle.click();
}

// Dark Mode Theme Change
function changeTheme() {
 document.querySelector('body').classList.toggle('dark');
 if (document.querySelector('body').classList.contains('dark')) {
  localStorage.setItem('theme', 'dark');
 } else {
  localStorage.setItem('theme', 'light');
 }
}

// Hover Function for Mobile
document.addEventListener('touchstart', function () {}, true);

// Variables for API & Location Heading
const apiKey = '62b039f8311079712478a1f47699e0e4';
const apiWeather = 'https://api.openweathermap.org/data/2.5/weather';
const apiOneCall = 'https://api.openweathermap.org/data/2.5/onecall';
let units = 'imperial';
const locationHeading = document.querySelector('#location');
const geolocationButton = document.querySelector('#geolocation-btn');

// User Location Preference
const userLocation = localStorage.getItem('location');
if (userLocation) {
 updateWeatherByName(userLocation);
} else {
 updateWeatherByName('ADDIS ABABA');
}

// Call API by City Name
function updateWeatherByName(location) {
 axios
  .get(`${apiWeather}?q=${location}&appid=${apiKey}&units=${units}`)
  .then(displayCurrentTemperature, function () {
   alert(
    'There was a problem with your request! Try again or check back later.'
   );
  });
}

// Call API by Geolocation
geolocationButton.addEventListener('click', function () {
 navigator.geolocation.getCurrentPosition(getLocation);
});

function getLocation(position) {
 const lon = position.coords.longitude;
 const lat = position.coords.latitude;

 axios
  .get(`${apiWeather}?lat=${lat}&lon=${lon}&appid=${apiKey}&units=${units}`)
  .then(displayCurrentTemperature);
}

// Call API by Search Functionality
function searchCity(event) {
 event.preventDefault();
 const searchInput = document.querySelector('#search-input').value;
 if (searchInput) {
  updateWeatherByName(searchInput);
 }
}

const searchBtn = document.querySelector('.search-form');
searchBtn.addEventListener('submit', searchCity);

// Call API for Daily Forecast
function getForecast(coordinates) {
 axios
  .get(
   `${apiOneCall}?lat=${coordinates.lat}&lon=${coordinates.lon}&exclude=minutely,hourly,alerts&appid=${apiKey}&units=${units}`
  )
  .then(displayForecast);
}

// Change Temperature Type & Formula to Toggle Between C & F Values
const allTemps = document.querySelectorAll('#temp-now, .temps, .faded-temp');
const fahrenheit = document.querySelectorAll('.fahrenheit');
const celsius = document.querySelector('.celsius');
const windUnit = document.querySelector('#wind-unit');

function toggleTemp(event) {
 event.preventDefault();
 if (celsius.innerHTML === 'C') {
  celsius.innerHTML = 'F';
  fahrenheit.forEach(el => (el.innerHTML = 'C'));
  allTemps.forEach(
   el => (el.textContent = Math.round((el.innerHTML - 32) * (5 / 9)))
  );
  windUnit.innerHTML = `km/h`;
  units = 'metric';
 } else if (celsius.innerHTML === 'F') {
  celsius.innerHTML = 'C';
  fahrenheit.forEach(el => (el.innerHTML = 'F'));
  allTemps.forEach(
   el => (el.textContent = Math.round(el.innerHTML * (9 / 5) + 32))
  );
  windUnit.innerHTML = `mph`;
  units = 'imperial';
 }
 // Update Data to Reflect Celsius or Fahrenheit Change
 updateWeatherByName(locationHeading.textContent);
}

celsius.addEventListener('click', toggleTemp);

// Variables for Elements Representing Data
const currentTemp = document.querySelector('#temp-now');
const highTemp = document.querySelector('#high-temp');
const lowTemp = document.querySelector('#low-temp');
const feelsLikeTemp = document.querySelector('#feels-like');
const tempDescription = document.querySelector('#description-temp');
const wind = document.querySelector('#wind');
const humidity = document.querySelector('#humidity');
const visibility = document.querySelector('#visibility');
const clouds = document.querySelector('#clouds');
const sunrise = document.querySelector('#sunrise-time');
const sunset = document.querySelector('#sunset-time');
const scenery = document.querySelector('#scenery');
const conditionMsg = document.querySelector('#condition-msg');
const todaysDate = document.querySelector('#today');

// Display Temperature
function displayCurrentTemperature(response) {
 if (response.status == 200) {
  const data = response.data;

  // Sunset & Sunrise Times
  const apiSunrise = data.sys.sunrise * 1000;
  const apiSunset = data.sys.sunset * 1000;
  const options = {
   hour: '2-digit',
   minute: '2-digit',
   hour12: true,
  };
  sunrise.innerHTML = localDate(apiSunrise).toLocaleString([], options);
  sunset.innerHTML = localDate(apiSunset).toLocaleString([], options);

  // Get Local Date Object for Searched Cities
  function localDate(unix) {
   const date = new Date();
   const timestamp = unix;
   const offset = date.getTimezoneOffset() * 60000;
   const utc = timestamp + offset;
   const updatedDate = new Date(utc + 1000 * data.timezone);
   return updatedDate;
  }

  // Change Current Time/Date to Location
  const today = new Date();
  const localToday = today.getTime();
  const dateStatement = `${localDate(localToday).toLocaleDateString([], {
   weekday: 'long',
   month: 'long',
   day: 'numeric',
  })} at ${localDate(localToday).toLocaleString([], options)}`;
  todaysDate.innerHTML = `${dateStatement}`;

  // Change Landscape Image Based on Sunset / Sunrises
  const sunriseHour = localDate(apiSunrise).getHours();
  const sunsetHour = localDate(apiSunset).getHours();

  localDate(localToday).getHours() < sunriseHour ||
  localDate(localToday).getHours() >= sunsetHour
   ? (scenery.src = './assets/night-landscape.png')
   : (scenery.src = './assets/day-landscape.png');

  // Update Weather Details
  locationHeading.innerHTML = `${data.name}, ${data.sys.country}`;
  currentTemp.innerHTML = `${Math.round(data.main.temp)}`;
  highTemp.innerHTML = `${Math.round(data.main.temp_max)}`;
  lowTemp.innerHTML = `${Math.round(data.main.temp_min)}`;
  feelsLikeTemp.innerHTML = `${Math.round(data.main.feels_like)}`;
  tempDescription.innerHTML = `${data.weather[0].description}`;
  wind.innerHTML = `${Math.round(data.wind.speed)}`;
  humidity.innerHTML = `${data.main.humidity}`;
  visibility.innerHTML = `${Math.round(data.visibility / 1000)}`;
  clouds.innerHTML = `${data.clouds.all}`;

  // Change Icon for Main Overview
  axios.get('./icon.json').then(icon => {
   for (let i = 0; i < icon.data.length; i++) {
    if (
     data.weather[0].icon === icon.data[i].icon &&
     data.weather[0].id === icon.data[i].id
    ) {
     const mainWeatherIcon = document.querySelector('.default-main-icon');
     mainWeatherIcon.setAttribute('src', icon.data[i].src);
     mainWeatherIcon.setAttribute('alt', icon.data[i].alt);
    }
   }
  });

  // Weather Condition Message Indicator
  const weatherType = data.weather[0].main;
  if (
   weatherType === 'Rain' ||
   weatherType === 'Drizzle' ||
   weatherType === 'Clouds'
  ) {
   conditionMsg.innerHTML = `<i class="fa-solid fa-umbrella"></i> Umbrella Required`;
  } else if (weatherType === 'Thunderstorm' || weatherType === 'Tornado') {
   conditionMsg.innerHTML = `<i class="fa-solid fa-cloud-bolt"></i> Stay Indoors`;
  } else if (weatherType === 'Snow') {
   conditionMsg.innerHTML = `<i class="fa-solid fa-snowflake"></i> Dress Warm`;
  } else if (weatherType === 'Clear') {
   conditionMsg.innerHTML = `<i class="fa-solid fa-circle-check"></i> Ideal Conditions`;
  } else if (
   weatherType === 'Mist' ||
   weatherType === 'Fog' ||
   weatherType === 'Haze'
  ) {
   conditionMsg.innerHTML = `<i class="fa-solid fa-triangle-exclamation"></i> Poor Visibility`;
  } else {
   conditionMsg.innerHTML = `<i class="fa-solid fa-triangle-exclamation"></i> Poor Air Quality`;
  }

  // Call Daily Forecast Function Based on Current Location Data
  getForecast(response.data.coord);

  // Local Storage
  localStorage.setItem('location', `${data.name}`);
 }
}

// Display Daily Forecast Data
function displayForecast(response) {
 // Added Dew Point // Original API Call Does Not Support
 const dewPoint = document.querySelector('#dew-point');
 dewPoint.innerHTML = `${Math.round(response.data.current.dew_point)}`;
 // Daily Forecast
 const forecastData = response.data.daily;
 const forecastContainer = document.querySelector('.full-forecast');
 let forecastHTML = '';
 forecastData.forEach(function (day, index) {
  if (index < 7) {
   forecastHTML += `<div class="daily m-2 m-md-0">
       <p>${formatDay(day.dt)}</p>
       <img
        src="./assets/loading.svg"
        class="weather-icon forecast-icon mb-2"
        height="45px"
        width="50px"
       />
       <p>
        <span class="temps">${Math.round(
         day.temp.max
        )}</span>°<span class="fahrenheit">${
    units === 'metric' ? 'C' : 'F'
   } </span
        ><br />
        <span class="daily-low">
         <span class="forecast-low temps">${Math.round(
          day.temp.min
         )}</span>°<span class="fahrenheit"
          >${units === 'metric' ? 'C' : 'F'}
         </span>
        </span>
       </p>
      </div>
      `;
   // Icon Matching for Each Daily Forecast
   axios.get('./icon.json').then(icon => {
    for (let i = 0; i < icon.data.length; i++) {
     if (
      day.weather[0].id === icon.data[i].id &&
      day.weather[0].icon === icon.data[i].icon
     ) {
      forecastHTML = forecastHTML.replace(
       'src="./assets/loading.svg"',
       `src="${icon.data[i].src}"`
      );
     }
    }
    forecastContainer.innerHTML = forecastHTML;
   });
  }
 });
}
// Format Daily Forecast Unix Timestamps
function formatDay(unix) {
 const date = new Date(unix * 1000);
 const day = date.getDay();
 const days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
 return days[day];
}

// Display Temperatures for Global Forecast (Default)
const cityTemps = document.querySelectorAll('.global-temps');
const cityWeatherDesc = document.querySelectorAll('.global-descriptions');
const cityNames = document.querySelectorAll('.global-name');
const countryNames = document.querySelectorAll('.country-name');
const cities = [
 'Seattle',
 'Rabat',
 'London',
 'Paris',
 'Delhi',
 'Jakarta',
 'Manila',
 'Shanghai',
 'Tokyo',
 'Cairo',
 'Dhaka',
 'New York',
 'Istanbul',
 'Los Angeles',
 'Munich',
 'Dubai',
];

// Shuffle Array for Randomized Cities
cities.sort(() => Math.random() - 0.5);

// Default Information for Global Forecast Section
function displayGlobalTemperature() {
 for (let i = 0; i < 5; i++) {
  axios
   .get(`${apiWeather}?q=${cities[i]}&appid=${apiKey}&units=${units}`)
   .then(response => {
    const data = response.data;
    cityNames[i].innerHTML = `${data.name}`;
    countryNames[i].innerHTML = `${data.sys.country}`;
    cityTemps[i].innerHTML = Math.round(data.main.temp);
    cityWeatherDesc[i].innerHTML = `${data.weather[0].description}`;
    axios.get('./icon.json').then(icon => {
     for (let k = 0; k < icon.data.length; k++) {
      if (
       data.weather[0].id === icon.data[k].id &&
       data.weather[0].icon === icon.data[k].icon
      ) {
       let globalWeatherIcon = document.querySelectorAll('.global-icon');
       globalWeatherIcon[i].setAttribute('src', icon.data[k].src);
       globalWeatherIcon[i].setAttribute('alt', icon.data[k].alt);
      }
     }
    });
   });
 }
}

// Click on "Other Cities" To Display Weather For That Region
let globalContainers = document.querySelectorAll('.global-item');

for (let i = 0; i < 5; i++) {
 globalContainers[i].addEventListener('click', () => {
  updateWeatherByName(cities[i]);
  window.scrollTo({
   top: 0,
   behavior: 'smooth',
  });
 });
}

// Default Location to Show
displayGlobalTemperature();

 

Проверьте живую демонстрацию здесь: -