Skip to content

Commit

Permalink
Merge pull request #16 from nspalo/development
Browse files Browse the repository at this point in the history
BWA-Dev-5-Weather-App-UI-Display-Enhancement
  • Loading branch information
nspalo authored Sep 9, 2023
2 parents 371fc47 + 9021b90 commit 735441e
Show file tree
Hide file tree
Showing 11 changed files with 291 additions and 24 deletions.
31 changes: 31 additions & 0 deletions src/app/Enums/Direction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace App\Enums;

enum Direction: string
{
case North = "N";
case NorthEast = "NE";
case East = "E";
case SouthEast = "SE";
case South = "S";
case SouthWest = "SW";
case West = "W";
case NorthSouth = "NW";

/**
* Convert Degrees to Direction using 8 Wind Compass Implementation
* - Cardinal Directions: N, E, S, W
* - Ordinal Directions: NE, SE, SW, NW
*/
public static function convertFromDegrees(int $degrees = 0): string
{
if($degrees < 0) {
$degrees *= -1; // Handle negative input value
}

$direction = floor(($degrees/45)) % 8;

return self::cases()[$direction]->value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
35 changes: 30 additions & 5 deletions src/app/Services/OpenWeatherApi/Resources/WeatherResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -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'],
Expand All @@ -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
Expand All @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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'],
Expand All @@ -29,6 +29,8 @@ public function getResponse(): array
'timezone' => $this->resource['city']['timezone'],
'name' => $this->resource['city']['name'],
]);

$forecast[] = $weatherData->getResponse();
}

return $forecast;
Expand Down
17 changes: 17 additions & 0 deletions src/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
3 changes: 3 additions & 0 deletions src/resources/sass/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@

// Bootstrap
@import 'bootstrap/scss/bootstrap';

// Bootstrap-icons
@import 'bootstrap-icons/font/bootstrap-icons.css';
12 changes: 11 additions & 1 deletion src/resources/views/layouts/main.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,19 @@

<!-- Scripts -->
@vite(['resources/sass/app.scss', 'resources/js/app.js'])

<style>
body {
background-color: #aed6ff !important;
}
.display-4 {
font-size: 5.5rem;
}
</style>
</head>
<body>
<div id="app" class="col-lg-8 mx-auto p-4 py-md-5">
<div id="app" class="col-lg-8 mx-auto p-1 py-md-5">
@include("layouts.header")

<main>
Expand Down
151 changes: 144 additions & 7 deletions src/resources/views/weather-app/weather-update.blade.php
Original file line number Diff line number Diff line change
@@ -1,17 +1,154 @@
@extends('layouts.main')

@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">{{ __('Weather') }}</div>
<div class="container">
<div class="row justify-content-center">
<div class="col-xl-12">

<div class="row d-flex justify-content-center align-items-center h-100">
<div class="col-sm-12 col-md-8 col-lg-10 col-xl-12">

<!-- Current Weather -->
<div class="card">

<!-- Header: Weather Card -->
<div class="card-header">
<div class="d-flex">
<h2 class="flex-grow-1"><i class="bi bi-geo-alt"></i> {{ $geolocation['formatted'] }}</h2>
<h6>{{ $weather['date'] }} {{ $weather['time'] }}</h6>
</div>

<form class="row g-3">
<div class="d-flex input-group rounded mb-3">
<input id="inputAddress2" class="form-control rounded" type="search" placeholder="City" aria-label="Search" aria-describedby="search-input">
<button id="search-button" class="btn btn-outline-secondary rounded" type="button">Search</button>
</div>
</form>
</div><!-- Header: Weather Card -->

<!-- Body: Weather Card -->
<div class="card-body">

<div class="row g-0">

<div class="col-md-8">
<div class="d-flex flex-column align-items-center text-center mt-5 mb-4">

<h3 class="card-title border-bottom-1 fs-1">
{{ $weather['day_of_week'] }}, {{ $weather['date'] }} {{ $weather['time'] }}
</h3>

<div class="d-flex flex-row">
<div class="d-flex flex-column align-items-center">
<img src="https://openweathermap.org/img/wn/{{ $weather['icon'] }}@4x.png" width="300" alt="weather-icon">
</div>

<div class="d-flex flex-column text-center mt-5 mb-4">

<h3 class="card-title border-bottom-1">{{ $weather['description'] }}</h3>
<h1 class="display-4 mb-0 font-weight-bold" data-bs-toggle="tooltip" title="Temperature" style="color: #1C2331;">{{ $weather['temp'] }}°C</h1>
<span class="small fs-4" style="color: #868B94">Feels like <i class="bi bi-thermometer-half"></i> {{ $weather['feels_like'] }}°C</span>

<div class="d-flex flex-row fs-3">
<div data-bs-toggle="tooltip" title="Highest Temperature">
<span class="ms-1"><i class="bi bi-thermometer-low"></i> {{ $weather['temp_min'] }}</span>
</div>
<span>&nbsp;~&nbsp;</span>
<div data-bs-toggle="tooltip" title="Lowest Temperature">
<span class="ms-1"><i class="bi bi-thermometer-high"></i> {{ $weather['temp_max'] }}</span>
</div>
<span>°C</span>
</div>
</div>

</div>

</div>
</div>
<div class="col-md-4">

<div class="d-flex flex-column mt-5 mb-4">
<div class="flex-grow-1 fs-2">
<div data-bs-toggle="tooltip" title="Wind Speed"><span class="ms-1"><i class="bi bi-wind"></i> {{ $weather['wind_speed'] }} km/h</span></div>
<div data-bs-toggle="tooltip" title="Wind Direction"><span class="ms-1"><i class="bi bi-compass"></i> {{ $weather['wind_direction'] }}</span></div>
<div data-bs-toggle="tooltip" title="Humidity"><span class="ms-1"><i class="bi bi-moisture"></i> {{ $weather['humidity'] }}% </span></div>
<div data-bs-toggle="tooltip" title="Atmospheric pressure"><span class="ms-1"><i class="bi bi-speedometer2"></i> {{ $weather['pressure'] }}hPa </span></div>
<div data-bs-toggle="tooltip" title="Sunrise"><span class="ms-1"><i class="bi bi-brightness-alt-high"></i> {{ $weather['sunrise'] }}</span></div>
<div data-bs-toggle="tooltip" title="Sunset"><span class="ms-1"><i class="bi bi-brightness-alt-low"></i> {{ $weather['sunset'] }}</span></div>
</div>
</div>

<div class="card-body">
<h1>HELLO AGAIN BOOTSTRAP!</h1>
</div>

</div>

</div><!-- Body: Weather Card -->

<!-- Footer: Weather Card -->
<!-- TODO: DISABLED FOR NOW, NOT SURE WHAT TO PUT!!!
<div class="card-footer text-end">
<small class="text-muted ">-- footer --</small>
</div>
-->
<!-- Footer: Weather Card -->

</div><!-- Current Weather -->


<!-- 5 Days Weather Forecast -->
<div class="card-group">
@foreach($weatherForecasts as $forecast)

<!-- Weather Forecast -->
<div class="card">
<!-- Header: Weather Card -->
<div class="d-flex flex-column text-center mt-1 mb-2">
<div class="d-flex align-items-center">
<div class="flex-grow-1" style="font-size: 1rem;">
<div>
<img src="https://openweathermap.org/img/wn/{{ $forecast['icon'] }}@4x.png" alt="weather-icon">
</div>
<div>
<h3><span class="ms-1">{{ $forecast['temp'] }}°C</span></h3>
</div>
<div class="small">
<span class="ms-1">Feels like {{ $forecast['feels_like'] }}°C</span>
</div>
</div>
</div>
</div><!-- Header: Weather Card -->

<!-- Body: Weather Card -->
<div class="card-body text-center pt-2">
<h4 class="card-title border-bottom-1">{{ $forecast['description'] }}</h4>
<div class="d-flex align-items-center">
<div class="flex-grow-1" style="font-size: 1rem;">
<div data-bs-toggle="tooltip" title="owest Temperature"><span class="ms-1"><i class="bi bi-thermometer-low"></i> {{ $forecast['temp_min'] }}</span></div>
<div data-bs-toggle="tooltip" title="Highest Temperature"><span class="ms-1"><i class="bi bi-thermometer-high"></i> {{ $forecast['temp_max'] }}</span></div>
<div data-bs-toggle="tooltip" title="Wind Speed"><span class="ms-1"><i class="bi bi-wind"></i> {{ $forecast['wind_speed'] }} km/h</span></div>
<div data-bs-toggle="tooltip" title="Wind Direction"><span class="ms-1"><i class="bi bi-compass"></i> {{ $forecast['wind_direction'] }}</span></div>
<div data-bs-toggle="tooltip" title="Humidity"><span class="ms-1"><i class="bi bi-moisture"></i> {{ $forecast['humidity'] }}% </span></div>
<div data-bs-toggle="tooltip" title="Atmospheric pressure"><span class="ms-1"><i class="bi bi-speedometer2"></i> {{ $forecast['pressure'] }}hPa </span></div>
<div data-bs-toggle="tooltip" title="Sunrise"><span class="ms-1"><i class="bi bi-brightness-alt-high"></i> {{ $forecast['sunrise'] }}</span></div>
<div data-bs-toggle="tooltip" title="Sunset"><span class="ms-1"><i class="bi bi-brightness-alt-low"></i> {{ $forecast['sunset'] }}</span></div>
</div>
</div>
</div><!-- Body: Weather Card -->

<!-- Footer: Weather Card -->
<div class="card-footer text-end">
<small class="text-muted ">{{ $forecast['date'] }} {{ $forecast['time'] }}</small>
</div><!-- Footer: Weather Card -->
</div><!-- Weather Forecast -->

@endforeach
</div><!-- 5 Days Weather Forecast -->

</div>
</div>


</div>
</div>
</div>
@endsection
Loading

0 comments on commit 735441e

Please sign in to comment.