diff --git a/frontend/src/routes/_layout/weather-hub.tsx b/frontend/src/routes/_layout/weather-hub.tsx
index 63e1d3b..05133f5 100644
--- a/frontend/src/routes/_layout/weather-hub.tsx
+++ b/frontend/src/routes/_layout/weather-hub.tsx
@@ -124,6 +124,18 @@ interface WindDirectionPayload {
// Wrapper type for useQuery data if API responses are nested under a 'data' property
type ApiNestedResponse
= { data?: P };
+// Auto center map component
+const MapCenter = ({ center }: { center: [number, number] }) => {
+ const map = useMap();
+ useEffect(() => {
+ map.setView(center, map.getZoom());
+ }, [center, map]);
+ return null;
+};
+
+// Singapore coordinates (centered on the island)
+const center: [number, number] = [1.3521, 103.8198];
+
export const Route = createFileRoute("/_layout/weather-hub")({
component: WeatherHub,
})
@@ -239,7 +251,7 @@ function TwoHourForecast() {
{/* View Mode Toggle */}
-
Grid
-
-
+
{forecastsWithLocation.length > 0 ? (
@@ -323,6 +335,7 @@ function TwoHourForecast() {
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution="© OpenStreetMap contributors"
/>
+
{forecastsWithLocation.map((forecast, index) => (
) : (
-
@@ -380,8 +393,8 @@ function AirTemperature() {
// Calculate average temperature
const validReadings = latestReading.data.filter(reading => reading.value !== null);
- const avgTemp = validReadings.length > 0
- ? validReadings.reduce((sum, reading) => sum + reading.value, 0) / validReadings.length
+ const avgTemp = validReadings.length > 0
+ ? validReadings.reduce((sum, reading) => sum + reading.value, 0) / validReadings.length
: 0;
return (
@@ -563,13 +576,13 @@ function WindDirection() {
// Calculate circular average direction (proper method for wind directions)
const validReadings = latestReading.data.filter(reading => reading.value !== null);
let avgDirection = 0;
-
+
if (validReadings.length > 0) {
// Convert degrees to radians, calculate vector average, then back to degrees
const radians = validReadings.map(reading => (reading.value! * Math.PI) / 180);
const sinSum = radians.reduce((sum, rad) => sum + Math.sin(rad), 0);
const cosSum = radians.reduce((sum, rad) => sum + Math.cos(rad), 0);
-
+
const avgRadians = Math.atan2(sinSum / validReadings.length, cosSum / validReadings.length);
avgDirection = Math.round(((avgRadians * 180) / Math.PI + 360) % 360);
}
@@ -625,16 +638,16 @@ function WindDirection() {
// Component to handle map invalidation when tab becomes visible
function MapInvalidator() {
const map = useMap();
-
+
useEffect(() => {
// Small delay to ensure the container is fully visible
const timer = setTimeout(() => {
map.invalidateSize();
}, 100);
-
+
return () => clearTimeout(timer);
}, [map]);
-
+
return null;
}
@@ -704,25 +717,32 @@ function WeatherMap() {
const generalWeather = getWeatherForLocation();
return (
-
-
-
- {latestTempReading.data.map((reading) => {
- const station = tempStationMap.get(reading.stationId);
- if (!station || reading.value === null) return null;
+
+
+
+
+
- const windDirection = windDataMap.get(reading.stationId);
- const cardinalDirection = getCardinalDirection(windDirection);
+ {latestTempReading.data.map((reading) => {
+ const station = tempStationMap.get(reading.stationId);
+ if (!station || reading.value === null) return null;
- return (
- ${cardinalDirection}
`,
- className: 'custom-weather-marker',
- iconSize: [60, 50],
- iconAnchor: [30, 50]
- })}
- />
- );
- })}
-
+ className: 'custom-weather-marker',
+ iconSize: [60, 50],
+ iconAnchor: [30, 50]
+ })}
+ />
+ );
+ })}
+
+
);
}