api fixes/updates

This commit is contained in:
Nabeel Shahzad 2018-05-01 20:58:05 -05:00
parent 50abda71cb
commit b96f1cd7c4
17 changed files with 1282 additions and 1604 deletions

View File

@ -29,6 +29,7 @@ class CreateAcarsTables extends Migration
$table->unsignedInteger('gs')->nullable(); $table->unsignedInteger('gs')->nullable();
$table->unsignedInteger('transponder')->nullable(); $table->unsignedInteger('transponder')->nullable();
$table->string('autopilot')->nullable(); $table->string('autopilot')->nullable();
$table->decimal('fuel')->nullable();
$table->decimal('fuel_flow')->nullable(); $table->decimal('fuel_flow')->nullable();
$table->string('sim_time')->nullable(); $table->string('sim_time')->nullable();

File diff suppressed because it is too large Load Diff

View File

@ -240,7 +240,8 @@ class PirepController extends Controller
*/ */
public function update($id, UpdateRequest $request) public function update($id, UpdateRequest $request)
{ {
Log::info('PIREP Update, user '.Auth::id(), $request->post()); Log::info('PIREP Update, user '.Auth::id());
Log::info($request->getContent());
$user = Auth::user(); $user = Auth::user();
$pirep = Pirep::find($id); $pirep = Pirep::find($id);

View File

@ -26,12 +26,13 @@ class PositionRequest extends FormRequest
'positions.*.lat' => 'required|numeric', 'positions.*.lat' => 'required|numeric',
'positions.*.lon' => 'required|numeric', 'positions.*.lon' => 'required|numeric',
'positions.*.altitude' => 'nullable|numeric', 'positions.*.altitude' => 'nullable|numeric',
'positions.*.heading' => 'nullable|integer|between:0,360', 'positions.*.heading' => 'nullable|numeric|between:0,360',
'positions.*.vs' => 'nullable', 'positions.*.vs' => 'nullable',
'positions.*.gs' => 'nullable', 'positions.*.gs' => 'nullable',
'positions.*.transponder' => 'nullable', 'positions.*.transponder' => 'nullable',
'positions.*.autopilot' => 'nullable', 'positions.*.autopilot' => 'nullable',
'positions.*.fuel_flow' => 'nullable', 'positions.*.fuel' => 'nullable|numeric',
'positions.*.fuel_flow' => 'nullable|numeric',
'positions.*.log' => 'nullable', 'positions.*.log' => 'nullable',
'positions.*.created_at' => 'nullable|date', 'positions.*.created_at' => 'nullable|date',
]; ];

View File

@ -43,9 +43,9 @@ class UpdateRequest extends FormRequest
'notes' => 'nullable', 'notes' => 'nullable',
'source_name' => 'nullable|max:25', 'source_name' => 'nullable|max:25',
'landing_rate' => 'nullable|numeric', 'landing_rate' => 'nullable|numeric',
'block_off_time' => 'nullable|date', 'block_off_time' => 'nullable',
'block_on_time' => 'nullable|date', 'block_on_time' => 'nullable',
'created_at' => 'nullable|date', 'created_at' => 'nullable',
'status' => 'nullable', 'status' => 'nullable',
'score' => 'nullable|integer', 'score' => 'nullable|integer',

View File

@ -33,6 +33,8 @@ use PhpUnitsOfMeasure\Exception\NonStringUnitName;
* @property integer block_time * @property integer block_time
* @property integer flight_time In minutes * @property integer flight_time In minutes
* @property integer planned_flight_time * @property integer planned_flight_time
* @property mixed planned_distance
* @property mixed distance
* @property integer score * @property integer score
* @property User user * @property User user
* @property Flight|null flight * @property Flight|null flight
@ -105,11 +107,20 @@ class Pirep extends Model
'score' => 'integer', 'score' => 'integer',
'source' => 'integer', 'source' => 'integer',
'state' => 'integer', 'state' => 'integer',
'block_off_time' => 'datetime', #'block_off_time' => 'datetime',
'block_on_time' => 'datetime', #'block_on_time' => 'datetime',
'submitted_at' => 'datetime', #'submitted_at' => 'datetime',
]; ];
/*protected $dates = [
'block_off_time',
'block_on_time',
'submitted_at',
'created_at',
'updated_at',
'deleted_at'
];*/
public static $rules = [ public static $rules = [
'airline_id' => 'required|exists:airlines,id', 'airline_id' => 'required|exists:airlines,id',
'aircraft_id' => 'required|exists:aircraft,id', 'aircraft_id' => 'required|exists:aircraft,id',
@ -140,6 +151,24 @@ class Pirep extends Model
return $flight_id; return $flight_id;
} }
/**
* Return the block off time in carbon format
* @return Carbon
*/
public function getBlockOffTimeAttribute()
{
return new Carbon($this->attributes['block_off_time']);
}
/**
* Return the block on time
* @return Carbon
*/
public function getBlockOnTimeAttribute()
{
return new Carbon($this->attributes['block_on_time']);
}
/** /**
* Return a new Length unit so conversions can be made * Return a new Length unit so conversions can be made
* @return int|Distance * @return int|Distance
@ -236,16 +265,16 @@ class Pirep extends Model
*/ */
public function getProgressPercentAttribute() public function getProgressPercentAttribute()
{ {
$upper_bound = $this->flight_time; $upper_bound = $this->distance['nmi'];
if($this->planned_flight_time) { if($this->planned_distance) {
$upper_bound = $this->planned_flight_time; $upper_bound = $this->planned_distance['nmi'];
} }
if(!$upper_bound) { if(!$upper_bound) {
$upper_bound = 1; $upper_bound = 1;
} }
return round(($this->flight_time / $upper_bound) * 100, 0); return round(($this->distance['nmi'] / $upper_bound) * 100, 0);
} }
/** /**

View File

@ -18,6 +18,7 @@ use App\Models\Setting;
use App\Models\Subfleet; use App\Models\Subfleet;
use App\Repositories\SettingRepository; use App\Repositories\SettingRepository;
use App\Services\ModuleService; use App\Services\ModuleService;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Schema; use Illuminate\Support\Facades\Schema;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
use View; use View;
@ -27,6 +28,11 @@ class AppServiceProvider extends ServiceProvider
public function boot(): void public function boot(): void
{ {
Schema::defaultStringLength(191); Schema::defaultStringLength(191);
Carbon::serializeUsing(function ($carbon) {
return $carbon->format('U');
});
$this->app->bind('setting', SettingRepository::class); $this->app->bind('setting', SettingRepository::class);
View::share('moduleSvc', app(ModuleService::class)); View::share('moduleSvc', app(ModuleService::class));
@ -39,6 +45,7 @@ class AppServiceProvider extends ServiceProvider
PirepField::observe(PirepFieldObserver::class); PirepField::observe(PirepFieldObserver::class);
Setting::observe(SettingObserver::class); Setting::observe(SettingObserver::class);
Subfleet::observe(SubfleetObserver::class); Subfleet::observe(SubfleetObserver::class);
} }
/** /**

View File

@ -10838,246 +10838,6 @@ button.close {
.select2-container--classic.select2-container--open .select2-dropdown { .select2-container--classic.select2-container--open .select2-dropdown {
border-color: #5897fb; } border-color: #5897fb; }
@charset "UTF-8";
/*!
* Pikaday
* Copyright © 2014 David Bushell | BSD & MIT license | http://dbushell.com/
*/
.pika-single {
z-index: 9999;
display: block;
position: relative;
color: #333;
background: #fff;
border: 1px solid #ccc;
border-bottom-color: #bbb;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
/*
clear child float (pika-lendar), using the famous micro clearfix hack
http://nicolasgallagher.com/micro-clearfix-hack/
*/
.pika-single:before,
.pika-single:after {
content: " ";
display: table;
}
.pika-single:after { clear: both }
.pika-single { *zoom: 1 }
.pika-single.is-hidden {
display: none;
}
.pika-single.is-bound {
position: absolute;
box-shadow: 0 5px 15px -5px rgba(0,0,0,.5);
}
.pika-lendar {
float: left;
width: 240px;
margin: 8px;
}
.pika-title {
position: relative;
text-align: center;
}
.pika-label {
display: inline-block;
*display: inline;
position: relative;
z-index: 9999;
overflow: hidden;
margin: 0;
padding: 5px 3px;
font-size: 14px;
line-height: 20px;
font-weight: bold;
background-color: #fff;
}
.pika-title select {
cursor: pointer;
position: absolute;
z-index: 9998;
margin: 0;
left: 0;
top: 5px;
filter: alpha(opacity=0);
opacity: 0;
}
.pika-prev,
.pika-next {
display: block;
cursor: pointer;
position: relative;
outline: none;
border: 0;
padding: 0;
width: 20px;
height: 30px;
/* hide text using text-indent trick, using width value (it's enough) */
text-indent: 20px;
white-space: nowrap;
overflow: hidden;
background-color: transparent;
background-position: center center;
background-repeat: no-repeat;
background-size: 75% 75%;
opacity: .5;
*position: absolute;
*top: 0;
}
.pika-prev:hover,
.pika-next:hover {
opacity: 1;
}
.pika-prev,
.is-rtl .pika-next {
float: left;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAUklEQVR42u3VMQoAIBADQf8Pgj+OD9hG2CtONJB2ymQkKe0HbwAP0xucDiQWARITIDEBEnMgMQ8S8+AqBIl6kKgHiXqQqAeJepBo/z38J/U0uAHlaBkBl9I4GwAAAABJRU5ErkJggg==');
*left: 0;
}
.pika-next,
.is-rtl .pika-prev {
float: right;
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAeCAYAAAAsEj5rAAAAU0lEQVR42u3VOwoAMAgE0dwfAnNjU26bYkBCFGwfiL9VVWoO+BJ4Gf3gtsEKKoFBNTCoCAYVwaAiGNQGMUHMkjGbgjk2mIONuXo0nC8XnCf1JXgArVIZAQh5TKYAAAAASUVORK5CYII=');
*right: 0;
}
.pika-prev.is-disabled,
.pika-next.is-disabled {
cursor: default;
opacity: .2;
}
.pika-select {
display: inline-block;
*display: inline;
}
.pika-table {
width: 100%;
border-collapse: collapse;
border-spacing: 0;
border: 0;
}
.pika-table th,
.pika-table td {
width: 14.285714285714286%;
padding: 0;
}
.pika-table th {
color: #999;
font-size: 12px;
line-height: 25px;
font-weight: bold;
text-align: center;
}
.pika-button {
cursor: pointer;
display: block;
box-sizing: border-box;
-moz-box-sizing: border-box;
outline: none;
border: 0;
margin: 0;
width: 100%;
padding: 5px;
color: #666;
font-size: 12px;
line-height: 15px;
text-align: right;
background: #f5f5f5;
}
.pika-week {
font-size: 11px;
color: #999;
}
.is-today .pika-button {
color: #33aaff;
font-weight: bold;
}
.is-selected .pika-button,
.has-event .pika-button {
color: #fff;
font-weight: bold;
background: #33aaff;
box-shadow: inset 0 1px 3px #178fe5;
border-radius: 3px;
}
.has-event .pika-button {
background: #005da9;
box-shadow: inset 0 1px 3px #0076c9;
}
.is-disabled .pika-button,
.is-inrange .pika-button {
background: #D5E9F7;
}
.is-startrange .pika-button {
color: #fff;
background: #6CB31D;
box-shadow: none;
border-radius: 3px;
}
.is-endrange .pika-button {
color: #fff;
background: #33aaff;
box-shadow: none;
border-radius: 3px;
}
.is-disabled .pika-button {
pointer-events: none;
cursor: default;
color: #999;
opacity: .3;
}
.is-outside-current-month .pika-button {
color: #999;
opacity: .3;
}
.is-selection-disabled {
pointer-events: none;
cursor: default;
}
.pika-button:hover,
.pika-row.pick-whole-week:hover .pika-button {
color: #fff;
background: #ff8000;
box-shadow: none;
border-radius: 3px;
}
/* styling for abbr */
.pika-table abbr {
border-bottom: none;
cursor: help;
}
/*! X-editable - v1.5.1 /*! X-editable - v1.5.1
* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery * In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
* http://github.com/vitalets/x-editable * http://github.com/vitalets/x-editable

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,16 +1,16 @@
{ {
"/assets/frontend/js/app.js": "/assets/frontend/js/app.js?id=3d5b0dff38050f6b5e0b", "/assets/frontend/js/app.js": "/assets/frontend/js/app.js?id=cd886ba18357a1c96ec0",
"/assets/frontend/css/now-ui-kit.css": "/assets/frontend/css/now-ui-kit.css?id=b0a0f05b94a4486db4f2", "/assets/frontend/css/now-ui-kit.css": "/assets/frontend/css/now-ui-kit.css?id=b0a0f05b94a4486db4f2",
"/assets/admin/css/vendor.min.css": "/assets/admin/css/vendor.min.css?id=cc80aec3cf1646f83d8d", "/assets/admin/css/vendor.min.css": "/assets/admin/css/vendor.min.css?id=cc80aec3cf1646f83d8d",
"/assets/admin/js/app.js": "/assets/admin/js/app.js?id=926a7c24ec36533523e3", "/assets/admin/js/app.js": "/assets/admin/js/app.js?id=559d5e8e5d6ecc64a3af",
"/assets/installer/js/app.js": "/assets/installer/js/app.js?id=c65781eda730445d666e", "/assets/installer/js/app.js": "/assets/installer/js/app.js?id=c65781eda730445d666e",
"/assets/fonts/glyphicons-halflings-regular.woff2": "/assets/fonts/glyphicons-halflings-regular.woff2?id=b5b5055c6d812c0f9f0d", "/assets/fonts/glyphicons-halflings-regular.woff2": "/assets/fonts/glyphicons-halflings-regular.woff2?id=b5b5055c6d812c0f9f0d",
"/assets/admin/fonts/glyphicons-halflings-regular.woff2": "/assets/admin/fonts/glyphicons-halflings-regular.woff2?id=b5b5055c6d812c0f9f0d", "/assets/admin/fonts/glyphicons-halflings-regular.woff2": "/assets/admin/fonts/glyphicons-halflings-regular.woff2?id=b5b5055c6d812c0f9f0d",
"/assets/admin/img/clear.png": "/assets/admin/img/clear.png?id=0e92f4c3efc6988a3c96", "/assets/admin/img/clear.png": "/assets/admin/img/clear.png?id=0e92f4c3efc6988a3c96",
"/assets/admin/img/loading.gif": "/assets/admin/img/loading.gif?id=90a4b76b4f11558691f6", "/assets/admin/img/loading.gif": "/assets/admin/img/loading.gif?id=90a4b76b4f11558691f6",
"/assets/global/js/jquery.js": "/assets/global/js/jquery.js?id=6a07da9fae934baf3f74", "/assets/global/js/jquery.js": "/assets/global/js/jquery.js?id=6a07da9fae934baf3f74",
"/assets/admin/css/vendor.css": "/assets/admin/css/vendor.css?id=99aedbd62dfa118e7b73", "/assets/admin/css/vendor.css": "/assets/admin/css/vendor.css?id=d4c03403265f42272050",
"/assets/admin/js/vendor.js": "/assets/admin/js/vendor.js?id=5130233c88c71fc60135", "/assets/admin/js/vendor.js": "/assets/admin/js/vendor.js?id=aa7db4bedfe23409f625",
"/assets/admin/css/blue.png": "/assets/admin/css/blue.png?id=753a3c0dec86d3a38d9c", "/assets/admin/css/blue.png": "/assets/admin/css/blue.png?id=753a3c0dec86d3a38d9c",
"/assets/admin/css/blue@2x.png": "/assets/admin/css/blue@2x.png?id=97da23d47b838cbd4bef", "/assets/admin/css/blue@2x.png": "/assets/admin/css/blue@2x.png?id=97da23d47b838cbd4bef",
"/assets/global/js/vendor.js": "/assets/global/js/vendor.js?id=6436d215691e8f38eb12", "/assets/global/js/vendor.js": "/assets/global/js/vendor.js?id=6436d215691e8f38eb12",

View File

@ -1,14 +1,9 @@
const leaflet = require('leaflet'); const leaflet = require('leaflet');
import draw_base_map from './base_map' import draw_base_map from './base_map'
import { addWMSLayer } from './helpers'; import {addWMSLayer} from './helpers';
import { import {ACTUAL_ROUTE_COLOR, CIRCLE_COLOR, PLAN_ROUTE_COLOR} from './config'
ACTUAL_ROUTE_COLOR,
PLAN_ROUTE_COLOR,
CIRCLE_COLOR
} from './config'
/** /**
* Show some popup text when a feature is clicked on * Show some popup text when a feature is clicked on
@ -16,12 +11,12 @@ import {
* @param layer * @param layer
*/ */
export const onFeaturePointClick = (feature, layer) => { export const onFeaturePointClick = (feature, layer) => {
let popup_html = ''; let popup_html = '';
if (feature.properties && feature.properties.popup) { if (feature.properties && feature.properties.popup) {
popup_html += feature.properties.popup popup_html += feature.properties.popup
} }
layer.bindPopup(popup_html) layer.bindPopup(popup_html)
}; };
/** /**
@ -31,14 +26,14 @@ export const onFeaturePointClick = (feature, layer) => {
* @returns {*} * @returns {*}
*/ */
export const pointToLayer = (feature, latlng) => { export const pointToLayer = (feature, latlng) => {
return leaflet.circleMarker(latlng, { return leaflet.circleMarker(latlng, {
radius: 5, radius: 5,
fillColor: CIRCLE_COLOR, fillColor: CIRCLE_COLOR,
color: '#000', color: '#000',
weight: 1, weight: 1,
opacity: 1, opacity: 1,
fillOpacity: 0.8 fillOpacity: 0.8
}) })
} }
/** /**
@ -48,90 +43,125 @@ export const pointToLayer = (feature, latlng) => {
*/ */
export default (opts) => { export default (opts) => {
opts = Object.assign({ opts = Object.assign({
route_points: null,
planned_route_line: null,
actual_route_points: null,
actual_route_line: null,
render_elem: 'map',
metar_wms: {
url: '',
params: {}
},
}, opts);
console.log(opts); route_points: null,
planned_route_line: null,
actual_route_points: null,
actual_route_line: null,
render_elem: 'map',
live_map: false,
aircraft_icon: '/assets/img/acars/aircraft.png',
metar_wms: {
url: '',
params: {}
},
}, opts);
let map = draw_base_map(opts); const aircraftIcon = leaflet.icon({
iconUrl: opts.aircraft_icon,
if (opts.metar_wms.url !== '') { iconSize: [42, 42],
addWMSLayer(map, opts.metar_wms); iconAnchor: [21, 21],
}
let geodesicLayer = leaflet.geodesic([], {
weight: 4,
opacity: 0.9,
color: PLAN_ROUTE_COLOR,
steps: 50,
wrap: false,
}).addTo(map);
geodesicLayer.geoJson(opts.planned_route_line);
try {
map.fitBounds(geodesicLayer.getBounds())
} catch (e) {
console.log(e)
}
// Draw the route points after
if (opts.route_points !== null) {
let route_points = leaflet.geoJSON(opts.route_points, {
onEachFeature: onFeaturePointClick,
pointToLayer: pointToLayer,
style: {
'color': PLAN_ROUTE_COLOR,
'weight': 3,
'opacity': 0.65,
},
}); });
route_points.addTo(map); let map = draw_base_map(opts);
} let layerLiveFlight;
/** if (opts.metar_wms.url !== '') {
* draw the actual route addWMSLayer(map, opts.metar_wms);
*/ }
if (opts.actual_route_line !== null && opts.actual_route_line.features.length > 0) {
let geodesicLayer = leaflet.geodesic([], { let geodesicLayer = leaflet.geodesic([], {
weight: 3, weight: 4,
opacity: 0.9, opacity: 0.9,
color: ACTUAL_ROUTE_COLOR, color: PLAN_ROUTE_COLOR,
steps: 50, steps: 50,
wrap: false, wrap: false,
}).addTo(map); }).addTo(map);
geodesicLayer.geoJson(opts.actual_route_line); geodesicLayer.geoJson(opts.planned_route_line);
try { try {
map.fitBounds(geodesicLayer.getBounds()) map.fitBounds(geodesicLayer.getBounds())
} catch (e) { } catch (e) {
console.log(e) console.log(e)
} }
}
if (opts.actual_route_points !== null && opts.actual_route_points.features.length > 0) { // Draw the route points after
let route_points = leaflet.geoJSON(opts.actual_route_points, { if (opts.route_points !== null) {
onEachFeature: onFeaturePointClick, let route_points = leaflet.geoJSON(opts.route_points, {
pointToLayer: pointToLayer, onEachFeature: onFeaturePointClick,
style: { pointToLayer: pointToLayer,
'color': ACTUAL_ROUTE_COLOR, style: {
'weight': 3, 'color': PLAN_ROUTE_COLOR,
'opacity': 0.65, 'weight': 3,
}, 'opacity': 0.65,
}); },
});
route_points.addTo(map) route_points.addTo(map);
} }
/**
* draw the actual route
*/
if (opts.actual_route_line !== null && opts.actual_route_line.features.length > 0) {
let geodesicLayer = leaflet.geodesic([], {
weight: 3,
opacity: 0.9,
color: ACTUAL_ROUTE_COLOR,
steps: 50,
wrap: false,
}).addTo(map);
geodesicLayer.geoJson(opts.actual_route_line);
try {
map.fitBounds(geodesicLayer.getBounds())
} catch (e) {
console.log(e)
}
}
if (opts.actual_route_points !== null && opts.actual_route_points.features.length > 0) {
let route_points = leaflet.geoJSON(opts.actual_route_points, {
onEachFeature: onFeaturePointClick,
pointToLayer: pointToLayer,
style: {
'color': ACTUAL_ROUTE_COLOR,
'weight': 3,
'opacity': 0.65,
},
});
route_points.addTo(map)
}
/**
*
*/
const liveFlight = () => {
const uri = opts.pirep_uri;
const live_route = $.ajax({
url: uri,
dataType: 'json',
error: console.log
});
$.when(live_route).done((routeJson) => {
layerLiveFlight = leaflet.geoJSON(routeJson, {
pointToLayer: function (feature, latlon) {
return leaflet.marker(latlon, {
icon: aircraftIcon,
rotationAngle: feature.properties.heading
})
}
});
layerLiveFlight.addTo(map)
});
};
setInterval(liveFlight, 10000);
}; };

View File

@ -9,10 +9,12 @@
@section('scripts') @section('scripts')
<script type="text/javascript"> <script type="text/javascript">
phpvms.map.render_route_map({ phpvms.map.render_route_map({
pirep_uri: '{!! url('/api/pireps/'.$pirep->id.'/acars/geojson') !!}',
route_points: {!! json_encode($map_features['planned_rte_points']) !!}, route_points: {!! json_encode($map_features['planned_rte_points']) !!},
planned_route_line: {!! json_encode($map_features['planned_rte_line']) !!}, planned_route_line: {!! json_encode($map_features['planned_rte_line']) !!},
actual_route_line: {!! json_encode($map_features['actual_route_line']) !!}, actual_route_line: {!! json_encode($map_features['actual_route_line']) !!},
actual_route_points: {!! json_encode($map_features['actual_route_points']) !!}, actual_route_points: {!! json_encode($map_features['actual_route_points']) !!},
aircraft_icon: '{!! public_asset('/assets/img/acars/aircraft.png') !!}',
}); });
</script> </script>
@endsection @endsection

View File

@ -9,7 +9,13 @@
<div class="col-12"> <div class="col-12">
<p> <p>
<h2 style="margin-bottom: 5px;">{{$pirep->airline->code}}{{ $pirep->ident }}</h2> <h2 style="margin-bottom: 5px;">{{$pirep->airline->code}}{{ $pirep->ident }}</h2>
<p>Arrived {{$pirep->created_at->diffForHumans()}}</p> <p>
@if($pirep->state === PirepState::IN_PROGRESS)
@else
Arrived {{$pirep->created_at->diffForHumans()}}
@endif
</p>
</p> </p>
</div> </div>
@ -55,8 +61,10 @@
<div class="progress" style="margin: 20px 0;"> <div class="progress" style="margin: 20px 0;">
<div class="progress-bar progress-bar-success" role="progressbar" <div class="progress-bar progress-bar-success" role="progressbar"
aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100"
style="width: {{$pirep->progress_percent}}%"> style="width: {{$pirep->progress_percent}}%;">
{{ Utils::minutesToTimeString($pirep->flight_time) }} {{--<p style="padding: 10px">
{{ Utils::minutesToTimeString($pirep->flight_time) }}
</p>--}}
</div> </div>
</div> </div>
</div> </div>
@ -78,8 +86,8 @@
<div class="col-4"> <div class="col-4">
<h2>&nbsp;</h2> <h2>&nbsp;</h2>
<table class="table table-hover table-condensed"> <table class="table table-striped">
<tr> {{--<tr>
<td width="30%">Status</td> <td width="30%">Status</td>
<td> <td>
@php @php
@ -96,6 +104,15 @@
{{ PirepState::label($pirep->state) }} {{ PirepState::label($pirep->state) }}
</div> </div>
</td> </td>
</tr>--}}
<tr>
<td width="30%">State</td>
<td>
<div class="badge badge-info">
{{ PirepStatus::label($pirep->status) }}
</div>
</td>
</tr> </tr>
<tr> <tr>

View File

@ -16,9 +16,10 @@
<table class="table"> <table class="table">
@foreach($pireps as $pirep) @foreach($pireps as $pirep)
<tr> <tr>
<td>{{ $pirep->ident }}</td> <td>{{ $pirep->airline->code }}{{ $pirep->ident }}</td>
<td>{{ $pirep->dpt_airport_id }}</td> <td>{{ $pirep->dpt_airport_id }}</td>
<td>{{ $pirep->arr_airport_id }}</td> <td>{{ $pirep->arr_airport_id }}</td>
<td>{{ $pirep->aircraft->name }}</td>
<td> <td>
{{ PirepStatus::label($pirep->status) }} {{ PirepStatus::label($pirep->status) }}
</td> </td>

View File

@ -9,8 +9,8 @@ class UtilsTest extends TestCase
public function testDates() public function testDates()
{ {
$carbon = new \Carbon\Carbon('2018-03-18 00:20:43'); $carbon = new \Carbon\Carbon('2018-04-28T12:55:40Z');
//echo $carbon; $this->assertNotNull($carbon);
} }
public function testSecondsToTimeParts() public function testSecondsToTimeParts()