feat: add weather widget
All checks were successful
renovate / renovate (push) Successful in 1m3s
test-build / build (push) Successful in 1m47s

This commit is contained in:
2026-02-10 21:42:04 -06:00
parent 63cbcdf39b
commit b6dfc738f1
15 changed files with 164 additions and 25 deletions

View File

@@ -11,7 +11,7 @@ interface Props {
}
---
<section class="lg:px- relative mx-auto mb-20 max-w-[85rem] px-4 pt-30 pb-30 sm:px-6">
<section class="lg:px- relative mx-auto mb-20 max-w-340 px-4 pt-30 pb-30 sm:px-6">
<div
class="smooth-reveal absolute top-[55%] left-0 scale-90 md:top-[20%] xl:top-[25%] xl:left-[10%]"
>

View File

@@ -18,7 +18,7 @@ const recentPosts = posts
.slice(0, 3);
---
<section class="mx-auto mb-20 max-w-[85rem] px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full">
<section class="mx-auto mb-20 max-w-340 px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full">
<div class="mx-auto mb-10 max-w-2xl text-center lg:mb-14">
<h1
class="smooth-reveal block text-4xl font-bold text-neutral-800 md:text-5xl md:leading-tight lg:text-5xl dark:text-neutral-200"

View File

@@ -54,7 +54,7 @@ const shadowClasses = 'shadow-xs hover:shadow-lg';
<div class="relative h-1.5 w-full overflow-hidden rounded-full bg-stone-500/20 sm:h-2 dark:bg-stone-500/20">
<div
class="progress-bar-animate from-steel via-bermuda to-steel absolute top-0 left-0 h-full rounded-full bg-gradient-to-r transition-all duration-1000"
class="progress-bar-animate from-steel via-bermuda to-steel absolute top-0 left-0 h-full rounded-full bg-linear-to-r transition-all duration-1000"
style={`width: ${skill.level}%`}
/>
</div>
@@ -70,13 +70,13 @@ const shadowClasses = 'shadow-xs hover:shadow-lg';
}
</div>
<!-- Gradient overlays for smooth fade effect -->
<!-- Gradient overlays -->
<div
class="absolute top-0 bottom-0 left-0 z-10 w-12 bg-gradient-to-r from-neutral-200 to-transparent sm:w-24 dark:from-stone-700"
class="absolute top-0 bottom-0 left-0 z-10 w-12 bg-linear-to-r from-neutral-200 to-transparent sm:w-24 dark:from-stone-700"
>
</div>
<div
class="absolute top-0 right-0 bottom-0 z-10 w-12 bg-gradient-to-l from-neutral-200 to-transparent sm:w-24 dark:from-stone-700"
class="absolute top-0 right-0 bottom-0 z-10 w-12 bg-linear-to-l from-neutral-200 to-transparent sm:w-24 dark:from-stone-700"
>
</div>
</div>
@@ -85,7 +85,7 @@ const shadowClasses = 'shadow-xs hover:shadow-lg';
<script>
document.addEventListener('astro:page-load', () => {
// Create seamless infinite scrolling effect
// Create infinite scrolling effect
function setupInfiniteScroll() {
const cards = document.querySelectorAll('.skill-card');
if (!cards.length) return;

View File

@@ -0,0 +1,58 @@
---
import { getFiveDayForecast } from '@support/weather';
const { latitude = "44.95", longitude = "-93.09", cityName = "St. Paul, Minnesota" } = Astro.props;
const { forecastDays, error } = await getFiveDayForecast(latitude, longitude);
const borderClasses = 'border border-neutral-100 dark:border-stone-500/20';
const bgColorClasses = 'bg-neutral-100/80 hover:bg-neutral-100 dark:bg-neutral-800/60 dark:hover:bg-neutral-800/90';
const shadowClasses = 'shadow-xs hover:shadow-md dark:shadow-md dark:hover:shadow-lg';
---
<section class="mx-auto mb-20 max-w-340 px-4 py-10 sm:px-6 lg:px-8 lg:py-14 2xl:max-w-full">
<div class="mx-auto mb-10 max-w-2xl text-center lg:mb-14">
<h1 class="smooth-reveal block text-4xl font-bold text-neutral-800 md:text-5xl md:leading-tight lg:text-5xl dark:text-neutral-200">
Weather in my Area
</h1>
<div class="smooth-reveal mx-auto mt-5 max-w-3xl text-center">
<p class="text-lg text-pretty text-neutral-600 dark:text-neutral-400">
5 day forecast for {cityName}
</p>
</div>
</div>
{error ? (
<div class={`rounded-xl p-10 text-center text-yellow-500 ${borderClasses} ${bgColorClasses}`}>
{error}
</div>
) : (
<div class="flex flex-wrap justify-center gap-4 lg:gap-6">
{forecastDays.map((day) => (
<div class="smooth-reveal-2 group flex flex-col">
<div class={`rounded-xl duration-300 transition-all w-32 md:w-44 ${borderClasses} ${bgColorClasses} ${shadowClasses}`}>
<div class="p-4 text-center">
<span class="block text-xs font-bold tracking-widest text-neutral-500 uppercase dark:text-neutral-400">
{day.dayName}
</span>
<div class="flex justify-center my-2">
<img
src={`https://openweathermap.org/img/wn/${day.icon}@2x.png`}
alt={day.label}
class="h-12 w-12 drop-shadow-sm group-hover:scale-110 transition-transform duration-300"
/>
</div>
<div class="mt-2">
<span class="group-hover:text-steel dark:group-hover:text-bermuda transition-all duration-300 block text-2xl font-bold text-neutral-600 dark:text-neutral-300">
{day.temp}°F
</span>
<span class="mt-1 block text-xs text-neutral-500 dark:text-neutral-400 capitalize">
{day.label}
</span>
</div>
</div>
</div>
</div>
))}
</div>
)}
</section>