Skip to content

Commit

Permalink
my current location
Browse files Browse the repository at this point in the history
  • Loading branch information
mariojgt committed Sep 27, 2024
1 parent 81135b3 commit 6cfc0e5
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 79 deletions.
2 changes: 1 addition & 1 deletion .nuxt/nuxt.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Generated by nuxi
/// <reference types="@nuxt/ui" />
/// <reference types="@nuxt/devtools" />
/// <reference types="@nuxt/telemetry" />
/// <reference types="@nuxt/ui" />
/// <reference types="nuxt" />
/// <reference path="types/app-defaults.d.ts" />
/// <reference path="types/plugins.d.ts" />
Expand Down
2 changes: 1 addition & 1 deletion .nuxt/tailwind.config.cjs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// generated by the @nuxtjs/tailwindcss <https://github.com/nuxt-modules/tailwindcss> module at 27/09/2024, 21:32:56
// generated by the @nuxtjs/tailwindcss <https://github.com/nuxt-modules/tailwindcss> module at 27/09/2024, 22:48:17
const configMerger = require("/Users/mariojosegoes/Documents/YoyoWeather/node_modules/@nuxtjs/tailwindcss/dist/runtime/merger.js");

const inlineConfig = {"content":[],"theme":{"extend":{}},"plugins":[],"darkMode":"class"};
Expand Down
167 changes: 90 additions & 77 deletions pages/index.vue
Original file line number Diff line number Diff line change
@@ -1,66 +1,60 @@
<template>
<div class="min-h-screen bg-gradient-to-br from-blue-400 to-blue-600 text-white p-5">
<!-- App Header -->
<header class="text-center py-6">
<h1 class="text-5xl font-extrabold tracking-wide">YoyoWeather</h1>
<p class="text-xl mt-2 font-light">Your 5-Day Weather Forecast Companion</p>
</header>

<!-- Search Bar -->
<div class="flex justify-center my-8 gap-2 md:gap-4 flex-col md:flex-row">
<UInput
class="w-full md:w-1/2 bg-white text-gray-800 rounded-md shadow-lg focus:ring-2 focus:ring-blue-500"
v-model="location"
variant="outline"
placeholder="Enter a location for the weather forecast"
/>
<UButton
@click="searchWeather(location)"
label="Search"
class="px-6 py-2 bg-green-500 text-white rounded-md shadow-md hover:bg-green-600 transition-all"
/>
</div>

<!-- Quick Location Buttons -->
<div class="flex justify-center my-8 gap-2 md:gap-4 flex-col md:flex-row">
<UButton
@click="searchWeather('London')"
class="px-6 py-2 bg-blue-500 text-white rounded-md shadow-md hover:bg-blue-600 transition-all">
London
</UButton>
<UButton
@click="searchWeather('Paris')"
class="px-6 py-2 bg-blue-500 text-white rounded-md shadow-md hover:bg-blue-600 transition-all">
Paris
</UButton>
<UButton
@click="searchWeather('New York')"
class="px-6 py-2 bg-blue-500 text-white rounded-md shadow-md hover:bg-blue-600 transition-all">
New York
</UButton>
<UButton
@click="searchWeather('Los Angeles')"
class="px-6 py-2 bg-blue-500 text-white rounded-md shadow-md hover:bg-blue-600 transition-all">
Los Angeles
</UButton>
</div>

<!-- Weather Forecast Header -->
<div v-if="forecast.length > 0" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-5 gap-6 p-6">
<h2 class="text-center text-2xl font-bold col-span-full">Weather Forecast for {{ location }}</h2>
</div>

<!-- Weather Cards -->
<div v-if="forecast.length > 0" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-5 gap-6 p-6">
<WeatherCard v-for="(day, index) in forecast" :key="index" :day="day" />
</div>

<!-- Error Message -->
<div v-else class="text-center text-gray-600">
<UAlert v-if="error" :title="error" color="red" />
</div>
<!-- App Header -->
<header class="text-center py-6">
<h1 class="text-5xl font-extrabold tracking-wide">YoyoWeather</h1>
<p class="text-xl mt-2 font-light">Your 5-Day Weather Forecast Companion</p>
</header>

<!-- Search Bar -->
<div class="flex justify-center my-8 gap-2 md:gap-4 flex-col md:flex-row">
<UInput class="w-full md:w-1/2 bg-white text-gray-800 rounded-md shadow-lg focus:ring-2 focus:ring-blue-500"
v-model="location" variant="outline" placeholder="Enter a location for the weather forecast" />
<UButton @click="searchWeather(location)" label="Search"
class="px-6 py-2 bg-green-500 text-white rounded-md shadow-md hover:bg-green-600 transition-all" />
</div>

<!-- Quick Location Buttons -->
<div class="flex justify-center my-8 gap-2 md:gap-4 flex-col md:flex-row">
<UButton @click="searchWeather('London')"
class="px-6 py-2 bg-blue-500 text-white rounded-md shadow-md hover:bg-blue-600 transition-all">
London
</UButton>
<UButton @click="searchWeather('Paris')"
class="px-6 py-2 bg-blue-500 text-white rounded-md shadow-md hover:bg-blue-600 transition-all">
Paris
</UButton>
<UButton @click="searchWeather('New York')"
class="px-6 py-2 bg-blue-500 text-white rounded-md shadow-md hover:bg-blue-600 transition-all">
New York
</UButton>
<UButton @click="searchWeather('Los Angeles')"
class="px-6 py-2 bg-blue-500 text-white rounded-md shadow-md hover:bg-blue-600 transition-all">
Los Angeles
</UButton>
<!-- New Button for Current Location -->
<UButton @click="getCurrentLocation"
class="px-6 py-2 bg-yellow-500 text-white rounded-md shadow-md hover:bg-yellow-600 transition-all">
Use My Location
</UButton>
</div>

<!-- Weather Forecast Header -->
<div v-if="forecast.length > 0" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-5 gap-6 p-6">
<h2 class="text-center text-2xl font-bold col-span-full">Weather Forecast for {{ location }}</h2>
</div>

<!-- Weather Cards -->
<div v-if="forecast.length > 0" class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-5 gap-6 p-6">
<WeatherCard v-for="(day, index) in forecast" :key="index" :day="day" />
</div>

<!-- Error Message -->
<div v-else class="text-center text-gray-600">
<UAlert v-if="error" :title="error" color="red" />
</div>
</div>
</template>
</template>

<script setup lang="ts">
import { ref } from 'vue'
Expand All @@ -81,7 +75,6 @@ const forecast = ref<Forecast[]>([])
const error = ref<string>('')
const searchWeather = async (defaultLocation: string = '') => {
if (defaultLocation) {
location.value = defaultLocation
}
Expand All @@ -100,22 +93,8 @@ const searchWeather = async (defaultLocation: string = '') => {
if (geoData.results && geoData.results.length > 0) {
const { latitude, longitude } = geoData.results[0]
// Step 2: Get weather forecast from the Weather API
const weatherResponse = await fetch(
`https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}&daily=temperature_2m_max,temperature_2m_min,weathercode,windspeed_10m_max&timezone=auto`
)
const weatherData = await weatherResponse.json()
// Get the forecast for the next 5 days
forecast.value = weatherData.daily.time.slice(0, 5).map((date: string, index: number) => ({
date: new Date(date).toLocaleDateString('en-US', { weekday: 'long', day: 'numeric' }),
icon: getWeatherIcon(weatherData.daily.weathercode[index]),
description: getWeatherDescription(weatherData.daily.weathercode[index]),
temperature: Math.round(weatherData.daily.temperature_2m_max[index]),
windSpeed: Math.round(weatherData.daily.windspeed_10m_max[index])
}))
error.value = ''
// Use the reusable function to get the weather data
await fetchWeatherByCoordinates(latitude, longitude)
} else {
toast.add({ title: 'Location not found. Please try another search.', color: 'red' })
error.value = 'Location not found. Please try another search.'
Expand All @@ -125,6 +104,40 @@ const searchWeather = async (defaultLocation: string = '') => {
}
}
const fetchWeatherByCoordinates = async (latitude: number, longitude: number) => {
try {
const weatherResponse = await fetch(
`https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}&daily=temperature_2m_max,temperature_2m_min,weathercode,windspeed_10m_max&timezone=auto`
)
const weatherData = await weatherResponse.json()
forecast.value = weatherData.daily.time.slice(0, 5).map((date: string, index: number) => ({
date: new Date(date).toLocaleDateString('en-US', { weekday: 'long', day: 'numeric' }),
icon: getWeatherIcon(weatherData.daily.weathercode[index]),
description: getWeatherDescription(weatherData.daily.weathercode[index]),
temperature: Math.round(weatherData.daily.temperature_2m_max[index]),
windSpeed: Math.round(weatherData.daily.windspeed_10m_max[index]),
}))
error.value = ''
} catch (err) {
error.value = 'There was an error fetching the weather data.'
}
}
const getCurrentLocation = () => {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(async (position) => {
const { latitude, longitude } = position.coords
await fetchWeatherByCoordinates(latitude, longitude)
}, () => {
error.value = 'Unable to retrieve your location.'
})
} else {
error.value = 'Geolocation is not supported by this browser.'
}
}
// Helper functions
const getWeatherIcon = (code: number) => {
Expand Down

0 comments on commit 6cfc0e5

Please sign in to comment.