daily-briefing/web/src/components/WeatherCard.tsx

95 lines
3 KiB
TypeScript
Raw Normal View History

import { Thermometer, Droplets, Wind, CloudOff } from "lucide-react";
import type { WeatherData } from "../api";
interface WeatherCardProps {
data: WeatherData;
accent: "cyan" | "amber";
}
const ACCENT = {
cyan: { strip: "gold", text: "text-gold", glow: "data-glow-gold", tag: "border-gold/30 text-gold bg-gold/5" },
amber: { strip: "mint", text: "text-mint", glow: "data-glow-mint", tag: "border-mint/30 text-mint bg-mint/5" },
} as const;
export default function WeatherCard({ data, accent }: WeatherCardProps) {
const a = ACCENT[accent];
if (data.error) {
return (
<div className="deck-card p-5 animate-fade-in">
<div className="flex items-center gap-3 text-cherry">
<CloudOff className="w-5 h-5" />
<div>
<p className="text-sm font-medium">Wetter nicht verfügbar</p>
<p className="text-xs text-base-600 mt-0.5">{data.location || "Unbekannt"}</p>
</div>
</div>
</div>
);
}
return (
<div className="deck-card corner-marks p-6 animate-fade-in" data-accent={a.strip}>
{/* Location tag */}
<div className="mb-5">
<span className={`tag ${a.tag}`}>{data.location}</span>
</div>
{/* Temperature hero */}
<div className="flex items-start justify-between mb-6">
<div>
<div className="flex items-baseline gap-0.5">
<span className={`text-5xl font-mono font-bold ${a.text} ${a.glow} tracking-tighter`}>
{Math.round(data.temp)}
</span>
<span className="text-xl font-light text-base-500">°</span>
</div>
<p className="text-sm text-base-600 mt-1 capitalize font-light">{data.description}</p>
</div>
<span className="text-5xl select-none opacity-80" role="img" aria-label="weather">
{data.icon}
</span>
</div>
{/* Stats row */}
<div className="grid grid-cols-3 gap-px bg-base-300">
<StatCell
icon={<Thermometer className="w-3 h-3 text-base-500" />}
label="Gefühlt"
value={`${Math.round(data.feels_like)}°`}
/>
<StatCell
icon={<Droplets className="w-3 h-3 text-base-500" />}
label="Feuchte"
value={`${data.humidity}%`}
/>
<StatCell
icon={<Wind className="w-3 h-3 text-base-500" />}
label="Wind"
value={`${Math.round(data.wind_kmh)}`}
unit="km/h"
/>
</div>
</div>
);
}
function StatCell({ icon, label, value, unit }: {
icon: React.ReactNode;
label: string;
value: string;
unit?: string;
}) {
return (
<div className="flex flex-col items-center gap-1.5 py-3 bg-base-50">
{icon}
<div className="flex items-baseline gap-0.5">
<span className="text-sm data-value text-base-900">{value}</span>
{unit && <span className="text-[9px] text-base-500">{unit}</span>}
</div>
<span className="data-label">{label}</span>
</div>
);
}