feat(component): add WeatherSprite with animations
Introduces a new WeatherSprite component featuring Lottie animations based on WMO weather codes. Includes utility subcomponents for displaying titles and indicators.
This commit is contained in:
parent
fd591b44c3
commit
00fbfeeb17
74
src/components/weather/animated-sprite.tsx
Normal file
74
src/components/weather/animated-sprite.tsx
Normal file
@ -0,0 +1,74 @@
|
||||
'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>)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user