where('type', 'hourly') ->with('periods') ->orderByDesc('reported_at') ->first(); $latestWeekly = WeatherReport::query() ->where('type', 'weekly') ->with('periods') ->orderByDesc('reported_at') ->first(); $currentPeriod = $latestHourly?->periods->first(); $hourlyForecast = $latestHourly?->periods ->take(6) ->map(fn ($period) => [ 'time' => $period->start_time->format('H:i'), 'hour' => $period->start_time->format('H'), 'temperature' => $period->temperature, 'temperatureUnit' => $period->temperature_unit, 'icon' => $this->mapIconToEmoji($period->short_forecast), 'shortForecast' => $period->short_forecast, 'precipitationProbability' => $period->precipitation_probability, ]); $weeklyForecast = $latestWeekly?->periods ->filter(fn ($period) => $period->is_daytime) ->take(7) ->values() ->map(fn ($period) => [ 'name' => $period->name, 'temperature' => $period->temperature, 'temperatureUnit' => $period->temperature_unit, 'icon' => $this->mapIconToEmoji($period->short_forecast), 'shortForecast' => $period->short_forecast, 'precipitationProbability' => $period->precipitation_probability, 'windSpeed' => $period->wind_speed, 'windDirection' => $period->wind_direction, 'detailedForecast' => $period->detailed_forecast, ]); return Inertia::render('Weather', [ 'current' => $currentPeriod ? [ 'temperature' => $currentPeriod->temperature, 'temperatureUnit' => $currentPeriod->temperature_unit, 'shortForecast' => $currentPeriod->short_forecast, 'detailedForecast' => $currentPeriod->detailed_forecast, 'windSpeed' => $currentPeriod->wind_speed, 'windDirection' => $currentPeriod->wind_direction, 'humidity' => $currentPeriod->relative_humidity, 'dewpoint' => $currentPeriod->dewpoint_celsius, 'precipitationProbability' => $currentPeriod->precipitation_probability, 'isDaytime' => $currentPeriod->is_daytime, 'icon' => $this->mapIconToEmoji($currentPeriod->short_forecast), ] : null, 'hourlyForecast' => $hourlyForecast ?? collect(), 'weeklyForecast' => $weeklyForecast ?? collect(), 'location' => [ 'latitude' => $latestHourly?->latitude, 'longitude' => $latestHourly?->longitude, 'name' => 'Utah County', ], 'reportedAt' => $latestHourly?->reported_at?->format('M d, Y H:i'), ]); } private function mapIconToEmoji(?string $forecast): string { if (! $forecast) { return 'cloud'; } $forecast = strtolower($forecast); return match (true) { str_contains($forecast, 'sunny') || str_contains($forecast, 'clear') => 'sun', str_contains($forecast, 'partly') && str_contains($forecast, 'cloud') => 'cloud-sun', str_contains($forecast, 'mostly cloudy') => 'cloud', str_contains($forecast, 'cloud') => 'cloud', str_contains($forecast, 'rain') && str_contains($forecast, 'snow') => 'cloud-snow', str_contains($forecast, 'snow') => 'cloud-snow', str_contains($forecast, 'rain') || str_contains($forecast, 'shower') => 'cloud-rain', str_contains($forecast, 'thunder') || str_contains($forecast, 'storm') => 'cloud-lightning', str_contains($forecast, 'fog') || str_contains($forecast, 'mist') => 'cloud-fog', str_contains($forecast, 'wind') => 'wind', default => 'cloud', }; } }