Horje
Create a Weather Monitoring Dashboard with Next.js

This project involves building a Weather Monitoring Dashboard using NextJS. The dashboard allows users to check the current weather and forecast for a specific city, as well as an hourly forecast for the next few hours and a daily forecast for the next four days.

Output Preview: Let us have a look at how the final output will look like.

Screenshot-2024-03-13-123532

Prerequisites:

Approach to Create Weather Monitoring Dashboard with NextJS:

  • Fetch current weather data using the OpenWeatherMap API based on geolocation or city search.
  • Display current weather information including temperature, city name, and cloud conditions.
  • Fetch hourly and daily forecasts for the specified location.
  • Render hourly forecast data dynamically.
  • Render daily forecast data dynamically.

Steps to Create the NextJS App:

Step 1: Set up a NextJS project and navigate to that project folder

npx create-next-app weather-monitoring-dashboard

Step 2: Navigate to the root directory of your project.

cd weather-monitoring-dashboard

Step 3: Install necessary dependencies (axios for making HTTP requests).

npm install axios

Project Structure:

Screenshot-2024-03-13-123553

  • Create or replace index.js and _app.js of pages folder using following code
  • generate your own api from openweathermap and replace it with index.js apikey
  • create globals.css with the code given below inside styles

Example: Below is an example of building a weather monitoring dashboard with NextJS.

CSS
/* styles/global.css */

body {
    height: 100%;
    background: rgb(72, 37, 37);
    padding: 1rem 5rem;
    font-family: 'Roboto', sans-serif;
    text-transform: capitalize;
    /* background: linear-gradient(45deg, rgba(183, 204, 248, 0.717), rgba(7, 43, 127, 0.679)), url(); */
    background-repeat: no-repeat;
    background-position: center;
    background-size: cover;
}

.header {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.header h1 {
    color: rgb(214, 147, 45);
    text-decoration: underline;
    font-family: 'Orbitron', sans-serif;
}

#input {
    font-size: 18px;
    padding: 5px 10px;
    outline: none;
    border: none;
    border-radius: 15px;
    background: aliceblue;
}

#search {
    background: none;
    padding: 5px 20px;
    color: aliceblue;
    outline: none;
    background: cadetblue;
    font-size: 17px;
    border-radius: 15px;
    cursor: pointer;
    border: none;
}

.weather {
    text-align: center;
    color: aliceblue;
}

#city {
    font-size: 30px;
}

/* .weather img {
    width: 120px;
    height: 120px;
    border-radius: 50%;
    background: rgba(240, 248, 255, 0.408);
  } */

#temperature {
    font-size: 50px;
    margin: 0;
    margin-left: 30px;
    margin-bottom: 10px;
}

.temp-box {
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 30px 0;
}

#clouds {
    font-size: 20px;
    background: rgba(153, 205, 50, 0.778);
    padding: 2px 20px;
    border-radius: 15px;
}

main {
    display: grid;
    grid-column-gap: 25px;
    grid-template-columns: 1fr 5px 1fr;
    align-items: center;
    margin: 0 50px;
    color: white;
}

.next {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin: 10px 0;
}

.next p,
.next h3 {
    margin: 3px 0;
}

.forecstD {
    margin: 20px 50px;
    color: aliceblue;
}

.weekF {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
}

.cast-header {
    color: aliceblue;
    background: rgba(254, 189, 132, 0.539);
    width: max-content;
    padding: 5px 15px;
    border-radius: 20px;
    font-size: 18px;
    margin-bottom: 5px;
}

.divider1,
.divider2 {
    background: rgba(254, 189, 132, 0.539);
    height: 200px;
    border-radius: 5px;
}

.divider2 {
    height: 5px;
    width: 30%;
    margin: 0 auto;
}

.time,
.date {
    color: rgb(254, 189, 132);
}

.desc {
    color: rgb(196, 255, 77);
}
JavaScript
//pages/index.js
import { useState, useEffect } from 'react';
import axios from 'axios';
import { useRouter } from 'next/router';

const apikey = "feff206daa60b539abe8fae8f2ab7f29";

const Weather = () => {
    const router = useRouter();
    const [city, setCity] = useState('');
    const [weatherData, setWeatherData] = useState(null);

    useEffect(() => {
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition((position) => {
                const { latitude, longitude } = position.coords;
                const url = `
http://api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&appid=${apikey}`;

                fetchWeatherData(url);
            });
        }
    }, []);

    const fetchWeatherData = async (url) => {
        try {
            const response = await axios.get(url);
            const data = response.data;
            console.log(data);
            weatherReport(data);
        } catch (error) {
            console.error('Error fetching weather data:', error);
        }
    };

    const searchByCity = async () => {
        try {
            const urlsearch = `http://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${apikey}`;
            const response = await axios.get(urlsearch);
            const data = response.data;
            console.log(data);
            weatherReport(data);
        } catch (error) {
            console.error('Error fetching weather data:', error);
        }
        setCity('');
    };

    const weatherReport = async (data) => {
        const urlcast = `http://api.openweathermap.org/data/2.5/forecast?q=${data.name}&appid=${apikey}`;
        try {
            const response = await axios.get(urlcast);
            const forecast = response.data;
            console.log(forecast.city);
            hourForecast(forecast);
            dayForecast(forecast);

            console.log(data);
            document.getElementById('city').innerText = data.name + ', ' + data.sys.country;
            console.log(data.name, data.sys.country);

            console.log(Math.floor(data.main.temp - 273));
            document.getElementById('temperature').innerText = Math.floor(data.main.temp - 273) + ' °C';

            document.getElementById('clouds').innerText = data.weather[0].description;
            console.log(data.weather[0].description);

            let icon1 = data.weather[0].icon;
            let iconurl = "http://api.openweathermap.org/img/w/" + icon1 + ".png";
            document.getElementById('img').src = iconurl;
        } catch (error) {
            console.error('Error fetching forecast data:', error);
        }
    };

    const hourForecast = (forecast) => {
        document.querySelector('.templist').innerHTML = '';
        for (let i = 0; i < 5; i++) {
            var date = new Date(forecast.list[i].dt * 1000);
            console.log((date.toLocaleTimeString(
                undefined, 'Asia/Kolkata')).replace(':00', ''));

            let hourR = document.createElement('div');
            hourR.setAttribute('class', 'next');

            let div = document.createElement('div');
            let time = document.createElement('p');
            time.setAttribute('class', 'time');
            time.innerText = (date.toLocaleTimeString(
                undefined, 'Asia/Kolkata')).replace(':00', '');

            let temp = document.createElement('p');
            temp.innerText = Math.floor(
                (forecast.list[i].main.temp_max - 273)) + ' °C' + ' / ' +
                Math.floor((forecast.list[i].main.temp_min - 273)) + ' °C';

            div.appendChild(time);
            div.appendChild(temp);

            let desc = document.createElement('p');
            desc.setAttribute('class', 'desc');
            desc.innerText = forecast.list[i].weather[0].description;

            hourR.appendChild(div);
            hourR.appendChild(desc);
            document.querySelector('.templist').appendChild(hourR);
        }
    };

    const dayForecast = (forecast) => {
        document.querySelector('.weekF').innerHTML = '';
        for (let i = 8; i < forecast.list.length; i += 8) {
            console.log(forecast.list[i]);
            let div = document.createElement('div');
            div.setAttribute('class', 'dayF');

            let day = document.createElement('p');
            day.setAttribute('class', 'date');
            day.innerText = new Date(
                forecast.list[i].dt * 1000).toDateString(
                    undefined, 'Asia/Kolkata');
            div.appendChild(day);

            let temp = document.createElement('p');
            temp.innerText = Math.floor(
                (forecast.list[i].main.temp_max - 273)) + ' °C' + ' / ' +
                Math.floor((forecast.list[i].main.temp_min - 273)) + ' °C';
            div.appendChild(temp);

            let description = document.createElement('p');
            description.setAttribute('class', 'desc');
            description.innerText = forecast.list[i].weather[0].description;
            div.appendChild(description);

            document.querySelector('.weekF').appendChild(div);
        }
    };

    return (
        <div>
            <div className="header">
                <h1>WEATHER Monitoring Dashboard</h1>
                <div>
                    <input
                        type="text"
                        name=""
                        id="input"
                        placeholder="Enter city name"
                        value={city}
                        onChange={(e) => setCity(e.target.value)}
                    />
                    <button id="search" onClick={searchByCity}>
                        Search
                    </button>
                </div>
            </div>

            <main>
                <div className="weather">
                    <h2 id="city">Delhi,IN</h2>
                    <div className="temp-box">
                        <p id="temperature">26 °C</p>
                    </div>
                    <span id="clouds">Broken Clouds</span>
                </div>

                <div className="divider"></div>

                <div className="forecast">
                    <p className="cast-header">Upcoming forecast</p>
                    <div className="forecast-list templist">
                        {/* Hourly forecast will be rendered here */}
                    </div>
                </div>
            </main>

            <div className="divider-2"></div>

            <div className="forecast-2">
                <p className="cast-header"> Next 4 days forecast</p>
                <div className="forecast-list-2 weekF">
                    {/* Daily forecast will be rendered here */}
                </div>
            </div>
        </div>
    );
};

export default Weather;
JavaScript
//pages/_app.js
import '../styles/globals.css';  // Adjust the path as needed

export default function App({ Component, pageProps }) {
    return <Component {...pageProps} />;
}

Start your application using the following command.

npm run dev

Output: Open your web browser and navigate to http://localhost:3000 to see your Weather Monitoring Dashboard in action.

weathermonitoring




Reffered: https://www.geeksforgeeks.org


Dev Scripter

Related
Design Facebook | System Design Design Facebook | System Design
Workout Planner using MERN Stack Workout Planner using MERN Stack
Design Optimization in OOAD Design Optimization in OOAD
Music Playlist App using MERN Stack Music Playlist App using MERN Stack
How To Create ECR Repository In AWS Using Terraform ? How To Create ECR Repository In AWS Using Terraform ?

Type:
Geek
Category:
Coding
Sub Category:
Tutorial
Uploaded by:
Admin
Views:
17