Vue JS Scaffolding (#2493)

* client ui

* Paddin out client detail view

* Padding out clients

* Padding out clients

* show maps

* Padding out clients

* fixes for migrations

* client padding

* Working on different Client UX

* more client ux

* New Client UI

* Vue Scaffolding
This commit is contained in:
David Bomba 2018-11-07 16:22:36 +11:00 committed by GitHub
parent db8f962d9b
commit 1ad857bac9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 42808 additions and 103 deletions

View File

@ -31,4 +31,6 @@ MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MULTI_DB_ENABLED=true
POSTMARK_API_TOKEN=
POSTMARK_API_TOKEN=
GOOGLE_MAPS_API_KEY

View File

@ -120,7 +120,15 @@ class ClientController extends Controller
{
$client = $request->entity(Client::class, request('client'));
dd($client);
$client->load('contacts', 'primary_billing_location', 'primary_shipping_location', 'locations', 'primary_contact');
$data = [
'header' => $this->headerData(),
'client' => $client,
];
return view('client.edit', $data);
}
/**

View File

@ -21,9 +21,14 @@ class Client extends BaseModel
return $this->hasMany(ClientLocation::class);
}
public function primary_location()
public function primary_billing_location()
{
return $this->hasMany(ClientLocation::class)->whereIsPrimary(true);
return $this->hasMany(ClientLocation::class)->whereIsPrimaryBilling(true);
}
public function primary_shipping_location()
{
return $this->hasMany(ClientLocation::class)->whereIsPrimaryShipping(true);
}
public function primary_contact()

View File

@ -5,5 +5,8 @@ namespace App\Models\Presenters;
class ClientPresenter extends EntityPresenter
{
public function name()
{
return $this->entity->name ?: $this->entity->primary_contact->first()->first_name . ' '. $this->entity->primary_contact->first()->last_name;
}
}

View File

@ -27,6 +27,7 @@
"laravel/framework": "5.7.*",
"laravel/socialite": "^3.1",
"laravel/tinker": "^1.0",
"mariuzzo/laravel-js-localization": "^1.4",
"nwidart/laravel-modules": "^4.0",
"predis/predis": "^1.1",
"spatie/laravel-html": "^2.19",

237
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "753b0ff8fa34e1e5a54d950d3d780d30",
"content-hash": "b872ce32e507245bb3568a6a1bd18c51",
"packages": [
{
"name": "asgrim/ofxparser",
@ -1473,6 +1473,89 @@
],
"time": "2018-11-01T10:33:16+00:00"
},
{
"name": "mariuzzo/laravel-js-localization",
"version": "v1.4.7",
"source": {
"type": "git",
"url": "https://github.com/rmariuzzo/Laravel-JS-Localization.git",
"reference": "e36ea8dadfa680d862262af2ea4abbe5697bc03e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/rmariuzzo/Laravel-JS-Localization/zipball/e36ea8dadfa680d862262af2ea4abbe5697bc03e",
"reference": "e36ea8dadfa680d862262af2ea4abbe5697bc03e",
"shasum": ""
},
"require": {
"illuminate/config": ">=4.2",
"illuminate/console": ">=4.2",
"illuminate/filesystem": ">=4.2",
"php": ">=5.4.0",
"tedivm/jshrink": "1.0.*"
},
"require-dev": {
"phpunit/phpunit": "4.8.*"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Mariuzzo\\LaravelJsLocalization\\LaravelJsLocalizationServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Mariuzzo\\LaravelJsLocalization\\": "src/Mariuzzo/LaravelJsLocalization/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Rubens Mariuzzo",
"email": "rubens@mariuzzo.com",
"homepage": "https://github.com/rmariuzzo",
"role": "Developer"
},
{
"name": "German Popoter",
"email": "me@gpopoteur.com",
"homepage": "https://github.com/gpopoteur",
"role": "Developer"
},
{
"name": "Galievskiy Dmitriy",
"homepage": "https://github.com/xAockd",
"role": "Developer"
},
{
"name": "Ramon Ackermann",
"homepage": "https://github.com/sboo",
"role": "Developer"
},
{
"name": "Pe Ell",
"homepage": "https://github.com/a-komarev",
"role": "Developer"
}
],
"description": "Laravel Localization in JavaScript",
"homepage": "https://github.com/rmariuzzo/laravel-js-localization",
"keywords": [
"JS",
"i18n",
"javascript",
"lang",
"laravel",
"laravel 5",
"localization"
],
"time": "2017-11-23T04:07:56+00:00"
},
{
"name": "markbaker/complex",
"version": "1.4.7",
@ -2544,16 +2627,16 @@
},
{
"name": "symfony/console",
"version": "v4.1.6",
"version": "v4.1.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "dc7122fe5f6113cfaba3b3de575d31112c9aa60b"
"reference": "432122af37d8cd52fba1b294b11976e0d20df595"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/dc7122fe5f6113cfaba3b3de575d31112c9aa60b",
"reference": "dc7122fe5f6113cfaba3b3de575d31112c9aa60b",
"url": "https://api.github.com/repos/symfony/console/zipball/432122af37d8cd52fba1b294b11976e0d20df595",
"reference": "432122af37d8cd52fba1b294b11976e0d20df595",
"shasum": ""
},
"require": {
@ -2608,11 +2691,11 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
"time": "2018-10-03T08:15:46+00:00"
"time": "2018-10-31T09:30:44+00:00"
},
{
"name": "symfony/css-selector",
"version": "v4.1.6",
"version": "v4.1.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
@ -2665,16 +2748,16 @@
},
{
"name": "symfony/debug",
"version": "v4.1.6",
"version": "v4.1.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/debug.git",
"reference": "e3f76ce6198f81994e019bb2b4e533e9de1b9b90"
"reference": "19090917b848a799cbae4800abf740fe4eb71c1d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/debug/zipball/e3f76ce6198f81994e019bb2b4e533e9de1b9b90",
"reference": "e3f76ce6198f81994e019bb2b4e533e9de1b9b90",
"url": "https://api.github.com/repos/symfony/debug/zipball/19090917b848a799cbae4800abf740fe4eb71c1d",
"reference": "19090917b848a799cbae4800abf740fe4eb71c1d",
"shasum": ""
},
"require": {
@ -2717,20 +2800,20 @@
],
"description": "Symfony Debug Component",
"homepage": "https://symfony.com",
"time": "2018-10-02T16:36:10+00:00"
"time": "2018-10-31T09:09:42+00:00"
},
{
"name": "symfony/event-dispatcher",
"version": "v4.1.6",
"version": "v4.1.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
"reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e"
"reference": "552541dad078c85d9414b09c041ede488b456cd5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/bfb30c2ad377615a463ebbc875eba64a99f6aa3e",
"reference": "bfb30c2ad377615a463ebbc875eba64a99f6aa3e",
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/552541dad078c85d9414b09c041ede488b456cd5",
"reference": "552541dad078c85d9414b09c041ede488b456cd5",
"shasum": ""
},
"require": {
@ -2780,11 +2863,11 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
"time": "2018-07-26T09:10:45+00:00"
"time": "2018-10-10T13:52:42+00:00"
},
{
"name": "symfony/finder",
"version": "v4.1.6",
"version": "v4.1.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
@ -2833,16 +2916,16 @@
},
{
"name": "symfony/http-foundation",
"version": "v4.1.6",
"version": "v4.1.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-foundation.git",
"reference": "d528136617ff24f530e70df9605acc1b788b08d4"
"reference": "82d494c1492b0dd24bbc5c2d963fb02eb44491af"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/d528136617ff24f530e70df9605acc1b788b08d4",
"reference": "d528136617ff24f530e70df9605acc1b788b08d4",
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/82d494c1492b0dd24bbc5c2d963fb02eb44491af",
"reference": "82d494c1492b0dd24bbc5c2d963fb02eb44491af",
"shasum": ""
},
"require": {
@ -2883,20 +2966,20 @@
],
"description": "Symfony HttpFoundation Component",
"homepage": "https://symfony.com",
"time": "2018-10-03T08:48:45+00:00"
"time": "2018-10-31T09:09:42+00:00"
},
{
"name": "symfony/http-kernel",
"version": "v4.1.6",
"version": "v4.1.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/http-kernel.git",
"reference": "f5e7c15a5d010be0e16ce798594c5960451d4220"
"reference": "958be64ab13b65172ad646ef5ae20364c2305fae"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/f5e7c15a5d010be0e16ce798594c5960451d4220",
"reference": "f5e7c15a5d010be0e16ce798594c5960451d4220",
"url": "https://api.github.com/repos/symfony/http-kernel/zipball/958be64ab13b65172ad646ef5ae20364c2305fae",
"reference": "958be64ab13b65172ad646ef5ae20364c2305fae",
"shasum": ""
},
"require": {
@ -2970,7 +3053,7 @@
],
"description": "Symfony HttpKernel Component",
"homepage": "https://symfony.com",
"time": "2018-10-03T12:53:38+00:00"
"time": "2018-11-03T11:11:23+00:00"
},
{
"name": "symfony/polyfill-ctype",
@ -3146,16 +3229,16 @@
},
{
"name": "symfony/process",
"version": "v4.1.6",
"version": "v4.1.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
"reference": "ee33c0322a8fee0855afcc11fff81e6b1011b529"
"reference": "3e83acef94d979b1de946599ef86b3a352abcdc9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/process/zipball/ee33c0322a8fee0855afcc11fff81e6b1011b529",
"reference": "ee33c0322a8fee0855afcc11fff81e6b1011b529",
"url": "https://api.github.com/repos/symfony/process/zipball/3e83acef94d979b1de946599ef86b3a352abcdc9",
"reference": "3e83acef94d979b1de946599ef86b3a352abcdc9",
"shasum": ""
},
"require": {
@ -3191,20 +3274,20 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
"time": "2018-10-02T12:40:59+00:00"
"time": "2018-10-14T20:48:13+00:00"
},
{
"name": "symfony/routing",
"version": "v4.1.6",
"version": "v4.1.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/routing.git",
"reference": "537803f0bdfede36b9acef052d2e4d447d9fa0e9"
"reference": "d4a3c14cfbe6b9c05a1d6e948654022d4d1ad3fd"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/routing/zipball/537803f0bdfede36b9acef052d2e4d447d9fa0e9",
"reference": "537803f0bdfede36b9acef052d2e4d447d9fa0e9",
"url": "https://api.github.com/repos/symfony/routing/zipball/d4a3c14cfbe6b9c05a1d6e948654022d4d1ad3fd",
"reference": "d4a3c14cfbe6b9c05a1d6e948654022d4d1ad3fd",
"shasum": ""
},
"require": {
@ -3268,20 +3351,20 @@
"uri",
"url"
],
"time": "2018-10-02T12:40:59+00:00"
"time": "2018-10-28T18:38:52+00:00"
},
{
"name": "symfony/translation",
"version": "v4.1.6",
"version": "v4.1.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/translation.git",
"reference": "9f0b61e339160a466ebcde167a6c5521c810e304"
"reference": "aa04dc1c75b7d3da7bd7003104cd0cfc5dff635c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/9f0b61e339160a466ebcde167a6c5521c810e304",
"reference": "9f0b61e339160a466ebcde167a6c5521c810e304",
"url": "https://api.github.com/repos/symfony/translation/zipball/aa04dc1c75b7d3da7bd7003104cd0cfc5dff635c",
"reference": "aa04dc1c75b7d3da7bd7003104cd0cfc5dff635c",
"shasum": ""
},
"require": {
@ -3337,11 +3420,11 @@
],
"description": "Symfony Translation Component",
"homepage": "https://symfony.com",
"time": "2018-10-02T16:36:10+00:00"
"time": "2018-10-28T18:38:52+00:00"
},
{
"name": "symfony/var-dumper",
"version": "v4.1.6",
"version": "v4.1.7",
"source": {
"type": "git",
"url": "https://github.com/symfony/var-dumper.git",
@ -3414,6 +3497,52 @@
],
"time": "2018-10-02T16:36:10+00:00"
},
{
"name": "tedivm/jshrink",
"version": "v1.0.1",
"source": {
"type": "git",
"url": "https://github.com/tedious/JShrink.git",
"reference": "7575d9d96f113bc7c1c28ec8231ee086751a9078"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/tedious/JShrink/zipball/7575d9d96f113bc7c1c28ec8231ee086751a9078",
"reference": "7575d9d96f113bc7c1c28ec8231ee086751a9078",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"fabpot/php-cs-fixer": "0.4.0",
"phpunit/phpunit": "4.0.*",
"satooshi/php-coveralls": "dev-master"
},
"type": "library",
"autoload": {
"psr-0": {
"JShrink": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Robert Hafner",
"email": "tedivm@tedivm.com"
}
],
"description": "Javascript Minifier built in PHP",
"homepage": "http://github.com/tedious/JShrink",
"keywords": [
"javascript",
"minifier"
],
"time": "2014-11-11T03:54:14+00:00"
},
{
"name": "tijsverkoyen/css-to-inline-styles",
"version": "2.2.1",
@ -3709,16 +3838,16 @@
},
{
"name": "yajra/laravel-datatables-editor",
"version": "v1.5.0",
"version": "v1.6.1",
"source": {
"type": "git",
"url": "https://github.com/yajra/laravel-datatables-editor.git",
"reference": "14db7b99172fa4afc830e6ee4e8093c3f3bc3a61"
"reference": "da9cf617c202115bdb13357ee091b0ba4a4ac224"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yajra/laravel-datatables-editor/zipball/14db7b99172fa4afc830e6ee4e8093c3f3bc3a61",
"reference": "14db7b99172fa4afc830e6ee4e8093c3f3bc3a61",
"url": "https://api.github.com/repos/yajra/laravel-datatables-editor/zipball/da9cf617c202115bdb13357ee091b0ba4a4ac224",
"reference": "da9cf617c202115bdb13357ee091b0ba4a4ac224",
"shasum": ""
},
"require": {
@ -3767,7 +3896,7 @@
"jquery",
"laravel"
],
"time": "2018-09-05T06:13:38+00:00"
"time": "2018-11-03T03:57:04+00:00"
},
{
"name": "yajra/laravel-datatables-fractal",
@ -3829,16 +3958,16 @@
},
{
"name": "yajra/laravel-datatables-html",
"version": "v3.11.0",
"version": "v3.12.7",
"source": {
"type": "git",
"url": "https://github.com/yajra/laravel-datatables-html.git",
"reference": "78bf4ba15d343696f20c0a40119b7a679e0690d2"
"reference": "50be05aeb281fb5009a27d3aecb6df2633095e68"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yajra/laravel-datatables-html/zipball/78bf4ba15d343696f20c0a40119b7a679e0690d2",
"reference": "78bf4ba15d343696f20c0a40119b7a679e0690d2",
"url": "https://api.github.com/repos/yajra/laravel-datatables-html/zipball/50be05aeb281fb5009a27d3aecb6df2633095e68",
"reference": "50be05aeb281fb5009a27d3aecb6df2633095e68",
"shasum": ""
},
"require": {
@ -3884,7 +4013,7 @@
"jquery",
"laravel"
],
"time": "2018-11-02T12:37:52+00:00"
"time": "2018-11-03T04:21:45+00:00"
},
{
"name": "yajra/laravel-datatables-oracle",

View File

@ -9,6 +9,7 @@ return [
'app_version' => '0.1',
'terms_version' => '1.0.1',
'app_env' => env('APP_ENV', 'development'),
'google_maps_api_key' => env('GOOGLE_MAPS_API_KEY'),
'environment' => env('NINJA_ENVIRONMENT', 'selfhost'), // 'hosted', 'development', 'selfhost', 'reseller'

View File

@ -14,6 +14,7 @@ $factory->define(App\Models\Client::class, function (Faker $faker) {
'custom_value1' => $faker->text(20),
'custom_value2' => $faker->text(20),
'payment_terms' => $faker->text(40),
];
});

View File

@ -14,8 +14,8 @@ class CreatePasswordResetsTable extends Migration
public function up()
{
Schema::create('password_resets', function (Blueprint $table) {
$table->string('email')->index();
$table->string('token');
$table->string('email', 128)->index();
$table->string('token', 255);
$table->timestamp('created_at')->nullable();
});
}

View File

@ -247,7 +247,9 @@ class CreateUsersTable extends Migration
$table->string('phone')->nullable();
$table->decimal('latitude', 11, 8)->nullable();
$table->decimal('longitude', 11, 8)->nullable();
$table->boolean('is_primary')->default(false);
$table->boolean('is_primary_billing')->default(false);
$table->boolean('is_primary_shipping')->default(false);
$table->enum('type', ['billing', 'shipping'])->nullable();
$table->text('description')->nullable();
$table->text('private_notes')->nullable();

View File

@ -79,7 +79,7 @@ class RandomDataSeeder extends Seeder
factory(\App\Models\ClientLocation::class,1)->create([
'client_id' => $c->id,
'is_primary' => 1
'is_primary_billing' => 1
]);
factory(\App\Models\ClientLocation::class,10)->create([

View File

@ -78,7 +78,7 @@ class UsersTableSeeder extends Seeder
factory(\App\Models\ClientLocation::class,1)->create([
'client_id' => $c->id,
'is_primary' => 1
'is_primary_billing' => 1
]);
factory(\App\Models\ClientLocation::class,10)->create([

View File

@ -30,6 +30,7 @@
},
"dependencies": {
"laravel-echo": "^1.4.0",
"quill": "^1.3.6",
"socket.io-client": "^2.1.1"
}
}

16918
public/css/ninja.css vendored

File diff suppressed because one or more lines are too long

25194
public/js/ninja.js vendored

File diff suppressed because one or more lines are too long

11
resources/js/app.js vendored
View File

@ -9,6 +9,7 @@ require('./bootstrap');
window.Vue = require('vue');
Vue.config.devtools = true;
/**
* Next, we will create a fresh Vue application instance and attach it to
@ -18,6 +19,10 @@ window.Vue = require('vue');
Vue.component('example-component', require('./components/ExampleComponent.vue'));
const app = new Vue({
el: '#app'
});
window.onload = function () {
const app = new Vue({
el: '#app'
});
}

View File

@ -3104,6 +3104,7 @@ $LANG = array(
'adjust_fee_percent_help' => 'Adjust percent to account for fee',
'email_already_register' => 'This email is already linked to an account',
'create_account' => 'Create Account',
'locations' => 'Locations',
);
return $LANG;

View File

@ -0,0 +1,64 @@
@extends('layouts.master')
@section('head')
<link rel="stylesheet" href="//cdn.datatables.net/1.10.18/css/dataTables.bootstrap4.min.css">
<script src="//cdn.datatables.net/1.10.18/js/jquery.dataTables.min.js"></script>
<script src="//cdn.datatables.net/1.10.18/js/dataTables.bootstrap4.min.js"></script>
@endsection
@section('header')
@include('header', $header)
@parent
@endsection
@section('sidebar')
@include('sidebar')
@endsection
@section('body')
<main class="main">
<!-- Breadcrumb-->
{{ Breadcrumbs::render('clients.edit', $client) }}
<div class="container-fluid" >
<div class="row">
<div class="col-lg-12">
{{ html()->form('PUT', route('signup.submit'))->open() }}
<example-component></example-component>
</div>
</div>
{{ html()->form()->close() }}
</div>
</main>
@include('dashboard.aside')
@endsection
@section('footer')
@include('footer')
@endsection

View File

@ -0,0 +1,49 @@
<div class="col-lg-5">
<div class="card">
<div class="card-header bg-primary">@lang('texts.edit_client')</div>
<div class="card-body">
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.client_name')</label>
<div class="col-sm-9">
{{ html()->input('name')->placeholder(__('texts.client_name'))->value($client->present()->name)->class('form-control')->id('name') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.id_number')</label>
<div class="col-sm-9">
{{ html()->input('id_number')->placeholder(__('texts.id_number'))->value($client->id_number)->class('form-control')->id('id_number') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.vat_number')</label>
<div class="col-sm-9">
{{ html()->input('vat_number')->placeholder(__('texts.vat_number'))->value($client->vat_number)->class('form-control')->id('vat_number') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.website')</label>
<div class="col-sm-9">
{{ html()->input('website')->placeholder(__('texts.website'))->value($client->website)->class('form-control')->id('website') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.custom_value1')</label>
<div class="col-sm-9">
{{ html()->input('custom_value1')->placeholder(__('texts.custom_value1'))->value($client->custom_value1)->class('form-control')->id('custom_value1') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.custom_value2')</label>
<div class="col-sm-9">
{{ html()->input('custom_value2')->placeholder(__('texts.custom_value2'))->value($client->custom_value2)->class('form-control')->id('custom_value2') }}
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,50 @@
<div class="card">
<div class="card-header bg-primary">{{ $address }}</div>
<div class="card-body">
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.address1')</label>
<div class="col-lg-9">
{{ html()->input('address1')->placeholder(__('texts.address1'))->value($location->address1)->class('form-control')->id('address1') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.address2')</label>
<div class="col-lg-9">
{{ html()->input('address2')->placeholder(__('texts.address2'))->value($location->address2)->class('form-control')->id('address2') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.city')</label>
<div class="col-lg-9">
{{ html()->input('city')->placeholder(__('texts.city'))->value($location->city)->class('form-control')->id('city') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.state')</label>
<div class="col-lg-9">
{{ html()->input('state')->placeholder(__('texts.state'))->value($location->state)->class('form-control')->id('state') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.postal_code')</label>
<div class="col-lg-9">
{{ html()->input('postal_code')->placeholder(__('texts.postal_code'))->value($location->postal_code)->class('form-control')->id('postal_code') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-lg-3 col-form-label text-right">@lang('texts.country')</label>
<div class="col-lg-9">
{{ html()->input('country')->placeholder(__('texts.country'))->value($location->country)->class('form-control')->id('country') }}
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,66 @@
<div class="col-lg-12">
<ul class="nav nav-pills nav-justified" id="pills-tab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="pills-address-tab" data-toggle="pill" href="#pills-address" role="tab" aria-controls="pills-address" aria-selected="true">Address</a>
</li>
<li class="nav-item">
<a class="nav-link" id="pills-contact-tab" data-toggle="pill" href="#pills-contact" role="tab" aria-controls="pills-contact" aria-selected="false">Contacts</a>
</li>
<li class="nav-item">
<a class="nav-link" id="pills-notes-tab" data-toggle="pill" href="#pills-notes" role="tab" aria-controls="pills-notes" aria-selected="false">Notes</a>
</li>
<li class="nav-item">
<a class="nav-link" id="pills-settings-tab" data-toggle="pill" href="#pills-settings" role="tab" aria-controls="pills-settings" aria-selected="false">Settings</a>
</li>
</ul>
<div class="tab-content" id="pills-tabContent">
<div class="tab-pane fade show active" id="pills-address" role="tabpanel" aria-labelledby="pills-address-tab">
<div class="row">
<div class="col-lg-6">
@include('client.partial.client_location', ['location' => $client->primary_billing_location->first(), 'address' => 'Billing'])
</div>
<div class="col-lg-6">
@include('client.partial.client_location', ['location' => $client->primary_billing_location->first(), 'address' => 'Shipping'])
</div>
</div>
</div>
<div class="tab-pane fade" id="pills-contact" role="tabpanel" aria-labelledby="pills-contact-tab">
@foreach($client->contacts as $contact)
@include('client.partial.contact_details', ['contact' => $contact])
@endforeach
</div>
<div class="tab-pane fade" id="pills-notes" role="tabpanel" aria-labelledby="pills-notes-tab">
<link href="https://cdn.quilljs.com/1.0.0/quill.snow.css" rel="stylesheet">
<!-- Create the toolbar container -->
<div id="toolbar">
<button class="ql-bold">Bold</button>
<button class="ql-italic">Italic</button>
</div>
<!-- Create the editor container -->
<div id="editor">
<p>Hello World!</p>
</div>
<!-- Include the Quill library -->
<script src="https://cdn.quilljs.com/1.0.0/quill.js"></script>
<!-- Initialize Quill editor -->
<script>
var editor = new Quill('#editor', {
modules: { toolbar: '#toolbar' },
theme: 'snow'
});
</script>
</div>
<div class="tab-pane fade" id="pills-settings" role="tabpanel" aria-labelledby="pills-settings-tab">
@include('client.partial.client_settings', $client)
</div>
</div>
</div>

View File

@ -0,0 +1,65 @@
<div class="col-lg-5">
<div class="card">
<div class="card-header bg-primary">@lang('texts.settings')</div>
<div class="card-body">
<fieldset class="form-group row">
<label for="date" class="col-sm-3 col-form-label text-right">Currency</label>
<div class="input-group col-sm-5">
<span class="input-group-prepend">
<span class="input-group-text">
<i class="fa fa-usd"></i>
</span>
</span>
<input class="form-control" id="date" type="text">
</div>
<small class="text-muted">ex. USD</small>
</fieldset>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.currency')</label>
<div class="col-sm-9">
{{ html()->input('name')->placeholder(__('texts.client_name'))->value($client->present()->name)->class('form-control')->id('name') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.id_number')</label>
<div class="col-sm-9">
{{ html()->input('id_number')->placeholder(__('texts.id_number'))->value($client->id_number)->class('form-control')->id('id_number') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.vat_number')</label>
<div class="col-sm-9">
{{ html()->input('vat_number')->placeholder(__('texts.vat_number'))->value($client->vat_number)->class('form-control')->id('vat_number') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.website')</label>
<div class="col-sm-9">
{{ html()->input('website')->placeholder(__('texts.website'))->value($client->website)->class('form-control')->id('website') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.custom_value1')</label>
<div class="col-sm-9">
{{ html()->input('custom_value1')->placeholder(__('texts.custom_value1'))->value($client->custom_value1)->class('form-control')->id('custom_value1') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.custom_value2')</label>
<div class="col-sm-9">
{{ html()->input('custom_value2')->placeholder(__('texts.custom_value2'))->value($client->custom_value2)->class('form-control')->id('custom_value2') }}
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,54 @@
<div class="col-lg-7">
<div class="row">
<div class="col-lg-6">
<div class="card">
<div class="card-header bg-primary">Invoice statistics - All Time</div>
<div class="card-body">
<ul class="list-group">
<li class="list-group-item d-flex list-group-item-action justify-content-between align-items-center">
Paid $12,239.00
<a href="#" class="badge badge-success badge-pill">12</a>
</li>
<li class="list-group-item d-flex list-group-item-action justify-content-between align-items-center">
Overdue $2,239.00
<a href="#" class="badge badge-danger badge-pill">123</a>
</li>
</ul>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="card">
<div class="card-header bg-primary">Invoice statistics - Date Range
<div class="btn-group float-right show">
<button class="btn btn-transparent dropdown-toggle p-0" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="icon-settings"></i>
</button>
<div class="dropdown-menu dropdown-menu-right" x-placement="bottom-end" style="position: absolute; will-change: transform; top: 0px; left: 0px; transform: translate3d(-143px, 23px, 0px);">
<a class="dropdown-item" href="#">Set Date Range</a>
</div>
</div>
</div>
<div class="card-body">
<ul class="list-group">
<li class="list-group-item d-flex list-group-item-action justify-content-between align-items-center">
Paid $12,239.00
<a href="#" class="badge badge-success badge-pill">12</a>
</li>
<li class="list-group-item d-flex list-group-item-action justify-content-between align-items-center">
Overdue $2,239.00
<a href="#" class="badge badge-danger badge-pill">123</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,51 @@
<div class="col-lg-6">
<div class="card">
<div class="card-header bg-primary">@lang('texts.contact_information')</div>
<div class="card-body">
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.first_name')</label>
<div class="col-sm-9">
{{ html()->input('first_name')->placeholder(__('texts.first_name'))->value($contact->first_name)->class('form-control')->id('first_name') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.last_name')</label>
<div class="col-sm-9">
{{ html()->input('last_name')->placeholder(__('texts.last_name'))->value($contact->last_name)->class('form-control')->id('last_name') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.email')</label>
<div class="col-sm-9">
{{ html()->input('email')->placeholder(__('texts.email'))->value($contact->first_name)->class('form-control')->id('email') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.phone')</label>
<div class="col-sm-9">
{{ html()->input('phone')->placeholder(__('texts.phone'))->value($contact->phone)->class('form-control')->id('phone') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.custom_value1')</label>
<div class="col-sm-9">
{{ html()->input('custom_value1')->placeholder(__('texts.custom_value1'))->value($contact->custom_value1)->class('form-control')->id('custom_value1') }}
</div>
</div>
<div class="form-group row">
<label for="name" class="col-sm-3 col-form-label text-right">@lang('texts.custom_value2')</label>
<div class="col-sm-9">
{{ html()->input('custom_value2')->placeholder(__('texts.custom_value2'))->value($contact->custom_value2)->class('form-control')->id('custom_value2') }}
</div>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1 @@
<div id="map{!! $location->id !!}" style="height:400px; width:100%;"></div>

View File

@ -0,0 +1,46 @@
<script type="text/javascript">
function initMap() {
var locations = {!! $locations !!}
var maps = [];
for (var i = 0; i < locations.length; i++) {
console.log(locations[i][1]);
var map = new google.maps.Map(document.getElementById('map' + locations[i].id ), {
zoom: 8,
center: {lat: -34.397, lng: 150.644}
});
var geocoder = new google.maps.Geocoder();
var address = locations[i].address1 + ' ' + locations[i].address2+ ' ' + locations[i].city + ' ' + locations[i].state + ' ' + locations[i].postal_code + ' ' + locations[i].country;
geocodeAddress(geocoder, map + locations[i], address);
};
}
initMap();
//google.maps.event.addDomListener(window, 'load', initMap);
function geocodeAddress(geocoder, resultsMap, address) {
geocoder.geocode({'address': address}, function(results, status) {
if (status === 'OK') {
resultsMap.setCenter(results[0].geometry.location);
var marker = new google.maps.Marker({
map: resultsMap,
position: results[0].geometry.location
});
} else {
alert('Geocode was not successful for the following reason: ' + status);
}
});
}
</script>

View File

@ -23,7 +23,7 @@
<div class="list-group-item list-group-item-accent-secondary bg-light text-center font-weight-bold text-muted text-uppercase small">Today</div>
<div class="list-group-item list-group-item-accent-warning list-group-item-divider">
<div class="avatar float-right">
<img class="img-avatar" src="images/logo.png" alt="admin@bootstrapmaster.com">
<img class="img-avatar" src="/images/logo.png" alt="admin@bootstrapmaster.com">
</div>
<div>Meeting with
<strong>Lucas</strong>
@ -35,7 +35,7 @@
</div>
<div class="list-group-item list-group-item-accent-info">
<div class="avatar float-right">
<img class="img-avatar" src="images/logo.png" alt="admin@bootstrapmaster.com">
<img class="img-avatar" src="/images/logo.png" alt="admin@bootstrapmaster.com">
</div>
<div>Skype with
<strong>Megan</strong>
@ -56,19 +56,19 @@
<i class="icon-home"></i>  creativeLabs HQ</small>
<div class="avatars-stack mt-2">
<div class="avatar avatar-xs">
<img class="img-avatar" src="images/logo.png" alt="admin@bootstrapmaster.com">
<img class="img-avatar" src="/images/logo.png" alt="admin@bootstrapmaster.com">
</div>
<div class="avatar avatar-xs">
<img class="img-avatar" src="images/logo.png" alt="admin@bootstrapmaster.com">
<img class="img-avatar" src="/images/logo.png" alt="admin@bootstrapmaster.com">
</div>
<div class="avatar avatar-xs">
<img class="img-avatar" src="images/logo.png" alt="admin@bootstrapmaster.com">
<img class="img-avatar" src="/images/logo.png" alt="admin@bootstrapmaster.com">
</div>
<div class="avatar avatar-xs">
<img class="img-avatar" src="images/logo.png" alt="admin@bootstrapmaster.com">
<img class="img-avatar" src="/images/logo.png" alt="admin@bootstrapmaster.com">
</div>
<div class="avatar avatar-xs">
<img class="img-avatar" src="images/logo.png" alt="admin@bootstrapmaster.com">
<img class="img-avatar" src="/images/logo.png" alt="admin@bootstrapmaster.com">
</div>
</div>
</div>
@ -90,25 +90,25 @@
<i class="icon-home"></i>  creativeLabs HQ</small>
<div class="avatars-stack mt-2">
<div class="avatar avatar-xs">
<img class="img-avatar" src="images/logo.png" alt="admin@bootstrapmaster.com">
<img class="img-avatar" src="/images/logo.png" alt="admin@bootstrapmaster.com">
</div>
<div class="avatar avatar-xs">
<img class="img-avatar" src="images/logo.png" alt="admin@bootstrapmaster.com">
<img class="img-avatar" src="/images/logo.png" alt="admin@bootstrapmaster.com">
</div>
<div class="avatar avatar-xs">
<img class="img-avatar" src="images/logo.png" alt="admin@bootstrapmaster.com">
<img class="img-avatar" src="/images/logo.png" alt="admin@bootstrapmaster.com">
</div>
<div class="avatar avatar-xs">
<img class="img-avatar" src="images/logo.png" alt="admin@bootstrapmaster.com">
<img class="img-avatar" src="/images/logo.png" alt="admin@bootstrapmaster.com">
</div>
<div class="avatar avatar-xs">
<img class="img-avatar" src="images/logo.png" alt="admin@bootstrapmaster.com">
<img class="img-avatar" src="/images/logo.png" alt="admin@bootstrapmaster.com">
</div>
<div class="avatar avatar-xs">
<img class="img-avatar" src="images/logo.png" alt="admin@bootstrapmaster.com">
<img class="img-avatar" src="/images/logo.png" alt="admin@bootstrapmaster.com">
</div>
<div class="avatar avatar-xs">
<img class="img-avatar" src="images/logo.png" alt="admin@bootstrapmaster.com">
<img class="img-avatar" src="/images/logo.png" alt="admin@bootstrapmaster.com">
</div>
</div>
</div>
@ -118,7 +118,7 @@
<div class="message">
<div class="py-3 pb-5 mr-3 float-left">
<div class="avatar">
<img class="img-avatar" src="images/logo.png" alt="admin@bootstrapmaster.com">
<img class="img-avatar" src="/images/logo.png" alt="admin@bootstrapmaster.com">
<span class="avatar-status badge-success"></span>
</div>
</div>
@ -133,7 +133,7 @@
<div class="message">
<div class="py-3 pb-5 mr-3 float-left">
<div class="avatar">
<img class="img-avatar" src="images/logo.png" alt="admin@bootstrapmaster.com">
<img class="img-avatar" src="/images/logo.png" alt="admin@bootstrapmaster.com">
<span class="avatar-status badge-success"></span>
</div>
</div>
@ -148,7 +148,7 @@
<div class="message">
<div class="py-3 pb-5 mr-3 float-left">
<div class="avatar">
<img class="img-avatar" src="images/logo.png" alt="admin@bootstrapmaster.com">
<img class="img-avatar" src="/images/logo.png" alt="admin@bootstrapmaster.com">
<span class="avatar-status badge-success"></span>
</div>
</div>
@ -163,7 +163,7 @@
<div class="message">
<div class="py-3 pb-5 mr-3 float-left">
<div class="avatar">
<img class="img-avatar" src="images/logo.png" alt="admin@bootstrapmaster.com">
<img class="img-avatar" src="/images/logo.png" alt="admin@bootstrapmaster.com">
<span class="avatar-status badge-success"></span>
</div>
</div>
@ -178,7 +178,7 @@
<div class="message">
<div class="py-3 pb-5 mr-3 float-left">
<div class="avatar">
<img class="img-avatar" src="images/logo.png" alt="admin@bootstrapmaster.com">
<img class="img-avatar" src="/images/logo.png" alt="admin@bootstrapmaster.com">
<span class="avatar-status badge-success"></span>
</div>
</div>

View File

@ -1,11 +1,11 @@
<footer class="app-footer">
<div>
<a href="https://coreui.io">Invoice Ninja</a>
<a href="https://invoiceninja.com">Invoice Ninja</a>
<span>&copy; 2018 Invoice Ninja LLC.</span>
</div>
<div class="ml-auto">
<span>Powered by</span>
<a href="https://invioceninja.com">InvoiceNinja</a>
<a href="https://invoiceninja.com">InvoiceNinja</a>
</div>
</footer>

View File

@ -4,8 +4,8 @@
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="https://invoiceninja.com">
<img class="navbar-brand-full" src="images/logo.png" width="50" height="50" alt="Invoice Ninja Logo">
<img class="navbar-brand-minimized" src="images/logo.png" width="30" height="30" alt="Invoice Ninja Logo">
<img class="navbar-brand-full" src="/images/logo.png" width="50" height="50" alt="Invoice Ninja Logo">
<img class="navbar-brand-minimized" src="/images/logo.png" width="30" height="30" alt="Invoice Ninja Logo">
</a>
<button class="sidebar-minimizer brand-minimizer" type="button">
<span class="navbar-toggler-icon"></span>
@ -110,7 +110,7 @@
<li class="nav-item dropdown">
<a class="nav-link" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
<img class="img-avatar" src="images/logo.png" alt=""> {{ auth()->user()->present()->name }}
<img class="img-avatar" src="/images/logo.png" alt=""> {{ auth()->user()->present()->name }}
</a>
<div class="dropdown-menu dropdown-menu-right">
<div class="dropdown-header text-center">
@ -134,4 +134,4 @@
<span class="navbar-toggler-icon"></span>
</button>
</header>
<div class="app-body">
<div class="app-body" id="app">

View File

@ -9,4 +9,9 @@ Breadcrumbs::for('dashboard', function ($trail) {
Breadcrumbs::for('clients', function ($trail) {
$trail->parent('dashboard');
$trail->push(trans('texts.clients'), route('clients.index'));
});
});
Breadcrumbs::for('clients.edit', function($trail, $client) {
$trail->parent('clients');
$trail->push($client->name, route('clients.edit', $client));
});

3
webpack.mix.js vendored
View File

@ -1,5 +1,6 @@
const mix = require('laravel-mix');
/*
|--------------------------------------------------------------------------
| Mix Asset Management
@ -15,6 +16,8 @@ mix.js('resources/js/app.js', 'public/js/vendor');
mix.scripts([
'node_modules/@coreui/coreui/dist/js/coreui.js',
//'node_modules/vue/dist/vue.min.js',
'node_modules/vue/dist/vue.js',
'public/js/vendor/app.js'
], 'public/js/ninja.js');