Files
weather-app/frontend/src/components/WeatherForm.tsx

83 lines
2.7 KiB
TypeScript

import React from "react";
import { useState } from "react";
import { fetchWeather } from "../utils/apiFunc";
import Cookies from "js-cookie";
import { toast } from "react-toastify";
import WeatherData from "./WeatherData";
import { useEffect } from "react";
const WeatherCard: React.FC = () => {
const [city, setCity] = useState("");
const [loading, setLoading] = useState(false);
const [weatherData, setWeatherData] = useState(false);
console.log(loading); // only for better reading because a syntax error would appear
const getAPIKey = () => Cookies.get("apiKey") || "";
const handleCityChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setCity(event.target.value);
};
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
setLoading(true);
toast
.promise(fetchWeather(city, getAPIKey(), "metric"), {
pending: "Fetching weather data...",
success: "Weather data loaded successfully!",
error: "Error loading weather data! (Check console for details)",
})
.then(() => {
if (localStorage.getItem("weather")) {
setWeatherData(true);
} else {
setWeatherData(false);
}
setLoading(false);
});
};
// Check if weather data is already in localStorage - when entering the page via URL/reload
useEffect(() => {
if (localStorage.getItem("weather")) {
setWeatherData(true);
} else {
setWeatherData(false);
}
}, []);
return (
<div className="w-full max-w-lg mx-auto bg-white/80 rounded-2xl shadow-xl p-8 mt-8">
<h2 className="text-3xl font-bold mb-4 text-blue-700 flex items-center gap-2">
Weather
</h2>
<p className="mb-2 text-gray-600">
Current weather will be displayed here.
</p>
<form onSubmit={handleSubmit} className="flex flex-col gap-4 mt-4">
<label htmlFor="city" className="font-medium text-gray-700">
Enter City:
</label>
<input
type="text"
id="city"
name="city"
onChange={handleCityChange}
value={city}
placeholder="City Name"
required
className="border border-blue-300 rounded-xl px-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-400 bg-blue-50 text-blue-900 font-mono"
/>
<button
type="submit"
className="bg-gradient-to-r from-blue-600 to-blue-400 text-white font-bold px-6 py-3 rounded-xl shadow-lg hover:from-blue-700 hover:to-blue-500 transition-all"
>
Get Weather
</button>
</form>
{weatherData && <WeatherData />}
</div>
);
};
export default WeatherCard;