Skip to content
This repository was archived by the owner on Nov 19, 2023. It is now read-only.

UI overhaul #16

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# IDE
.vscode
*.code-workspace
15 changes: 15 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"@testing-library/user-event": "^13.5.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-icons": "^4.7.1",
"react-scripts": "5.0.1",
"web-vitals": "^2.1.4"
},
Expand Down
67 changes: 32 additions & 35 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,25 @@
import React, { useCallback } from 'react';
import { useState, useEffect } from 'react';
import React, { useCallback } from "react";
import { useState, useEffect } from "react";

import Weather from './components/Weather';
import LoadingIndicator from './UI/LoadingIndicator';
import Weather from "./components/Weather";
import LoadingIndicator from "./UI/LoadingIndicator";
import { BsFillGeoAltFill } from "react-icons/bs";

import './app.css';
import "./app.css";

function App() {
const [data, setData] = useState(null);
const [place, setPlace] = useState(null);
const [search, setSearch] = useState('');
const [location, setLocation] = useState('');
const [search, setSearch] = useState("");
const [location, setLocation] = useState("");
const [isLoading, setIsLoading] = useState(false);

function handleSearch(e) {
setSearch(e.target.value);
}

async function geoHandler() {
setSearch('');
setSearch("");
setIsLoading(true);
await navigator.geolocation.getCurrentPosition((position) => {
const crd = position.coords;
Expand All @@ -30,10 +31,10 @@ function App() {

const fetchData = useCallback(async (search, location) => {
const options = {
method: 'GET',
method: "GET",
headers: {
'X-RapidAPI-Key': '0173291af0msh62b3ca25953f210p13d732jsn66b4d9f97708',
'X-RapidAPI-Host': 'weatherapi-com.p.rapidapi.com',
"X-RapidAPI-Key": "0173291af0msh62b3ca25953f210p13d732jsn66b4d9f97708",
"X-RapidAPI-Host": "weatherapi-com.p.rapidapi.com",
},
};
const url = `https://weatherapi-com.p.rapidapi.com/current.json?q=${
Expand All @@ -52,34 +53,30 @@ function App() {
});
}, [location, search, fetchData]);

let display = data ? (
<Weather place={place} data={data} />
) : (
<p>no data found 😬</p>
);

return (
<>
<div className="container">
<h1>WEATHER APPLICATION</h1>
<div className="search-sec">
<input
type="text"
value={search}
placeholder="Search by City..."
onChange={handleSearch}
/>
</div>
<div>
<p>or</p>
</div>
<div>
<button onClick={geoHandler}>Find me!</button>
<div className="widget-wrapper">
<div className="weather-header">
<h1>WEATHER</h1>
{isLoading && <LoadingIndicator />}
</div>
<div className="search-sec">
<input
type="text"
value={search}
placeholder="Search by City..."
onChange={handleSearch}
className="city-search"
/>
<button onClick={geoHandler} className="find-me-btn">
<BsFillGeoAltFill size={18} />
</button>
</div>
<br />
<br />
{<Weather place={place} data={data} />}
</div>
<br />
<br />
{isLoading && <LoadingIndicator />}
{display}
</div>
<span className="credit">Ranvir@zetabug/github</span>
</>
Expand Down
13 changes: 7 additions & 6 deletions src/UI/LoadingIndicator.css
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
.lds-ring {
display: inline-block;
position: relative;
width: 54px;
height: 54px;
width: 25px;
height: 25px;
margin-left:10px
}
.lds-ring div {
box-sizing: border-box;
display: block;
position: absolute;
width: 44px;
height: 44px;
width: 20px;
height: 20px;
margin: 6px;
border: 6px solid #ff2058;
border: 6px solid #ffffff;
border-radius: 50%;
animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
border-color: #ff2058 transparent transparent transparent;
border-color: #ffffff transparent transparent transparent;
}
.lds-ring div:nth-child(1) {
animation-delay: -0.45s;
Expand Down
76 changes: 57 additions & 19 deletions src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,61 @@
font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
}
h1 {
text-align: center;
margin-top: 3rem;
font-size: 24pt;
margin-bottom: 5px;
}
.container {
height: 100vh;
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
gap: 2rem;
align-items: center;
justify-content: center;
}
input {
outline: none;
border: 1px solid black;
width: 300px;
height: 30px;
padding: 4px;
color: #000;

.widget-wrapper {
border: 3px solid #fff;
color: #fff;
display: flex;
flex-direction: column;
border-radius: 10px;
padding-left: 30px;
padding-right: 30px;
padding-top: 10px;
padding-bottom: 10px;
background-size: 300% 300%;
background-image: linear-gradient(
-45deg,
rgb(35, 193, 103) 0%,
rgb(0, 190, 57) 25%,
rgb(75, 96, 255) 51%,
rgb(2, 0, 27) 100%
);
animation: AnimateBG 5s ease infinite;
box-shadow: rgba(0, 0, 0, 0.25) 0px 14px 28px, rgba(0, 0, 0, 0.22) 0px 10px 10px;
}

@keyframes AnimateBG {
0%{background-position: 0% 50%}
50%{background-position:100% 50%}
100%{background-position:0% 50%}
}

img {
height: 100px;
.weather-header {
display: inline-flex;
}

.city-search {
outline: none;
border: 1px solid #fff;
flex-grow: 1;
min-width: 200px;
height: 30px;
padding: 6px;
color: #fff;
border-radius: 7px;
background-color: transparent;
}
.credit {
position: fixed;
Expand All @@ -39,14 +72,19 @@ img {
p {
font-size: 2rem;
}

button {
.search-sec {
display: flex;
}
.find-me-btn {
cursor: pointer;
background-color: transparent;
border: 1px solid #8a2b06;
padding: 0.5rem 2rem;
border-radius: 25px;
margin-left: 1rem;
font-family: 'Courier New', Courier, monospace;
font-weight: bold;
padding: 1px 5px;
border-radius: 7px;
margin-left: 10px;
transition: all .2s;
color: #8a2b06;
}
.find-me-btn:hover {
transform: scale(1.1);
}
35 changes: 30 additions & 5 deletions src/components/Weather.css
Original file line number Diff line number Diff line change
@@ -1,10 +1,35 @@
.output-sec {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.8rem;
font-size: 1.5rem;
margin-top: 5px;
position: relative;
background: radial-gradient();
}
.output-sec .location {
text-transform: uppercase;

.status-img {
width: 60px;
aspect-ratio: 1/1;
position: absolute;
bottom: 0;
right: 0;
padding: 0;
margin: 0;
}

.location {
border-bottom: 1px solid #fff;
padding-bottom: 5px;
margin-bottom: 5px;
}

p:nth-child(1) {
overflow: hidden;
white-space: nowrap;
max-width: 250px;
text-overflow: ellipsis;
font-size: 16pt;
}

p:nth-child(2) {
font-size: 12pt;
}
32 changes: 22 additions & 10 deletions src/components/Weather.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,28 @@
import './Weather.css';
import "./Weather.css";

const Weather = (props) => {
return (
<div className="output-sec">
<div className="location">
{props.place.name}, {props.place.region}
</div>
<img src={props.data.condition.icon} alt="" />
<div className="sky-status">{props.data.condition.text}</div>
<div className="temp">Temperature : {props.data.temp_c}°C</div>
<div className="humidity">Humidity : {props.data.humidity}</div>
</div>
<>
{props.data && props.place ? (
<div className="output-sec">
<div className="location">
<p title={props.place.name}>{props.place.name}</p>
<p>{props.place.region}</p>
</div>
<img className="status-img" src={props.data.condition.icon} alt="" />
<div className="sky-status">{props.data.condition.text}</div>
<div className="temp">Temperature : {props.data.temp_c}°C</div>
<div className="humidity">Humidity : {props.data.humidity}</div>
</div>
) : (
<div className="output-sec">
<div className="location">Please enter a city...</div>
<div className="sky-status">N/A</div>
<div className="temp">Temperature : -999°C</div>
<div className="humidity">Humidity : 0%</div>
</div>
)}
</>
);
};

Expand Down