Closed vannut closed 2 years ago
Since I couldn't find a way to get the existing antlers tag {{ forecast }}
to work within the current_data
blade view I created an Action to do the logic Tags\Forecast.php
did. This is now used in Forecast.php
as well as ControlPanelController.php
.
In Forecast.php
use Vannut\StatamicWeather\Actions\CreateForecastAction;
public function index(): Collection
{
$locale = strtolower($this->params->get('locale'));
$daily = (new CreateForecastAction())->make($locale);
return $daily;
}
In ControlPanelController.php
use Vannut\StatamicWeather\Actions\CreateForecastAction;
public function currentData()
{
if (Storage::exists('weather-forecast.json'))
{
$json = json_encode(
json_decode(Storage::get('weather-forecast.json')),
JSON_PRETTY_PRINT
);
$daily = (new CreateForecastAction())->make();
} else
{
$json = false;
}
return view('weather::current_data', [
'json' => $json,
'forecast' => $daily
]);
}
And of course in Actions\CreateForecastAction.php
<?php
namespace Vannut\StatamicWeather\Actions;
use Storage;
use Illuminate\Support\Collection;
use Vannut\StatamicWeather\Settings;
use Vannut\StatamicWeather\ConversionTrait;
class CreateForecastAction {
use ConversionTrait;
public function make($lang = null)
{
$config = (new Settings)->get();
if ($lang)
{
$locale = $lang;
} else
{
$locale = strtolower($config->get('lang', 'en'));
}
$units = $config->get('units', 'metric');
$json = json_decode(Storage::get('weather-forecast.json'), true);
return 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'] = '°C';
} else
{
$item['temp_unit'] = '°F';
}
return $item;
});
}
}
With everything set up you can now use this data in current_weather.blade.php
with a slightly modified version of your existing forecast template
@extends('statamic::layout')
@section('title', 'Weather settings')
@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>
<div class="flex flex-wrap">
@if( ! $json )
<h1 class="mt-4">Current Data</h1>
<p><em>No data stored yet</em></p>
@else
<div class="lg:w-1/4 w-full">
<h1 class="mt-4">Current Data</h1>
<div name="textarea">
<textarea
id="field_textarea"
class="input-text"
style="width:100%; overflow-wrap: break-word; height: 450px;"
>{{ $json }}</textarea>
</div>
</div>
<div class=" px-2">
<div>
<h1 class="mt-4">Current Forecast</h1>
<div class="">
<div class="flex justify-center py-2">
<div class="flex flex-wrap bg-neutral-100">
@foreach($forecast as $daily)
<div class="p-1 w-full sm:w-1/2 lg:w-1/3 xl:w-auto">
<div class="rounded-xl bg-white">
<div class="lining-nums p-4 text-center">
<span
class="text-primary text-lg">{{date('l',$daily['dt'])}}</span><br/>
<span class="text-xs">{{date('Y-m-d',$daily['dt'])}}</span>
</div>
<div class="pb-4 text-5xl flex flex-col text-center justify-center">
<i class="fal {{ $daily['icon'] }}"></i>
<span class="text-xs">{{$daily['weather'][0]['description']}}</span>
</div>
<div class="pb-2 flex items-center justify-center">
<div class="text-sm">
{{ round($daily['temp']['max']) }}<span
class="text-neutral-700">{!! $daily['temp_unit']!!}</span>
</div>
<div class="text-sm">
<span class="text-neutral-700"> / </span>
{{ round($daily['temp']['min']) }}<span
class="text-neutral-700">{!! $daily['temp_unit']!!}</span>
</div>
</div>
<div class="flex items-center justify-center pb-4">
<div>
<i class="fal fa-wind"></i>
{{ $daily['wind_compass']}} {{ $daily['wind_bft'] }}<span
class="text-neutral-700">Bft</span>
</div>
</div>
<div class="flex items-center justify-center pb-4">
<div>
{{ $daily['pressure'] }}<span
class="text-neutral-700">hPa</span>
</div>
</div>
</div>
</div>
@endforeach
</div>
</div>
</div>
</div>
</div>
@endif
</div>
@endsection
of course it's quite bare and could use some additional styling, but it's working
(except for the icons, since I am using a different version of Fontawesome it's not rendering them for me. Maybe it would be better to pass the SVG directly instead of the classes)
As a widget:
Create the widget src/Widgets/CurrentForecast.php
<?php
namespace Vannut\StatamicWeather\Widgets;
use Statamic\Widgets\Widget;
use Vannut\StatamicWeather\Actions\CreateForecastAction;
class CurrentForecast extends Widget
{
/**
* The HTML that should be shown in the widget.
*
* @return string|\Illuminate\View\View
*/
public function html()
{
$forecast=(new CreateForecastAction())->make();
return view('vannut::widgets.current_forecast',['forecast'=>$forecast]);
}
}
In views/Widgets/current_forecast.blade.php
(I just copy/pasted this part from above, could be turned into a component I guess)
<div class="card p-1 content">
<h1 class="mt-4">Current Forecast</h1>
<div class="">
<div class="flex justify-center py-2">
<div class="flex flex-wrap bg-neutral-100">
@foreach($forecast as $daily)
<div class="p-1 w-full sm:w-1/2 lg:w-1/3 xl:w-auto">
<div class="rounded-xl bg-white">
<div class="lining-nums p-4 text-center">
<span
class="text-primary text-lg">{{date('l',$daily['dt'])}}</span><br/>
<span class="text-xs">{{date('Y-m-d',$daily['dt'])}}</span>
</div>
<div class="pb-4 text-5xl flex flex-col text-center justify-center">
<i class="fal {{ $daily['icon'] }}"></i>
<span class="text-xs">{{$daily['weather'][0]['description']}}</span>
</div>
<div class="pb-2 flex items-center justify-center">
<div class="text-sm">
{{ round($daily['temp']['max']) }}<span
class="text-neutral-700">{!! $daily['temp_unit']!!}</span>
</div>
<div class="text-sm">
<span class="text-neutral-700"> / </span>
<span
style="color:{{$daily['uvi_color']}}">{{ round($daily['temp']['min']) }}</span>
<span class="text-neutral-700">{!! $daily['temp_unit']!!}</span>
</div>
</div>
<div class="flex items-center justify-center pb-4">
<div>
<i class="fal fa-wind"></i>
{{ $daily['wind_compass']}} {{ $daily['wind_bft'] }}<span
class="text-neutral-700">Bft</span>
</div>
</div>
<div class="flex items-center justify-center pb-4">
<div>
{{ $daily['pressure'] }}<span
class="text-neutral-700">hPa</span>
</div>
</div>
</div>
</div>
@endforeach
</div>
</div>
</div>
</div>
Register in ServiceProvider.php
use Vannut\StatamicWeather\Widgets\CurrentForecast;
protected $viewNamespace = 'vannut';
protected $widgets = [
CurrentForecast::class
];
And finally register it in config/statamic/cp.php
'widgets' => [
'current_forecast',
],
Now you have the forecast as a widget within the CP dashboard
Added this in the latest pr #11
As we have the current weather, wouldn't it be cool to display a small widget with the forecast?
Just a simple table with date, temperature, wind & pressure?