11 changed files with 202 additions and 0 deletions
-
35app/Http/Controllers/Api/OutletController.php
-
13app/Http/Controllers/OutletMapController.php
-
19app/Http/Resources/Outlet.php
-
19app/Http/Resources/OutletCollection.php
-
4app/Outlet.php
-
5resources/lang/en/menu.php
-
1resources/views/layouts/app.blade.php
-
57resources/views/outlets/map.blade.php
-
7routes/api.php
-
1routes/web.php
-
41tests/Feature/Api/OutletListingTest.php
@ -0,0 +1,35 @@ |
|||
<?php |
|||
|
|||
namespace App\Http\Controllers\Api; |
|||
|
|||
use App\Outlet; |
|||
use Illuminate\Http\Request; |
|||
use App\Http\Controllers\Controller; |
|||
use App\Http\Resources\Outlet as OutletResource; |
|||
|
|||
class OutletController extends Controller |
|||
{ |
|||
public function index(Request $request) |
|||
{ |
|||
$outlets = Outlet::all(); |
|||
|
|||
$geoJSONdata = $outlets->map(function ($outlet) { |
|||
return [ |
|||
'type' => 'Feature', |
|||
'properties' => new OutletResource($outlet), |
|||
'geometry' => [ |
|||
'type' => 'Point', |
|||
'coordinates' => [ |
|||
$outlet->longitude, |
|||
$outlet->latitude, |
|||
], |
|||
], |
|||
]; |
|||
}); |
|||
|
|||
return response()->json([ |
|||
'type' => 'FeatureCollection', |
|||
'features' => $geoJSONdata, |
|||
]); |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
<?php |
|||
|
|||
namespace App\Http\Controllers; |
|||
|
|||
use Illuminate\Http\Request; |
|||
|
|||
class OutletMapController extends Controller |
|||
{ |
|||
public function index(Request $request) |
|||
{ |
|||
return view('outlets.map'); |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
<?php |
|||
|
|||
namespace App\Http\Resources; |
|||
|
|||
use Illuminate\Http\Resources\Json\JsonResource; |
|||
|
|||
class Outlet extends JsonResource |
|||
{ |
|||
/** |
|||
* Transform the resource into an array. |
|||
* |
|||
* @param \Illuminate\Http\Request $request |
|||
* @return array |
|||
*/ |
|||
public function toArray($request) |
|||
{ |
|||
return parent::toArray($request); |
|||
} |
|||
} |
|||
@ -0,0 +1,19 @@ |
|||
<?php |
|||
|
|||
namespace App\Http\Resources; |
|||
|
|||
use Illuminate\Http\Resources\Json\ResourceCollection; |
|||
|
|||
class OutletCollection extends ResourceCollection |
|||
{ |
|||
/** |
|||
* Transform the resource collection into an array. |
|||
* |
|||
* @param \Illuminate\Http\Request $request |
|||
* @return array |
|||
*/ |
|||
public function toArray($request) |
|||
{ |
|||
return parent::toArray($request); |
|||
} |
|||
} |
|||
@ -0,0 +1,5 @@ |
|||
<?php |
|||
|
|||
return [ |
|||
'our_outlets' => 'Our Outlets', |
|||
]; |
|||
@ -0,0 +1,57 @@ |
|||
@extends('layouts.app') |
|||
|
|||
@section('content') |
|||
<div class="card"> |
|||
<div class="card-body" id="mapid"></div> |
|||
</div> |
|||
@endsection |
|||
|
|||
@section('styles') |
|||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" |
|||
integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" |
|||
crossorigin=""/> |
|||
|
|||
<style> |
|||
#mapid { min-height: 500px; }
|
|||
</style> |
|||
@endsection |
|||
@push('scripts') |
|||
<!-- Make sure you put this AFTER Leaflet's CSS --> |
|||
<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet.js" |
|||
integrity="sha512-/Nsx9X4HebavoBvEBuyp3I7od5tA0UzAxs+j83KgC8PU0kgB4XiK4Lfe4y4cgBtaRJQEIFCW+oC506aPT2L1zw==" |
|||
crossorigin=""></script> |
|||
|
|||
<script> |
|||
var map = L.map('mapid').setView(['-3.313695', '114.590148'], 13); |
|||
var baseUrl = "{{ url('/') }}"; |
|||
|
|||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { |
|||
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' |
|||
}).addTo(map); |
|||
|
|||
axios.get('{{ route('api.outlets.index') }}') |
|||
.then(function (response) { |
|||
console.log(response.data); |
|||
L.geoJSON(response.data, { |
|||
pointToLayer: function(geoJsonPoint, latlng) { |
|||
var myIcon = L.icon({ |
|||
iconUrl: baseUrl + '/images/marker-icon-green.png', |
|||
shadowUrl: baseUrl + '/images/marker-shadow.png', |
|||
iconSize: [25, 41], |
|||
iconAnchor: [12, 41], |
|||
popupAnchor: [1, -34], |
|||
shadowSize: [41, 41], |
|||
className: 'marker-icon-green', |
|||
}); |
|||
return L.marker(latlng, { icon: myIcon }); |
|||
} |
|||
}) |
|||
.bindPopup(function (layer) { |
|||
return layer.feature.properties.map_popup_content; |
|||
}).addTo(map); |
|||
}) |
|||
.catch(function (error) { |
|||
console.log(error); |
|||
}); |
|||
</script> |
|||
@endpush |
|||
@ -0,0 +1,41 @@ |
|||
<?php |
|||
|
|||
namespace Tests\Feature\Api; |
|||
|
|||
use App\Outlet; |
|||
use Tests\BrowserKitTest as TestCase; |
|||
use Illuminate\Foundation\Testing\RefreshDatabase; |
|||
|
|||
class OutletListingTest extends TestCase |
|||
{ |
|||
use RefreshDatabase; |
|||
|
|||
/** @test */ |
|||
public function guest_can_retrieve_outlet_list() |
|||
{ |
|||
$outlet = factory(Outlet::class)->create(); |
|||
|
|||
$this->getJson(route('api.outlets.index')); |
|||
|
|||
$this->seeJsonSubset([ |
|||
'type' => 'FeatureCollection', |
|||
'features' => [ |
|||
[ |
|||
'type' => 'Feature', |
|||
'properties' => [ |
|||
'name' => $outlet->name, |
|||
'address' => $outlet->address, |
|||
'coordinate' => $outlet->coordinate, |
|||
], |
|||
'geometry' => [ |
|||
'type' => 'Point', |
|||
'coordinates' => [ |
|||
$outlet->longitude, |
|||
$outlet->latitude, |
|||
], |
|||
], |
|||
], |
|||
], |
|||
]); |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue