diff --git a/src/App.jsx b/src/App.jsx index 0fa4e90..910845a 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -59,7 +59,7 @@ export default function App() { } /> } /> } /> - } /> + } /> } /> } /> } /> diff --git a/src/pages/Space.jsx b/src/pages/Space.jsx index d6a9115..1e88f72 100644 --- a/src/pages/Space.jsx +++ b/src/pages/Space.jsx @@ -3,8 +3,8 @@ * --------------------------------- * Easy: * - [x] Refresh button / auto-refresh interval selector - * - [ ] Show last updated timestamp - * - [ ] Style astronauts list with craft grouping + * - [x] Show last updated timestamp + * - [x] Style astronauts list with craft grouping * - [ ] Add loading skeleton or placeholder map area * Medium: * - [ ] Integrate Leaflet map w/ marker at ISS coords @@ -24,13 +24,16 @@ import Card from '../components/Card.jsx'; import IssMap from '../components/IssMap.jsx'; import DashboardControls from "../components/DashboardControls.jsx"; -export default function Space() { + +export default function Space({ theme = 'light' }) { const [iss, setIss] = useState(null); const [crew, setCrew] = useState([]); const [error, setError] = useState(null); const [loading, setLoading] = useState(false); const [lastUpdated, setLastUpdated] = useState(null); - + + const isDark = theme === 'dark'; + // Fetch both ISS position + crew async function fetchData() { try { @@ -56,34 +59,177 @@ export default function Space() { useEffect(() => { fetchData(); }, []); - - //leaflet map component + + // Proper dark/light theme colors + const bgColor = isDark ? '#0f172a' : '#f8fafc'; + const textColor = isDark ? '#f1f5f9' : '#1e293b'; + const cardBg = isDark ? '#1e293b' : '#ffffff'; + const subText = isDark ? '#94a3b8' : '#64748b'; + const accent = isDark ? '#38bdf8' : '#2563eb'; + const listBg = isDark ? '#334155' : '#f1f5f9'; + const borderColor = isDark ? '#334155' : '#e2e8f0'; + return ( -
-

Space & Astronomy

- +
+

+ 🌌 Space & Astronomy Dashboard +

+ +
+ +
+ {loading && } - {iss && ( - -

Latitude: {iss.iss_position.latitude}

-

Longitude: {iss.iss_position.longitude}

- {lastUpdated && ( -

- Last updated: {lastUpdated.toLocaleTimeString()} -

- )} - + +
+ {iss && ( + +
+

+ Latitude: {iss.iss_position.latitude} +

+

+ Longitude: {iss.iss_position.longitude} +

+ {lastUpdated && ( +

+ Last updated: {lastUpdated.toLocaleTimeString()} +

+ )} +
+ +
+ +
+
+ )} + + +
    + {crew.map((p) => ( +
  • + + {p.name} + + + 🚀 {p.craft} + +
  • + ))} +
- )} - -
    - {crew.map(p => ( -
  • {p.name} — {p.craft}
  • - ))} -
-
- {/* TODO: Add next ISS pass prediction form */} +
+ +

+ Data sourced from{' '} + e.target.style.textDecoration = 'underline'} + onMouseLeave={(e) => e.target.style.textDecoration = 'none'} + > + Open Notify API + +

); -} +} \ No newline at end of file diff --git a/src/pages/Weather.jsx b/src/pages/Weather.jsx index 1aae834..6a68d52 100644 --- a/src/pages/Weather.jsx +++ b/src/pages/Weather.jsx @@ -81,10 +81,14 @@ function renderWeatherAnimation(variant) { return (
{Array.from({ length: 12 }).map((_, i) => ( - + ))}
); @@ -92,20 +96,22 @@ function renderWeatherAnimation(variant) { if (variant === "snow") { return ( - <> -
- {Array.from({ length: 12 }).map((_, i) => ( - + {Array.from({ length: 12 }).map((_, i) => ( + - ))} -
- + }} + /> + ))} +
); } @@ -234,59 +240,109 @@ export default function Weather() {
- - - + +
{loading && } - {error && fetchWeather(city)} />} + {error && ( + fetchWeather(city)} + /> + )} {data && !loading && (
- - {current && ( - <> - {getIconUrl(current.weatherIconUrl) && ( - Weather icon - )} -

- Temperature: {displayTemp(Number(current.temp_C))}°{unit} -

-

Feels Like: {displayTemp(Number(current.FeelsLikeC))}°{unit}

-

Wind: {current.windspeedKmph} km/h

-

Humidity: {current.humidity}%

-

Desc: {current.weatherDesc?.[0]?.value}

- - )} + {/* Current Weather */} + +

{data.nearest_area?.[0]?.areaName?.[0]?.value || city}

+

+ {current && getIconUrl(current.weatherIconUrl) && ( + {current.weatherDesc?.[0]?.value + )} + + Temperature:{" "} + {displayTemp(Number(current.temp_C))}°{unit} + +

+

+ Humidity: {current.humidity}% +

+

+ Desc: {current.weatherDesc?.[0]?.value} +

+ {/* 3-Day Forecast */} {forecast.map((day, i) => { - const badge = getBadgeStyle(day.hourly?.[0]?.weatherDesc?.[0]?.value); + const condition = + day.hourly?.[0]?.weatherDesc?.[0]?.value || "Clear"; + const badge = getBadgeStyle(condition); + return ( + {day.hourly?.[0] && + getIconUrl(day.hourly?.[0]?.weatherIconUrl) && ( +
+ { + (e.currentTarget.style.display = "none") + } + /> +
+ )} +
- {badge.label} + Avg Temp:{" "} + {displayTemp(Number(day.avgtempC))}°{unit} +
+ {badge.label} +
-

Avg Temp: {displayTemp(Number(day.avgtempC))}°{unit}

-

Sunrise: {day.astronomy?.[0]?.sunrise}

-

Sunset: {day.astronomy?.[0]?.sunset}

+

+ Sunrise: {day.astronomy?.[0]?.sunrise} +

+

+ Sunset: {day.astronomy?.[0]?.sunset} +

); })} @@ -295,13 +351,15 @@ export default function Weather() { {loading && (
- {Array(3).fill(null).map((_, i) => ( - }> - - - - - ))} + {Array(3) + .fill(null) + .map((_, i) => ( + }> + + + + + ))}
)}