feat: enhance weather fetching experience with loading state and notifications

This commit is contained in:
2025-07-29 23:40:24 +02:00
parent bf8c270171
commit dcfbbb2f22
7 changed files with 47 additions and 12 deletions
+10 -2
View File
@@ -1,11 +1,12 @@
import { useState } from "react";
import React from "react";
import { changeAPIcookie } from "../utils/changeAPIcookie";
interface Props {
currentAPIKey: string;
}
function ChangeAPI({ currentAPIKey }: Props) {
const ChangeAPI: React.FC<Props> = ({ currentAPIKey }) => {
const [apiKey, setApiKey] = useState(currentAPIKey);
return (
@@ -14,6 +15,13 @@ function ChangeAPI({ currentAPIKey }: Props) {
<p className="mb-6 text-gray-600">
Update your API key to fetch weather data.
</p>
<p className="mb-6 text-gray-600">
We are using{" "}
<a href="https://openweathermap.org/api">
<strong>OpenWeatherMap</strong>
</a>{" "}
API for fetching weather data.
</p>
<form className="flex flex-col gap-4">
<label htmlFor="apiKey" className="font-medium text-gray-700">
API Key:
@@ -38,6 +46,6 @@ function ChangeAPI({ currentAPIKey }: Props) {
</form>
</div>
);
}
};
export default ChangeAPI;
+1 -1
View File
@@ -21,7 +21,7 @@ const Header: React.FC = () => {
</button>
</header>
{apiCard && (
<div className="fixed inset-0 bg-black bg-opacity-40 flex items-center justify-center z-50">
<div className="fixed inset-0 bg-gray-800 bg-opacity-40 flex items-center justify-center z-50">
<div className="bg-white rounded-xl shadow-lg p-8 w-full max-w-md relative">
<button
className="absolute top-4 right-4 text-gray-400 hover:text-blue-600 text-xl"
+15
View File
@@ -0,0 +1,15 @@
import React from "react";
interface Props {
message: string;
}
const IsLoading: React.FC<Props> = ({ message }) => {
return (
<div>
<p>{message}</p>
</div>
);
};
export default IsLoading;
+12 -2
View File
@@ -2,18 +2,27 @@ import React from "react";
import { useState } from "react";
import { fetchWeather } from "../utils/apiFunc";
import Cookies from "js-cookie";
import IsLoading from "./IsLoading";
import { toast } from "react-toastify";
const WeatherCard: React.FC = () => {
const [city, setCity] = useState("");
const [loading, setLoading] = useState(false);
const getAPIKey = () => Cookies.get("apiKey") || "";
const handleCityChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setCity(event.target.value);
};
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
fetchWeather(city, getAPIKey());
setLoading(true);
toast.promise(fetchWeather(city, getAPIKey()), {
pending: "Fetching weather data...",
success: "Weather data loaded successfully!",
error: "Error loading weather data!",
});
setLoading(false);
};
return (
@@ -33,6 +42,7 @@ const WeatherCard: React.FC = () => {
/>
<button type="submit">Get Weather</button>
</form>
{loading && <IsLoading message="Loading weather data..." />}
</div>
);
};