feat: add weather widget
This commit is contained in:
@@ -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%]"
|
||||
>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
|
||||
58
src/components/ui/sections/WeatherSection.astro
Normal file
58
src/components/ui/sections/WeatherSection.astro
Normal 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>
|
||||
Reference in New Issue
Block a user