· 6 years ago · Jan 21, 2020, 08:32 AM
1import React from "react";
2import { Row, Col } from "react-bootstrap";
3import axios from "axios";
4import qs from 'qs';
5import Popup from "reactjs-popup";
6import { Link } from 'react-router-dom';
7
8import NavBar from "../utils/NavBar";
9import Autocomplete from "../utils/Autocomplete";
10import API from "../utils/API";
11
12//theme
13import { ThemeProvider } from 'styled-components';
14import { lightTheme, darkTheme } from '../utils/theme/theme';
15import { GlobalStyles } from '../utils/theme/global';
16
17//import SliderCSS
18import Slider from "react-slick";
19import "slick-carousel/slick/slick.css";
20import "slick-carousel/slick/slick-theme.css";
21
22const lienAPI = 'https://localhost:8800/';
23const imagesPublic = 'https://localhost:3000/images/';
24
25export class Dash extends React.Component {
26
27 constructor() {
28 super();
29 this.state = {
30 villeData: [],
31 tabVilles: [],
32 username: [],
33 value: '',
34 suggestions: [],
35 index: 0,
36 open: false,
37 nbVilles: 0,
38 theme: 'light'
39 };
40 this.openModal = this.openModal.bind(this);
41 this.closeModal = this.closeModal.bind(this);
42 }
43
44 componentDidMount() {
45 //recupération des villes
46 let tabVilles = [];
47 const data = require('../utils/city.json');
48 for (let i in data) {
49 tabVilles.push(data[i].name)
50 }
51 this.setState({ tabVilles });
52
53 //recupération des informations de l utilisateur
54 const APIURL = lienAPI;
55 const token = localStorage.getItem("token");
56 axios({
57 method: 'post',
58 url: `${APIURL}user/info`,
59 data: qs.stringify({
60 token: token
61 }),
62 headers: {
63 'content-type': 'application/x-www-form-urlencoded;charset=utf-8'
64 }
65 })
66 .then((res) => {
67 const username = res.data.username;
68 const villes = res.data.villes.sort();
69 let nbVilles = 0;
70
71 //recupération des données météos
72 for (let i in villes) {
73 if (villes[i] === "") {
74 //ne rien faire si le nom de ville = ""
75 } else {
76 nbVilles++;
77 const APIKey = '90a25ba3238d572e206c22a67b68949f';
78 const APIMeteo = `https://api.openweathermap.org/data/2.5/weather?q=${villes[i]}&mode=json&appid=${APIKey}&units=metric`;
79 axios({
80 method: 'get',
81 url: APIMeteo,
82 headers: {
83 'content-type': 'application/x-www-form-urlencoded;charset=utf-8'
84 }
85 })
86 .then((res) => {
87
88 const content = res.data;
89 const updatedVilleData = [...this.state.villeData];
90 let image = content.weather[0].main;
91 switch (image) {
92 case 'Thunderstorm':
93 image = imagesPublic + 'storm_'
94 break;
95 case 'Drizzle':
96 image = imagesPublic + 'raining_'
97 break;
98 case 'Rain':
99 image = imagesPublic + 'raining_'
100 break;
101 case 'Snow':
102 image = imagesPublic + 'snowing_'
103 break;
104 case 'Clear':
105 image = imagesPublic + 'sunny_'
106 break;
107 case 'Clouds':
108 image = imagesPublic + 'cloudy_'
109 break;
110 default:
111 image = imagesPublic + 'br.png'
112 }
113 const newVilleData = villes[i] + ';' + content.name + ';' + content.main.temp + ';' + content.main.temp_max + ';' + content.main.temp_min + ';' + content.weather[0].main + ';' + image;
114 updatedVilleData[updatedVilleData.length] = newVilleData;
115 this.setState({
116 villeData: updatedVilleData
117 });
118 }, (error) => {
119 console.log(error);
120 });
121 }
122 }
123
124 this.setState({ username, nbVilles });
125
126
127 }, (error) => {
128 console.log(error);
129 })
130
131 const themeStorage = localStorage.getItem("theme");
132 if (themeStorage) {
133 this.setState({ theme: themeStorage });
134 }
135
136 }
137
138 openModal() {
139 this.setState({ open: true });
140 }
141 closeModal() {
142 this.setState({ open: false });
143 }
144
145 setTheme(data) {
146 this.setState({ theme: data });
147 localStorage.setItem("theme", data);
148 }
149
150 render() {
151 const { villeData, username, tabVilles, nbVilles, theme } = this.state;
152 //récupération des données météos
153 let nameDB = [];
154 let name = [];
155 let temp = [];
156 let tempMax = [];
157 let tempMin = [];
158 let etat = [];
159 let image = [];
160 for (let i in villeData.sort()) {
161
162 let data = villeData[i].split(';');
163 nameDB.push(data[0]);
164 name.push(data[1]);
165 temp.push(data[2]);
166 tempMax.push(data[3]);
167 tempMin.push(data[4]);
168 etat.push(data[5]);
169 image.push(data[6] + this.state.theme + '.png');
170 }
171
172 async function rmvCity(city) {
173 if (!city || city.length === 0) {
174 return;
175 }
176 const token = localStorage.getItem("token");
177 await API.rmvCity(city, token);
178 window.location.href = "/dash";
179 };
180
181 const settingsSlide = {
182 focusOnSelect: true,
183 dots: true,
184 infinite: true,
185 speed: 500,
186 slidesToShow: 3,
187 slidesToScroll: 1,
188 centerMode: true,
189 };
190
191 function Villes() {
192 if (nbVilles > 3) {
193 return (
194 <div className="col">
195 <Slider {...settingsSlide}>
196 {
197 name.map((data, i, callback) => {
198 return (
199 <div className="col-smcard style2 border rounded shadow-lg p-3 mb-3" key={i}>
200 <img className="card-img-top" src={image[i]} alt="meteo" />
201 <div className="card-body">
202 <h5 className="card-title text-center">{name[i]}</h5>
203 <p className="card-text text-center">{etat[i]}</p>
204 <p className="card-text text-center">température actuelle : {temp[i]} °C</p>
205 <div className="row">
206 <div className="col">
207 Température Max : {tempMax[i]} °C
208 </div>
209 <div className="col">
210 Température Min : {tempMin[i]} °C
211 </div>
212 </div>
213 <br />
214 <div className="row justify-content-md-center">
215 <Link to={`meteo#${nameDB[i]}`} style={{ textDecoration: "none", color: "#FFF" }}><button type="button" className="btn btn-success" >Détails</button></Link>
216      
217 <button type="button" className="btn btn-danger" onClick={() => { rmvCity(nameDB[i]) }}>Supprimer</button>
218 </div>
219
220 </div>
221 </div>
222 )
223
224 })
225 }
226 </Slider>
227 </div>
228 );
229 } else {
230 return (
231 name.map((data, i, callback) => {
232
233 return (
234 <div className="col-smcard style2 border rounded shadow-lg p-3 mb-3" key={i}>
235 <img className="card-img-top" src={image[i]} alt="meteo" />
236 <div className="card-body">
237 <h5 className="card-title text-center">{data}</h5>
238 <p className="card-text text-center">{etat[i]}</p>
239 <p className="card-text text-center">température actuelle : {temp[i]} °C</p>
240 <div className="row">
241 <div className="col">
242 Température Max : {tempMax[i]} °C
243 </div>
244 <div className="col">
245 Température Min : {tempMin[i]} °C
246 </div>
247 </div>
248 <br />
249 <div className="row justify-content-md-center">
250 <Link to={`meteo#${nameDB[i]}`} style={{ textDecoration: "none", color: "#FFF" }}><button type="button" className="btn btn-success" >Détails</button></Link>
251      
252 <button type="button" className="btn btn-danger" onClick={() => { rmvCity(nameDB[i]) }}>Supprimer</button>
253 </div>
254
255 </div>
256 </div>
257 )
258
259 })
260 )
261 }
262
263 }
264
265 const toggleTheme = () => {
266 if (theme === 'light') {
267 this.setTheme('dark');
268 } else {
269 this.setTheme('light');
270 }
271 }
272
273 const themeInverse = () => {
274 if (theme === 'light') {
275 return 'dark';
276 } else {
277 return 'light';
278 }
279 }
280
281 return (
282 <ThemeProvider theme={theme === 'light' ? lightTheme : darkTheme}>
283 <GlobalStyles />
284 <div className="Dash">
285
286 <div className="rounded-0">
287 <NavBar
288 username={username}
289 theme={theme}
290 />
291 </div>
292
293 <div className="container">
294 <div className="row justify-content-md-center">
295 <div className="col-md-auto">
296
297 <div className="text-center ">
298
299 <button className="btn btn-primary btn border rounded shadow-lg p-3 mb-3" onClick={this.openModal}>
300 Rechercher/Ajouter une Ville
301 </button>
302 <br /><br />
303 <Popup
304 open={this.state.open}
305 closeOnDocumentClick
306 onClose={this.closeModal}
307 >
308 <Row className="justify-content-md-center">
309 <Col md="auto">
310 <br />
311 <div className={"card style1 text-center bg-" + theme}>
312 <div className="card-body">
313 <h5 className="card-title text-center">Rechercher/Ajouter une Ville</h5>
314 <Autocomplete suggestions={tabVilles} theme={theme} />
315 </div>
316 </div>
317 <br />
318 </Col>
319 </Row>
320 </Popup>
321 </div>
322 <div className="text-center ">
323 <div className="row ">
324
325 <Villes />
326
327 </div>
328 <br /><br /><br />
329 <button type="button" className={"btn btn-outline-" + themeInverse()} onClick={toggleTheme}>Switch Theme</button>
330 </div>
331 </div>
332 </div>
333 </div>
334 </div>
335 </ThemeProvider>
336 );
337 }
338}