Skip to content

Commit

Permalink
Merge pull request #11 from vannut/dashboard-widget
Browse files Browse the repository at this point in the history
Adding dashboard Widget and Editions
  • Loading branch information
vannut authored Dec 13, 2021
2 parents 722a0ef + 773002b commit fe99515
Show file tree
Hide file tree
Showing 10 changed files with 269 additions and 77 deletions.
21 changes: 15 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Display the current weather or a 7-day forecast for any lat/lon on earth.

> Attention: this addon is a work in progress and not production ready yet. Find something broken or missing: please create [an issue](https://github.com/vannut/statamic-weather-addon/issues)!
> Attention: Find something broken or missing: please create [an issue](https://github.com/vannut/statamic-weather-addon/issues)!
## OpenWeatherMap
The weather data itself is coming from the OpenWeatherMap api. Especially the [One-Call API](https://openweathermap.org/api/one-call-api) which delivers all the relevant data in _one call_. And to make it even better: It's free for the first 1,000,000 calls/month (or 60 calls/minute)
Expand All @@ -13,9 +13,9 @@ The weather data itself is coming from the OpenWeatherMap api. Especially the [O
3. After signing in go to API keys and generate a new one.
4. Go to your Statamic Control Panel and look for the Weather entry. It should be in the sidebar.
5. Fill out the settings-form with your api-key, latitude & longitude
6. Go to the Command line and perform the first initial fetch of your specific data: `php artisan weather:fetchForecast`
6. Go to the Current Data page and fetch your first weather forecast!
6. Or Go to the Command line and perform the first initial fetch of your specific data: `php artisan weather:fetchForecast`

> In a next version this would be this command can be run from the utilities section of statamic.

## Renewing the forecast
Nothing is as changeable as the weather. Therefore this addon adds [a hourly call](https://github.com/vannut/statamic-weather-addon/blob/master/src/ServiceProvider.php#L25) to the scheduler of Statamic/Laravel.
Expand All @@ -39,10 +39,10 @@ Next to the data provided by the API, the addon adds a couple of nice additional
You'll have two tags to your disposal: `{{ forecast }}` and `{{ current_weather }}`

## Simple 7 day forecast
With the `{{ forecast }}` tag you will be able to display a card per day with the forecast.
This data is located in the `days` array which you can traverse and add your styling magic.
With the `{{ forecast }}` tag you will be able to display a card per day with the forecast.
This data is located in the `days` array which you can traverse and add your styling magic.

This is a very simple example:
This is a very simple example:
```html
<div class="flex bg-neutral-100">
{{ forecast :locale="site" }}
Expand Down Expand Up @@ -98,6 +98,15 @@ Want to display the current weather of your location? Use the `{{ current_weathe
{{ /current_weather }}
```

## Widget

You can add a basic Forecast widget to your CP dashboard, by adding it in your `/config/statamic/cp.php`:
```php
'widgets' => [
'current_forecast',
]
```

---
<p>
<a href="https://statamic.com"><img src="https://img.shields.io/badge/Statamic-3.0+-FF269E?style=for-the-badge" alt="Compatible with Statamic v3"></a>
Expand Down
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
},
"extra": {
"statamic": {
"name": "Weather",
"description": "Voeg Weer toe aan Statamic"
"name": "Weather Forecast",
"description": "Display the current weather or a 7-day forecast for any lat/lon on earth.",
"editions": ["free", "coffee"]
},
"laravel": {
"providers": [
Expand Down
112 changes: 89 additions & 23 deletions resources/views/current_data.blade.php
Original file line number Diff line number Diff line change
@@ -1,31 +1,97 @@
@extends('statamic::layout')
@section('title', 'Weather settings')
@section('wrapper_class', 'max-w-md ml-0')
@section('title', 'Current data')
@section('wrapper_class', 'max-w-full ml-0')

@section('content')

<form
title="Fetch current Weather"
method="post"
action="{{ cp_route('weather.data.fetchWeather') }}"
>
<button class="btn-primary" type="submit">Fetch/update Weather data</button>
@csrf
</form>

<h1 class="mt-4">Current Data</h1>
@if( ! $json )
<p><em>No data stored yet</em></p>
@else
<div name="textarea">
<textarea
id="field_textarea"
class="input-text"
style="width:100%; overflow-wrap: break-word; height: 450px;"
>{{ $json }}</textarea>

@if( ! $json )
<div>
<header>
<h1 class="mb-2">
No data stored
</h1>
</header>
<div class="card content">
<p>
We don't have any data stored yet.
</p>
<form
title="Fetch current Weather"
method="post"
action="{{ cp_route('weather.data.fetchWeather') }}"
>
<button class="btn-primary" type="submit">Fetch/update</button>
@csrf
</form>
</div>
</div>
@else
<div>
<header class="mt-3 mb-2">
<div class="flex items-center justify-between">
<h1>Current Data</h1>
<form
title="Fetch current Weather"
method="post"
action="{{ cp_route('weather.data.fetchWeather') }}"
>
<button class="btn-primary" type="submit">Fetch/update</button>
@csrf
</form>
</div>
</header>
<div class="card p-2 content">
<table>
@foreach($forecast['days'] as $day)
<tr>
<td>
<span
class="text-primary text-lg">{{date('l',$day['dt'])}}</span>

<span class="text-xs">{{date('Y-m-d',$day['dt'])}}</span>
</td>
<td class="px-2">
{{$day['weather'][0]['description']}}
</td>
<td class="px-2">
{{ round($day['temp']['max']) }}
<span class="text-neutral-700">{!! $day['temp_unit']!!}</span>
</td>
<td class="px-2">
{{ round($day['temp']['min']) }}
<span class="text-neutral-700">{!! $day['temp_unit']!!}</span>
</td>
<td class="px-2">
{{ $day['wind_compass']}} {{ $day['wind_bft'] }}
<span class="text-neutral-700">Bft</span>
</td>
<td>
{{ $day['pressure'] }}
<span class="text-neutral-700">hPa</span>
</td>

</tr>
@endforeach
</table>
<div class="text-sm mt-2">
Fetched at {{ $forecast['fetched_at'] }}
</div>
</div>

<header class="mt-3 mb-2">
<h1>Raw JSON</h1>
</header>
<div class="card p-2 content">
<textarea
id="field_textarea"
class="input-text"
style="width:100%; overflow-wrap: break-word; height: 450px;"
>{{ $json }}</textarea>
</div>
</div>
@endif



@endsection
48 changes: 48 additions & 0 deletions resources/views/widgets/forecast.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<div class="card p-0 content">
<div class="py-3 px-4 border-b">
<h1>Current Weather Forecast</h1>
</div>
<div class="flex flex-wrap p-2">
@foreach($forecast['days'] as $daily)
<div class="w-1/2 sm:w-1/3 lg:w-1/4 p-1">
<div class="mb-2">
<div>
<strong>{{date('l',$daily['dt'])}}</strong><br>
<p>{{date('Y-m-d',$daily['dt'])}}</span></p>
</div>
<div class="my-2">
<div class="flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-thermometer-half" viewBox="0 0 16 16">
<path d="M9.5 12.5a1.5 1.5 0 1 1-2-1.415V6.5a.5.5 0 0 1 1 0v4.585a1.5 1.5 0 0 1 1 1.415z"/>
<path d="M5.5 2.5a2.5 2.5 0 0 1 5 0v7.55a3.5 3.5 0 1 1-5 0V2.5zM8 1a1.5 1.5 0 0 0-1.5 1.5v7.987l-.167.15a2.5 2.5 0 1 0 3.333 0l-.166-.15V2.5A1.5 1.5 0 0 0 8 1z"/>
</svg>
{{ round($daily['temp']['max']) }}
<span class="text-neutral-700">{!! $daily['temp_unit']!!}</span>
</div>

<div class="flex items-center">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-wind" viewBox="0 0 16 16">
<path d="M12.5 2A2.5 2.5 0 0 0 10 4.5a.5.5 0 0 1-1 0A3.5 3.5 0 1 1 12.5 8H.5a.5.5 0 0 1 0-1h12a2.5 2.5 0 0 0 0-5zm-7 1a1 1 0 0 0-1 1 .5.5 0 0 1-1 0 2 2 0 1 1 2 2h-5a.5.5 0 0 1 0-1h5a1 1 0 0 0 0-2zM0 9.5A.5.5 0 0 1 .5 9h10.042a3 3 0 1 1-3 3 .5.5 0 0 1 1 0 2 2 0 1 0 2-2H.5a.5.5 0 0 1-.5-.5z"/>
</svg>
<span>&nbsp;
{{ $daily['wind_compass']}} {{ $daily['wind_bft'] }}<span
class="text-neutral-700">Bft</span>
</span>
</div>
<div class="flex items-center">
<svg style="color:{{$daily['uvi_color']}}"
xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-sun-fill" viewBox="0 0 16 16">
<path d="M8 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM8 0a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 0zm0 13a.5.5 0 0 1 .5.5v2a.5.5 0 0 1-1 0v-2A.5.5 0 0 1 8 13zm8-5a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2a.5.5 0 0 1 .5.5zM3 8a.5.5 0 0 1-.5.5h-2a.5.5 0 0 1 0-1h2A.5.5 0 0 1 3 8zm10.657-5.657a.5.5 0 0 1 0 .707l-1.414 1.415a.5.5 0 1 1-.707-.708l1.414-1.414a.5.5 0 0 1 .707 0zm-9.193 9.193a.5.5 0 0 1 0 .707L3.05 13.657a.5.5 0 0 1-.707-.707l1.414-1.414a.5.5 0 0 1 .707 0zm9.193 2.121a.5.5 0 0 1-.707 0l-1.414-1.414a.5.5 0 0 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .707zM4.464 4.465a.5.5 0 0 1-.707 0L2.343 3.05a.5.5 0 1 1 .707-.707l1.414 1.414a.5.5 0 0 1 0 .708z"/>
</svg>
<span style="font-weight: 300; color:{{$daily['uvi_color']}}">{{$daily['uvi']}}</span>
</div>
<div>
{{$daily['weather'][0]['description']}}
</div>

</div>
</div>
</div>
@endforeach
</div>
</div>
16 changes: 11 additions & 5 deletions routes/cp.php
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
<?php

Route::namespace('\Vannut\StatamicWeather\Controllers')->group(function () {
Route::prefix('weather')->as('weather')->group(function () {

Route::prefix('weather')
->as('weather')
->group(function () {
Route::get(
'/',
'ControlPanelController@cpIndex'
)->name('.index');

// Data routes
Route::get(
'/',
'/data',
'ControlPanelController@currentData'
)->name('.data');
Route::post(
'/fetch-weather',
'/fetch-weather',
'ControlPanelController@fetchWeather'
)->name('.data.fetchWeather');


// Settings
Route::get('/settings', 'ControlPanelController@index')->name('.settings');
Route::post('/update-settings', 'ControlPanelController@update')->name('.settings.update');

});
});
54 changes: 54 additions & 0 deletions src/Actions/CreateForecastDataAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php

namespace Vannut\StatamicWeather\Actions;

use Storage;
use Illuminate\Support\Collection;
use Vannut\StatamicWeather\Settings;
use \Vannut\StatamicWeather\ConversionTrait;

class CreateForecastDataAction {

use ConversionTrait;

public function execute(
string $locale = null
) : array {

$config = (new Settings)->get();
$units = $config->get('units', 'metric');
if (!$locale) {
$locale = strtolower($config->get('lang', 'en'));
}


$json = json_decode(Storage::get('weather-forecast.json'), true);
$daily = collect($json['daily'])
->map(function ($item) use ($locale, $units) {

$item['icon'] = $this->makeIcon($item['weather']);
$item['wind_compass'] = $this->degreeesToWindDirection($item['wind_deg'], $locale);

$item['wind_bft'] = ($units === 'metric')
? $this->msToBft($item['wind_speed'])
: $this->mphToBft($item['wind_speed']);

$item['uvi_color'] = $this->UVIndexToColor($item['uvi']);
$item['uvi_percentage'] = $this->UVIndexToPercentage($item['uvi']);
$item['pop_per'] = $item['pop'] * 100;

if ($units == 'metric') {
$item['temp_unit'] = '&deg;C';
} else {
$item['temp_unit'] = '&deg;F';
}
return $item;
});

return [
'fetched_at' => $json['fetched_at'],
'days' => $daily
];

}
}
21 changes: 14 additions & 7 deletions src/Controllers/ControlPanelController.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Illuminate\Support\Facades\Artisan;
use Statamic\Http\Controllers\CP\CpController;
use Vannut\StatamicWeather\Actions\FetchAndStoreAction;
use Vannut\StatamicWeather\Actions\CreateForecastDataAction;

class ControlPanelController extends CpController
{
Expand All @@ -19,22 +20,28 @@ public function __construct()
{
$this->settings = new Settings;
}
public function cpIndex() {
return redirect()->to(cp_route('weather.data'));
}

public function currentData()
{

public function currentData()
{
if (Storage::exists('weather-forecast.json')) {

$json = json_encode(
json_decode(Storage::get('weather-forecast.json')),
JSON_PRETTY_PRINT
);
$forecast = (new CreateForecastDataAction)->execute('en');
} else {
$json = false;
$forecast = false;
}



return view('weather::current_data', [
'json' => $json
'json' => $json,
'forecast' => $forecast
]);
}

Expand Down Expand Up @@ -84,7 +91,7 @@ public function update(Request $request)

public function fetchWeather()
{

$success = (new FetchAndStoreAction($this->settings->get()))->execute();

if ($success) {
Expand All @@ -93,7 +100,7 @@ public function fetchWeather()
Toast::error('Something went wrong');
}
return redirect()->back();

}


Expand Down
Loading

0 comments on commit fe99515

Please sign in to comment.