Skip to content

Commit

Permalink
Weather app project (take the whole day)
Browse files Browse the repository at this point in the history
  • Loading branch information
No0ne003 committed May 17, 2024
1 parent 742d263 commit 46f0906
Show file tree
Hide file tree
Showing 5 changed files with 207 additions and 8 deletions.
6 changes: 4 additions & 2 deletions src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { lazy, Suspense, useState } from "react";
import { ThemeProvider } from "@/components/theme-provider";
import { Link, Route, Routes, useNavigate } from "react-router-dom";
import { Route, Routes } from "react-router-dom";
import { useLocation } from "react-router-dom";
// layout
import Header from "@/layouts/header";
Expand Down Expand Up @@ -48,6 +48,7 @@ const UseWindowResizeTest = lazy(
() => import("./pages/CustomHooks/use-window-resize/test"),
);
const ScrollToSection = lazy(() => import("./pages/ScrollToSection"));
const WeatherApp = lazy(() => import("@/pages/Weather-app/index"));

function App() {
const [cursorVariant, setCursorVariant] = useState("default");
Expand All @@ -66,7 +67,7 @@ function App() {

<Header setCursorVariant={setCursorVariant} />
{location.pathname !== "/React-Projects/" && <GoBack />}
<Suspense fallback={<Loading />}>
<Suspense fallback={<div className="absolute flex justify-center items-center m-auto inset-0"><Loading /></div>}>
<Routes>
<Route path="React-Projects">
<Route
Expand Down Expand Up @@ -120,6 +121,7 @@ function App() {
path="scroll-to-particular-section"
element={<ScrollToSection />}
/>
<Route path="weather-app" element={<WeatherApp />} />
<Route path="*" element={<NotFound />} />
</Route>
</Routes>
Expand Down
21 changes: 21 additions & 0 deletions src/components/Search.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Button } from "./ui/button";
import { Input } from "./ui/input";

const Search = ({ search, setSearch, handleSearch }) => {
return (
<div className="w-full flex justify-center items-center gap-4">
<Input
type="text"
placeholder="Enter City Name"
name="search"
value={search}
onChange={(event) => setSearch(event.target.value)}
/>
<Button onClick={handleSearch} disabled={search === "" ? true : false}>
Search
</Button>
</div>
);
};

export default Search;
7 changes: 1 addition & 6 deletions src/components/ui/Loading.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@

const Loading = () => {
return (
<div className="absolute inset-0 m-auto flex justify-center items-center">
<div className="loader"></div>
</div>
);
return <div className="loader"></div>;
};

export default Loading;
12 changes: 12 additions & 0 deletions src/data/projects.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const projects = [
id: 2,
name: "Random Color Generator",
path: "color-generator",
tags: ['project']
},
{
id: 3,
Expand All @@ -23,6 +24,7 @@ export const projects = [
id: 5,
name: "Load More Button",
path: "load-more-data",
tags: ['project']
},
{
id: 6,
Expand All @@ -33,6 +35,7 @@ export const projects = [
id: 7,
name: "QR Code Generator",
path: "qr-code-generator",
tags: ['project']
},
{
id: 8,
Expand All @@ -53,6 +56,7 @@ export const projects = [
id: 11,
name: "Github Profile Finder",
path: "github-profile-finder",
tags: ['project']
},
{
id: 12,
Expand All @@ -63,6 +67,7 @@ export const projects = [
id: 13,
name: "Tic Tac Toe",
path: "tic-tac-toe",
tags: ['project']
},
{
id: 14,
Expand Down Expand Up @@ -91,5 +96,12 @@ export const projects = [
id: 18,
name: 'Scroll to particular section',
path: 'scroll-to-particular-section',
tags: ['project'],
},
{
id: 19,
name: 'Weather App',
path: 'weather-app',
tags: ['project']
}
];
169 changes: 169 additions & 0 deletions src/pages/Weather-app/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
import Search from "@/components/Search";
import Loading from "@/components/ui/Loading";
import { useEffect, useState } from "react";
import { FaCloud } from "react-icons/fa";
import { FaMapPin, FaWind } from "react-icons/fa6";
import { WiHumidity } from "react-icons/wi";

const WeatherApp = () => {
const [search, setSearch] = useState("");
const [loading, setLoading] = useState(false);
const [weatherData, setWeatherData] = useState(null);

async function fetchWeatherData(param) {
setLoading(true);
try {
const response = await fetch(
`https://api.openweathermap.org/data/2.5/weather?q=${param}&appid=4910fb3e9fe1947b8ae9b22b46fc8d37`,
);

const data = await response.json();

if (data) {
setWeatherData(data);
setLoading(false);
}
} catch (e) {
setLoading(false);
console.log(e);
}
}

function handleSearch() {
fetchWeatherData(search);
}

function getCurrentDate() {
return new Date().toLocaleDateString("en-us", {
weekday: "long",
month: "long",
day: "numeric",
year: "numeric",
});
}

useEffect(() => {
fetchWeatherData("marrakech");
}, []);

console.log(weatherData);

return (
<div className="container flex flex-col justify-start items-center gap-5 py-10 w-fit bg-secondary/40 aspect-[3/2]">
<Search
search={search}
setSearch={setSearch}
handleSearch={handleSearch}
/>
{loading ? (
<LoadingMsg />
) : weatherData?.cod === "404" && weatherData?.message ? (
<ErrorMsg />
) : (
<div className="flex flex-col justify-center items-center gap-7 w-full">
<div className="flex justify-between w-full">
<div className="flex flex-col gap-6 px-2">
<div>
<h2 className="flex gap-2 justify-center items-center">
<FaMapPin className="text-sm" />
{weatherData?.name}, <span>{weatherData?.sys?.country}</span>
</h2>
<span className="text-xs text-foreground/80">
{getCurrentDate()}
</span>
</div>

<div className="flex flex-col">
<div className="text-4xl font-semibold">
{weatherData?.main?.temp}
</div>
<p className="flex justify-start items-center text-xs text-foreground/80">
<span>
<img
className="w-7 grayscale"
src={
weatherData &&
weatherData.weather &&
weatherData.weather[0]
? `http://openweathermap.org/img/w/${weatherData.weather[0].icon}.png`
: null
}
alt={
weatherData &&
weatherData.weather &&
weatherData.weather[0]
? weatherData.weather[0].description
: null
}
/>
</span>
{weatherData && weatherData.weather && weatherData.weather[0]
? weatherData.weather[0].description
: null}
</p>
</div>
</div>

<div className="flex flex-col justify-center items-center">
<p>
{weatherData && weatherData.weather && weatherData.weather[0]
? weatherData.weather[0].description
: null}
</p>
<div>
<img
className="w-32"
src={
weatherData && weatherData.weather && weatherData.weather[0]
? `http://openweathermap.org/img/w/${weatherData.weather[0].icon}.png`
: null
}
alt={
weatherData && weatherData.weather && weatherData.weather[0]
? weatherData.weather[0].description
: null
}
/>
</div>
</div>
</div>

<div className="w-full flex justify-evenly items-center">
<div className="flex justify-center items-cetner gap-3 py-1 px-2 bg-secondary rounded-lg">
<FaWind size={20} />
<p>{weatherData?.wind?.speed} km/h</p>
</div>
<div className="flex justify-center items-cetner gap-3 py-1 px-2 bg-secondary rounded-lg">
<WiHumidity size={25} />
<p>{weatherData?.main?.humidity}%</p>
</div>
<div className="flex justify-center items-cetner gap-3 py-1 px-2 bg-secondary rounded-lg">
<FaCloud size={20} />
<p>{weatherData?.clouds?.all}%</p>
</div>
</div>
</div>
)}
</div>
);
};

const ErrorMsg = () => {
return (
<div className="text-4xl flex justify-center items-center w-full h-full">
<p>
City Not <span className="text-destructive font-bold">Found</span>
</p>
</div>
);
};

const LoadingMsg = () => {
return (
<div className="w-full inset-0 m-auto flex justify-center items-center">
<Loading />
</div>
);
};

export default WeatherApp;

0 comments on commit 46f0906

Please sign in to comment.