From 6b8d3c42f7daec98ea0f6f073895401de367ccc7 Mon Sep 17 00:00:00 2001 From: Froidefond Julien Date: Tue, 24 Feb 2026 16:50:26 +0100 Subject: [PATCH] refactor: extract WEATHER_EMOJIS and add scoring utils to weather-utils.ts Co-Authored-By: Claude Sonnet 4.6 --- src/components/weather/WeatherCard.tsx | 24 +--------- src/lib/weather-utils.ts | 63 ++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 23 deletions(-) create mode 100644 src/lib/weather-utils.ts diff --git a/src/components/weather/WeatherCard.tsx b/src/components/weather/WeatherCard.tsx index 2ca2ae3..20a38ff 100644 --- a/src/components/weather/WeatherCard.tsx +++ b/src/components/weather/WeatherCard.tsx @@ -5,29 +5,7 @@ import { createOrUpdateWeatherEntry } from '@/actions/weather'; import { Avatar } from '@/components/ui/Avatar'; import { Textarea } from '@/components/ui/Textarea'; import { Select } from '@/components/ui/Select'; - -const WEATHER_EMOJIS = [ - { emoji: '', label: 'Aucun' }, - { emoji: '☀️', label: 'Soleil' }, - { emoji: '🌤️', label: 'Soleil derrière nuage' }, - { emoji: '⛅', label: 'Soleil et nuages' }, - { emoji: '☁️', label: 'Nuages' }, - { emoji: '🌦️', label: 'Soleil et pluie' }, - { emoji: '🌧️', label: 'Pluie' }, - { emoji: '⛈️', label: 'Orage et pluie' }, - { emoji: '🌩️', label: 'Éclair' }, - { emoji: '❄️', label: 'Neige' }, - { emoji: '🌨️', label: 'Neige qui tombe' }, - { emoji: '🌪️', label: 'Tornade' }, - { emoji: '🌫️', label: 'Brouillard' }, - { emoji: '🌈', label: 'Arc-en-ciel' }, - { emoji: '🌊', label: 'Vague' }, - { emoji: '🔥', label: 'Feu' }, - { emoji: '💨', label: 'Vent' }, - { emoji: '⭐', label: 'Étoile' }, - { emoji: '🌟', label: 'Étoile brillante' }, - { emoji: '✨', label: 'Étincelles' }, -]; +import { WEATHER_EMOJIS } from '@/lib/weather-utils'; interface WeatherEntry { id: string; diff --git a/src/lib/weather-utils.ts b/src/lib/weather-utils.ts new file mode 100644 index 0000000..e6e5eb4 --- /dev/null +++ b/src/lib/weather-utils.ts @@ -0,0 +1,63 @@ +// src/lib/weather-utils.ts + +export const WEATHER_EMOJIS = [ + { emoji: '', label: 'Aucun' }, + { emoji: '☀️', label: 'Soleil' }, + { emoji: '🌤️', label: 'Soleil derrière nuage' }, + { emoji: '⛅', label: 'Soleil et nuages' }, + { emoji: '☁️', label: 'Nuages' }, + { emoji: '🌦️', label: 'Soleil et pluie' }, + { emoji: '🌧️', label: 'Pluie' }, + { emoji: '⛈️', label: 'Orage et pluie' }, + { emoji: '🌩️', label: 'Éclair' }, + { emoji: '❄️', label: 'Neige' }, + { emoji: '🌨️', label: 'Neige qui tombe' }, + { emoji: '🌪️', label: 'Tornade' }, + { emoji: '🌫️', label: 'Brouillard' }, + { emoji: '🌈', label: 'Arc-en-ciel' }, + { emoji: '🌊', label: 'Vague' }, + { emoji: '🔥', label: 'Feu' }, + { emoji: '💨', label: 'Vent' }, + { emoji: '⭐', label: 'Étoile' }, + { emoji: '🌟', label: 'Étoile brillante' }, + { emoji: '✨', label: 'Étincelles' }, +]; + +// Score = 1-based index in the list. Empty string = no value (excluded from scoring). +export function getEmojiScore(emoji: string | null | undefined): number | null { + if (!emoji) return null; + const idx = WEATHER_EMOJIS.findIndex((e) => e.emoji === emoji); + if (idx <= 0) return null; // idx 0 = '' (no value), or not found + return idx; // 1 = ☀️ (best), 19 = ✨ (worst) +} + +// Returns the emoji whose score is closest to the average of all scored emojis. +// Returns null if no scored emojis. +export function getAverageEmoji(emojis: (string | null | undefined)[]): string | null { + const scores = emojis.map(getEmojiScore).filter((s): s is number => s !== null); + if (scores.length === 0) return null; + const avg = scores.reduce((sum, s) => sum + s, 0) / scores.length; + // Find emoji with index closest to avg (skip index 0 = empty) + let closest: { emoji: string; dist: number } | null = null; + for (let i = 1; i < WEATHER_EMOJIS.length; i++) { + const dist = Math.abs(i - avg); + if (closest === null || dist < closest.dist) { + closest = { emoji: WEATHER_EMOJIS[i].emoji, dist }; + } + } + return closest?.emoji ?? null; +} + +// Returns evolution direction: 'up' (amélioration), 'down' (dégradation), 'same', or null (no previous). +export function getEmojiEvolution( + current: string | null | undefined, + previous: string | null | undefined +): 'up' | 'down' | 'same' | null { + const currentScore = getEmojiScore(current); + const previousScore = getEmojiScore(previous); + if (currentScore === null || previousScore === null) return null; + const delta = currentScore - previousScore; + if (delta < 0) return 'up'; // lower score = better weather + if (delta > 0) return 'down'; // higher score = worse weather + return 'same'; +}