├── .gitignore ├── README.md ├── composer.json ├── config └── nova-google-maps.php ├── dist ├── css │ └── field.css ├── js │ └── field.js └── mix-manifest.json ├── nova-google-maps-preview.png ├── package.json ├── resources ├── js │ ├── components │ │ ├── DetailField.vue │ │ ├── FormField.vue │ │ └── IndexField.vue │ ├── field.js │ └── hasMap.js └── sass │ └── field.scss ├── src ├── FieldServiceProvider.php └── GoogleMaps.php ├── webpack.mix.js └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /vendor 3 | /node_modules 4 | package-lock.json 5 | composer.phar 6 | composer.lock 7 | phpunit.xml 8 | .phpunit.result.cache 9 | .DS_Store 10 | Thumbs.db 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel Nova Google Maps Field 2 | 3 | A laravel nova field to easily enter an address (uses the Algolia Places API) and show a preview in a Google Map. The result is stored in a json column and contains all the data sent by Algolia. 4 | 5 | ![Preview of the nova-google-maps field](https://github.com/whitecube/nova-google-maps/raw/master/nova-google-maps-preview.png) 6 | 7 | ## Installation 8 | 9 | You can install the package via composer: 10 | 11 | ```bash 12 | composer require whitecube/nova-google-maps 13 | ``` 14 | 15 | ## Usage 16 | 17 | ``` php 18 | use Whitecube\NovaGoogleMaps\GoogleMaps; 19 | 20 | /** 21 | * Get the fields displayed by the resource. 22 | * 23 | * @param \Illuminate\Http\Request $request 24 | * @return array 25 | */ 26 | public function fields(Request $request) 27 | { 28 | return [ 29 | // ... 30 | 31 | GoogleMaps::make('Map') 32 | ->zoom(8) // Optionally set the zoom level 33 | ->defaultCoordinates($lat, $lng) // Optionally set the map's default center point 34 | ]; 35 | } 36 | ``` 37 | 38 | ## Storage 39 | The field stores the JSON data sent back by Algolia (minus a few unneeded sub-objects). This gives you a lot of information on the selected place/address. Here is an example: 40 | 41 | ```json 42 | { 43 | "name": "Bruxelles", 44 | "type": "city", 45 | "query": "Bruxelles", 46 | "value": "Bruxelles, Région de Bruxelles-Capitale - Brussels Hoofdstedelijk Gewest, Belgique", 47 | "county": "Bruxelles-Capitale", 48 | "latlng": {"lat": 50.8466, "lng": 4.3517}, 49 | "country": "Belgique", 50 | "postcode": "1000", 51 | "countryCode": "be", 52 | "administrative": "Région de Bruxelles-Capitale - Brussels Hoofdstedelijk Gewest" 53 | } 54 | ``` 55 | 56 | ## Configuration 57 | By default, you should reference your Google Maps API key in your `.env` file: 58 | 59 | ``` 60 | NOVA_GOOGLE_MAPS_API_KEY=your-api-key 61 | ``` 62 | 63 | Optionally, you can publish the config to change the API key location and the map's language by doing: `php artisan vendor:publish --tag=nova-google-maps`. 64 | 65 | ## 💖 Sponsorships 66 | 67 | If you are reliant on this package in your production applications, consider [sponsoring us](https://github.com/sponsors/whitecube)! It is the best way to help us keep doing what we love to do: making great open source software. 68 | 69 | ## Contributing 70 | 71 | Feel free to suggest changes, ask for new features or fix bugs yourself. We're sure there are still a lot of improvements that could be made, and we would be very happy to merge useful pull requests. 72 | 73 | Thanks! 74 | 75 | ## Made with ❤️ for open source 76 | 77 | At [Whitecube](https://www.whitecube.be) we use a lot of open source software as part of our daily work. 78 | So when we have an opportunity to give something back, we're super excited! 79 | 80 | We hope you will enjoy this small contribution from us and would love to [hear from you](mailto:hello@whitecube.be) if you find it useful in your projects. Follow us on [Twitter](https://twitter.com/whitecube_be) for more updates! 81 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "whitecube/nova-google-maps", 3 | "description": "A Laravel Nova field.", 4 | "keywords": [ 5 | "laravel", 6 | "nova" 7 | ], 8 | "license": "MIT", 9 | "require": { 10 | "php": ">=7.1.0" 11 | }, 12 | "autoload": { 13 | "psr-4": { 14 | "Whitecube\\NovaGoogleMaps\\": "src/" 15 | } 16 | }, 17 | "extra": { 18 | "laravel": { 19 | "providers": [ 20 | "Whitecube\\NovaGoogleMaps\\FieldServiceProvider" 21 | ] 22 | } 23 | }, 24 | "config": { 25 | "sort-packages": true 26 | }, 27 | "minimum-stability": "dev", 28 | "prefer-stable": true 29 | } 30 | -------------------------------------------------------------------------------- /config/nova-google-maps.php: -------------------------------------------------------------------------------- 1 | env('NOVA_GOOGLE_MAPS_API_KEY'), 5 | 'language' => 'en', 6 | ]; 7 | -------------------------------------------------------------------------------- /dist/css/field.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whitecube/nova-google-maps/1761cb462b528d0c94bc15c9ef5747ce8ae2d114/dist/css/field.css -------------------------------------------------------------------------------- /dist/mix-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "/js/field.js": "/js/field.js", 3 | "/css/field.css": "/css/field.css" 4 | } -------------------------------------------------------------------------------- /nova-google-maps-preview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whitecube/nova-google-maps/1761cb462b528d0c94bc15c9ef5747ce8ae2d114/nova-google-maps-preview.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "dev": "npm run development", 5 | "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 6 | "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", 7 | "watch-poll": "npm run watch -- --watch-poll", 8 | "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", 9 | "prod": "npm run production", 10 | "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" 11 | }, 12 | "devDependencies": { 13 | "cross-env": "^5.0.0", 14 | "laravel-mix": "^1.0", 15 | "laravel-nova": "^1.0" 16 | }, 17 | "dependencies": { 18 | "places.js": "^1.18.2", 19 | "vue": "^2.5.0" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /resources/js/components/DetailField.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 32 | 33 | 38 | -------------------------------------------------------------------------------- /resources/js/components/FormField.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 123 | 124 | 129 | -------------------------------------------------------------------------------- /resources/js/components/IndexField.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 20 | -------------------------------------------------------------------------------- /resources/js/field.js: -------------------------------------------------------------------------------- 1 | Nova.booting((Vue, router, store) => { 2 | Vue.component('index-nova-google-maps', require('./components/IndexField')) 3 | Vue.component('detail-nova-google-maps', require('./components/DetailField')) 4 | Vue.component('form-nova-google-maps', require('./components/FormField')) 5 | }) 6 | -------------------------------------------------------------------------------- /resources/js/hasMap.js: -------------------------------------------------------------------------------- 1 | export default { 2 | 3 | data() { 4 | return { 5 | location: null, 6 | marker: null, 7 | map: null 8 | } 9 | }, 10 | 11 | methods: { 12 | /** 13 | * Init the gmap 14 | */ 15 | initGmaps() { 16 | this.map = new google.maps.Map(this.$refs.map, { 17 | center: this.field.defaultCoordinates || {lat: -34.397, lng: 150.644}, 18 | zoom: this.field.zoom || 8 19 | }); 20 | }, 21 | 22 | /** 23 | * Set an active location 24 | */ 25 | setLocation(location) { 26 | this.clearMarker(); 27 | this.map.panTo(this.location.latlng); 28 | this.marker = new google.maps.Marker({ 29 | position: this.location.latlng, 30 | map: this.map 31 | }); 32 | }, 33 | 34 | /** 35 | * Clear the gmap's marker 36 | */ 37 | clearMarker() { 38 | if(!this.marker) return; 39 | 40 | this.marker.setMap(null); 41 | this.marker = null; 42 | }, 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /resources/sass/field.scss: -------------------------------------------------------------------------------- 1 | // Nova Tool CSS 2 | -------------------------------------------------------------------------------- /src/FieldServiceProvider.php: -------------------------------------------------------------------------------- 1 | gmapsScript()); 20 | Nova::script('nova-google-maps', __DIR__.'/../dist/js/field.js'); 21 | Nova::style('nova-google-maps', __DIR__.'/../dist/css/field.css'); 22 | }); 23 | 24 | $this->publishes([ 25 | __DIR__ . '/../config/nova-google-maps.php' => config_path('nova-google-maps.php'), 26 | ], 'nova-google-maps'); 27 | } 28 | 29 | /** 30 | * Register any application services. 31 | * 32 | * @return void 33 | */ 34 | public function register() 35 | { 36 | $this->mergeConfigFrom(__DIR__.'/../config/nova-google-maps.php', 'nova-google-maps'); 37 | } 38 | 39 | protected function gmapsScript() 40 | { 41 | return vsprintf( 42 | 'https://maps.googleapis.com/maps/api/js?key=%s&language=%s', 43 | [ 44 | config('nova-google-maps.api_key'), 45 | config('nova-google-maps.language'), 46 | ] 47 | ); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/GoogleMaps.php: -------------------------------------------------------------------------------- 1 | withMeta(['defaultCoordinates' => [ 26 | 'lat' => $lat, 27 | 'lng' => $lng 28 | ]]); 29 | } 30 | 31 | /** 32 | * Set the map's zoom level 33 | * 34 | * @param int $level 35 | * @return $this 36 | */ 37 | public function zoom($level = 15) 38 | { 39 | return $this->withMeta(['zoom' => $level]); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /webpack.mix.js: -------------------------------------------------------------------------------- 1 | let mix = require('laravel-mix') 2 | 3 | mix 4 | .setPublicPath('dist') 5 | .js('resources/js/field.js', 'js') 6 | .sass('resources/sass/field.scss', 'css') 7 | --------------------------------------------------------------------------------