Daily fixes and loading animations

This commit is contained in:
2026-06-24 11:08:23 -04:00
parent 811780125e
commit 8019dabe2a
4 changed files with 96 additions and 23 deletions

View File

@@ -1,8 +1,9 @@
<script setup lang="ts">
import Loading from '@/components/Loading.vue';
import {onMounted, ref} from 'vue';
import {api, BASE} from '../services/api';
import {api} from '../services/api';
const data = ref<any>({});
const data = ref<any>();
function dir(deg: number) {
if(deg > 22.5 && deg <= 67.5) return 'NE';
@@ -17,13 +18,12 @@ function dir(deg: number) {
onMounted(async () => {
data.value = await api.current();
console.log(data.value);
});
</script>
<style scoped lang="scss">
.today-card {
position: relative;
border-radius: 12px;
background: var(--surface);
border: 1px solid var(--border);
@@ -123,18 +123,26 @@ onMounted(async () => {
<template>
<div class="today-card">
<div class="flex-r align-items-center justify-between px-3">
<div class="flex-c justify-center align-items-center">
<img v-if="data.icon" :src="'https://openweathermap.org/img/wn/' + data.icon + '@2x.png'" class="today-icon" alt="weather" />
<div class="flex-r align-items-center justify-between">
<div v-if="!data" class="pos-rel br-2 overflow-hidden" style="width: 75px; height: 50px"><Loading/></div>
<div v-else class="flex-c justify-center align-items-center mx-3">
<img :src="'https://openweathermap.org/img/wn/' + data.icon + '@2x.png'" class="today-icon" alt="weather" />
<div class="today-label">{{ data.label }}</div>
</div>
<div class="flex-r align-items-center gap-2">
<div class="fs-6">
{{ data.temperature?.toFixed(0) }}°C
<div class="fs-6 m-0 p-0 flex-r align-items-center">
<div v-if="!data" class="d-inline-block pos-rel br-2 overflow-hidden" style="width: 50px; height: 1em"><Loading/></div>
<template v-else>{{ Math.round(data.temperature) }}°C</template>
</div>
<div class="flex-c fg-muted">
<span class="hi"> {{ 0 }}°</span>
<span class="lo"> {{ 0 }}°</span>
<div class="hi">
<div v-if="!data" class="d-inline-block pos-rel br-2 overflow-hidden" style="width: 25px; height: 1em"><Loading/></div>
<template v-else>{{ 0 }}°</template>
</div>
<div class="lo">
<div v-if="!data" class="d-inline-block pos-rel br-2 overflow-hidden" style="width: 25px; height: 1em"><Loading/></div>
<template v-else>{{ 0 }}°</template>
</div>
</div>
</div>
</div>
@@ -142,12 +150,35 @@ onMounted(async () => {
<div class="divider" />
<div class="stat-grid">
<div class="stat"><span class="stat-label">Precipitation</span><span class="stat-value">{{ !data.precipitation && data.raining == 'True' ? 'Spitting' : (data.precipitation || 0).toFixed(1) + 'mm'}}</span></div>
<div class="stat"><span class="stat-label">Humidity</span><span class="stat-value">{{ (data.humidity || 0).toFixed(0) }}%</span></div>
<div class="stat"><span class="stat-label">Wind</span><span class="stat-value">{{ data.wind_gusts || 0 }} Kph <span class="fg-muted">({{ dir(data.wind_direction || 0) }})</span></span></div>
<div class="stat"><span class="stat-label">Clouds</span><span class="stat-value">{{ (data.clouds || 0).toFixed(0) }}%</span></div>
<div class="stat"><span class="stat-label">Air Quality</span><span class="stat-value">{{ data.air_quality }} <span class="fg-muted">({{data.air_quality_label}})</span></span></div>
<div class="stat"><span class="stat-label">UV index</span><span class="stat-value">{{ (data.uv_index || 0).toFixed(1) }} <span class="fg-muted">({{data.uv_index_label}})</span></span></div>
<div class="stat">
<span class="stat-label">Precipitation</span>
<div v-if="!data" class="w-100 pos-rel br-2 overflow-hidden" style="height: 1.75em"><Loading/></div>
<span v-else class="stat-value">{{ !data.precipitation && data.raining == 'True' ? 'Spitting' : data.precipitation.toFixed(1) + 'mm'}}</span>
</div>
<div class="stat">
<span class="stat-label">Humidity</span>
<div v-if="!data" class="w-100 pos-rel br-2 overflow-hidden" style="height: 1.75em"><Loading/></div>
<span v-else class="stat-value">{{ Math.round(data.humidity) }}%</span>
</div>
<div class="stat">
<span class="stat-label">Wind</span>
<div v-if="!data" class="w-100 pos-rel br-2 overflow-hidden" style="height: 1.75em"><Loading/></div>
<span v-else class="stat-value">{{ data.wind_gusts }} Kph <span class="fg-muted">({{ dir(data.wind_direction) }})</span></span>
</div>
<div class="stat">
<span class="stat-label">Clouds</span>
<div v-if="!data" class="w-100 pos-rel br-2 overflow-hidden" style="height: 1.75em"><Loading/></div>
<span v-else class="stat-value">{{ Math.round(data.clouds) }}%</span></div>
<div class="stat">
<span class="stat-label">Air Quality</span>
<div v-if="!data" class="w-100 pos-rel br-2 overflow-hidden" style="height: 1.75em"><Loading/></div>
<span v-else class="stat-value">{{ data.air_quality }} <span class="fg-muted">({{data.air_quality_label}})</span></span>
</div>
<div class="stat">
<span class="stat-label">UV index</span>
<div v-if="!data" class="w-100 pos-rel br-2 overflow-hidden" style="height: 1.75em"><Loading/></div>
<span v-else class="stat-value">{{ data.uv_index.toFixed(1) }} <span class="fg-muted">({{data.uv_index_label}})</span></span>
</div>
</div>
</div>
</template>

View File

@@ -0,0 +1,43 @@
<style scoped lang="scss">
.shimmer {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.stroke {
height: 100%;
width: 100%;
background: #777;
}
.dark .animate {
animation: shimmer 3s infinite;
background: linear-gradient(90deg, #ffffff10 25%, #ffffff30 50%, #ffffff10 75%);
background-size: 200% 100%;
}
.animate {
animation: shimmer 3s infinite;
background: linear-gradient(to right, #e6e6e6 0%, #cccccc 50%, #e6e6e6 100%);
background-size: 200% 100%;
}
@keyframes shimmer {
from {
background-position: 200% 0;
}
to {
background-position: -200% 0;
}
}
</style>
<template>
<div class="shimmer">
<div class="stroke animate"></div>
</div>
</template>