feat: enhance weather fetching experience with loading state and notifications
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user