feat: add weather widget to user portal below navbar
This commit is contained in:
@@ -42,6 +42,16 @@ export async function GET() {
|
||||
[userId]
|
||||
);
|
||||
|
||||
// Get weather
|
||||
let weather = undefined;
|
||||
try {
|
||||
const weatherRes = await fetch('http://localhost:3000/api/weather');
|
||||
if (weatherRes.ok) {
|
||||
const weatherData = await weatherRes.json();
|
||||
weather = weatherData.data;
|
||||
}
|
||||
} catch { /* ignore */ }
|
||||
|
||||
return NextResponse.json({
|
||||
reservations,
|
||||
coupons,
|
||||
@@ -49,6 +59,7 @@ export async function GET() {
|
||||
benefits: benefits.map((b: { text: string }) => b.text),
|
||||
wifiPassword,
|
||||
trips,
|
||||
weather,
|
||||
});
|
||||
} catch (error) {
|
||||
if ((error as Error).message === 'Unauthorized') {
|
||||
|
||||
+36
-1
@@ -20,10 +20,16 @@ interface Message {
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
interface Weather {
|
||||
current: { celsius: number; fahrenheit: number; summary: string; windspeed: number; weathercode: number };
|
||||
today: { maxC: number; minC: number; maxF: number; minF: number; summary: string; weathercode: number };
|
||||
}
|
||||
|
||||
interface PortalData {
|
||||
trips: Trip[];
|
||||
wifiPassword: string;
|
||||
messages: Message[];
|
||||
weather?: Weather;
|
||||
}
|
||||
|
||||
const gold = '#E8A849';
|
||||
@@ -123,10 +129,39 @@ export default function UserPage() {
|
||||
|
||||
return (
|
||||
<main style={{ padding: '2rem', maxWidth: '64rem', margin: '0 auto' }}>
|
||||
<h1 style={{ fontSize: 'clamp(28px, 4vw, 42px)', fontWeight: 400, fontStyle: 'italic', color: navy, margin: '0 0 2rem' }}>
|
||||
<h1 style={{ fontSize: 'clamp(28px, 4vw, 42px)', fontWeight: 400, fontStyle: 'italic', color: navy, margin: '0 0 1.5rem' }}>
|
||||
Your Portal
|
||||
</h1>
|
||||
|
||||
{/* Weather Widget - Always visible below navbar */}
|
||||
{data.weather && (
|
||||
<div style={{ background: 'linear-gradient(135deg, #010D1E 0%, #1a2a3a 100%)', borderRadius: '16px', padding: '1.25rem 1.5rem', marginBottom: '2rem', display: 'flex', alignItems: 'center', gap: '2rem', flexWrap: 'wrap', boxShadow: '0 4px 16px rgba(1,13,30,0.2)' }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>
|
||||
<div style={{ fontSize: '48px' }}>
|
||||
{data.weather.current.weathercode <= 1 ? '☀️' : data.weather.current.weathercode === 2 ? '⛅' : data.weather.current.weathercode === 3 ? '☁️' : data.weather.current.weathercode >= 51 && data.weather.current.weathercode <= 55 ? '🌧️' : data.weather.current.weathercode >= 61 ? '🌧️' : '☀️'}
|
||||
</div>
|
||||
<div>
|
||||
<div style={{ fontSize: '28px', fontWeight: 600, color: '#fff' }}>{data.weather.current.celsius}°C</div>
|
||||
<div style={{ fontSize: '13px', color: 'rgba(255,255,255,0.7)' }}>{data.weather.current.summary}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ display: 'flex', gap: '2rem', flex: 1, justifyContent: 'flex-end', flexWrap: 'wrap' }}>
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<div style={{ fontSize: '11px', color: 'rgba(255,255,255,0.6)', textTransform: 'uppercase', letterSpacing: '0.05em' }}>High</div>
|
||||
<div style={{ fontSize: '20px', fontWeight: 500, color: '#E8A849' }}>{data.weather.today.maxC}°</div>
|
||||
</div>
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<div style={{ fontSize: '11px', color: 'rgba(255,255,255,0.6)', textTransform: 'uppercase', letterSpacing: '0.05em' }}>Low</div>
|
||||
<div style={{ fontSize: '20px', fontWeight: 500, color: '#88b4e8' }}>{data.weather.today.minC}°</div>
|
||||
</div>
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<div style={{ fontSize: '11px', color: 'rgba(255,255,255,0.6)', textTransform: 'uppercase', letterSpacing: '0.05em' }}>Wind</div>
|
||||
<div style={{ fontSize: '16px', color: '#fff' }}>{data.weather.current.windspeed} km/h</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Welcome Message - Show on reservation day */}
|
||||
{activeTrip && (
|
||||
<Section title="Welcome!" highlight>
|
||||
|
||||
Reference in New Issue
Block a user