From ebeb22aaa1702bf1870aa0aef1580f3cfd47de09 Mon Sep 17 00:00:00 2001 From: Noel Palo Date: Fri, 8 Sep 2023 23:00:57 +0800 Subject: [PATCH 1/3] feature/BWA-6-weather-app-ui-update - Add and load bootstrap-icons - Update landing page to display default data --- src/package-lock.json | 17 +++++ src/package.json | 1 + src/resources/sass/app.scss | 3 + src/resources/views/layouts/main.blade.php | 7 +- .../weather-app/weather-update.blade.php | 65 ++++++++++++++++--- 5 files changed, 84 insertions(+), 9 deletions(-) diff --git a/src/package-lock.json b/src/package-lock.json index 51eb832..68b35e5 100644 --- a/src/package-lock.json +++ b/src/package-lock.json @@ -8,6 +8,7 @@ "@popperjs/core": "^2.11.6", "axios": "^1.1.2", "bootstrap": "^5.2.3", + "bootstrap-icons": "^1.10.5", "laravel-vite-plugin": "^0.7.2", "lodash": "^4.17.19", "postcss": "^8.1.14", @@ -435,6 +436,22 @@ "@popperjs/core": "^2.11.8" } }, + "node_modules/bootstrap-icons": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/bootstrap-icons/-/bootstrap-icons-1.10.5.tgz", + "integrity": "sha512-oSX26F37V7QV7NCE53PPEL45d7EGXmBgHG3pDpZvcRaKVzWMqIRL9wcqJUyEha1esFtM3NJzvmxFXDxjJYD0jQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/twbs" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + } + ] + }, "node_modules/braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", diff --git a/src/package.json b/src/package.json index f9480ef..70092c8 100644 --- a/src/package.json +++ b/src/package.json @@ -8,6 +8,7 @@ "@popperjs/core": "^2.11.6", "axios": "^1.1.2", "bootstrap": "^5.2.3", + "bootstrap-icons": "^1.10.5", "laravel-vite-plugin": "^0.7.2", "lodash": "^4.17.19", "postcss": "^8.1.14", diff --git a/src/resources/sass/app.scss b/src/resources/sass/app.scss index 1026a0b..e875709 100644 --- a/src/resources/sass/app.scss +++ b/src/resources/sass/app.scss @@ -6,3 +6,6 @@ // Bootstrap @import 'bootstrap/scss/bootstrap'; + +// Bootstrap-icons +@import 'bootstrap-icons/font/bootstrap-icons.css'; diff --git a/src/resources/views/layouts/main.blade.php b/src/resources/views/layouts/main.blade.php index 851784b..613e987 100644 --- a/src/resources/views/layouts/main.blade.php +++ b/src/resources/views/layouts/main.blade.php @@ -13,11 +13,16 @@ + @vite(['resources/sass/app.scss', 'resources/js/app.js']) -
+
@include("layouts.header")
diff --git a/src/resources/views/weather-app/weather-update.blade.php b/src/resources/views/weather-app/weather-update.blade.php index 3bc52a8..fd933d5 100644 --- a/src/resources/views/weather-app/weather-update.blade.php +++ b/src/resources/views/weather-app/weather-update.blade.php @@ -1,17 +1,66 @@ @extends('layouts.main') @section('content') -
-
-
-
-
{{ __('Weather') }}
- -
-

HELLO AGAIN BOOTSTRAP!

+
+
+
+ + +
+
+ +
+
+ + +
+

{{ $geolocation['formatted'] }}

+
15:07
+
+ +
+
+ + +
+
+ +
+
+
+
{{ $weather['current']['temp'] }}°C
+ Feels like {{ $weather['current']['feels_like'] }}°C + {{ $weather['current']['description'] }} +
+
+ weather-icon +
+ +
+
+
sunrise: {{ $weather['current']['sunrise'] }}
+
sunset: {{ $weather['current']['sunset'] }}
+
temp_max: {{ $weather['current']['temp_max'] }}
+
temp_min: {{ $weather['current']['temp_min'] }}
+
wind speed: {{ $weather['current']['wind_speed'] }} km/h
+
wind deg: {{ $weather['current']['wind_direction'] }}
+
humidity: {{ $weather['current']['humidity'] }}%
+
+ +
+
+ + + +
+
+ + +
+
@endsection From 7a31b09a3f8839c772c09877026f542760c69136 Mon Sep 17 00:00:00 2001 From: Noel Palo Date: Sat, 9 Sep 2023 13:17:44 +0800 Subject: [PATCH 2/3] feature/BWA-6-weather-app-ui-update - Update UI Display - Fix Date & Time display - Fix Timezone - Fix Controller return data - Add Direction Enum & UnitTest - Add conversion from degrees to 8 point compass directions --- src/app/Enums/Direction.php | 31 ++++ .../WeatherApp/WeatherUpdateController.php | 8 +- .../Resources/WeatherResource.php | 35 ++++- .../Resources/WeatherResources.php | 4 +- src/resources/views/layouts/main.blade.php | 9 +- .../weather-app/weather-update.blade.php | 146 ++++++++++++++---- src/tests/Unit/Enums/DirectionTest.php | 45 ++++++ 7 files changed, 236 insertions(+), 42 deletions(-) create mode 100644 src/app/Enums/Direction.php create mode 100644 src/tests/Unit/Enums/DirectionTest.php diff --git a/src/app/Enums/Direction.php b/src/app/Enums/Direction.php new file mode 100644 index 0000000..7879f17 --- /dev/null +++ b/src/app/Enums/Direction.php @@ -0,0 +1,31 @@ +value; + } +} diff --git a/src/app/Http/Controllers/WeatherApp/WeatherUpdateController.php b/src/app/Http/Controllers/WeatherApp/WeatherUpdateController.php index 2624834..ed122ed 100644 --- a/src/app/Http/Controllers/WeatherApp/WeatherUpdateController.php +++ b/src/app/Http/Controllers/WeatherApp/WeatherUpdateController.php @@ -37,11 +37,9 @@ public function index(Request $request): View ->getWeatherData($responseGeolocation); $data = [ - 'geolocation' => $responseGeolocation, - 'weather' => [ - 'current' => $responseCurrentWeather->getResponse(), - 'forecast' => $responseForecastWeather->getResponse(), - ] + 'geolocation' => $responseGeolocation->getResponse(), + 'weather' => $responseCurrentWeather->getResponse(), + 'weatherForecasts' => $responseForecastWeather->getResponse(), ]; return view('weather-app/weather-update', $data); diff --git a/src/app/Services/OpenWeatherApi/Resources/WeatherResource.php b/src/app/Services/OpenWeatherApi/Resources/WeatherResource.php index aac8ed8..8c52900 100644 --- a/src/app/Services/OpenWeatherApi/Resources/WeatherResource.php +++ b/src/app/Services/OpenWeatherApi/Resources/WeatherResource.php @@ -4,18 +4,27 @@ namespace App\Services\OpenWeatherApi\Resources; +use App\Enums\Direction; use App\Http\Resources\Resource; use App\Services\OpenWeatherApi\Interfaces\WeatherResourceInterface; +use Illuminate\Support\Carbon; +use Illuminate\Support\Str; class WeatherResource extends Resource implements WeatherResourceInterface { public function getResponse(): array { + $date = $this->getLocalDatetime($this->resource['dt'], $this->resource['timezone']); + return [ // Location Info 'country_code' => $this->resource['sys']['country'], 'country_city' => $this->resource['name'], 'timestamp' => $this->resource['dt'], + 'date' => $date->isoFormat('MMMM DD, YYYY'), + 'time' => $date->isoFormat('hh:mmA'), + 'month_day' =>$date->isoFormat('MMMM d'), + 'day_of_week' => $date->isoFormat('dddd'), 'timezone' => $this->resource['timezone'], 'coordinate' => [ 'lon' => $this->resource['coord']['lon'], @@ -24,7 +33,7 @@ public function getResponse(): array // Current Weather Data 'type' => $this->resource['weather'][0]['main'], // (Rain, Snow, Clouds etc.) - 'description' => $this->resource['weather'][0]['description'], + 'description' => Str::ucfirst($this->resource['weather'][0]['description']), 'icon' => $this->resource['weather'][0]['icon'], // Main @@ -33,14 +42,30 @@ public function getResponse(): array 'temp_max' => $this->resource['main']['temp_max'], 'feels_like' => $this->resource['main']['feels_like'], 'humidity' => $this->resource['main']['humidity'], + 'pressure' => $this->resource['main']['pressure'], // Wind - 'wind_speed' => $this->resource['wind']['speed'], - 'wind_direction' => $this->resource['wind']['deg'], + 'wind_speed' => ($this->resource['wind']['speed'] * 3.6), + 'wind_direction' => Direction::convertFromDegrees((int)$this->resource['wind']['deg']), // sys - 'sunrise' => $this->resource['sys']['sunrise'], - 'sunset' => $this->resource['sys']['sunset'], + 'sunrise' => $this->getLocalDatetime($this->resource['sys']['sunrise'], $this->resource['timezone']) + ->isoFormat('hh:mmA'), + 'sunset' => $this->getLocalDatetime($this->resource['sys']['sunset'], $this->resource['timezone']) + ->isoFormat('hh:mmA'), ]; } + + private function getLocalDatetime(int $unixTimestamp, int $timezoneInSeconds): Carbon + { + return Carbon::createFromTimestamp($unixTimestamp) + ->setTimezone( + $this->secondsToHour($timezoneInSeconds) + ); + } + + private function secondsToHour(int $seconds): int + { + return $seconds/3600; + } } diff --git a/src/app/Services/OpenWeatherApi/Resources/WeatherResources.php b/src/app/Services/OpenWeatherApi/Resources/WeatherResources.php index 02590c0..2d842bb 100644 --- a/src/app/Services/OpenWeatherApi/Resources/WeatherResources.php +++ b/src/app/Services/OpenWeatherApi/Resources/WeatherResources.php @@ -15,7 +15,7 @@ public function getResponse(): array $forecast = []; foreach ($weatherForecast as $weather) { - $forecast[] = new WeatherResource([ + $weatherData = new WeatherResource([ 'coord' => $this->resource['city']['coord'], 'weather' => $weather['weather'], 'main' => $weather['main'], @@ -29,6 +29,8 @@ public function getResponse(): array 'timezone' => $this->resource['city']['timezone'], 'name' => $this->resource['city']['name'], ]); + + $forecast[] = $weatherData->getResponse(); } return $forecast; diff --git a/src/resources/views/layouts/main.blade.php b/src/resources/views/layouts/main.blade.php index 613e987..eee7b49 100644 --- a/src/resources/views/layouts/main.blade.php +++ b/src/resources/views/layouts/main.blade.php @@ -13,13 +13,18 @@ + + @vite(['resources/sass/app.scss', 'resources/js/app.js']) + - - @vite(['resources/sass/app.scss', 'resources/js/app.js'])
diff --git a/src/resources/views/weather-app/weather-update.blade.php b/src/resources/views/weather-app/weather-update.blade.php index fd933d5..297aed6 100644 --- a/src/resources/views/weather-app/weather-update.blade.php +++ b/src/resources/views/weather-app/weather-update.blade.php @@ -5,56 +5,144 @@
-
-
-
- + +
+ +

{{ $geolocation['formatted'] }}

-
15:07
+
{{ $weather['date'] }} {{ $weather['time'] }}
-
- - -
+
+ + +
+
+ + +
+ +
+ +
+
+ +

+ {{ $weather['day_of_week'] }}, {{ $weather['date'] }} {{ $weather['time'] }} +

+ +
+
+ weather-icon +
+ +
+ +

{{ $weather['description'] }}

+

{{ $weather['temp'] }}°C

+ Feels like {{ $weather['feels_like'] }}°C + +
+
+ {{ $weather['temp_min'] }} +
+  ~  +
+ {{ $weather['temp_max'] }} +
+ °C +
+
+ +
-
-
-
-
{{ $weather['current']['temp'] }}°C
- Feels like {{ $weather['current']['feels_like'] }}°C - {{ $weather['current']['description'] }} -
-
- weather-icon
-
+
+ +
+
+
{{ $weather['wind_speed'] }} km/h
+
{{ $weather['wind_direction'] }}
+
{{ $weather['humidity'] }}%
+
{{ $weather['pressure'] }}hPa
+
{{ $weather['sunrise'] }}
+
{{ $weather['sunset'] }}
+
+
-
-
-
sunrise: {{ $weather['current']['sunrise'] }}
-
sunset: {{ $weather['current']['sunset'] }}
-
temp_max: {{ $weather['current']['temp_max'] }}
-
temp_min: {{ $weather['current']['temp_min'] }}
-
wind speed: {{ $weather['current']['wind_speed'] }} km/h
-
wind deg: {{ $weather['current']['wind_direction'] }}
-
humidity: {{ $weather['current']['humidity'] }}%
+
+ + + + + +
+ + + +
+ @foreach($weatherForecasts as $forecast) + + +
+ +
+
+
+
+ weather-icon +
+
+

{{ $forecast['temp'] }}°C

+
+
+ Feels like {{ $forecast['feels_like'] }}°C +
+
+
+
+ + +
+

{{ $forecast['description'] }}

+
+
+
{{ $forecast['temp_min'] }}
+
{{ $forecast['temp_max'] }}
+
{{ $forecast['wind_speed'] }} km/h
+
{{ $forecast['wind_direction'] }}
+
{{ $forecast['humidity'] }}%
+
{{ $forecast['pressure'] }}hPa
+
{{ $forecast['sunrise'] }}
+
{{ $forecast['sunset'] }}
+
+
+
+ + +
+ @endforeach +
diff --git a/src/tests/Unit/Enums/DirectionTest.php b/src/tests/Unit/Enums/DirectionTest.php new file mode 100644 index 0000000..725db9b --- /dev/null +++ b/src/tests/Unit/Enums/DirectionTest.php @@ -0,0 +1,45 @@ + ['degrees' => '0', 'expected' => 'N']; + yield 'North 360' => ['degrees' => '360', 'expected' => 'N']; + yield 'East' => ['degrees' => '90', 'expected' => 'E']; + yield 'South' => ['degrees' => '180', 'expected' => 'S']; + yield 'West' => ['degrees' => '270', 'expected' => 'W']; + + // Test Ordinal Directions + yield 'North East' => ['degrees' => '45', 'expected' => 'NE']; + yield 'South East' => ['degrees' => '135', 'expected' => 'SE']; + yield 'South West' => ['degrees' => '225', 'expected' => 'SW']; + yield 'North West' => ['degrees' => '315', 'expected' => 'NW']; + + // Test for Anything unexpected! + yield 'North 10' => ['degrees' => '10', 'expected' => 'N']; + yield 'South West 269' => ['degrees' => '269', 'expected' => 'SW']; + yield 'South East 154' => ['degrees' => '145', 'expected' => 'SE']; + yield 'South 900' => ['degrees' => '900', 'expected' => 'S']; + yield 'West 271.5' => ['degrees' => '271.5', 'expected' => 'W']; + yield 'West -271.5' => ['degrees' => '-271.5', 'expected' => 'W']; + } + + /** + * @dataProvider getDegreesTestData + */ + public function testDirection(string $degrees, string $expected): void + { + $direction = Direction::convertFromDegrees((int)$degrees); + + $this->assertEquals($expected, $direction); + } +} From 2466c6d409e1a345a42dd760f78f414e8e9dd1a8 Mon Sep 17 00:00:00 2001 From: Noel Palo Date: Sat, 9 Sep 2023 13:18:03 +0800 Subject: [PATCH 3/3] feature/BWA-6-weather-app-ui-update - Update UI Display - Fix Date & Time display - Fix Timezone - Fix Controller return data - Add Direction Enum & UnitTest - Add conversion from degrees to 8 point compass directions --- .../API/WeatherApp/WeatherUpdateApiController.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/app/Http/Controllers/API/WeatherApp/WeatherUpdateApiController.php b/src/app/Http/Controllers/API/WeatherApp/WeatherUpdateApiController.php index 7048584..ad8ca46 100644 --- a/src/app/Http/Controllers/API/WeatherApp/WeatherUpdateApiController.php +++ b/src/app/Http/Controllers/API/WeatherApp/WeatherUpdateApiController.php @@ -37,11 +37,9 @@ public function __invoke(Request $request): JsonResource ->getWeatherData($responseGeolocation); $data = [ - 'geolocation' => $responseGeolocation, - 'weather' => [ - 'current' => $responseCurrentWeather->getResponse(), - 'forecast' => $responseForecastWeather->getResponse(), - ] + 'geolocation' => $responseGeolocation->getResponse(), + 'weather' => $responseCurrentWeather->getResponse(), + 'weatherForecasts' => $responseForecastWeather->getResponse(), ]; return new JsonResource($data);