From 7b97a0eb6524cb0e812f515f16104e0c6cd39f2d Mon Sep 17 00:00:00 2001 From: ChrQR Date: Mon, 6 May 2024 23:22:57 +0200 Subject: [PATCH] Fixed some things. Need to fix google places call. It is refreshing the page when receiving the data, thus resetting the state. It's a job for tomorrow. --- app/actions.ts | 22 ++++- app/defaultState.ts | 171 ++++++++++++++++++---------------- app/page.tsx | 22 +++-- components/LocationSearch.tsx | 45 ++++----- components/Temperature.tsx | 15 +-- components/WeatherNow.tsx | 42 +++++---- types/types.ts | 101 ++++++++++---------- 7 files changed, 227 insertions(+), 191 deletions(-) diff --git a/app/actions.ts b/app/actions.ts index 4f72c6f..9da3589 100644 --- a/app/actions.ts +++ b/app/actions.ts @@ -1,14 +1,28 @@ 'use server' -import { LocationType } from "@/types/types"; +import { Forecast, LocationType, coordType } from "@/types/types"; -export async function getLocation(searchLocation: string){ +//takes address and returns coords in obj as {lat: number, lng: number} +export async function getLocation(searchLocation: string): Promise{ const placesKey = "AIzaSyBf1ip4XogdC6XmbfDhxS_RJDOSieycJpQ"; - const url = `https://maps.googleapis.com/maps/api/geocode/json?${searchLocation}&key=${placesKey}`; + const url = `https://maps.googleapis.com/maps/api/geocode/json?address=${searchLocation}&key=${placesKey}`; const res = await fetch(url); if (!res.ok) { throw new Error(`There was an error fetching the data`); } - const data = await res.json(); + const data: LocationType = await res.json(); + return data.results[0].geometry.location; + } + +export async function getForecast(geoLocation: coordType): Promise { + const { lat, lng } = geoLocation; + const appId = "546911d860cb81f16585f7973b394b70"; + const res = await fetch( + `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lng}&appid=${appId}` + ); + if (!res.ok) { + throw new Error(`Failed to fetch the weather data`); + } + const data: Forecast = await res.json(); return data; } \ No newline at end of file diff --git a/app/defaultState.ts b/app/defaultState.ts index 4629674..8d1bf77 100644 --- a/app/defaultState.ts +++ b/app/defaultState.ts @@ -1,80 +1,95 @@ export const defaultState = { - "results": [ - { - "address_components": [ - { - "long_name": "Sluseholmen", - "short_name": "Sluseholmen", - "types": [ - "route" - ] - }, - { - "long_name": "Vesterbro", - "short_name": "Vesterbro", - "types": [ - "political", - "sublocality", - "sublocality_level_1" - ] - }, - { - "long_name": "København", - "short_name": "København", - "types": [ - "locality", - "political" - ] - }, - { - "long_name": "Denmark", - "short_name": "DK", - "types": [ - "country", - "political" - ] - }, - { - "long_name": "2450", - "short_name": "2450", - "types": [ - "postal_code" - ] - } - ], - "formatted_address": "Sluseholmen, 2450 København, Denmark", - "geometry": { - "bounds": { - "northeast": { - "lat": 55.64754749999999, - "lng": 12.5502837 - }, - "southwest": { - "lat": 55.6435823, - "lng": 12.5452758 - } - }, - "location": { - "lat": 55.6452427, - "lng": 12.5475522 - }, - "location_type": "GEOMETRIC_CENTER", - "viewport": { - "northeast": { - "lat": 55.64754749999999, - "lng": 12.5502837 - }, - "southwest": { - "lat": 55.6435823, - "lng": 12.5452758 - } - } + results: [ + { + address_components: [ + { + long_name: "Sluseholmen", + short_name: "Sluseholmen", + types: ["route"], }, - "place_id": "ChIJBzR68YNUUkYRoxbRfFuUlEM", - "types": [ - "route" - ] - } - ], - "status": "OK" - } \ No newline at end of file + { + long_name: "Vesterbro", + short_name: "Vesterbro", + types: ["political", "sublocality", "sublocality_level_1"], + }, + { + long_name: "København", + short_name: "København", + types: ["locality", "political"], + }, + { + long_name: "Denmark", + short_name: "DK", + types: ["country", "political"], + }, + { + long_name: "2450", + short_name: "2450", + types: ["postal_code"], + }, + ], + formatted_address: "Sluseholmen, 2450 København, Denmark", + geometry: { + bounds: { + northeast: { + lat: 55.64754749999999, + lng: 12.5502837, + }, + southwest: { + lat: 55.6435823, + lng: 12.5452758, + }, + }, + location: { + lat: 55.6452427, + lng: 12.5475522, + }, + location_type: "GEOMETRIC_CENTER", + viewport: { + northeast: { + lat: 55.64754749999999, + lng: 12.5502837, + }, + southwest: { + lat: 55.6435823, + lng: 12.5452758, + }, + }, + }, + place_id: "ChIJBzR68YNUUkYRoxbRfFuUlEM", + types: ["route"], + }, + ], + status: "OK", +}; + +export const defaultForecast = { + coord: { lon: 12.5476, lat: 55.6452 }, + weather: [ + { id: 803, main: "Clouds", description: "broken clouds", icon: "04n" }, + ], + base: "stations", + main: { + temp: 284.38, + feels_like: 283.83, + temp_min: 283.94, + temp_max: 285.38, + pressure: 1013, + humidity: 87, + }, + visibility: 10000, + wind: { speed: 3.09, deg: 60 }, + clouds: { all: 75 }, + dt: 1715027131, + sys: { + type: 1, + id: 1575, + country: "DK", + sunrise: 1714965344, + sunset: 1715021822, + }, + timezone: 7200, + id: 2618424, + name: "Copenhagen municipality", + cod: 200, +}; diff --git a/app/page.tsx b/app/page.tsx index 46fbb10..49c81e2 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -2,20 +2,26 @@ import LocationSearch from '@/components/LocationSearch'; import WeatherNow from '../components/WeatherNow' import { useState } from 'react'; -import { LocationType } from '@/types/types'; - - -const [location, setLocation] = useState(undefined); -const { lat, lng } = location?.results[0].geometry.location; +import { defaultState } from './defaultState'; +import { coordType } from '@/types/types'; +const defaultGeoLocation: coordType = { + lat: 55.647229603577124, + lng: 12.54995987788925 +} export default function Home() { + const [geoLocation, setGeoLocation] = useState({ + lat: 55.647229603577124, + lng: 12.54995987788925 + }); return (
- -

The weather in {location?.results[0].address_components[0].long_name} for the next 3 days

- + +

The weather in {} for the next 3 days

+ +

{JSON.stringify(geoLocation)}

); diff --git a/components/LocationSearch.tsx b/components/LocationSearch.tsx index 876e6ef..67c9b8e 100644 --- a/components/LocationSearch.tsx +++ b/components/LocationSearch.tsx @@ -1,34 +1,37 @@ "use client"; -import { useState } from "react"; import { getLocation } from "@/app/actions"; -import { LocationType } from "@/types/types"; +import { useState } from "react"; +import { useFormStatus } from "react-dom"; export default function LocationSearch(props: any) { - const [searchLocation, setSearchLocation] = useState("Sluseholmen"); - const setLocation = props.setLocation; + const [searchLocation, setSearchLocation] = useState(""); + const setGeoLocation = props.setGeoLocation; const handleChange = (e: React.ChangeEvent) => { setSearchLocation(e.target.value); }; - const handleKeyDown = (e: any) => { - if (e.key === "Enter") { - const location: LocationType = getLocation(searchLocation); - setLocation(location); - } + const handleSubmit = (e: React.FormEvent) => { + const coordinates = getLocation(searchLocation); + setGeoLocation(coordinates); }; - + const { pending } = useFormStatus(); return ( <> - - +
+ + + +

{searchLocation}

); diff --git a/components/Temperature.tsx b/components/Temperature.tsx index 87e0d5a..4400113 100644 --- a/components/Temperature.tsx +++ b/components/Temperature.tsx @@ -1,17 +1,6 @@ -interface TempInfo { - tempInfo: { - temp: number; - feels_like: number; - temp_min: number; - temp_max: number; - pressure: number; - humidity: number; - sea_level: number; - grnd_level: number; - }; -}; +import { TempInfo } from "@/types/types"; -export default function Temperature(props: TempInfo) { +export default function Temperature(props: {tempInfo:TempInfo}) { const kelvin = 273.15; const tempInfo = props.tempInfo; const fullTemp = tempInfo.temp - kelvin; diff --git a/components/WeatherNow.tsx b/components/WeatherNow.tsx index 2d530b9..9b7ba65 100644 --- a/components/WeatherNow.tsx +++ b/components/WeatherNow.tsx @@ -1,26 +1,30 @@ +"use client"; + +import { getForecast } from "@/app/actions"; import Temperature from "./Temperature"; -import { Forecast, LocationType, coordType } from "@/types/types"; +import { Forecast, coordType } from "@/types/types"; +import { useEffect, useState } from "react"; +import { defaultForecast } from "@/app/defaultState"; -async function getForecast(location: LocationType): Promise { - const { lat, lng } = location.results[0].geometry.location; - const appId = "546911d860cb81f16585f7973b394b70"; - const res = await fetch( - `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lng}&appid=${appId}` - ); - if (!res.ok) { - throw new Error(`Failed to fetch the weather data`); - } - return res.json(); -} - -export default async function WeatherNow(props: { location: any }) { - const location = props.location; - const weather = await getForecast(location); +export default function WeatherNow(props: { geoLocation: coordType }) { + // const weather = getForecast(props.geoLocation); + const [weather, setWeather] = useState(defaultForecast); + useEffect(() => { + let mounted = true; + getForecast(props.geoLocation).then((data) => { + if (mounted) { + setWeather(data); + } + }); + return () => { + mounted = false; + }; + }, [props.geoLocation]); return ( -
+ <>

Forecast

- +

-
+ ); } diff --git a/types/types.ts b/types/types.ts index 97243af..e5d0b91 100644 --- a/types/types.ts +++ b/types/types.ts @@ -1,50 +1,45 @@ export interface Forecast { - coord: { - lon: number; - lat: number; - }; - weather: { - id: number; - main: string; - description: string; - icon: string; - }[]; - base: string; - main: { - temp: number; - feels_like: number; - temp_min: number; - temp_max: number; - pressure: number; - humidity: number; - sea_level: number; - grnd_level: number; - }; - visibility: number; - wind: { - speed: number; - deg: number; - gust: number; - }; - rain: { - onehour: number; - }; - clouds: { - all: number; - }; - dt: number; - sys: { - type: number; - id: number; - country: string; - sunrise: number; - sunset: number; - }; - timezone: number; + coord: { + lon: number; + lat: number; + }; + weather: Array<{ id: number; - name: string; - cod: number; - } + main: string; + description: string; + icon: string; + }>; + base: string; + main: { + temp: number; + feels_like: number; + temp_min: number; + temp_max: number; + pressure: number; + humidity: number; + }; + visibility: number; + wind: { + speed: number; + deg: number; + }; + clouds: { + all: number; + }; + dt: number; + sys: { + type: number; + id: number; + country: string; + sunrise: number; + sunset: number; + }; + timezone: number; + id: number; + name: string; + cod: number; +} + export interface LocationType { results: { @@ -88,6 +83,16 @@ export interface LocationType { } export interface coordType { - latitude: string; - longtitude: string; - } \ No newline at end of file + lat: number; + lng: number; + } +export type EffectCallback = () => (void | (() => void | undefined)); + +export interface TempInfo { + temp: number; + feels_like: number; + temp_min: number; + temp_max: number; + pressure: number; + humidity: number; +} \ No newline at end of file