From 6628f1e6703ae788de6e90b5d8d6944d67079def Mon Sep 17 00:00:00 2001 From: michaelschal <35957947-michaelschal@users.noreply.replit.com> Date: Fri, 15 Aug 2025 08:45:00 +0000 Subject: [PATCH 1/3] Translate weather conditions to French for better display Translate English weather descriptions to French in the weather widget for both current and previous year data, and add weather icons for previous year. Replit-Commit-Author: Agent Replit-Commit-Session-Id: d43bd811-9372-45a7-8ac9-4a954c0538e1 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/d43bd811-9372-45a7-8ac9-4a954c0538e1/nYabaNx --- attached_assets/image_1755247383413.png | Bin 0 -> 15748 bytes client/src/components/WeatherWidget.tsx | 42 +++++++++++++++++++++--- cookies.txt | 2 +- 3 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 attached_assets/image_1755247383413.png diff --git a/attached_assets/image_1755247383413.png b/attached_assets/image_1755247383413.png new file mode 100644 index 0000000000000000000000000000000000000000..dc1035f59257b84b5a8d78b0b2a30acac2caa754 GIT binary patch literal 15748 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 hScB>R*GE3GrAs { + const conditionLower = condition.toLowerCase(); + + // Traductions complètes anglais -> français + if (conditionLower.includes('clear')) return 'Dégagé'; + if (conditionLower.includes('sunny')) return 'Ensoleillé'; + if (conditionLower.includes('fair')) return 'Beau temps'; + if (conditionLower.includes('partly cloudy')) return 'Partiellement nuageux'; + if (conditionLower.includes('cloudy')) return 'Nuageux'; + if (conditionLower.includes('overcast')) return 'Couvert'; + if (conditionLower.includes('rain')) { + if (conditionLower.includes('heavy')) return 'Pluie forte'; + if (conditionLower.includes('light')) return 'Pluie légère'; + return 'Pluie'; + } + if (conditionLower.includes('shower')) return 'Averses'; + if (conditionLower.includes('drizzle')) return 'Bruine'; + if (conditionLower.includes('thunderstorm') || conditionLower.includes('thunder')) return 'Orage'; + if (conditionLower.includes('snow')) { + if (conditionLower.includes('heavy')) return 'Neige forte'; + if (conditionLower.includes('light')) return 'Neige légère'; + return 'Neige'; + } + if (conditionLower.includes('fog')) return 'Brouillard'; + if (conditionLower.includes('mist')) return 'Brume'; + if (conditionLower.includes('wind')) return 'Venteux'; + + // Si déjà en français, retourner tel quel + return condition; +}; const WeatherIcon = ({ condition, size = 20 }: { condition: string; size?: number }) => { const iconClass = `h-${Math.floor(size/4)} w-${Math.floor(size/4)}`; @@ -119,7 +148,7 @@ export default function WeatherWidget() { {location.split(',')[0]} - {weather.currentYear?.condition || 'Inconnu'} + {translateWeatherCondition(weather.currentYear?.condition || 'Inconnu')} @@ -140,14 +169,17 @@ export default function WeatherWidget() { <>
-
- {Math.round(previousTemp)}° +
+ +
+ {Math.round(previousTemp)}° +
Année dernière
- {weather.previousYear?.condition || ''} + {translateWeatherCondition(weather.previousYear?.condition || '')}
diff --git a/cookies.txt b/cookies.txt index a0cd3af..b017d67 100644 --- a/cookies.txt +++ b/cookies.txt @@ -2,4 +2,4 @@ # https://curl.se/docs/http-cookies.html # This file was generated by libcurl! Edit at your own risk. -#HttpOnly_localhost FALSE / FALSE 1755333603 connect.sid s%3AQqa7VC9Kmev2sSuyP6rb67zs4VszjTJP.RwnrDHc4pdPJyIwe93Hg9PTGpAF73AsiSmjdDq4MC4c +#HttpOnly_localhost FALSE / FALSE 1755333868 connect.sid s%3ASXoX5QR3PzEoabdE6kmVpS41nTbxgfBD.FrsSh7UcEUki0dMf4G%2BxKbZVB4nXKRMmG4JtXotjr7o From 7a083a0203d5023151a0dba673c90dda0d924259 Mon Sep 17 00:00:00 2001 From: michaelschal <35957947-michaelschal@users.noreply.replit.com> Date: Fri, 15 Aug 2025 08:46:54 +0000 Subject: [PATCH 2/3] Show current date alongside weather and force French translations for conditions Move weather condition translation logic to the backend and display the current date in the weather widget. Replit-Commit-Author: Agent Replit-Commit-Session-Id: d43bd811-9372-45a7-8ac9-4a954c0538e1 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/d43bd811-9372-45a7-8ac9-4a954c0538e1/IljTqYl --- client/src/components/WeatherWidget.tsx | 43 +++++++------------------ cookies.txt | 2 +- server/weatherService.ts | 38 ++++++++++++++++++++-- 3 files changed, 49 insertions(+), 34 deletions(-) diff --git a/client/src/components/WeatherWidget.tsx b/client/src/components/WeatherWidget.tsx index 67a062b..73a2b6d 100644 --- a/client/src/components/WeatherWidget.tsx +++ b/client/src/components/WeatherWidget.tsx @@ -21,35 +21,13 @@ interface WeatherResponse { location: string; } -const translateWeatherCondition = (condition: string): string => { - const conditionLower = condition.toLowerCase(); - - // Traductions complètes anglais -> français - if (conditionLower.includes('clear')) return 'Dégagé'; - if (conditionLower.includes('sunny')) return 'Ensoleillé'; - if (conditionLower.includes('fair')) return 'Beau temps'; - if (conditionLower.includes('partly cloudy')) return 'Partiellement nuageux'; - if (conditionLower.includes('cloudy')) return 'Nuageux'; - if (conditionLower.includes('overcast')) return 'Couvert'; - if (conditionLower.includes('rain')) { - if (conditionLower.includes('heavy')) return 'Pluie forte'; - if (conditionLower.includes('light')) return 'Pluie légère'; - return 'Pluie'; - } - if (conditionLower.includes('shower')) return 'Averses'; - if (conditionLower.includes('drizzle')) return 'Bruine'; - if (conditionLower.includes('thunderstorm') || conditionLower.includes('thunder')) return 'Orage'; - if (conditionLower.includes('snow')) { - if (conditionLower.includes('heavy')) return 'Neige forte'; - if (conditionLower.includes('light')) return 'Neige légère'; - return 'Neige'; - } - if (conditionLower.includes('fog')) return 'Brouillard'; - if (conditionLower.includes('mist')) return 'Brume'; - if (conditionLower.includes('wind')) return 'Venteux'; - - // Si déjà en français, retourner tel quel - return condition; +const formatDate = (date: Date): string => { + return date.toLocaleDateString('fr-FR', { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric' + }); }; const WeatherIcon = ({ condition, size = 20 }: { condition: string; size?: number }) => { @@ -148,7 +126,10 @@ export default function WeatherWidget() { {location.split(',')[0]} - {translateWeatherCondition(weather.currentYear?.condition || 'Inconnu')} + {weather.currentYear?.condition || 'Inconnu'} + + + {formatDate(new Date())}
@@ -179,7 +160,7 @@ export default function WeatherWidget() { Année dernière
- {translateWeatherCondition(weather.previousYear?.condition || '')} + {weather.previousYear?.condition || ''}
diff --git a/cookies.txt b/cookies.txt index b017d67..badf3f7 100644 --- a/cookies.txt +++ b/cookies.txt @@ -2,4 +2,4 @@ # https://curl.se/docs/http-cookies.html # This file was generated by libcurl! Edit at your own risk. -#HttpOnly_localhost FALSE / FALSE 1755333868 connect.sid s%3ASXoX5QR3PzEoabdE6kmVpS41nTbxgfBD.FrsSh7UcEUki0dMf4G%2BxKbZVB4nXKRMmG4JtXotjr7o +#HttpOnly_localhost FALSE / FALSE 1755333988 connect.sid s%3AISLqM3nMPwDqTr6rJYeqzJe6pp6ETpGJ.UEpHxk3T4DOjAZ6VGJsJ%2FHoasP2kzqayut1IaOzPG9E diff --git a/server/weatherService.ts b/server/weatherService.ts index bb4b865..a692724 100644 --- a/server/weatherService.ts +++ b/server/weatherService.ts @@ -70,7 +70,41 @@ export class WeatherService { } /** - * Convertit les données de l'API en format WeatherData + * Traduit les conditions météo en français + */ + private translateConditionToFrench(condition: string): string { + const conditionLower = condition.toLowerCase(); + + // Traductions anglais -> français + if (conditionLower.includes('clear')) return 'Dégagé'; + if (conditionLower.includes('sunny')) return 'Ensoleillé'; + if (conditionLower.includes('fair')) return 'Beau temps'; + if (conditionLower.includes('partly cloudy')) return 'Partiellement nuageux'; + if (conditionLower.includes('cloudy')) return 'Nuageux'; + if (conditionLower.includes('overcast')) return 'Couvert'; + if (conditionLower.includes('rain')) { + if (conditionLower.includes('heavy')) return 'Pluie forte'; + if (conditionLower.includes('light')) return 'Pluie légère'; + return 'Pluie'; + } + if (conditionLower.includes('shower')) return 'Averses'; + if (conditionLower.includes('drizzle')) return 'Bruine'; + if (conditionLower.includes('thunderstorm') || conditionLower.includes('thunder')) return 'Orage'; + if (conditionLower.includes('snow')) { + if (conditionLower.includes('heavy')) return 'Neige forte'; + if (conditionLower.includes('light')) return 'Neige légère'; + return 'Neige'; + } + if (conditionLower.includes('fog')) return 'Brouillard'; + if (conditionLower.includes('mist')) return 'Brume'; + if (conditionLower.includes('wind')) return 'Venteux'; + + // Si déjà en français, retourner tel quel + return condition; + } + + /** + * Convertit les données de l'API en format WeatherData avec traduction française forcée */ convertApiDataToWeatherData(apiData: WeatherApiResponse, location: string, isCurrentYear: boolean): InsertWeatherData | null { if (!apiData.days || apiData.days.length === 0) { @@ -86,7 +120,7 @@ export class WeatherService { tempMax: todayData.tempmax.toString(), tempMin: todayData.tempmin.toString(), icon: todayData.icon, - conditions: todayData.conditions, + conditions: this.translateConditionToFrench(todayData.conditions), // Traduction forcée isCurrentYear // Pas de createdAt/updatedAt - gérés par la base de données }; From 369638f3d6e129a7706750dbcd48f31ade1eee0a Mon Sep 17 00:00:00 2001 From: michaelschal <35957947-michaelschal@users.noreply.replit.com> Date: Fri, 15 Aug 2025 08:48:58 +0000 Subject: [PATCH 3/3] Add a widget to display the current date alongside weather information Introduce a new DateWidget component, integrated into the main layout to display the current date, and refactor WeatherWidget to remove redundant date formatting. Replit-Commit-Author: Agent Replit-Commit-Session-Id: d43bd811-9372-45a7-8ac9-4a954c0538e1 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/1957c339-2757-4d1f-8e92-e9f71a1ce58e/d43bd811-9372-45a7-8ac9-4a954c0538e1/dB3dp7l --- client/src/components/DateWidget.tsx | 34 +++++++++++++++++++++++++ client/src/components/Layout.tsx | 8 ++++-- client/src/components/WeatherWidget.tsx | 12 +-------- 3 files changed, 41 insertions(+), 13 deletions(-) create mode 100644 client/src/components/DateWidget.tsx diff --git a/client/src/components/DateWidget.tsx b/client/src/components/DateWidget.tsx new file mode 100644 index 0000000..2d44f04 --- /dev/null +++ b/client/src/components/DateWidget.tsx @@ -0,0 +1,34 @@ +import { Card, CardContent } from "@/components/ui/card"; +import { Calendar } from "lucide-react"; + +const formatDate = (date: Date): string => { + return date.toLocaleDateString('fr-FR', { + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric' + }); +}; + + + +export default function DateWidget() { + const now = new Date(); + + return ( + + +
+
+ +
+
+ + {formatDate(now)} + +
+
+
+
+ ); +} \ No newline at end of file diff --git a/client/src/components/Layout.tsx b/client/src/components/Layout.tsx index 1d60d87..bf3b9ec 100644 --- a/client/src/components/Layout.tsx +++ b/client/src/components/Layout.tsx @@ -7,6 +7,7 @@ import { useAuthUnified } from "@/hooks/useAuthUnified"; import { useIsMobile } from "@/hooks/use-mobile"; import Sidebar from "./Sidebar"; import WeatherWidget from "./WeatherWidget"; +import DateWidget from "./DateWidget"; import type { Group } from "@shared/schema"; interface StoreContextType { @@ -92,8 +93,11 @@ export default function Layout({ children }: LayoutProps) { )} - {/* Weather widget */} - + {/* Weather and Date widgets */} +
+ + +
{/* Store selector for admin - responsive */} diff --git a/client/src/components/WeatherWidget.tsx b/client/src/components/WeatherWidget.tsx index 73a2b6d..0920590 100644 --- a/client/src/components/WeatherWidget.tsx +++ b/client/src/components/WeatherWidget.tsx @@ -21,14 +21,7 @@ interface WeatherResponse { location: string; } -const formatDate = (date: Date): string => { - return date.toLocaleDateString('fr-FR', { - weekday: 'long', - year: 'numeric', - month: 'long', - day: 'numeric' - }); -}; + const WeatherIcon = ({ condition, size = 20 }: { condition: string; size?: number }) => { const iconClass = `h-${Math.floor(size/4)} w-${Math.floor(size/4)}`; @@ -128,9 +121,6 @@ export default function WeatherWidget() { {weather.currentYear?.condition || 'Inconnu'} - - {formatDate(new Date())} -