add react-toastify for notifications and implement weather fetching functionality

This commit is contained in:
2025-07-27 13:33:54 +02:00
parent a1f4de1a8b
commit 5f514d4578
8 changed files with 97 additions and 5 deletions

View File

@@ -1,4 +1,5 @@
import "./App.css";
import "react-toastify/dist/ReactToastify.css";
import Layout from "./Layout/Layout.tsx";
import WeatherCard from "./components/WeatherCard";

View File

@@ -1,5 +1,6 @@
import React from "react";
import Header from "../components/Header";
import { ToastContainer } from "react-toastify";
type LayoutProps = {
children: React.ReactNode;
@@ -7,8 +8,9 @@ type LayoutProps = {
const Layout: React.FC<LayoutProps> = ({ children }) => {
return (
<div className="flex flex-col min-h-screen bg-gradient-to-br from-blue-50 via-blue-100 to-blue-200 dark:from-gray-900 dark:via-gray-950 dark:to-gray-900">
<div>
<Header />
<ToastContainer />
<main>{children}</main>
</div>
);

View File

@@ -7,6 +7,7 @@ const Header: React.FC = () => {
if (apiKey) {
Cookies.set("apiKey", apiKey);
}
console.log(Cookies.get("apiKey"));
};
return (
<header>

View File

@@ -1,17 +1,40 @@
import React from "react";
import { useState } from "react";
import { fetchWeather } from "../utils/apiFunc";
import Cookies from "js-cookie";
const WeatherCard: React.FC = () => {
const [city, setCity] = useState("");
const apiKey = Cookies.get("apiKey") || "";
const handleCityChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setCity(event.target.value);
};
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
fetchWeather(city, apiKey);
};
const WeaatherCard: React.FC = () => {
return (
<div>
<h2>Weather Card</h2>
<p>Current Weather will be displayed here</p>
<form action="" method="post">
<form onSubmit={handleSubmit}>
<label htmlFor="city">Enter City:</label>
<input type="text" id="city" name="city" placeholder="City Name" />
<input
type="text"
id="city"
name="city"
onChange={handleCityChange}
value={city}
placeholder="City Name"
required
/>
<button type="submit">Get Weather</button>
</form>
</div>
);
};
export default WeaatherCard;
export default WeatherCard;

View File

@@ -0,0 +1,24 @@
import { myToast } from "./toastify";
export const fetchWeather = async (city: string, apiKey: string) => {
// Get location data
const location = await fetch(
`http://api.openweathermap.org/geo/1.0/direct?q=${city}&appid=${apiKey}`
).then((response) => {
if (response.status === 401) {
myToast("Request Failed! Check API key and city name.", "error");
throw new Error("Network response was not ok");
} else if (response.ok) {
return response.json();
}
});
const lat = location[0].lat;
const lon = location[0].lon;
// Get weather data
const weather = await fetch(
`https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${apiKey}`
).then((response) => response.json());
console.log(weather);
myToast("Successfully fetched weather data", "success");
};

View File

@@ -0,0 +1,17 @@
import { toast, type ToastOptions } from "react-toastify";
export type ToastType = "success" | "error" | "info" | "warning";
export const myToast = (message: string, msgType: ToastType) => {
let config: ToastOptions = {
position: "top-right",
autoClose: 5000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
theme: "dark",
};
toast[msgType](message, config);
};