├── .env ├── .eslintrc.cjs ├── .gitignore ├── index.html ├── package-lock.json ├── package.json ├── postcss.config.js ├── public └── vite.svg ├── src ├── App.css ├── App.jsx ├── Components │ ├── BackgroundLayout.jsx │ ├── MiniCard.jsx │ ├── WeatherCard.jsx │ └── index.jsx ├── Context │ └── index.jsx ├── Utils │ └── useDate.jsx ├── assets │ ├── icons │ │ ├── cloud.png │ │ ├── fog.png │ │ ├── rain.png │ │ ├── search.svg │ │ ├── snow.png │ │ ├── storm.png │ │ ├── sun.png │ │ └── windy.png │ └── images │ │ ├── Clear.jpg │ │ ├── Cloudy.jpg │ │ ├── Rainy.jpg │ │ ├── Stormy.jpg │ │ ├── Sunny.jpg │ │ ├── fog.png │ │ └── snow.jpg ├── index.css └── main.jsx ├── tailwind.config.js └── vite.config.js /.env: -------------------------------------------------------------------------------- 1 | VITE_API_KEY=62692b25f8msh8f66a03f0c092cdp17e96fjsn18fc2f27db3a -------------------------------------------------------------------------------- /.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { browser: true, es2020: true }, 3 | extends: [ 4 | 'eslint:recommended', 5 | 'plugin:react/recommended', 6 | 'plugin:react/jsx-runtime', 7 | 'plugin:react-hooks/recommended', 8 | ], 9 | parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }, 10 | settings: { react: { version: '18.2' } }, 11 | plugins: ['react-refresh'], 12 | rules: { 13 | 'react-refresh/only-export-components': 'warn', 14 | }, 15 | } 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + React 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "weather-app", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "vite build", 9 | "lint": "eslint src --ext js,jsx --report-unused-disable-directives --max-warnings 0", 10 | "preview": "vite preview" 11 | }, 12 | "dependencies": { 13 | "axios": "^1.4.0", 14 | "react": "^18.2.0", 15 | "react-dom": "^18.2.0" 16 | }, 17 | "devDependencies": { 18 | "@types/react": "^18.0.37", 19 | "@types/react-dom": "^18.0.11", 20 | "@vitejs/plugin-react": "^4.0.0", 21 | "autoprefixer": "^10.4.14", 22 | "eslint": "^8.38.0", 23 | "eslint-plugin-react": "^7.32.2", 24 | "eslint-plugin-react-hooks": "^4.6.0", 25 | "eslint-plugin-react-refresh": "^0.3.4", 26 | "postcss": "^8.4.24", 27 | "tailwindcss": "^3.3.2", 28 | "vite": "^4.3.9" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /public/vite.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myprojectideas/Weather_application/0e8159d28b8d422c80cdb6ec21b14b18213df564/src/App.css -------------------------------------------------------------------------------- /src/App.jsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react' 2 | import './App.css' 3 | import search from './assets/icons/search.svg' 4 | import { useStateContext } from './Context' 5 | import { BackgroundLayout, WeatherCard, MiniCard } from './Components' 6 | 7 | function App() { 8 | 9 | const [input, setInput] = useState('') 10 | const { weather, thisLocation, values, place, setPlace } = useStateContext() 11 | // console.log(weather) 12 | 13 | const submitCity = () => { 14 | setPlace(input) 15 | setInput('') 16 | } 17 | 18 | return ( 19 |
20 | 32 | 33 |
34 | 43 | 44 |
45 | { 46 | values?.slice(1, 7).map(curr => { 47 | return ( 48 | 54 | ) 55 | }) 56 | } 57 |
58 |
59 |
60 | ) 61 | } 62 | 63 | export default App 64 | -------------------------------------------------------------------------------- /src/Components/BackgroundLayout.jsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState } from 'react' 2 | import { useStateContext } from '../Context' 3 | //images 4 | import Clear from '../assets/images/Clear.jpg' 5 | import Fog from '../assets/images/fog.png' 6 | import Cloudy from '../assets/images/Cloudy.jpg' 7 | import Rainy from '../assets/images/Rainy.jpg' 8 | import Snow from '../assets/images/snow.jpg' 9 | import Stormy from '../assets/images/Stormy.jpg' 10 | import Sunny from '../assets/images/Sunny.jpg' 11 | 12 | const BackgroundLayout = () => { 13 | 14 | const { weather } = useStateContext() 15 | const [image, setImage] = useState(Clear) 16 | 17 | useEffect(() => { 18 | if (weather.conditions) { 19 | let imageString = weather.conditions 20 | if (imageString.toLowerCase().includes('clear')) { 21 | setImage(Clear) 22 | } else if (imageString.toLowerCase().includes('cloud')) { 23 | setImage(Cloudy) 24 | } else if (imageString.toLowerCase().includes('rain') || imageString.toLowerCase().includes('shower')) { 25 | setImage(Rainy) 26 | } else if (imageString.toLowerCase().includes('snow')) { 27 | setImage(Snow) 28 | } else if (imageString.toLowerCase().includes('fog')) { 29 | setImage(Fog) 30 | } else if (imageString.toLowerCase().includes('thunder') || imageString.toLowerCase().includes('storm')) { 31 | setImage(Stormy) 32 | } 33 | } 34 | }, [weather]) 35 | 36 | return ( 37 | weather_image 38 | ) 39 | } 40 | 41 | export default BackgroundLayout -------------------------------------------------------------------------------- /src/Components/MiniCard.jsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/prop-types */ 2 | import React, { useEffect, useState } from 'react' 3 | import sun from '../assets/icons/sun.png' 4 | import cloud from '../assets/icons/cloud.png' 5 | import fog from '../assets/icons/fog.png' 6 | import rain from '../assets/icons/rain.png' 7 | import snow from '../assets/icons/snow.png' 8 | import storm from '../assets/icons/storm.png' 9 | import wind from '../assets/icons/windy.png' 10 | 11 | const MiniCard = ({ time, temp, iconString }) => { 12 | const [icon, setIcon] = useState() 13 | 14 | useEffect(() => { 15 | if (iconString) { 16 | if (iconString.toLowerCase().includes('cloud')) { 17 | setIcon(cloud) 18 | } else if (iconString.toLowerCase().includes('rain')) { 19 | setIcon(rain) 20 | } else if (iconString.toLowerCase().includes('clear')) { 21 | setIcon(sun) 22 | } else if (iconString.toLowerCase().includes('thunder')) { 23 | setIcon(storm) 24 | } else if (iconString.toLowerCase().includes('fog')) { 25 | setIcon(fog) 26 | } else if (iconString.toLowerCase().includes('snow')) { 27 | setIcon(snow) 28 | } else if (iconString.toLowerCase().includes('wind')) { 29 | setIcon(wind) 30 | } 31 | } 32 | }, [iconString]) 33 | return ( 34 |
35 |

36 | {new Date(time).toLocaleTimeString('en', { weekday: 'long' }).split(" ")[0]} 37 |

38 |
39 |
40 | forecast not available 41 |
42 |

{temp}°C

43 |
44 | ) 45 | } 46 | 47 | export default MiniCard -------------------------------------------------------------------------------- /src/Components/WeatherCard.jsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/prop-types */ 2 | import React, { useEffect, useState } from 'react' 3 | import { useDate } from '../Utils/useDate' 4 | import sun from '../assets/icons/sun.png' 5 | import cloud from '../assets/icons/cloud.png' 6 | import fog from '../assets/icons/fog.png' 7 | import rain from '../assets/icons/rain.png' 8 | import snow from '../assets/icons/snow.png' 9 | import storm from '../assets/icons/storm.png' 10 | import wind from '../assets/icons/windy.png' 11 | import '../index.css' 12 | 13 | const WeatherCard = ({ 14 | temperature, 15 | windspeed, 16 | humidity, 17 | place, 18 | heatIndex, 19 | iconString, 20 | conditions, 21 | }) => { 22 | 23 | const [icon, setIcon] = useState(sun) 24 | const { time } = useDate() 25 | 26 | useEffect(() => { 27 | if (iconString) { 28 | if (iconString.toLowerCase().includes('cloud')) { 29 | setIcon(cloud) 30 | } else if (iconString.toLowerCase().includes('rain')) { 31 | setIcon(rain) 32 | } else if (iconString.toLowerCase().includes('clear')) { 33 | setIcon(sun) 34 | } else if (iconString.toLowerCase().includes('thunder')) { 35 | setIcon(storm) 36 | } else if (iconString.toLowerCase().includes('fog')) { 37 | setIcon(fog) 38 | } else if (iconString.toLowerCase().includes('snow')) { 39 | setIcon(snow) 40 | } else if (iconString.toLowerCase().includes('wind')) { 41 | setIcon(wind) 42 | } 43 | } 44 | }, [iconString]) 45 | 46 | return ( 47 |
48 |
49 | weather_icon 50 |

{temperature} °C

51 |
52 |
53 | {place} 54 |
55 |
56 |

{new Date().toDateString()}

57 |

{time}

58 |
59 |
60 |

Wind Speed

{windspeed} km/h

61 |

Humidity

{humidity} gm/m³

62 |
63 |
64 |

Heat Index

65 |

{heatIndex ? heatIndex : 'N/A'}

66 |
67 |
68 |
69 | {conditions} 70 |
71 |
72 | ) 73 | } 74 | 75 | export default WeatherCard -------------------------------------------------------------------------------- /src/Components/index.jsx: -------------------------------------------------------------------------------- 1 | export {default as BackgroundLayout} from './BackgroundLayout' 2 | export {default as MiniCard} from './MiniCard' 3 | export {default as WeatherCard} from './WeatherCard' 4 | -------------------------------------------------------------------------------- /src/Context/index.jsx: -------------------------------------------------------------------------------- 1 | import { useContext, createContext, useState, useEffect } from "react"; 2 | import axios from 'axios' 3 | 4 | const StateContext = createContext() 5 | 6 | export const StateContextProvider = ({ children }) => { 7 | const [weather, setWeather] = useState({}) 8 | const [values, setValues] = useState([]) 9 | const [place, setPlace] = useState('Jaipur') 10 | const [thisLocation, setLocation] = useState('') 11 | 12 | // fetch api 13 | const fetchWeather = async () => { 14 | const options = { 15 | method: 'GET', 16 | url: 'https://visual-crossing-weather.p.rapidapi.com/forecast', 17 | params: { 18 | aggregateHours: '24', 19 | location: place, 20 | contentType: 'json', 21 | unitGroup: 'metric', 22 | shortColumnNames: 0, 23 | }, 24 | headers: { 25 | 'X-RapidAPI-Key': import.meta.env.VITE_API_KEY, 26 | 'X-RapidAPI-Host': 'visual-crossing-weather.p.rapidapi.com' 27 | } 28 | } 29 | 30 | try { 31 | const response = await axios.request(options); 32 | console.log(response.data) 33 | const thisData = Object.values(response.data.locations)[0] 34 | setLocation(thisData.address) 35 | setValues(thisData.values) 36 | setWeather(thisData.values[0]) 37 | } catch (e) { 38 | console.error(e); 39 | // if the api throws error. 40 | alert('This place does not exist') 41 | } 42 | } 43 | 44 | useEffect(() => { 45 | fetchWeather() 46 | }, [place]) 47 | 48 | useEffect(() => { 49 | console.log(values) 50 | }, [values]) 51 | 52 | return ( 53 | 60 | {children} 61 | 62 | ) 63 | } 64 | 65 | export const useStateContext = () => useContext(StateContext) -------------------------------------------------------------------------------- /src/Utils/useDate.jsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | 3 | export const useDate = () => { 4 | const locale = 'en'; 5 | const [today, setDate] = useState(new Date()) 6 | 7 | useEffect(() => { 8 | const timer = setInterval(() => { 9 | setDate(new Date()) 10 | }, 60*1000) 11 | 12 | return () => { 13 | clearInterval(timer) 14 | } 15 | },[]) 16 | 17 | const day = today.toLocaleDateString(locale, {weekday: 'long'}) 18 | const date = `${day}, ${today.getDate()}, ${today.toLocaleDateString(locale, {month: 'long'})}\n\n` 19 | const time = today.toLocaleDateString(locale, { hour: 'numeric', hour12: true, minute: 'numeric' }) 20 | 21 | return { 22 | date, time 23 | } 24 | } -------------------------------------------------------------------------------- /src/assets/icons/cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myprojectideas/Weather_application/0e8159d28b8d422c80cdb6ec21b14b18213df564/src/assets/icons/cloud.png -------------------------------------------------------------------------------- /src/assets/icons/fog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myprojectideas/Weather_application/0e8159d28b8d422c80cdb6ec21b14b18213df564/src/assets/icons/fog.png -------------------------------------------------------------------------------- /src/assets/icons/rain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myprojectideas/Weather_application/0e8159d28b8d422c80cdb6ec21b14b18213df564/src/assets/icons/rain.png -------------------------------------------------------------------------------- /src/assets/icons/search.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/icons/snow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myprojectideas/Weather_application/0e8159d28b8d422c80cdb6ec21b14b18213df564/src/assets/icons/snow.png -------------------------------------------------------------------------------- /src/assets/icons/storm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myprojectideas/Weather_application/0e8159d28b8d422c80cdb6ec21b14b18213df564/src/assets/icons/storm.png -------------------------------------------------------------------------------- /src/assets/icons/sun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myprojectideas/Weather_application/0e8159d28b8d422c80cdb6ec21b14b18213df564/src/assets/icons/sun.png -------------------------------------------------------------------------------- /src/assets/icons/windy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myprojectideas/Weather_application/0e8159d28b8d422c80cdb6ec21b14b18213df564/src/assets/icons/windy.png -------------------------------------------------------------------------------- /src/assets/images/Clear.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myprojectideas/Weather_application/0e8159d28b8d422c80cdb6ec21b14b18213df564/src/assets/images/Clear.jpg -------------------------------------------------------------------------------- /src/assets/images/Cloudy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myprojectideas/Weather_application/0e8159d28b8d422c80cdb6ec21b14b18213df564/src/assets/images/Cloudy.jpg -------------------------------------------------------------------------------- /src/assets/images/Rainy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myprojectideas/Weather_application/0e8159d28b8d422c80cdb6ec21b14b18213df564/src/assets/images/Rainy.jpg -------------------------------------------------------------------------------- /src/assets/images/Stormy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myprojectideas/Weather_application/0e8159d28b8d422c80cdb6ec21b14b18213df564/src/assets/images/Stormy.jpg -------------------------------------------------------------------------------- /src/assets/images/Sunny.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myprojectideas/Weather_application/0e8159d28b8d422c80cdb6ec21b14b18213df564/src/assets/images/Sunny.jpg -------------------------------------------------------------------------------- /src/assets/images/fog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myprojectideas/Weather_application/0e8159d28b8d422c80cdb6ec21b14b18213df564/src/assets/images/fog.png -------------------------------------------------------------------------------- /src/assets/images/snow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/myprojectideas/Weather_application/0e8159d28b8d422c80cdb6ec21b14b18213df564/src/assets/images/snow.jpg -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | *, 6 | ::before, 7 | ::after { 8 | margin: 0; 9 | padding: 0; 10 | box-sizing: border-box; 11 | } 12 | 13 | .glassCard{ 14 | background: rgba(225,225,225,0.18); 15 | box-shadow: 0 8px 32px 0 rgba(31,38,135,0.37); 16 | backdrop-filter: blur(8px); 17 | -webkit-backdrop-filter: blur(8px); 18 | border-radius: 10px; 19 | border: 1px solid rgba(225,225,225,0.18); 20 | } 21 | -------------------------------------------------------------------------------- /src/main.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom/client' 3 | import App from './App.jsx' 4 | import './index.css' 5 | import { StateContextProvider } from './Context/index.jsx' 6 | 7 | ReactDOM.createRoot(document.getElementById('root')).render( 8 | 9 | 10 | , 11 | ) 12 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | export default { 3 | content: [ 4 | "./index.html", 5 | "./src/**/*.{js,ts,jsx,tsx}", 6 | ], 7 | theme: { 8 | extend: {}, 9 | }, 10 | plugins: [], 11 | } 12 | 13 | -------------------------------------------------------------------------------- /vite.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'vite' 2 | import react from '@vitejs/plugin-react' 3 | 4 | // https://vitejs.dev/config/ 5 | export default defineConfig({ 6 | plugins: [react()], 7 | }) 8 | --------------------------------------------------------------------------------