Changed to open-meteo api and added location name to geoLocation state from places api

This commit is contained in:
ChrQR 2024-05-10 01:00:26 +02:00
parent 55b425c03a
commit 59bbcaea69
5 changed files with 145 additions and 75 deletions

View File

@ -10,12 +10,15 @@ export async function getLocation(searchLocation: string): Promise<coordType>{
throw new Error(`There was an error fetching the data`); throw new Error(`There was an error fetching the data`);
} }
const data: LocationType = await res.json(); const data: LocationType = await res.json();
return data.results[0].geometry.location; return {
name: data.results[0].formatted_address,
geo: data.results[0].geometry.location
}
} }
// takes coordinates in coordType format and returns json with weather forecast. // takes coordinates in coordType format and returns json with weather forecast.
export async function getForecast(geoLocation: coordType): Promise<Forecast> { export async function getForecast(geoLocation: coordType): Promise<Forecast> {
const { lat, lng } = geoLocation; const { lat, lng } = geoLocation.geo;
const appId = process.env.WEATHER_API; const appId = process.env.WEATHER_API;
const res = await fetch( const res = await fetch(
`https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lng}&appid=${appId}` `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lng}&appid=${appId}`
@ -28,11 +31,10 @@ export async function getForecast(geoLocation: coordType): Promise<Forecast> {
} }
export async function getHourlyForecast(geoLocation: coordType): Promise<HourlyForecast> { export async function getHourlyForecast(geoLocation: coordType): Promise<HourlyForecast> {
const { lat, lng } = geoLocation; const { lat, lng } = geoLocation.geo;
const appId = process.env.WEATHER_API; const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
const res = await fetch( const url = `https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lng}&current=temperature_2m,apparent_temperature,is_day,precipitation,rain,showers,snowfall,weather_code,cloud_cover,wind_speed_10m,wind_direction_10m&hourly=temperature_2m,apparent_temperature,precipitation_probability,precipitation,weather_code,wind_speed_10m,is_day&daily=weather_code,temperature_2m_max,temperature_2m_min,apparent_temperature_max,apparent_temperature_min,sunrise,sunset,daylight_duration,sunshine_duration,uv_index_max,precipitation_sum,precipitation_hours,wind_speed_10m_max&timezone=${tz}`
`https://pro.openweathermap.org/data/2.5/forecast/hourly?lat=${lat}&lon=${lng}&appid=${appId}&mode=json&` const res = await fetch(url);
);
if (!res.ok) { if (!res.ok) {
throw new Error(`Failed to fetch the weather data`); throw new Error(`Failed to fetch the weather data`);
} }

File diff suppressed because one or more lines are too long

View File

@ -3,7 +3,6 @@ import React, { useContext, useState } from "react";
import { getLocation } from "@/app/actions"; import { getLocation } from "@/app/actions";
import { LocationContext } from "@/app/page"; import { LocationContext } from "@/app/page";
export default function LocationSearch() { export default function LocationSearch() {
const [searchLocation, setSearchLocation] = useState(""); const [searchLocation, setSearchLocation] = useState("");
const { geoLocation, setGeoLocation } = useContext(LocationContext); const { geoLocation, setGeoLocation } = useContext(LocationContext);

View File

@ -1,20 +1,28 @@
"use client"; "use client";
import { getForecast } from "@/app/actions"; import { getForecast, getHourlyForecast } from "@/app/actions";
import Temperature from "./Temperature"; import Temperature from "./Temperature";
import { Forecast, coordType } from "@/types/types"; import { Forecast, HourlyForecast, WeatherContextType, coordType } from "@/types/types";
import { useContext, useEffect, useState } from "react"; import { createContext, useContext, useEffect, useState } from "react";
import { defaultForecast } from "@/app/defaultState"; import { defaultForecast, defaultHourlyForecast } from "@/app/defaultState";
import { LocationContext } from "@/app/page"; import { LocationContext } from "@/app/page";
export const weatherContext = createContext<WeatherContextType>({
weather: defaultHourlyForecast,
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<Forecast>(defaultForecast); const [weather, setWeather] = useState<HourlyForecast>(defaultHourlyForecast);
const contextValue: WeatherContextType = {
weather,
setWeather
};
useEffect(() => { useEffect(() => {
let mounted = true; let mounted = true;
getForecast(geoLocation).then((data) => { getHourlyForecast(geoLocation).then((data) => {
if (mounted) { if (mounted) {
setWeather(data); setWeather(data);
} }
@ -25,8 +33,7 @@ export default function WeatherNow() {
}, [geoLocation]); }, [geoLocation]);
return ( return (
<> <>
<h1>Here is the current weather in {weather.name}</h1> <h1>Here is the current weather in {geoLocation.name}</h1>
<Temperature tempInfo={weather?.main} />
</> </>
); );
} }

View File

@ -41,59 +41,107 @@ export interface Forecast {
} }
export interface HourlyForecast { export interface HourlyForecast {
cod: string; latitude: number;
message: number; longitude: number;
cnt: number; generationtime_ms: number;
list: Array<{ utc_offset_seconds: number;
dt: number; timezone: string;
main: { timezone_abbreviation: string;
temp: number; elevation: number;
feels_like: number; current_units: CurrentUnits;
temp_min: number; current: CurrentWeather;
temp_max: number; hourly_units: HourlyUnits;
pressure: number; hourly: HourlyWeather;
sea_level: number; daily_units: DailyUnits;
grnd_level: number; daily: DailyWeather;
humidity: number; }
temp_kf: number;
}; interface CurrentUnits {
weather: Array<{ time: string;
id: number; interval: string;
main: string; temperature_2m: string;
description: string; apparent_temperature: string;
icon: string; is_day: string;
}>; precipitation: string;
clouds: { rain: string;
all: number; showers: string;
}; snowfall: string;
wind: { weather_code: string;
speed: number; cloud_cover: string;
deg: number; wind_speed_10m: string;
gust: number; wind_direction_10m: string;
}; }
visibility: number;
pop: number; interface CurrentWeather {
rain?: { time: string;
"1h": number; interval: number;
}; temperature_2m: number;
sys: { apparent_temperature: number;
pod: string; is_day: number;
}; precipitation: number;
dt_txt: string; rain: number;
}>; showers: number;
city: { snowfall: number;
id: number; weather_code: number;
name: string; cloud_cover: number;
coord: { wind_speed_10m: number;
lat: number; wind_direction_10m: number;
lon: number; }
};
country: string; interface HourlyUnits {
population: number; time: string;
timezone: number; temperature_2m: string;
sunrise: number; apparent_temperature: string;
sunset: number; precipitation_probability: string;
}; precipitation: string;
weather_code: string;
wind_speed_10m: string;
is_day: string;
}
interface HourlyWeather {
time: string[];
temperature_2m: number[];
apparent_temperature: number[];
precipitation_probability: number[];
precipitation: number[];
weather_code: number[];
wind_speed_10m: number[];
is_day: number[];
}
interface DailyUnits {
time: string;
weather_code: string;
temperature_2m_max: string;
temperature_2m_min: string;
apparent_temperature_max: string;
apparent_temperature_min: string;
sunrise: string;
sunset: string;
daylight_duration: string;
sunshine_duration: string;
uv_index_max: string;
precipitation_sum: string;
precipitation_hours: string;
wind_speed_10m_max: string;
}
interface DailyWeather {
time: string[];
weather_code: number[];
temperature_2m_max: number[];
temperature_2m_min: number[];
apparent_temperature_max: number[];
apparent_temperature_min: number[];
sunrise: string[];
sunset: string[];
daylight_duration: number[];
sunshine_duration: number[];
uv_index_max: number[];
precipitation_sum: number[];
precipitation_hours: number[];
wind_speed_10m_max: number[];
} }
export interface LocationType { export interface LocationType {
@ -138,9 +186,12 @@ export interface LocationType {
} }
export interface coordType { export interface coordType {
lat: number; name: string;
lng: number; geo: {
lat: number;
lng: number;}
} }
export type EffectCallback = () => void | (() => void | undefined); export type EffectCallback = () => void | (() => void | undefined);
export interface TempInfo { export interface TempInfo {
@ -157,3 +208,8 @@ export interface LocationContextType {
geoLocation: coordType; geoLocation: coordType;
setGeoLocation: React.Dispatch<React.SetStateAction<coordType>>; setGeoLocation: React.Dispatch<React.SetStateAction<coordType>>;
} }
export interface WeatherContextType {
weather: HourlyForecast;
setWeather: React.Dispatch<React.SetStateAction<HourlyForecast>>;
}