/
Ponpon1228
/
Project
Обзор
Документация
Войти
/
Ponpon1228
/
Project
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
src/App.js
133 строки
5 KB
xomimishka
Initial commit
24 ноя 2025, 15:54
24 ноя 2025, 15:54
d23c86f
Код
Авторство
О чём код?
import React, { useState } from "react"; import axios from "axios"; import "./App.scss"; export default function App() { const [q, setQ] = useState(""); const [foundCities, setFoundCities] = useState([]); const [candidates, setCandidates] = useState([]); const [forecast, setForecast] = useState(null); const [error, setError] = useState(""); const [loading, setLoading] = useState(false); const searchCity = async () => { setError(""); setFoundCities([]); setCandidates([]); setForecast(null); if (!q.trim()) { setError("Введите название города"); return; } try { const res = await axios.get(`http://localhost:5000/find-city?name=${encodeURIComponent(q.trim())}`); if (res.data.status === "single") { await loadForecast(res.data.city.id); return; } if (res.data.status === "multiple") { setFoundCities(res.data.cities); return; } setCandidates(res.data.candidates || []); if ((res.data.candidates || []).length === 0) { setError("Город не найден. Можете попробовать другое написание."); } } catch (err) { console.error(err); setError("Ошибка поиска города"); } }; const addCandidate = async (cand) => { setError(""); setLoading(true); try { const res = await axios.post("http://localhost:5000/add-city", cand); await loadForecast(res.data.id); setCandidates([]); } catch (err) { console.error(err); setError(err.response?.data?.error || "Ошибка добавления города"); } finally { setLoading(false); } }; const selectDbCity = async (id) => { await loadForecast(id); setFoundCities([]); }; const loadForecast = async (id) => { setError(""); setLoading(true); setForecast(null); try { const res = await axios.get(`http://localhost:5000/forecast?id=${id}`); setForecast(res.data); } catch (err) { console.error(err); setError(err.response?.data?.error || "Ошибка получения прогноза"); } finally { setLoading(false); } }; return ( <div className="App"> <h1>Прогноз погоды</h1> <div className="input-group"> <input className="city-input" value={q} onChange={(e) => setQ(e.target.value)} placeholder="Введите город" /> <button className="fetch-btn" onClick={searchCity}>Найти</button> </div> {error && <p className="error-msg">{error}</p>} {loading && <p>Загрузка...</p>} {foundCities.length > 0 && ( <div className="city-list"> <p>Найдено несколько вариантов — выберите:</p> {foundCities.map((c) => ( <button key={c.id} onClick={() => selectDbCity(c.id)} className="city-choose"> {c.name}, {c.country} </button> ))} </div> )} {candidates.length > 0 && ( <div className="candidates"> <p>Найдено в сервисе (выберите, чтобы добавить в базу):</p> {candidates.map((c, idx) => ( <div key={idx} className="candidate-row"> <div> <strong>{c.name}</strong>, {c.country} — ({c.lat.toFixed(2)}, {c.lon.toFixed(2)}) </div> <button onClick={() => addCandidate(c)}>Добавить и показать</button> </div> ))} </div> )} {forecast && ( <div className="current-weather"> <h2>{forecast.city.name}, {forecast.city.country}</h2> <img src={`https:${forecast.forecast.icon}`} alt={forecast.forecast.condition_text} /> <p className="weather-title">{forecast.forecast.condition_text}</p> <div className="weather-info"> <p><strong>Температура:</strong> {forecast.forecast.temperature?.toFixed(1) ?? "—"}°C</p> <p><strong>Ощущается как:</strong> {forecast.forecast.feels_like?.toFixed(1) ?? "—"}°C</p> <p><strong>Влажность:</strong> {forecast.forecast.humidity?.toFixed(0) ?? "—"}%</p> <p><strong>Ветер:</strong> {forecast.forecast.wind_speed?.toFixed(1) ?? "—"} м/с ({forecast.forecast.wind_dir ?? "—"})</p> <p><strong>Облачность:</strong> {forecast.forecast.cloud?.toFixed(0) ?? "—"}%</p> <p><strong>Видимость:</strong> {forecast.forecast.visibility?.toFixed(1) ?? "—"} км</p> <p><strong>Давление:</strong> {forecast.forecast.pressure ?? "—"} мб</p> <p><strong>Осадки:</strong> {forecast.forecast.precip ?? "—"} мм</p> <p><strong>UV индекс:</strong> {forecast.forecast.uv ?? "—"}</p> </div> </div> )} </div> ); }