React Weather App ب Dark Sky & Algolia Places


فهاد ال projet الجديد غادي نشوفو كيفاش نقادو React Weather App لي هو تطبيق ديال حالة الطقس ب Dark Sky & Algolia Places.

بالنسبة ل dark sky هو موقع لي كيوفرنا الإمكانية ديال الحصول على حالة الطقس ديال مجموعة من المدن مجانا و algolia places كتوفرنا واحد ل package لي كيمكنا باش نبحثوا على المدن لي بغينا.

المستخدم غادي تكون عندو الإمكانية ديال إدخال مدينة فحقل البحث ومنبعد غادي يحصل على حالة الطقس الحالية الخاصة بدك المدينة.

نظرة سريعة بالفيديو


1- فتح حساب ف algolia & dark sky


قبل ما نبداو زيد projet جديد ب create-react-app منبعد باش تخدم بل algolia ممكن تفتح الحساب ديالك كيف ما درت فالفيديو المرفق ما بغيتيش ممكن تخدم بل clé ديالي.

أما بالنسبة ل dark sky فالمشكل هنا هو أنا الحسابات الجديدة مبقاتش كتفتح ممكن أيضا تخدم بل clé ديالي.

غادي نزيدو des packages لي غادي نحتاجو places.js و moment.js غادي تدير ل commande :

npm install --save moment places.js

من بعد ف App.js غادي  نزيدو des variables لي غادي نحتاجو عندي weather لي غادي تكون فيها حالة الطقس الحالية و data لي غادي تكون فيها حالة الطقس ديال الأيام القادمة.

عندي أيضا ل key لي هو ل clé ديال dark sky و iconLink لي هو رابط غادي نحتاجو باش نسترجع ل icon لي غادي تكون فيها حالة الطقس مثلا غيمة ولا أمطار ولا شمس.

الكود ديال هاد الجزء هو :

                                    
                                        const [weather, setWeather] = React.useState(null);
  const [data, setData] = React.useState([]);
  const key = "1d5cfbb4b1ba74f6287033207b5f59d7";
  const iconLink = "https://darksky.net/images/weather-icons/";
                                    
                                

2- البحث عن مدينة معينة


من بعد غادي نزيدو fonction getPlaces لي غادي تاخد ل appId ديال app لي زدتي ف algolia أو خدم بديالي بالإضافة ل clé والحقل ديال البحث لي هنا حددناه بل id لي هو adress-input من بعد وغادي نزيدو الحقل.

منبعد فاش كنبدا نكتب فالحقل وكنختار لمدينة كنعطيها ل fonction getWeather لي المهمة ديالها هي إسترجاع حالة الطقس.

وفل hook useEffect أول مكتشارجا la page كن exécuter ل fonction getPlaces باش فاش كنبدا الكتابة فالحقل كيطلعولي المدن لي غادي نختار منهم.

الكود ديال هاد الجزء هو :


                                    
                                        React.useEffect(() => {
    getPlaces();
  }, []);

  function getPlaces() {
    let placeAutoComplete = places({
      appId: "pl84BDTK7HU7",
      apiKey: "671cd803cf905b98ff3217c773e5207a",
      container: document.querySelector("#adress-input"),
    });
    placeAutoComplete.on("change", function (e) {
      getWeather(e.suggestion);
    });
  }
                                    
                                

3- إسترجاع حالة الطقس


من بعد فل fonction getWeather كنسترجع الإحداثيات ديال المدينة لي إختاريت وكنعطيها للرابط ديال dark sky ومنتما كنسترجع المعلومات الخاصة بحالة الطقس ديال دك المدينة وكنعطيها لل variable weather والأيام القادمة ل variable data.

غادي نزيدو أيضا fonction convertTimesstamp

لي الدور ديالها غادي يكون هو تحويل التاريخ من timestamp لتاريخ لي ممكن نقراوه.

الكود ديال هاد الجزء هو :


                                      
                                        async function getWeather(suggestion) {
    const proxy = "https://cors-anywhere.herokuapp.com/";
    let apiUrl = `https://api.darksky.net/forecast/${key}/${suggestion.latlng.lat},${suggestion.latlng.lng}?lang=fr&units=ca`;
    const data = await fetch(proxy + apiUrl);
    const resData = await data.json();
    const weatherData = {
      time: resData.currently.time,
      summary: resData.currently.summary,
      icon: `${resData.currently.icon}.png`,
      temperature: `${Math.round(resData.currently.temperature)} C`,
      humidity: resData.currently.humidity,
    };
    setWeather(weatherData);
    setData(resData.daily.data);
  }


function convertTimesstamp(time) {
    let day = moment.unix(time).locale("fr").utc();
    return day.format("dddd MMM Do");
  }
                                      
                                    

4- عرض حالة الطقس


من بعد ف render كنزيد الحقل لي عطيناه كيف قلنا id لي هو adress-input باش ل fonction getPlaces كتعرف فين غادي تعرض المدن.

من بعد كنتحقق يلا كانت ل variable weather عامرة كنعرض المعلومات لي إسترجعنا وكنحول time بل ل fonction convertTimesstamp لي زدنا لتاريخ ممكن نقراوه نفس الشي بالنسبة ل variable data.

الكود ديال هاد الجزء هو :

                                        
                                            <div className="container">
      <div className="row my-4">
        <div className="col-md-6 mx-auto">
          <div className="card bg-white text-dark">
            <div className="card-header">
              <h3 className="card-title mt-2 text-center">React Weather</h3>
            </div>
            <div className="card-body">
              <div className="row">
                <div className="col-md-12">
                  <div className="form-group">
                    <input
                      type="text"
                      name="city"
                      id="adress-input"
                      className="form-control"
                      placeholder="Entrer une ville"
                      onChange={(event) => setCity(event.target.value)}
                    />
                  </div>
                </div>
              </div>
              {weather !== null && (
                <div className="weather border-bot">
                  <div className="weather-header">
                    <img
                      src={iconLink + weather.icon}
                      alt="icon"
                      width="80"
                      height="80"
                      className="img-fluid"
                    />
                    <h3 className="temperature mr-2 font-weight-">
                      {weather.temperature}
                    </h3>
                    <h3 className="temperature my-2 font-weight-bold">
                      {moment().calendar()}
                    </h3>
                    <h5 className="font-weight-bold">{weather.summary}</h5>
                  </div>
                </div>
              )}
              <div className="row">
                {data !== null &&
                  data.map((day) => (
                    <div className="col-md-3 mb-1">
                      <div className="day" key={day.time}>
                        <span className="text-dark font-weight-bold">
                          {convertTimesstamp(day.time)}
                        </span>
                        <img
                          src={iconLink + day.icon + ".png"}
                          alt="icon"
                          width="50"
                          height="50"
                          className="img-fluid"
                        />
                        <span className="text-dark">
                          Max {Math.round(day.temperatureHigh) + "C"}
                        </span>
                        <span className="text-dark">
                          Min {Math.round(day.temperatureLow) + "C"}
                        </span>
                      </div>
                    </div>
                  ))}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
                                        
                                    

5- الكود كامل


الكود ديال ل projet كامل هو :

                                        
                                            import React from "react";
import places from "places.js";
import moment from "moment";
import "moment/locale/fr";

function App() {
  const [weather, setWeather] = React.useState(null);
  const [data, setData] = React.useState([]);
  const key = "1d5cfbb4b1ba74f6287033207b5f59d7";
  const iconLink = "https://darksky.net/images/weather-icons/";

  React.useEffect(() => {
    getPlaces();
  }, []);

  async function getWeather(suggestion) {
    const proxy = "https://cors-anywhere.herokuapp.com/";
    let apiUrl = `https://api.darksky.net/forecast/${key}/${suggestion.latlng.lat},${suggestion.latlng.lng}?lang=fr&units=ca`;
    const data = await fetch(proxy + apiUrl);
    const resData = await data.json();
    const weatherData = {
      time: resData.currently.time,
      summary: resData.currently.summary,
      icon: `${resData.currently.icon}.png`,
      temperature: `${Math.round(resData.currently.temperature)} C`,
      humidity: resData.currently.humidity,
    };
    setWeather(weatherData);
    setData(resData.daily.data);
  }

  function getPlaces() {
    let placeAutoComplete = places({
      appId: "pl84BDTK7HU7",
      apiKey: "671cd803cf905b98ff3217c773e5207a",
      container: document.querySelector("#adress-input"),
    });
    placeAutoComplete.on("change", function (e) {
      getWeather(e.suggestion);
    });
  }

  function convertTimesstamp(time) {
    let day = moment.unix(time).locale("fr").utc();
    return day.format("dddd MMM Do");
  }

  return (
    <div className="container">
      <div className="row my-4">
        <div className="col-md-6 mx-auto">
          <div className="card bg-white text-dark">
            <div className="card-header">
              <h3 className="card-title mt-2 text-center">React Weather</h3>
            </div>
            <div className="card-body">
              <div className="row">
                <div className="col-md-12">
                  <div className="form-group">
                    <input
                      type="text"
                      name="city"
                      id="adress-input"
                      className="form-control"
                      placeholder="Entrer une ville"
                      onChange={(event) => setCity(event.target.value)}
                    />
                  </div>
                </div>
              </div>
              {weather !== null && (
                <div className="weather border-bot">
                  <div className="weather-header">
                    <img
                      src={iconLink + weather.icon}
                      alt="icon"
                      width="80"
                      height="80"
                      className="img-fluid"
                    />
                    <h3 className="temperature mr-2 font-weight-">
                      {weather.temperature}
                    </h3>
                    <h3 className="temperature my-2 font-weight-bold">
                      {moment().calendar()}
                    </h3>
                    <h5 className="font-weight-bold">{weather.summary}</h5>
                  </div>
                </div>
              )}
              <div className="row">
                {data !== null &&
                  data.map((day) => (
                    <div className="col-md-3 mb-1">
                      <div className="day" key={day.time}>
                        <span className="text-dark font-weight-bold">
                          {convertTimesstamp(day.time)}
                        </span>
                        <img
                          src={iconLink + day.icon + ".png"}
                          alt="icon"
                          width="50"
                          height="50"
                          className="img-fluid"
                        />
                        <span className="text-dark">
                          Max {Math.round(day.temperatureHigh) + "C"}
                        </span>
                        <span className="text-dark">
                          Min {Math.round(day.temperatureLow) + "C"}
                        </span>
                      </div>
                    </div>
                  ))}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

export default App;
                                        
                                    

كلمات مفاتيح :