diff --git a/source/class/Pqooxdoo/Application.js b/source/class/Pqooxdoo/Application.js index 0b2d41ba7bba378d5e3d6a36490095c68d188fbd..b0be2d4d80cf6055cd5a3c4dfd862b534a642163 100644 --- a/source/class/Pqooxdoo/Application.js +++ b/source/class/Pqooxdoo/Application.js @@ -4,18 +4,20 @@ qx.Class.define("Pqooxdoo.Application", { members: { main() { super.main(); - + let root = this.getRoot(); root.setBackgroundColor("#87CEEB"); - // Conteneur principal avec mise en page en HBox pour aligner la recherche et la météo - let container = new qx.ui.container.Composite(new qx.ui.layout.HBox(20)).set({ + let container = new qx.ui.container.Composite(new qx.ui.layout.VBox(10)).set({ padding: 20, width: 900, height: 600 }); - // Conteneur de la recherche à gauche + let topContainer = new qx.ui.container.Composite(new qx.ui.layout.HBox(20)).set({ + width: 900 + }); + let searchContainer = new qx.ui.container.Composite(new qx.ui.layout.VBox(10)).set({ width: 300, padding: 10 @@ -39,10 +41,9 @@ qx.Class.define("Pqooxdoo.Application", { searchContainer.add(txtVille); searchContainer.add(btnAfficher); - // Conteneur pour la météo du jour à gauche let weatherContainer = new qx.ui.container.Composite(new qx.ui.layout.VBox(10)).set({ padding: 10, - width: 300 + width: 400 }); let imgWeather = new qx.ui.basic.Image().set({ scale: true, width: 150, height: 150 }); @@ -50,31 +51,47 @@ qx.Class.define("Pqooxdoo.Application", { font: new qx.bom.Font(18, ["Arial", "sans-serif"]), textColor: "#FFFFFF" }); - + let lblResultat1 = new qx.ui.basic.Label("").set({ + font: new qx.bom.Font(18, ["Arial", "sans-serif"]), + textColor: "#FFFFFF" + }); let lblTempMinMax = new qx.ui.basic.Label(""); let lblHumidity = new qx.ui.basic.Label(""); let lblWind = new qx.ui.basic.Label(""); let lblPressure = new qx.ui.basic.Label(""); weatherContainer.add(lblResultat); + weatherContainer.add(lblResultat1); weatherContainer.add(imgWeather); weatherContainer.add(lblTempMinMax); weatherContainer.add(lblHumidity); weatherContainer.add(lblWind); weatherContainer.add(lblPressure); - // Ajouter les conteneurs dans le container principal - container.add(searchContainer); - container.add(weatherContainer); + topContainer.add(searchContainer); + topContainer.add(weatherContainer); + + let forecastContainer = new qx.ui.container.Composite(new qx.ui.layout.VBox(10)).set({ + alignX: "left", + width: 900 + }); + + let previsionLabel = new qx.ui.basic.Label("Prévision des 5 prochains jours").set({ + font: new qx.bom.Font(16, ["Arial", "sans-serif"]).set({ bold: true }), + textColor: "#FFFFFF", + marginBottom: 10 + }); - // Tableau horizontal pour les 5 prochains jours (ajouté en bas) - let daysContainer = new qx.ui.container.Composite(new qx.ui.layout.HBox(20)).set({ - alignX: "center", - marginTop: 30, + let daysContainer = new qx.ui.container.Composite(new qx.ui.layout.HBox(10)).set({ + alignX: "left", width: 900 }); - container.add(daysContainer); // Ajoute le tableau sous la météo actuelle + forecastContainer.add(previsionLabel); + forecastContainer.add(daysContainer); + + container.add(topContainer); + container.add(forecastContainer); let doc = this.getRoot(); doc.add(container, { edge: 0 }); @@ -82,7 +99,7 @@ qx.Class.define("Pqooxdoo.Application", { btnAfficher.addListener("execute", () => { let ville = txtVille.getValue(); if (ville) { - this._fetchWeatherData(ville, lblResultat, imgWeather, lblHumidity, lblWind, lblPressure, lblTempMinMax, daysContainer); + this._fetchWeatherData(ville, lblResultat, lblResultat1, imgWeather, lblHumidity, lblWind, lblPressure, lblTempMinMax, daysContainer); } else { lblResultat.setValue("Veuillez entrer une ville"); } @@ -91,87 +108,77 @@ qx.Class.define("Pqooxdoo.Application", { _getFormattedDate(dayOffset = 0) { let today = new Date(); - today.setDate(today.getDate() + dayOffset); // Ajuste la date selon le jour actuel ou le jour demandé + today.setDate(today.getDate() + dayOffset); return today.toLocaleDateString("fr-FR", { - weekday: "long", // Jour de la semaine - year: "numeric", // Année - month: "long", // Mois - day: "numeric" // Jour du mois + weekday: "long", + day: "numeric" }); }, - _fetchWeatherData(ville, lblResultat, imgWeather, lblHumidity, lblWind, lblPressure, lblTempMinMax, daysContainer) { + _fetchWeatherData(ville, lblResultat, lblResultat1, imgWeather, lblHumidity, lblWind, lblPressure, lblTempMinMax, daysContainer) { let apiKey = "49862134e34fcce7bb7435c5d6ef0265"; - let url = `https://api.openweathermap.org/data/2.5/forecast?q=${ville}&appid=${apiKey}&units=metric&lang=fr`; - + let url = `https://api.openweathermap.org/data/2.5/weather?q=${ville}&appid=${apiKey}&units=metric&lang=fr`; + let forecastUrl = `https://api.openweathermap.org/data/2.5/forecast?q=${ville}&appid=${apiKey}&units=metric&lang=fr`; + let req = new qx.io.request.Xhr(url); - req.addListener("success", function(e) { + req.addListener("success", function (e) { let response = e.getTarget().getResponse(); - - // Prend la première entrée de la liste pour afficher la météo du jour - let todayData = response.list[0]; // Première entrée pour la météo actuelle - - // Affichage des informations du jour - let description = todayData.weather[0].description; - let temperature = todayData.main.temp; - let tempMin = todayData.main.temp_min; - let tempMax = todayData.main.temp_max; - let icon = todayData.weather[0].icon; - let humidity = todayData.main.humidity; - let windSpeed = todayData.wind.speed; - let pressure = todayData.main.pressure; - - lblResultat.setValue(`Météo de ${ville} : ${description}, ${temperature}°C`); - lblTempMinMax.setValue(`Min: ${tempMin}°C / Max: ${tempMax}°C`); - imgWeather.setSource(`https://openweathermap.org/img/wn/${icon}@2x.png`); - lblHumidity.setValue(`Humidité : ${humidity}%`); - lblWind.setValue(`Vitesse du vent : ${windSpeed} m/s`); - lblPressure.setValue(`Pression : ${pressure} hPa`); - - // Récupère les données pour les 5 prochains jours - let forecastData = response.list.filter((data, index) => index % 8 === 0); // Filtre pour prendre 1 entrée toutes les 8 heures - - // Efface le tableau des jours précédents + lblResultat.setValue(`${response.name}, ${response.sys.country}`); + lblResultat1.setValue(`${response.weather[0].description}`); + lblTempMinMax.setValue(`Temp: ${response.main.temp}°C (min: ${response.main.temp_min}°C, max: ${response.main.temp_max}°C)`); + lblHumidity.setValue(`Humidité: ${response.main.humidity}%`); + lblWind.setValue(`Vent: ${response.wind.speed} m/s`); + lblPressure.setValue(`Pression: ${response.main.pressure} hPa`); + imgWeather.setSource(`https://openweathermap.org/img/wn/${response.weather[0].icon}@2x.png`); + }, this); + req.send(); + + let forecastReq = new qx.io.request.Xhr(forecastUrl); + forecastReq.addListener("success", function (e) { + let response = e.getTarget().getResponse(); + let uniqueDays = {}; + let forecastData = response.list.filter(data => { + let date = new Date(data.dt * 1000).getDate(); + if (!uniqueDays[date]) { + uniqueDays[date] = true; + return true; + } + return false; + }); + daysContainer.removeAll(); - - forecastData.slice(0, 5).forEach((data) => { - // Crée un conteneur pour chaque jour + forecastData.slice(0, 5).forEach((data, index) => { let dayBox = new qx.ui.container.Composite(new qx.ui.layout.VBox(5)).set({ alignX: "center", - + width: 130, + height: 160, + backgroundColor: "#ADD8E6" }); - let date = new Date(data.dt * 1000); // Convertir le timestamp - let dateLabel = new qx.ui.basic.Label(this._getFormattedDate(date)).set({ + let dateLabel = new qx.ui.basic.Label(this._getFormattedDate(index + 1)).set({ font: new qx.bom.Font(16, ["Arial", "sans-serif"]), textColor: "#FFFFFF" }); - - let imgWeather = new qx.ui.basic.Image().set({ + + let weatherIcon = new qx.ui.basic.Image().set({ source: `https://openweathermap.org/img/wn/${data.weather[0].icon}@2x.png`, scale: true, - width: 50, - height: 50 + width: 60, + height: 60 }); - + let tempLabel = new qx.ui.basic.Label(`${data.main.temp}°C`).set({ font: new qx.bom.Font(14, ["Arial", "sans-serif"]), textColor: "#FFFFFF" }); - + dayBox.add(dateLabel); - dayBox.add(imgWeather); + dayBox.add(weatherIcon); dayBox.add(tempLabel); - daysContainer.add(dayBox); }); }, this); - - req.addListener("fail", function() { - lblResultat.setValue("Impossible de récupérer la météo"); - }, this); - - req.send(); + forecastReq.send(); } } });