import {
CloudRain,
Droplets,
MapPin,
Navigation,
Sun,
Thermometer,
Wind,
ArrowRight,
Cloud,
type LucideIcon,
} from "lucide-react";
import type { WeatherForecastResponse } from "../../../types/weather";
type Props = {
theme: "dark" | "light";
forecast: WeatherForecastResponse | null;
loading: boolean;
error: string | null;
compact?: boolean;
onOpenMeteo?: () => void;
};
const RADIUS = "rounded-[5px]";
export function WeatherForecastCard({
theme,
forecast,
loading,
error,
compact = false,
onOpenMeteo,
}: Props) {
const isDark = theme === "dark";
if (compact) {
return (
);
}
return (
Previsão meteorológica
{forecast
? `${forecast.location.name}, ${forecast.location.country}`
: "Meteorologia externa"}
Dados externos de previsão
{forecast?.current.condition?.icon && (

)}
{loading ? (
A carregar previsão meteorológica...
) : error ? (
{error}
) : !forecast ? (
Sem previsão meteorológica disponível.
) : (
{forecast.daily.slice(1, 7).map((day) => (
))}
)}
);
}
function TodayForecastHero({
theme,
forecast,
}: {
theme: "dark" | "light";
forecast: WeatherForecastResponse;
}) {
const isDark = theme === "dark";
const today = forecast.daily[0];
return (
{today.condition?.icon && (

)}
Hoje
{formatDay(today.date)}
{Math.round(today.maxTemperatureC)}°
/ {Math.round(today.minTemperatureC)}°
{today.condition?.text ?? "--"}
);
}
function DailyForecastTile({
theme,
day,
}: {
theme: "dark" | "light";
day: WeatherForecastResponse["daily"][number];
}) {
const isDark = theme === "dark";
return (
{formatDay(day.date)}
{day.condition?.text ?? "--"}
{day.condition?.icon && (

)}
{Math.round(day.maxTemperatureC)}°
/ {Math.round(day.minTemperatureC)}°
{day.dailyRainChance}%
UV {day.uv.toFixed(0)}
);
}
function WeatherMiniStat({
theme,
icon: Icon,
label,
value,
}: {
theme: "dark" | "light";
icon: LucideIcon;
label: string;
value: string;
}) {
const isDark = theme === "dark";
return (
);
}
function StateMessage({
theme,
children,
}: {
theme: "dark" | "light";
children: string;
}) {
const isDark = theme === "dark";
return (
{children}
);
}
function formatDay(date: string) {
return new Date(date).toLocaleDateString("pt-PT", {
weekday: "short",
day: "2-digit",
});
}
const eyebrowDark =
"text-[11px] font-bold uppercase tracking-[0.22em] text-slate-500";
const eyebrowLight =
"text-[11px] font-bold uppercase tracking-[0.22em] text-slate-400";
const titleDark = "mt-2 text-xl font-black tracking-[-0.03em] text-slate-100";
const titleLight = "mt-2 text-xl font-black tracking-[-0.03em] text-slate-950";
const subtitleDark = "mt-1 flex items-center gap-2 text-sm text-slate-400";
const subtitleLight = "mt-1 flex items-center gap-2 text-sm text-slate-500";
function CompactWeatherCard({
theme,
forecast,
loading,
error,
onOpenMeteo,
}: {
theme: "dark" | "light";
forecast: WeatherForecastResponse | null;
loading: boolean;
error: string | null;
onOpenMeteo?: () => void;
}) {
const isDark = theme === "dark";
const today = forecast?.daily?.[0];
return (
{forecast
? `${forecast.location.name}, ${forecast.location.country}`
: "Meteorologia"}
{loading ? (
A carregar previsão...
) : error ? (
{error}
) : today ? (
<>
Hoje
{formatDay(today.date)}
{Math.round(today.maxTemperatureC)}°
/ {Math.round(today.minTemperatureC)}°
{today.condition?.text ?? "--"}
Chuva {today.dailyRainChance}%
UV {today.uv.toFixed(0)}
{today.condition?.icon ? (

) : (
)}
>
) : (
Sem previsão diária disponível.
)}
);
}