Hourlycard with temp and icon utilizing props
This commit is contained in:
parent
0a0481d63f
commit
65091eecf7
@ -5,8 +5,8 @@ import "./globals.css";
|
|||||||
const inter = Inter({ subsets: ["latin"] });
|
const inter = Inter({ subsets: ["latin"] });
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "Create Next App",
|
title: "Get the weather anywhere!",
|
||||||
description: "Generated by create next app",
|
description: "Get todays weather hour-by-hour or a 7 day forecast!",
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function RootLayout({
|
export default function RootLayout({
|
||||||
|
@ -4,7 +4,6 @@ import WeatherNow from '../components/WeatherNow'
|
|||||||
import { createContext, useState } from 'react';
|
import { createContext, useState } from 'react';
|
||||||
import { defaultGeoLocation } from './defaultState';
|
import { defaultGeoLocation } from './defaultState';
|
||||||
import { LocationContextType, coordType } from '@/types/types';
|
import { LocationContextType, coordType } from '@/types/types';
|
||||||
import WeatherIcon from '@/components/WeatherIcon';
|
|
||||||
|
|
||||||
|
|
||||||
export const LocationContext = createContext<LocationContextType>({
|
export const LocationContext = createContext<LocationContextType>({
|
||||||
@ -22,8 +21,8 @@ export default function Home() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main>
|
<main className='flex'>
|
||||||
<div className='block mx-auto max-w-4xl'>
|
<div className='mx-auto'>
|
||||||
<LocationContext.Provider value={contextValue}>
|
<LocationContext.Provider value={contextValue}>
|
||||||
<LocationSearch />
|
<LocationSearch />
|
||||||
<WeatherNow />
|
<WeatherNow />
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
import { LocationContext } from "@/app/page"
|
|
||||||
import { useContext } from "react"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default function HourlyCard() {
|
|
||||||
const { geoLocation } = useContext(LocationContext)
|
|
||||||
return (
|
|
||||||
<h1>Hejsa</h1>
|
|
||||||
)
|
|
||||||
};
|
|
14
components/HourlyCard/HourlyCard.tsx
Normal file
14
components/HourlyCard/HourlyCard.tsx
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import { HourlyCardPropType } from "@/types/types"
|
||||||
|
import WeatherIcon from "./WeatherIcon"
|
||||||
|
import HourlyTemp from "./HourlyTemp"
|
||||||
|
|
||||||
|
export default function HourlyCard(props: HourlyCardPropType) {
|
||||||
|
const weatherCode = props.weather.weather_code[props.timeIndex]
|
||||||
|
const temperature = props.weather.apparent_temperature[props.timeIndex]
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<WeatherIcon weatherCode={weatherCode}/>
|
||||||
|
<HourlyTemp temperature={temperature} />
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
};
|
7
components/HourlyCard/HourlyTemp.tsx
Normal file
7
components/HourlyCard/HourlyTemp.tsx
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
export default function HourlyTemp(props: {temperature: number;}) {
|
||||||
|
const feels = props.temperature;
|
||||||
|
return (
|
||||||
|
<p>{feels}°C</p>
|
||||||
|
)
|
||||||
|
}
|
@ -11,8 +11,6 @@ import cloud from '../public/cloud.svg'
|
|||||||
import moon from '../public/moon.svg'
|
import moon from '../public/moon.svg'
|
||||||
import sun from '../public/sun.svg'
|
import sun from '../public/sun.svg'
|
||||||
|
|
||||||
import { useContext } from "react";
|
|
||||||
import { WeatherContext } from "./WeatherNow";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -79,13 +77,12 @@ function getCurrentWeatherIcon(weatherCode: number) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// this component takes WeatherIconPropType as props and shows the weather icon for the hour index it is given in timeIndex prop.
|
||||||
export default function WeatherIcon() {
|
export default function WeatherIcon(props: {weatherCode: number}) {
|
||||||
const { weather } = useContext(WeatherContext)
|
const weatherCode = props.weatherCode
|
||||||
return(
|
return (
|
||||||
<>
|
<>
|
||||||
<Image src={getCurrentWeatherIcon(weather.current.weather_code)} alt="Weather icon"/>
|
<Image className="h-1/3 mx-auto" src={getCurrentWeatherIcon(weatherCode)} alt="Weather icon"/>
|
||||||
{JSON.stringify(weather.current.weather_code)}
|
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
};
|
};
|
@ -25,22 +25,18 @@ export default function LocationSearch() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
<input
|
<input
|
||||||
id="location"
|
className="my-4 w-full rounded h-8 px-2 box-border border-2 hover:shadow-md"
|
||||||
name="locationSearch"
|
id="location"
|
||||||
type="text"
|
name="locationSearch"
|
||||||
placeholder="Enter a location to get the weather"
|
type="text"
|
||||||
value={searchLocation}
|
placeholder="Enter a location to get the weather"
|
||||||
onChange={handleChange}
|
value={searchLocation}
|
||||||
disabled={pending}
|
onChange={handleChange}
|
||||||
/>
|
disabled={pending}
|
||||||
<button type="submit" disabled={pending}>
|
aria-label="Enter location to query the weather"
|
||||||
{pending ? "Searching..." : "Search"}
|
/>
|
||||||
</button>
|
</form>
|
||||||
<label htmlFor="location" className="hidden">
|
|
||||||
Enter location to get the weather!
|
|
||||||
</label>
|
|
||||||
</form>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
91
components/WeatherHero.tsx
Normal file
91
components/WeatherHero.tsx
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import Image from "next/image";
|
||||||
|
import cloudAndLightening from '../public/cloud-and-lightening.svg'
|
||||||
|
import cloudAndMoon from '../public/cloud-and-moon.svg'
|
||||||
|
import cloudAndRain from '../public/cloud-and-rain.svg'
|
||||||
|
import cloudAndSnow from '../public/cloud-and-snow.svg'
|
||||||
|
import cloudAndWind from '../public/cloud-and-wind.svg'
|
||||||
|
import cloudSnowRain from '../public/cloud-snow-rain.svg'
|
||||||
|
import cloudAndSun from '../public/cloud-and-sun.svg'
|
||||||
|
import cloudWindRain from '../public/cloud-wind-rain.svg'
|
||||||
|
import cloud from '../public/cloud.svg'
|
||||||
|
import moon from '../public/moon.svg'
|
||||||
|
import sun from '../public/sun.svg'
|
||||||
|
|
||||||
|
import { useContext } from "react";
|
||||||
|
import { WeatherContext } from "./WeatherNow";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function getCurrentWeatherIcon(weatherCode: number) {
|
||||||
|
switch (weatherCode) {
|
||||||
|
default:
|
||||||
|
return sun;
|
||||||
|
case 0: // clear sky
|
||||||
|
return sun;
|
||||||
|
case 1: // clear mainly
|
||||||
|
return cloudAndSun;
|
||||||
|
case 2: // partly cloudy
|
||||||
|
return cloud;
|
||||||
|
case 3: // overcast
|
||||||
|
return cloud;
|
||||||
|
case 45: // fog
|
||||||
|
return cloud;
|
||||||
|
case 48: // fog rime
|
||||||
|
return cloud;
|
||||||
|
case 51: // drizzle light
|
||||||
|
return cloudAndRain;
|
||||||
|
case 53: // drizzle moderate
|
||||||
|
return cloudAndRain;
|
||||||
|
case 55: // drizzle dense
|
||||||
|
return cloudAndRain;
|
||||||
|
case 56: // drizzle light freezing
|
||||||
|
return cloudSnowRain;
|
||||||
|
case 57: // drizzle dense freezing
|
||||||
|
return cloudSnowRain;
|
||||||
|
case 61: // rain slight
|
||||||
|
return cloudAndRain;
|
||||||
|
case 63: // rain moderate
|
||||||
|
return cloudAndRain;
|
||||||
|
case 65: // rain heavy
|
||||||
|
return cloudAndRain;
|
||||||
|
case 66: // rain light freezing
|
||||||
|
return cloudWindRain;
|
||||||
|
case 67: // rain dense freezing
|
||||||
|
return cloudWindRain;
|
||||||
|
case 71: // snow slight
|
||||||
|
return cloudAndSnow;
|
||||||
|
case 73: // snow moderate
|
||||||
|
return cloudAndSnow;
|
||||||
|
case 75: // snow heavy
|
||||||
|
return cloudAndSnow;
|
||||||
|
case 77: // snow grains
|
||||||
|
return cloudAndSnow;
|
||||||
|
case 80: // rain showers slight
|
||||||
|
return cloudAndRain;
|
||||||
|
case 81: // rain showers moderate
|
||||||
|
return cloudAndRain;
|
||||||
|
case 82: // rain showers violent
|
||||||
|
return cloudAndRain;
|
||||||
|
case 85: // snow showers slight
|
||||||
|
return cloudAndSnow;
|
||||||
|
case 86: // snow showers heavy
|
||||||
|
return cloudAndSnow;
|
||||||
|
case 95: // thunderstorm
|
||||||
|
return cloudAndLightening;
|
||||||
|
case 96: //thunderstorm hail slight
|
||||||
|
return cloudAndLightening;
|
||||||
|
case 99: //thunderstorm hail heavy
|
||||||
|
return cloudAndLightening;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export default function WeatherHero() {
|
||||||
|
const { weather } = useContext(WeatherContext);
|
||||||
|
const weatherCode = weather.current.weather_code;
|
||||||
|
return(
|
||||||
|
<>
|
||||||
|
<Image className="h-1/3 mx-auto" src={getCurrentWeatherIcon(weatherCode)} alt="Weather icon"/>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
};
|
@ -2,24 +2,23 @@
|
|||||||
|
|
||||||
import { getHourlyForecast } from "@/app/actions";
|
import { getHourlyForecast } from "@/app/actions";
|
||||||
import Temperature from "./Temperature";
|
import Temperature from "./Temperature";
|
||||||
import { HourlyForecast, WeatherContextType} from "@/types/types";
|
import { HourlyForecast, WeatherContextType } from "@/types/types";
|
||||||
import { createContext, useContext, useEffect, useState } from "react";
|
import { createContext, useContext, useEffect, useState } from "react";
|
||||||
import { defaultHourlyForecast } from "@/app/defaultState";
|
import { defaultHourlyForecast } from "@/app/defaultState";
|
||||||
import { LocationContext } from "@/app/page";
|
import { LocationContext } from "@/app/page";
|
||||||
import WeatherIcon from "./WeatherIcon";
|
import WeatherHero from "./WeatherHero";
|
||||||
|
|
||||||
export const WeatherContext = createContext<WeatherContextType>({
|
export const WeatherContext = createContext<WeatherContextType>({
|
||||||
weather: defaultHourlyForecast,
|
weather: defaultHourlyForecast,
|
||||||
setWeather: () => {} // Default function, does nothing
|
setWeather: () => {}, // Default function, does nothing
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
export default function WeatherNow() {
|
export default function WeatherNow() {
|
||||||
const { geoLocation } = useContext(LocationContext)
|
const { geoLocation } = useContext(LocationContext);
|
||||||
const [weather, setWeather] = useState<HourlyForecast>(defaultHourlyForecast);
|
const [weather, setWeather] = useState<HourlyForecast>(defaultHourlyForecast);
|
||||||
const contextValue: WeatherContextType = {
|
const contextValue: WeatherContextType = {
|
||||||
weather,
|
weather,
|
||||||
setWeather
|
setWeather,
|
||||||
};
|
};
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let mounted = true;
|
let mounted = true;
|
||||||
@ -34,9 +33,11 @@ export default function WeatherNow() {
|
|||||||
}, [geoLocation]);
|
}, [geoLocation]);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h1>Here is the current weather in {geoLocation.name}</h1>
|
<h1 className="my-4 text-2xl">
|
||||||
|
Here is the current weather in {geoLocation.name}
|
||||||
|
</h1>
|
||||||
<WeatherContext.Provider value={contextValue}>
|
<WeatherContext.Provider value={contextValue}>
|
||||||
<WeatherIcon />
|
<WeatherHero />
|
||||||
<Temperature />
|
<Temperature />
|
||||||
</WeatherContext.Provider>
|
</WeatherContext.Provider>
|
||||||
</>
|
</>
|
||||||
|
@ -99,7 +99,7 @@ interface HourlyUnits {
|
|||||||
is_day: string;
|
is_day: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface HourlyWeather {
|
export interface HourlyWeather {
|
||||||
time: string[];
|
time: string[];
|
||||||
temperature_2m: number[];
|
temperature_2m: number[];
|
||||||
apparent_temperature: number[];
|
apparent_temperature: number[];
|
||||||
@ -213,3 +213,8 @@ export interface WeatherContextType {
|
|||||||
weather: HourlyForecast;
|
weather: HourlyForecast;
|
||||||
setWeather: React.Dispatch<React.SetStateAction<HourlyForecast>>;
|
setWeather: React.Dispatch<React.SetStateAction<HourlyForecast>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface HourlyCardPropType {
|
||||||
|
weather: HourlyWeather;
|
||||||
|
timeIndex: number;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user