2026-03-02 01:48:51 +01:00
|
|
|
import { Thermometer, Droplets, Wind, CloudOff } from "lucide-react";
|
|
|
|
|
import type { WeatherData } from "../api";
|
|
|
|
|
|
|
|
|
|
interface WeatherCardProps {
|
|
|
|
|
data: WeatherData;
|
|
|
|
|
accent: "cyan" | "amber";
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-02 10:54:28 +01:00
|
|
|
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" },
|
2026-03-02 01:48:51 +01:00
|
|
|
} as const;
|
|
|
|
|
|
|
|
|
|
export default function WeatherCard({ data, accent }: WeatherCardProps) {
|
2026-03-02 10:54:28 +01:00
|
|
|
const a = ACCENT[accent];
|
2026-03-02 01:48:51 +01:00
|
|
|
|
|
|
|
|
if (data.error) {
|
|
|
|
|
return (
|
2026-03-02 10:54:28 +01:00
|
|
|
<div className="deck-card p-5 animate-fade-in">
|
|
|
|
|
<div className="flex items-center gap-3 text-cherry">
|
2026-03-02 01:48:51 +01:00
|
|
|
<CloudOff className="w-5 h-5" />
|
|
|
|
|
<div>
|
2026-03-02 10:54:28 +01:00
|
|
|
<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>
|
2026-03-02 01:48:51 +01:00
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (
|
2026-03-02 10:54:28 +01:00
|
|
|
<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>
|
2026-03-02 01:48:51 +01:00
|
|
|
</div>
|
|
|
|
|
|
2026-03-02 10:54:28 +01:00
|
|
|
{/* Temperature hero */}
|
|
|
|
|
<div className="flex items-start justify-between mb-6">
|
2026-03-02 01:48:51 +01:00
|
|
|
<div>
|
2026-03-02 10:54:28 +01:00
|
|
|
<div className="flex items-baseline gap-0.5">
|
|
|
|
|
<span className={`text-5xl font-mono font-bold ${a.text} ${a.glow} tracking-tighter`}>
|
2026-03-02 01:48:51 +01:00
|
|
|
{Math.round(data.temp)}
|
|
|
|
|
</span>
|
2026-03-02 10:54:28 +01:00
|
|
|
<span className="text-xl font-light text-base-500">°</span>
|
2026-03-02 01:48:51 +01:00
|
|
|
</div>
|
2026-03-02 10:54:28 +01:00
|
|
|
<p className="text-sm text-base-600 mt-1 capitalize font-light">{data.description}</p>
|
2026-03-02 01:48:51 +01:00
|
|
|
</div>
|
|
|
|
|
|
2026-03-02 10:54:28 +01:00
|
|
|
<span className="text-5xl select-none opacity-80" role="img" aria-label="weather">
|
2026-03-02 01:48:51 +01:00
|
|
|
{data.icon}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
|
2026-03-02 10:54:28 +01:00
|
|
|
{/* 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)}°`}
|
2026-03-02 01:48:51 +01:00
|
|
|
/>
|
2026-03-02 10:54:28 +01:00
|
|
|
<StatCell
|
|
|
|
|
icon={<Droplets className="w-3 h-3 text-base-500" />}
|
2026-03-02 01:48:51 +01:00
|
|
|
label="Feuchte"
|
|
|
|
|
value={`${data.humidity}%`}
|
|
|
|
|
/>
|
2026-03-02 10:54:28 +01:00
|
|
|
<StatCell
|
|
|
|
|
icon={<Wind className="w-3 h-3 text-base-500" />}
|
2026-03-02 01:48:51 +01:00
|
|
|
label="Wind"
|
2026-03-02 10:54:28 +01:00
|
|
|
value={`${Math.round(data.wind_kmh)}`}
|
|
|
|
|
unit="km/h"
|
2026-03-02 01:48:51 +01:00
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-02 10:54:28 +01:00
|
|
|
function StatCell({ icon, label, value, unit }: {
|
2026-03-02 01:48:51 +01:00
|
|
|
icon: React.ReactNode;
|
|
|
|
|
label: string;
|
|
|
|
|
value: string;
|
2026-03-02 10:54:28 +01:00
|
|
|
unit?: string;
|
2026-03-02 01:48:51 +01:00
|
|
|
}) {
|
|
|
|
|
return (
|
2026-03-02 10:54:28 +01:00
|
|
|
<div className="flex flex-col items-center gap-1.5 py-3 bg-base-50">
|
2026-03-02 01:48:51 +01:00
|
|
|
{icon}
|
2026-03-02 10:54:28 +01:00
|
|
|
<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>
|
2026-03-02 01:48:51 +01:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|