mirror of
https://github.com/ArthurDanjou/arthome.git
synced 2026-01-14 12:14:33 +01:00
Add weather and map
This commit is contained in:
@@ -8,5 +8,10 @@ NUXT_OAUTH_GOOGLE_CLIENT_ID=
|
||||
NUXT_OAUTH_GOOGLE_CLIENT_SECRET=
|
||||
NUXT_OAUTH_GOOGLE_REDIRECT_URL=
|
||||
|
||||
NUXT_OPEN_WEATHER_API_KEY=
|
||||
NUXT_OPEN_WEATHER_LAT=
|
||||
NUXT_OPEN_WEATHER_LON=
|
||||
NUXT_OPEN_WEATHER_LANG=
|
||||
NUXT_OPEN_WEATHER_UNITS=
|
||||
|
||||
NUXT_HUB_PROJECT_KEY=
|
||||
@@ -1,6 +0,0 @@
|
||||
export default defineAppConfig({
|
||||
ui: {
|
||||
primary: 'lime',
|
||||
gray: 'neutral',
|
||||
},
|
||||
})
|
||||
30
app/app.vue
30
app/app.vue
@@ -34,25 +34,27 @@ defineShortcuts({
|
||||
<div>
|
||||
<NuxtLoadingIndicator color="#808080" />
|
||||
<UContainer>
|
||||
<div class="absolute top-2 right-2 flex gap-2">
|
||||
<UTooltip v-if="loggedIn" text="Click to logout">
|
||||
<ClientOnly>
|
||||
<div class="absolute top-2 right-2 flex gap-2">
|
||||
<UTooltip v-if="loggedIn" text="Déconnexion">
|
||||
<UButton
|
||||
:label="user.name"
|
||||
color="gray"
|
||||
square
|
||||
trailing-icon="i-ph:person-arms-spread-duotone"
|
||||
variant="ghost"
|
||||
@click="clear"
|
||||
/>
|
||||
</UTooltip>
|
||||
<UButton
|
||||
:label="`Hello ${user.name}`"
|
||||
:icon="$colorMode.preference === 'dark' ? 'i-ph:moon-duotone' : 'i-ph:sun-duotone'"
|
||||
color="gray"
|
||||
square
|
||||
trailing-icon="i-ph:person-arms-spread-duotone"
|
||||
variant="ghost"
|
||||
@click="clear"
|
||||
@click="toggleColorMode"
|
||||
/>
|
||||
</UTooltip>
|
||||
<UButton
|
||||
:icon="$colorMode.preference === 'dark' ? 'i-ph:moon-duotone' : 'i-ph:sun-duotone'"
|
||||
color="gray"
|
||||
square
|
||||
variant="ghost"
|
||||
@click="toggleColorMode"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</ClientOnly>
|
||||
<NuxtPage />
|
||||
</UContainer>
|
||||
</div>
|
||||
|
||||
@@ -8,7 +8,7 @@ defineProps<{
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<section>
|
||||
<h1 class="font-bold text-xl mb-4">
|
||||
{{ title }}
|
||||
</h1>
|
||||
@@ -19,7 +19,7 @@ defineProps<{
|
||||
<span class="relative inline-flex rounded-full h-4 w-4 bg-green-500" />
|
||||
</div>
|
||||
<UCard
|
||||
:ui="{ body: { base: 'space-y-4 h-full' }, background: 'h-full duration-300 bg-white hover:bg-gray-100 dark:bg-gray-900 dark:hover:bg-gray-800' }"
|
||||
:ui="{ body: { base: 'h-full' }, background: 'h-full duration-300 bg-white hover:bg-gray-100 dark:bg-gray-900 dark:hover:bg-gray-800' }"
|
||||
>
|
||||
<div class="flex gap-4 items-center h-full">
|
||||
<UBadge :color="app.color" class="p-2" variant="soft">
|
||||
@@ -51,5 +51,5 @@ defineProps<{
|
||||
</UCard>
|
||||
</ULink>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
45
app/components/Map.vue
Normal file
45
app/components/Map.vue
Normal file
@@ -0,0 +1,45 @@
|
||||
<script lang="ts" setup>
|
||||
const config = useRuntimeConfig()
|
||||
|
||||
const coordinates = ref<[number, number]>([2.179040, 48.877419])
|
||||
const zoom = ref(11)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ClientOnly>
|
||||
<UCard :ui="{ base: 'h-72 md:col-span-2', body: { padding: '' } }">
|
||||
<div class="relative">
|
||||
<MapboxMap
|
||||
:options="{
|
||||
accessToken: config.public.mapbox.accessToken,
|
||||
style: config.public.mapbox.style,
|
||||
center: coordinates,
|
||||
zoom,
|
||||
projection: 'globe',
|
||||
}"
|
||||
class="absolute h-72"
|
||||
map-id="map"
|
||||
>
|
||||
<MapboxDefaultMarker
|
||||
:lnglat="coordinates"
|
||||
:options="{
|
||||
color: '#808080',
|
||||
size: 1.5,
|
||||
}"
|
||||
marker-id="marker"
|
||||
/>
|
||||
</MapboxMap>
|
||||
</div>
|
||||
</UCard>
|
||||
</ClientOnly>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.mapboxgl-control-container {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.mapboxgl-canvas {
|
||||
border-radius: 1rem;
|
||||
}
|
||||
</style>
|
||||
34
app/components/Weather.vue
Normal file
34
app/components/Weather.vue
Normal file
@@ -0,0 +1,34 @@
|
||||
<script lang="ts" setup>
|
||||
import type { WeatherType } from '~~/types/types'
|
||||
|
||||
const { data: weather } = await useFetch<WeatherType>('/api/weather')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section>
|
||||
<UCard v-if="weather" :ui="{ base: 'h-full' }">
|
||||
<template #header>
|
||||
<div class="flex items-center gap-2 text-blue-600 dark:text-blue-300">
|
||||
<UIcon name="i-ph:cloud-duotone" size="24" />
|
||||
<h3 class="font-bold text-lg">
|
||||
Météo
|
||||
</h3>
|
||||
</div>
|
||||
</template>
|
||||
<template #default>
|
||||
<div class="flex items-center h-full">
|
||||
<p class="text-lg h-full">
|
||||
Il fait actuellement
|
||||
<span class="text-blue-600 dark:text-blue-300">{{ weather.weather }}</span>
|
||||
à
|
||||
<span>{{ weather.city }}</span>,
|
||||
avec une température de
|
||||
<span class="text-blue-600 dark:text-blue-300">{{ weather.temp }}
|
||||
</span>
|
||||
°C
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
</UCard>
|
||||
</section>
|
||||
</template>
|
||||
@@ -16,20 +16,26 @@ const social = apps.filter(app => app._dir === 'social')
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<main class="my-8">
|
||||
<main class="my-12">
|
||||
<div v-if="date" class="flex flex-col items-center">
|
||||
<h1 class="text-6xl font-bold">
|
||||
{{ useDateFormat(date, 'HH:mm') }}
|
||||
<h1 class="text-6xl md:text-9xl font-bold">
|
||||
{{ useDateFormat(date, 'HH') }}
|
||||
<span class="animate-pulse">:</span>
|
||||
{{ useDateFormat(date, 'mm') }}
|
||||
</h1>
|
||||
<h1 class="text-2xl">
|
||||
<h1 class="text-2xl md:text-5xl">
|
||||
{{ useDateFormat(date, 'dddd D MMMM YYYY', { locales: () => 'fr-FR' }) }}
|
||||
</h1>
|
||||
</div>
|
||||
<div v-if="apps" class="space-y-12">
|
||||
<Application :apps="perso" title="Personal" />
|
||||
<div v-if="apps" class="space-y-12 mt-12">
|
||||
<section class="grid grid-cols-1 auto-rows-auto sm:grid-cols-3 gap-8">
|
||||
<Weather />
|
||||
<Map />
|
||||
</section>
|
||||
<Application :apps="perso" title="Personnel" />
|
||||
<Application :apps="social" title="Social" />
|
||||
<Application :apps="dev" title="Development" />
|
||||
<Application :apps="maths" title="Mathematics" />
|
||||
<Application :apps="dev" title="Développement" />
|
||||
<Application :apps="maths" title="Mathématiques" />
|
||||
</div>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
16
content/dev/hoppscotch.json
Normal file
16
content/dev/hoppscotch.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "HoppScotch.io",
|
||||
"url": "https://hoppscotch.io/",
|
||||
"tags": [
|
||||
{
|
||||
"name": "Dev",
|
||||
"color": "blue"
|
||||
},
|
||||
{
|
||||
"name": "Doc",
|
||||
"color": "purple"
|
||||
}
|
||||
],
|
||||
"icon": "i-simple-icons:hoppscotch",
|
||||
"color": "teal"
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
"url": "https://www.geogebra.org/calculator",
|
||||
"tags": [
|
||||
{
|
||||
"name": "maths",
|
||||
"name": "Maths",
|
||||
"color": "amber"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"url": "https://mathdf.com/fr/",
|
||||
"tags": [
|
||||
{
|
||||
"name": "maths",
|
||||
"name": "Maths",
|
||||
"color": "amber"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"url": "https://www.wolframalpha.com/",
|
||||
"tags": [
|
||||
{
|
||||
"name": "maths",
|
||||
"name": "Maths",
|
||||
"color": "amber"
|
||||
}
|
||||
],
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"url": "https://www.microsoft365.com/?auth=2",
|
||||
"tags": [
|
||||
{
|
||||
"name": "Studies",
|
||||
"name": "Etudes",
|
||||
"color": "sky"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"url": "https://outlook.office.com/mail/",
|
||||
"tags": [
|
||||
{
|
||||
"name": "Studies",
|
||||
"name": "Etudes",
|
||||
"color": "sky"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -22,7 +22,8 @@ export default defineNuxtConfig({
|
||||
'nuxt-auth-utils',
|
||||
'@nuxt/content',
|
||||
'@nuxthq/studio',
|
||||
"@nuxt/image"
|
||||
'@nuxt/image',
|
||||
'nuxt-mapbox',
|
||||
],
|
||||
|
||||
// Nuxt UI
|
||||
@@ -71,8 +72,18 @@ export default defineNuxtConfig({
|
||||
|
||||
// Nuxt Env
|
||||
runtimeConfig: {
|
||||
openWeather: {
|
||||
apiKey: '',
|
||||
lat: '',
|
||||
lon: '',
|
||||
lang: '',
|
||||
units: '',
|
||||
},
|
||||
public: {
|
||||
test: '',
|
||||
mapbox: {
|
||||
style: '',
|
||||
accessToken: '',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
@@ -35,6 +35,8 @@
|
||||
"eslint": "^9.9.0",
|
||||
"typescript": "^5.5.4",
|
||||
"vue-tsc": "^2.0.29",
|
||||
"wrangler": "^3.72.1"
|
||||
"wrangler": "^3.72.1",
|
||||
"mapbox-gl": "^3.6.0",
|
||||
"nuxt-mapbox": "^1.6.0"
|
||||
}
|
||||
}
|
||||
|
||||
725
pnpm-lock.yaml
generated
725
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
25
server/api/weather.get.ts
Normal file
25
server/api/weather.get.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import type { OpenWeatherType } from '~~/types/types'
|
||||
|
||||
export default defineCachedEventHandler(async (event) => {
|
||||
const config = useRuntimeConfig(event)
|
||||
console.log(config.openWeather)
|
||||
|
||||
const openWeather = await $fetch<OpenWeatherType>('https://api.openweathermap.org/data/2.5/weather', {
|
||||
params: {
|
||||
lat: config.openWeather.lat,
|
||||
lon: config.openWeather.lon,
|
||||
appid: config.openWeather.apiKey,
|
||||
lang: config.openWeather.lang,
|
||||
units: config.openWeather.units,
|
||||
},
|
||||
})
|
||||
console.log(openWeather)
|
||||
return {
|
||||
weather: openWeather.weather[0].description,
|
||||
city: openWeather.name,
|
||||
temp: openWeather.main.feels_like,
|
||||
}
|
||||
}, {
|
||||
maxAge: 60 * 60, // 1 hour
|
||||
name: 'weather',
|
||||
})
|
||||
@@ -14,3 +14,22 @@ export interface Tag {
|
||||
name: string
|
||||
color: string
|
||||
}
|
||||
|
||||
export interface OpenWeatherType {
|
||||
weather: Array<{
|
||||
description: string
|
||||
}>
|
||||
main: {
|
||||
feels_like: number
|
||||
}
|
||||
name: string
|
||||
}
|
||||
|
||||
export interface WeatherType {
|
||||
city: string
|
||||
weather: {
|
||||
type: string
|
||||
description: string
|
||||
}
|
||||
temp: number
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user