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"] });
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Create Next App",
|
||||
description: "Generated by create next app",
|
||||
title: "Get the weather anywhere!",
|
||||
description: "Get todays weather hour-by-hour or a 7 day forecast!",
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
|
@ -4,7 +4,6 @@ import WeatherNow from '../components/WeatherNow'
|
||||
import { createContext, useState } from 'react';
|
||||
import { defaultGeoLocation } from './defaultState';
|
||||
import { LocationContextType, coordType } from '@/types/types';
|
||||
import WeatherIcon from '@/components/WeatherIcon';
|
||||
|
||||
|
||||
export const LocationContext = createContext<LocationContextType>({
|
||||
@ -22,8 +21,8 @@ export default function Home() {
|
||||
};
|
||||
|
||||
return (
|
||||
<main>
|
||||
<div className='block mx-auto max-w-4xl'>
|
||||
<main className='flex'>
|
||||
<div className='mx-auto'>
|
||||
<LocationContext.Provider value={contextValue}>
|
||||
<LocationSearch />
|
||||
<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 sun from '../public/sun.svg'
|
||||
|
||||
import { useContext } from "react";
|
||||
import { WeatherContext } from "./WeatherNow";
|
||||
|
||||
|
||||
|
||||
@ -79,13 +77,12 @@ function getCurrentWeatherIcon(weatherCode: number) {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export default function WeatherIcon() {
|
||||
const { weather } = useContext(WeatherContext)
|
||||
return(
|
||||
// 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(props: {weatherCode: number}) {
|
||||
const weatherCode = props.weatherCode
|
||||
return (
|
||||
<>
|
||||
<Image src={getCurrentWeatherIcon(weather.current.weather_code)} alt="Weather icon"/>
|
||||
{JSON.stringify(weather.current.weather_code)}
|
||||
<Image className="h-1/3 mx-auto" src={getCurrentWeatherIcon(weatherCode)} alt="Weather icon"/>
|
||||
</>
|
||||
)
|
||||
};
|
@ -27,6 +27,7 @@ export default function LocationSearch() {
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<input
|
||||
className="my-4 w-full rounded h-8 px-2 box-border border-2 hover:shadow-md"
|
||||
id="location"
|
||||
name="locationSearch"
|
||||
type="text"
|
||||
@ -34,13 +35,8 @@ export default function LocationSearch() {
|
||||
value={searchLocation}
|
||||
onChange={handleChange}
|
||||
disabled={pending}
|
||||
aria-label="Enter location to query the weather"
|
||||
/>
|
||||
<button type="submit" disabled={pending}>
|
||||
{pending ? "Searching..." : "Search"}
|
||||
</button>
|
||||
<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 Temperature from "./Temperature";
|
||||
import { HourlyForecast, WeatherContextType} from "@/types/types";
|
||||
import { HourlyForecast, WeatherContextType } from "@/types/types";
|
||||
import { createContext, useContext, useEffect, useState } from "react";
|
||||
import { defaultHourlyForecast } from "@/app/defaultState";
|
||||
import { LocationContext } from "@/app/page";
|
||||
import WeatherIcon from "./WeatherIcon";
|
||||
import WeatherHero from "./WeatherHero";
|
||||
|
||||
export const WeatherContext = createContext<WeatherContextType>({
|
||||
weather: defaultHourlyForecast,
|
||||
setWeather: () => {} // Default function, does nothing
|
||||
setWeather: () => {}, // Default function, does nothing
|
||||
});
|
||||
|
||||
|
||||
export default function WeatherNow() {
|
||||
const { geoLocation } = useContext(LocationContext)
|
||||
const { geoLocation } = useContext(LocationContext);
|
||||
const [weather, setWeather] = useState<HourlyForecast>(defaultHourlyForecast);
|
||||
const contextValue: WeatherContextType = {
|
||||
weather,
|
||||
setWeather
|
||||
setWeather,
|
||||
};
|
||||
useEffect(() => {
|
||||
let mounted = true;
|
||||
@ -34,9 +33,11 @@ export default function WeatherNow() {
|
||||
}, [geoLocation]);
|
||||
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}>
|
||||
<WeatherIcon />
|
||||
<WeatherHero />
|
||||
<Temperature />
|
||||
</WeatherContext.Provider>
|
||||
</>
|
||||
|
@ -99,7 +99,7 @@ interface HourlyUnits {
|
||||
is_day: string;
|
||||
}
|
||||
|
||||
interface HourlyWeather {
|
||||
export interface HourlyWeather {
|
||||
time: string[];
|
||||
temperature_2m: number[];
|
||||
apparent_temperature: number[];
|
||||
@ -213,3 +213,8 @@ export interface WeatherContextType {
|
||||
weather: HourlyForecast;
|
||||
setWeather: React.Dispatch<React.SetStateAction<HourlyForecast>>;
|
||||
}
|
||||
|
||||
export interface HourlyCardPropType {
|
||||
weather: HourlyWeather;
|
||||
timeIndex: number;
|
||||
}
|
Loading…
Reference in New Issue
Block a user