Introduces a new WeatherSprite component featuring Lottie animations based on WMO weather codes. Includes utility subcomponents for displaying titles and indicators.
74 lines
2.2 KiB
TypeScript
74 lines
2.2 KiB
TypeScript
'use client'
|
|
import LottieReact from "@lottielab/lottie-player/react";
|
|
import {cn} from "@/lib/utils";
|
|
import {Clock4, LucideIcon} from "lucide-react";
|
|
import {DateFormatter} from "@/lib/date";
|
|
import Image from "next/image";
|
|
|
|
// Follow WMO weather interpretation codes.
|
|
interface SpriteTitleProps {
|
|
title?: string;
|
|
icon?: LucideIcon
|
|
}
|
|
|
|
function SpriteTitle(props: SpriteTitleProps) {
|
|
const Icon = props.icon || Clock4;
|
|
const title = props.title || new DateFormatter().generateFormattedDate(new Date(), { formatTemplate: "PPP", locale: "fr" })
|
|
return (<div className={"flex justify-center items-center gap-1"}>
|
|
<Icon/>
|
|
<h2 >{title}</h2>
|
|
</div>)
|
|
}
|
|
|
|
type SpriteIndicatorProps = {
|
|
type : "slippery" | "snow-covered" | "strong-wind"
|
|
className?: string
|
|
}
|
|
|
|
function SpriteIndicator(props: SpriteIndicatorProps) {
|
|
switch (props.type) {
|
|
case "slippery":
|
|
return (<div className={cn("animate-pulse scale-125", props.className)}>
|
|
<Image src={"route_glisante.svg"} alt={"Panneau route glisante"} width={256} height={256}/>
|
|
</div>)
|
|
}
|
|
}
|
|
|
|
interface WeatherSpriteProps {
|
|
weather: number;
|
|
title?: string;
|
|
indicator?: SpriteIndicatorProps
|
|
className?: string;
|
|
danger?: boolean;
|
|
}
|
|
|
|
export default function WeatherSprite(props: WeatherSpriteProps) {
|
|
const wmo = new Map([
|
|
[0, "clear.json"],
|
|
[1, "partial_cloud.json"],
|
|
[2, "partial_cloud.json"],
|
|
[3, "cloud.json"],
|
|
[45, "foggy.json"],
|
|
[48, "fog.json"],
|
|
])
|
|
const displayWmo = new Map([
|
|
[0, "Ciel clair"],
|
|
[1, "Principalement clair"],
|
|
[2, "Partiellement nuageux"],
|
|
[3, "Partiellement couvert"],
|
|
[45, "Brouillard"],
|
|
[48, "Brouillard givrant"],
|
|
])
|
|
|
|
|
|
return (<div className={cn("flex flex-col justify-center items-center gap-1 h-fit w-fit text-lg px-3 py-2 font-bold rounded-xl relative", props.danger ? "bg-destructive" : "", props.className)}>
|
|
{props.title && <SpriteTitle title={props.title}/>}
|
|
{
|
|
props.indicator && <div className={"absolute top-12 left-10 z-30"}>
|
|
<SpriteIndicator type={props.indicator.type} className={cn("w-20 h-20", props.indicator.className)}/>
|
|
</div>
|
|
}
|
|
<LottieReact src={wmo.get(props.weather) || "clear.json"} className={"w-full h-full z-5"}/>
|
|
<h3 className={"tracking-widest uppercase"}>{displayWmo.get(props.weather)}</h3>
|
|
</div>)
|
|
} |