import React, { useState, useEffect } from 'react'; import { Text, Box } from 'ink'; import fetch from 'node-fetch'; const locations = { Nancy: { latitude: 48.6921, longitude: 6.1844 }, Paris: { latitude: 48.8566, longitude: 2.3522 } }; function formatTime(date) { return date.toLocaleTimeString('fr-FR', { hour12: false }); } function formatDate(date) { return date.toLocaleDateString('fr-FR', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }); } function formatDateTimeUTC(utcString) { const date = new Date(utcString); return { date: formatDate(date), time: formatTime(date) }; } async function fetchWeather(lat, lon) { const url = `https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${lon}¤t_weather=true&temperature_unit=celsius&timezone=Europe/Paris`; const response = await fetch(url); const data = await response.json(); return data.current_weather; } const weatherCodeMap = { 0: { desc: 'Ciel clair', color: 'yellow' }, 1: { desc: 'Principalement clair', color: 'yellow' }, 2: { desc: 'Partiellement nuageux', color: 'cyan' }, 3: { desc: 'Couvert', color: 'gray' }, 45: { desc: 'Brouillard', color: 'gray' }, 48: { desc: 'Brouillard givrant', color: 'gray' }, 51: { desc: 'Bruine légère', color: 'blue' }, 53: { desc: 'Bruine modérée', color: 'blue' }, 55: { desc: 'Bruine dense', color: 'blue' }, 56: { desc: 'Bruine verglaçante légère', color: 'blue' }, 57: { desc: 'Bruine verglaçante dense', color: 'blue' }, 61: { desc: 'Pluie faible', color: 'blue' }, 63: { desc: 'Pluie modérée', color: 'blue' }, 65: { desc: 'Pluie forte', color: 'blue' }, 66: { desc: 'Pluie verglaçante légère', color: 'blue' }, 67: { desc: 'Pluie verglaçante forte', color: 'blue' }, 71: { desc: 'Chute de neige légère', color: 'white' }, 73: { desc: 'Chute de neige modérée', color: 'white' }, 75: { desc: 'Chute de neige forte', color: 'white' }, 77: { desc: 'Grains de neige', color: 'white' }, 80: { desc: 'Averses de pluie faibles', color: 'blue' }, 81: { desc: 'Averses de pluie modérées', color: 'blue' }, 82: { desc: 'Averses de pluie violentes', color: 'blue' }, 85: { desc: 'Averses de neige faibles', color: 'white' }, 86: { desc: 'Averses de neige fortes', color: 'white' }, 95: { desc: 'Orage', color: 'magenta' }, 96: { desc: 'Orage avec faible grêle', color: 'magenta' }, 99: { desc: 'Orage avec forte grêle', color: 'magenta' } }; export default function App({ name = 'Mathias' }) { const [now, setNow] = useState(new Date()); const [weatherNancy, setWeatherNancy] = useState(null); const [weatherParis, setWeatherParis] = useState(null); const [matchesInter, setMatchesInter] = useState(null); const [matchesParis, setMatchesParis] = useState(null); const INTER_ID = 6684; // SC Internacional team id const PARIS_ID = 1045; // Paris FC team id useEffect(() => { const timer = setInterval(() => { setNow(new Date()); }, 1000); async function updateWeather() { try { const nancyData = await fetchWeather(locations.Nancy.latitude, locations.Nancy.longitude); const parisData = await fetchWeather(locations.Paris.latitude, locations.Paris.longitude); setWeatherNancy(nancyData); setWeatherParis(parisData); } catch (error) { // gestion d'erreur météo } } async function fetchMatches(teamId, setMatches) { try { const response = await fetch( `https://api.football-data.org/v4/teams/${teamId}/matches?status=SCHEDULED`, { headers: { "X-Auth-Token": "1535f68086e542528841b5e276f50b45" } // Remplace par ton token } ); const data = await response.json(); const filtered = data.matches.map(match => { let opponent, homeAway; if (match.homeTeam.id === teamId) { opponent = match.awayTeam.name; homeAway = 'Home'; } else if (match.awayTeam.id === teamId) { opponent = match.homeTeam.name; homeAway = 'Away'; } else { return null; } const { date, time } = formatDateTimeUTC(match.utcDate); return { date, time, opponent, homeAway }; }).filter(Boolean); setMatches(filtered); } catch (error) { setMatches([]); } } updateWeather(); fetchMatches(INTER_ID, setMatchesInter); fetchMatches(PARIS_ID, setMatchesParis); const weatherInterval = setInterval(updateWeather, 60000); return () => { clearInterval(timer); clearInterval(weatherInterval); }; }, []); const renderWeather = (location, weather) => { if (!weather) return {location}: Loading weather...; const weatherInfo = weatherCodeMap[weather.weathercode] || { desc: 'Unknown', color: 'white' }; return ( {location}: {weatherInfo.desc},{' '} {weather.temperature}°C (Vent : {weather.windspeed} km/h) ); }; const translateHomeAway = (homeAway) => { if (homeAway === 'Home') return 'domicile'; if (homeAway === 'Away') return 'extérieur'; return homeAway; }; return ( Hello, {name} ! {formatDate(now)} {formatTime(now)} {renderWeather('Nancy', weatherNancy)} {renderWeather('Paris', weatherParis)} Matches à venir de SC Internacional : {!matchesInter && Chargement des matchs...} {matchesInter && matchesInter.length === 0 && Aucun match trouvé.} {matchesInter && matchesInter.slice(0, 2).map((m, i) => ( {m.date} {m.time} - SC Internacional vs {m.opponent} ({translateHomeAway(m.homeAway)}) ))} Matches à venir de Paris FC : {!matchesParis && Chargement des matchs...} {matchesParis && matchesParis.length === 0 && Aucun match trouvé.} {matchesParis && matchesParis.slice(0, 2).map((m, i) => ( {m.date} {m.time} - Paris FC vs {m.opponent} ({translateHomeAway(m.homeAway)}) ))} Press Ctrl+C to exit. ); }