Project: Membuat Aplikasi Cuaca API dengan HTML, CSS, dan JavaScript

Project: Membuat Aplikasi Cuaca API dengan HTML, CSS, dan JavaScript

Project: Membuat Aplikasi Cuaca dengan HTML, CSS, dan JavaScript

Membuat aplikasi cuaca adalah proyek yang sempurna untuk mempelajari pengembangan web front-end. Dalam artikel ini, kita akan membangun aplikasi cuaca yang menampilkan:

  • Cuaca saat ini
  • Prakiraan per jam
  • Pencarian berdasarkan lokasi
  • Deteksi lokasi pengguna

Tools yang Dibutuhkan

  1. Text Editor (VS Code, Sublime Text)
  2. Browser modern (Chrome, Firefox)
  3. Akun WeatherAPI (gratis)

Struktur File Proyek yang Disederhanakan

weather-app/
├── index.html
├── style.css
└── script.js

Langkah 1: Struktur HTML

html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Aplikasi Cuaca - Azroi</title>
  <!-- Font Awesome -->
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
  <!-- Google Fonts -->
  <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600&display=swap" rel="stylesheet">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <div class="container">
    <div class="search-section">
      <div class="input-wrapper">
        <i class="fas fa-search"></i>
        <input type="search" placeholder="Masukkan nama kota" class="search-input">
      </div>
      <button class="location-button">
        <i class="fas fa-location-arrow"></i>
      </button>
    </div>
    
    <div class="weather-section">
      <div class="current-weather">
        <i class="fas fa-sun weather-icon"></i>
        <h2 class="temperature">00<span>°C</span></h2>
        <h5 class="description">Deskripsi cuaca</h5>
      </div>
      
      <div class="hourly-weather">
        <ul class="weather-list"></ul>
      </div>
    </div>
  </div>
  
  <script src="script.js"></script>
</body>
</html>

Langkah 2: Styling CSS

css
/* Import Google Font */
@import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600&display=swap');

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: 'Montserrat', sans-serif;
}

body {
  background: linear-gradient(#6fe689, #cbfff4);
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh;
}

.container {
  background: white;
  border-radius: 10px;
  width: 100%;
  max-width: 425px;
  box-shadow: 0 10px 20px rgba(0,0,0,0.1);
}

.search-section {
  display: flex;
  gap: 10px;
  padding: 25px;
}

.input-wrapper {
  position: relative;
  width: 100%;
}

.input-wrapper i {
  position: absolute;
  left: 15px;
  top: 50%;
  transform: translateY(-50%);
  color: #5f41e4;
}

.search-input {
  width: 100%;
  padding: 15px 15px 15px 45px;
  border: 1px solid #beb0ff;
  border-radius: 6px;
  font-size: 1rem;
}

.location-button {
  background: white;
  border: 1px solid #beb0ff;
  border-radius: 5px;
  width: 56px;
  cursor: pointer;
  transition: 0.3s;
  color: #5f41e4;
}

.location-button:hover {
  background: #5f41e4;
  color: white;
}

.current-weather {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 20px 0 50px;
}

.weather-icon {
  font-size: 5rem;
  color: #ffcc00;
  margin-bottom: 20px;
}

.temperature {
  font-size: 3.5rem;
  margin: 10px 0;
  color: #333;
}

.description {
  color: #666;
  font-size: 1.2rem;
}

.hourly-weather {
  border-top: 1px solid #d5ccff;
  padding: 16px 25px;
}

.weather-list {
  display: flex;
  gap: 30px;
  overflow-x: auto;
  padding-bottom: 16px;
  list-style: none;
}

.weather-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  min-width: 60px;
}

.weather-item i {
  font-size: 1.5rem;
  margin: 5px 0;
}

.weather-item .time {
  font-size: 0.9rem;
  color: #666;
}

.weather-item .temperature {
  font-size: 1rem;
}

Langkah 3: Menambahkan Fungsi JavaScript 

javascript
const API_KEY = "MASUKAN_API_KEY_ANDA";
const searchInput = document.querySelector(".search-input");
const locationButton = document.querySelector(".location-button");
const weatherIcon = document.querySelector(".weather-icon");
const temperature = document.querySelector(".temperature");
const description = document.querySelector(".description");
const hourlyList = document.querySelector(".weather-list");

// Mapping kode cuaca ke icon Font Awesome
const weatherIcons = {
  1000: "fa-sun",           // Cerah
  1003: "fa-cloud-sun",     // Berawan sebagian
  1006: "fa-cloud",         // Berawan
  1009: "fa-cloud",         // Berawan penuh
  1030: "fa-smog",          // Kabut
  1063: "fa-cloud-rain",    // Hujan ringan
  1066: "fa-snowflake",     // Salju
  1069: "fa-snowflake",     // Hujan salju
  1072: "fa-cloud-rain",    // Hujan beku
  1087: "fa-bolt",          // Petir
  1114: "fa-wind",          // Angin salju
  1117: "fa-wind",          // Badai salju
  1135: "fa-smog",          // Kabut
  1147: "fa-smog",          // Kabut beku
  1150: "fa-cloud-rain",    // Hujan ringan
  1153: "fa-cloud-rain",    // Hujan ringan
  1168: "fa-cloud-rain",    // Hujan beku
  1171: "fa-cloud-rain",    // Hujan beku deras
  1180: "fa-cloud-rain",    // Hujan ringan
  1183: "fa-cloud-rain",    // Hujan ringan
  1186: "fa-cloud-showers-heavy", // Hujan sedang
  1189: "fa-cloud-showers-heavy", // Hujan deras
  1192: "fa-cloud-showers-heavy", // Hujan sangat deras
  1195: "fa-cloud-showers-heavy", // Hujan lebat
  1198: "fa-cloud-rain",    // Hujan ringan
  1201: "fa-cloud-showers-heavy", // Hujan sedang
  1204: "fa-snowflake",     // Hujan salju
  1207: "fa-snowflake",     // Hujan salju
  1210: "fa-snowflake",     // Salju ringan
  1213: "fa-snowflake",     // Salju sedang
  1216: "fa-snowflake",     // Salju deras
  1219: "fa-snowflake",     // Salju
  1222: "fa-snowflake",     // Salju lebat
  1225: "fa-snowflake",     // Salju sangat lebat
  1237: "fa-snowflake",     // Butiran es
  1240: "fa-cloud-rain",    // Hujan ringan
  1243: "fa-cloud-showers-heavy", // Hujan deras
  1246: "fa-cloud-showers-heavy", // Hujan sangat deras
  1249: "fa-snowflake",     // Hujan salju ringan
  1252: "fa-snowflake",     // Hujan salju deras
  1255: "fa-snowflake",     // Salju ringan
  1258: "fa-snowflake",     // Salju deras
  1261: "fa-snowflake",     // Butiran salju ringan
  1264: "fa-snowflake",     // Butiran salju deras
  1273: "fa-bolt",          // Hujan petir ringan
  1276: "fa-bolt",          // Hujan petir deras
  1279: "fa-snowflake",     // Hujan salju dengan petir
  1282: "fa-snowflake"      // Salju dengan petir
};

async function getWeatherData(location) {
  try {
    const response = await fetch(
      `https://api.weatherapi.com/v1/forecast.json?key=${API_KEY}&q=${location}&days=2`
    );
    const data = await response.json();
    
    updateCurrentWeather(data.current);
    updateHourlyForecast(data.forecast.forecastday);
    
  } catch (error) {
    console.error("Error fetching weather data:", error);
    alert("Gagal mengambil data cuaca. Coba lagi nanti.");
  }
}

function updateCurrentWeather(current) {
  const temp = Math.round(current.temp_c);
  const desc = current.condition.text;
  const code = current.condition.code;
  
  temperature.innerHTML = `${temp}<span>°C</span>`;
  description.textContent = desc;
  
  // Update icon menggunakan Font Awesome
  const iconClass = weatherIcons[code] || "fa-cloud";
  weatherIcon.className = `fas ${iconClass} weather-icon`;
  
  // Sesuaikan warna berdasarkan cuaca
  if (iconClass.includes("sun")) {
    weatherIcon.style.color = "#ffcc00";
  } else if (iconClass.includes("rain") || iconClass.includes("shower")) {
    weatherIcon.style.color = "#4d9de0";
  } else if (iconClass.includes("snow")) {
    weatherIcon.style.color = "#b8e1ff";
  } else if (iconClass.includes("bolt")) {
    weatherIcon.style.color = "#ffd166";
  } else {
    weatherIcon.style.color = "#7d7d7d";
  }
}

function updateHourlyForecast(forecastDays) {
  hourlyList.innerHTML = "";
  
  const combinedHours = [...forecastDays[0].hour, ...forecastDays[1].hour];
  const now = new Date();
  
  combinedHours
    .filter(hour => {
      const hourTime = new Date(hour.time);
      return hourTime > now && hourTime <= new Date(now.getTime() + 24 * 60 * 60 * 1000);
    })
    .slice(0, 12) // Ambil 12 jam berikutnya
    .forEach(hour => {
      const li = document.createElement("li");
      li.className = "weather-item";
      
      const time = new Date(hour.time).getHours() + ":00";
      const temp = Math.round(hour.temp_c);
      const code = hour.condition.code;
      const iconClass = weatherIcons[code] || "fa-cloud";
      
      li.innerHTML = `
        <p class="time">${time}</p>
        <i class="fas ${iconClass}"></i>
        <p class="temperature">${temp}°</p>
      `;
      
      hourlyList.appendChild(li);
    });
}

// Event listeners
searchInput.addEventListener("keypress", (e) => {
  if (e.key === "Enter" && searchInput.value.trim()) {
    getWeatherData(searchInput.value.trim());
  }
});

locationButton.addEventListener("click", () => {
  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(
      position => {
        const { latitude, longitude } = position.coords;
        getWeatherData(`${latitude},${longitude}`);
      },
      error => {
        alert("Izin lokasi ditolak. Silakan cari manual.");
      }
    );
  } else {
    alert("Browser tidak mendukung geolocation.");
  }
});

// Default location saat pertama load
getWeatherData("Jakarta");

Langkah 4: Mendapatkan API Key

  1. Daftar di WeatherAPI.com
  2. Dapatkan API Key gratis
  3. Ganti MASUKAN_API_KEY_ANDA dengan API Key Anda

Kesimpulan

Dengan mengikuti tutorial ini, Anda telah mempelajari:

  1. Membuat antarmuka pengguna dengan HTML/CSS
  2. Berkomunikasi dengan API eksternal
  3. Memproses data JSON
  4. Menangani input pengguna
  5. Menggunakan geolocation API

Proyek ini adalah dasar yang bagus untuk mengembangkan aplikasi web lebih lanjut.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *