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.
This commit is contained in:
		
							parent
							
								
									0a4e22a8ca
								
							
						
					
					
						commit
						7b97a0eb65
					
				@ -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<coordType>{
 | 
			
		||||
    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<Forecast> {
 | 
			
		||||
    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;
 | 
			
		||||
  }
 | 
			
		||||
@ -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"
 | 
			
		||||
  }
 | 
			
		||||
        {
 | 
			
		||||
          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,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										22
									
								
								app/page.tsx
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								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<LocationType | undefined>(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 (
 | 
			
		||||
    <main>
 | 
			
		||||
      <div className='block mx-auto max-w-4xl'>
 | 
			
		||||
        <LocationSearch setLocation={setLocation}/>
 | 
			
		||||
        <h1>The weather in {location?.results[0].address_components[0].long_name} for the next 3 days</h1>
 | 
			
		||||
        <WeatherNow location={location}/>
 | 
			
		||||
        <LocationSearch setGeoLocation={setGeoLocation}/>
 | 
			
		||||
        <h1>The weather in {} for the next 3 days</h1>
 | 
			
		||||
        <WeatherNow geoLocation={geoLocation}/>
 | 
			
		||||
        <p>{JSON.stringify(geoLocation)}</p>
 | 
			
		||||
      </div>
 | 
			
		||||
    </main>
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
@ -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<HTMLInputElement>) => {
 | 
			
		||||
    setSearchLocation(e.target.value);
 | 
			
		||||
  };
 | 
			
		||||
  const handleKeyDown = (e: any) => {
 | 
			
		||||
    if (e.key === "Enter") {
 | 
			
		||||
      const location: LocationType = getLocation(searchLocation);
 | 
			
		||||
      setLocation(location);
 | 
			
		||||
    }
 | 
			
		||||
  const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
 | 
			
		||||
    const coordinates = getLocation(searchLocation);
 | 
			
		||||
    setGeoLocation(coordinates);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const { pending } = useFormStatus();
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
      <input
 | 
			
		||||
        id="location"
 | 
			
		||||
        type="text"
 | 
			
		||||
        placeholder="enter a location to get the weather"
 | 
			
		||||
        value={searchLocation}
 | 
			
		||||
        onChange={handleChange}
 | 
			
		||||
        onKeyDown={handleKeyDown}
 | 
			
		||||
      />
 | 
			
		||||
      <label htmlFor="location" className="hidden">
 | 
			
		||||
        Enter location to get the weather!
 | 
			
		||||
      </label>
 | 
			
		||||
      <form onSubmit={handleSubmit}>
 | 
			
		||||
        <input
 | 
			
		||||
          id="location"
 | 
			
		||||
          name="locationSearch"
 | 
			
		||||
          type="text"
 | 
			
		||||
          placeholder="enter a location to get the weather"
 | 
			
		||||
          value={searchLocation}
 | 
			
		||||
          onChange={handleChange}
 | 
			
		||||
        />
 | 
			
		||||
        <button type="submit" disabled={pending}>
 | 
			
		||||
          {pending ? "Searching..." : "Search"}
 | 
			
		||||
        </button>
 | 
			
		||||
        <label htmlFor="location" className="hidden">
 | 
			
		||||
          Enter location to get the weather!
 | 
			
		||||
        </label>
 | 
			
		||||
      </form>
 | 
			
		||||
      <p>{searchLocation}</p>
 | 
			
		||||
    </>
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
@ -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<Forecast> {
 | 
			
		||||
  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<Forecast>(defaultForecast);
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    let mounted = true;
 | 
			
		||||
    getForecast(props.geoLocation).then((data) => {
 | 
			
		||||
      if (mounted) {
 | 
			
		||||
        setWeather(data);
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
    return () => {
 | 
			
		||||
      mounted = false;
 | 
			
		||||
    };
 | 
			
		||||
  }, [props.geoLocation]);
 | 
			
		||||
  return (
 | 
			
		||||
    <main>
 | 
			
		||||
    <>
 | 
			
		||||
      <h1>Forecast</h1>
 | 
			
		||||
      <Temperature tempInfo={weather.main}/>
 | 
			
		||||
      <Temperature tempInfo={weather?.main} />
 | 
			
		||||
      <p></p>
 | 
			
		||||
    </main>
 | 
			
		||||
    </>
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
    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;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user