add new side nav layout

shift-build-2464
Nadim Salloum 2021-05-15 00:10:17 +02:00
parent 9d8beb2630
commit 8a7c533bb5
16 changed files with 2300 additions and 157 deletions

View File

@ -37,6 +37,8 @@ class ContactController extends Controller
'name' => $contact->name,
'company' => $contact->company,
'phone' => $contact->phone,
'email' => $contact->email,
'address' => $contact->address,
'fullCity' => $contact->fullCity,
'link' => route('contacts.edit', $contact),
'deleted_at' => $contact->deleted_at,
@ -51,6 +53,10 @@ class ContactController extends Controller
return Contact::orderBy('company', $direction);
case 'fullCity':
return Contact::orderBy('city', $direction);
case 'email':
return Contact::orderBy('email', $direction);
case 'address':
return Contact::orderBy('address', $direction);
default:
return Contact::orderByName($direction);
}

View File

@ -74,7 +74,11 @@ class Contact extends Model
$query->where('firstname', 'like', '%' . $search . '%')
->orWhere('lastname', 'like', '%' . $search . '%')
->orWhere('company', 'like', '%' . $search . '%')
->orWhere('email', 'like', '%' . $search . '%');
->orWhere('email', 'like', '%' . $search . '%')
->orWhere('zip', 'like', $search . '%')
->orWhere('city', 'like', '%' . $search . '%')
->orWhere('address', 'like', '%' . $search . '%')
->orWhere('phone', 'like', '%' . $search . '%');
});
})->when($filters['trashed'] ?? null, function ($query, $trashed) {
if ($trashed === 'with') {

67
package-lock.json generated
View File

@ -5,7 +5,8 @@
"packages": {
"": {
"dependencies": {
"vue-unicons": "^3.2.1"
"vue-unicons": "^3.2.1",
"vuex": "^4.0.0"
},
"devDependencies": {
"@inertiajs/inertia": "^0.8.4",
@ -350,8 +351,7 @@
"node_modules/@babel/helper-validator-identifier": {
"version": "7.14.0",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
"integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
"dev": true
"integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A=="
},
"node_modules/@babel/helper-validator-option": {
"version": "7.12.17",
@ -459,7 +459,6 @@
"version": "7.14.1",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.1.tgz",
"integrity": "sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q==",
"dev": true,
"bin": {
"parser": "bin/babel-parser.js"
},
@ -1437,7 +1436,6 @@
"version": "7.14.1",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.1.tgz",
"integrity": "sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA==",
"dev": true,
"dependencies": {
"@babel/helper-validator-identifier": "^7.14.0",
"to-fast-properties": "^2.0.0"
@ -2318,7 +2316,6 @@
"version": "3.0.11",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.0.11.tgz",
"integrity": "sha512-6sFj6TBac1y2cWCvYCA8YzHJEbsVkX7zdRs/3yK/n1ilvRqcn983XvpBbnN3v4mZ1UiQycTvOiajJmOgN9EVgw==",
"dev": true,
"dependencies": {
"@babel/parser": "^7.12.0",
"@babel/types": "^7.12.0",
@ -2331,7 +2328,6 @@
"version": "3.0.11",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.0.11.tgz",
"integrity": "sha512-+3xB50uGeY5Fv9eMKVJs2WSRULfgwaTJsy23OIltKgMrynnIj8hTYY2UL97HCoz78aDw1VDXdrBQ4qepWjnQcw==",
"dev": true,
"dependencies": {
"@vue/compiler-core": "3.0.11",
"@vue/shared": "3.0.11"
@ -2378,7 +2374,6 @@
"version": "3.0.11",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.0.11.tgz",
"integrity": "sha512-SKM3YKxtXHBPMf7yufXeBhCZ4XZDKP9/iXeQSC8bBO3ivBuzAi4aZi0bNoeE2IF2iGfP/AHEt1OU4ARj4ao/Xw==",
"dev": true,
"dependencies": {
"@vue/shared": "3.0.11"
}
@ -2387,7 +2382,6 @@
"version": "3.0.11",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.0.11.tgz",
"integrity": "sha512-87XPNwHfz9JkmOlayBeCCfMh9PT2NBnv795DSbi//C/RaAnc/bGZgECjmkD7oXJ526BZbgk9QZBPdFT8KMxkAg==",
"dev": true,
"dependencies": {
"@vue/reactivity": "3.0.11",
"@vue/shared": "3.0.11"
@ -2397,7 +2391,6 @@
"version": "3.0.11",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.0.11.tgz",
"integrity": "sha512-jm3FVQESY3y2hKZ2wlkcmFDDyqaPyU3p1IdAX92zTNeCH7I8zZ37PtlE1b9NlCtzV53WjB4TZAYh9yDCMIEumA==",
"dev": true,
"dependencies": {
"@vue/runtime-core": "3.0.11",
"@vue/shared": "3.0.11",
@ -2407,8 +2400,7 @@
"node_modules/@vue/shared": {
"version": "3.0.11",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.0.11.tgz",
"integrity": "sha512-b+zB8A2so8eCE0JsxjL24J7vdGl8rzPQ09hZNhystm+KqSbKcAej1A+Hbva1rCMmTTqA+hFnUSDc5kouEo0JzA==",
"dev": true
"integrity": "sha512-b+zB8A2so8eCE0JsxjL24J7vdGl8rzPQ09hZNhystm+KqSbKcAej1A+Hbva1rCMmTTqA+hFnUSDc5kouEo0JzA=="
},
"node_modules/@webassemblyjs/ast": {
"version": "1.11.0",
@ -5023,8 +5015,7 @@
"node_modules/csstype": {
"version": "2.6.17",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.17.tgz",
"integrity": "sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A==",
"dev": true
"integrity": "sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A=="
},
"node_modules/debug": {
"version": "4.3.1",
@ -5647,8 +5638,7 @@
"node_modules/estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"dev": true
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
},
"node_modules/esutils": {
"version": "2.0.3",
@ -13987,7 +13977,6 @@
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
@ -14846,7 +14835,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
"integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
"dev": true,
"engines": {
"node": ">=4"
}
@ -15364,7 +15352,6 @@
"version": "3.0.11",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.0.11.tgz",
"integrity": "sha512-3/eUi4InQz8MPzruHYSTQPxtM3LdZ1/S/BvaU021zBnZi0laRUyH6pfuE4wtUeLvI8wmUNwj5wrZFvbHUXL9dw==",
"dev": true,
"dependencies": {
"@vue/compiler-dom": "3.0.11",
"@vue/runtime-dom": "3.0.11",
@ -15434,6 +15421,14 @@
"resolved": "https://registry.npmjs.org/vue/-/vue-2.6.12.tgz",
"integrity": "sha512-uhmLFETqPPNyuLLbsKz6ioJ4q7AZHzD8ZVFNATNyICSZouqP2Sz0rotWQC8UNBF6VGSCs5abnKJoStA6JbCbfg=="
},
"node_modules/vuex": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-4.0.0.tgz",
"integrity": "sha512-56VPujlHscP5q/e7Jlpqc40sja4vOhC4uJD1llBCWolVI8ND4+VzisDVkUMl+z5y0MpIImW6HjhNc+ZvuizgOw==",
"peerDependencies": {
"vue": "^3.0.2"
}
},
"node_modules/watchpack": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz",
@ -16236,8 +16231,7 @@
"@babel/helper-validator-identifier": {
"version": "7.14.0",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz",
"integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==",
"dev": true
"integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A=="
},
"@babel/helper-validator-option": {
"version": "7.12.17",
@ -16334,8 +16328,7 @@
"@babel/parser": {
"version": "7.14.1",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.1.tgz",
"integrity": "sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q==",
"dev": true
"integrity": "sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q=="
},
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
"version": "7.13.12",
@ -17107,7 +17100,6 @@
"version": "7.14.1",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.1.tgz",
"integrity": "sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA==",
"dev": true,
"requires": {
"@babel/helper-validator-identifier": "^7.14.0",
"to-fast-properties": "^2.0.0"
@ -17876,7 +17868,6 @@
"version": "3.0.11",
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.0.11.tgz",
"integrity": "sha512-6sFj6TBac1y2cWCvYCA8YzHJEbsVkX7zdRs/3yK/n1ilvRqcn983XvpBbnN3v4mZ1UiQycTvOiajJmOgN9EVgw==",
"dev": true,
"requires": {
"@babel/parser": "^7.12.0",
"@babel/types": "^7.12.0",
@ -17889,7 +17880,6 @@
"version": "3.0.11",
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.0.11.tgz",
"integrity": "sha512-+3xB50uGeY5Fv9eMKVJs2WSRULfgwaTJsy23OIltKgMrynnIj8hTYY2UL97HCoz78aDw1VDXdrBQ4qepWjnQcw==",
"dev": true,
"requires": {
"@vue/compiler-core": "3.0.11",
"@vue/shared": "3.0.11"
@ -17933,7 +17923,6 @@
"version": "3.0.11",
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.0.11.tgz",
"integrity": "sha512-SKM3YKxtXHBPMf7yufXeBhCZ4XZDKP9/iXeQSC8bBO3ivBuzAi4aZi0bNoeE2IF2iGfP/AHEt1OU4ARj4ao/Xw==",
"dev": true,
"requires": {
"@vue/shared": "3.0.11"
}
@ -17942,7 +17931,6 @@
"version": "3.0.11",
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.0.11.tgz",
"integrity": "sha512-87XPNwHfz9JkmOlayBeCCfMh9PT2NBnv795DSbi//C/RaAnc/bGZgECjmkD7oXJ526BZbgk9QZBPdFT8KMxkAg==",
"dev": true,
"requires": {
"@vue/reactivity": "3.0.11",
"@vue/shared": "3.0.11"
@ -17952,7 +17940,6 @@
"version": "3.0.11",
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.0.11.tgz",
"integrity": "sha512-jm3FVQESY3y2hKZ2wlkcmFDDyqaPyU3p1IdAX92zTNeCH7I8zZ37PtlE1b9NlCtzV53WjB4TZAYh9yDCMIEumA==",
"dev": true,
"requires": {
"@vue/runtime-core": "3.0.11",
"@vue/shared": "3.0.11",
@ -17962,8 +17949,7 @@
"@vue/shared": {
"version": "3.0.11",
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.0.11.tgz",
"integrity": "sha512-b+zB8A2so8eCE0JsxjL24J7vdGl8rzPQ09hZNhystm+KqSbKcAej1A+Hbva1rCMmTTqA+hFnUSDc5kouEo0JzA==",
"dev": true
"integrity": "sha512-b+zB8A2so8eCE0JsxjL24J7vdGl8rzPQ09hZNhystm+KqSbKcAej1A+Hbva1rCMmTTqA+hFnUSDc5kouEo0JzA=="
},
"@webassemblyjs/ast": {
"version": "1.11.0",
@ -20081,8 +20067,7 @@
"csstype": {
"version": "2.6.17",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.17.tgz",
"integrity": "sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A==",
"dev": true
"integrity": "sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A=="
},
"debug": {
"version": "4.3.1",
@ -20572,8 +20557,7 @@
"estree-walker": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"dev": true
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
},
"esutils": {
"version": "2.0.3",
@ -27186,8 +27170,7 @@
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
},
"source-map-resolve": {
"version": "0.5.3",
@ -27882,8 +27865,7 @@
"to-fast-properties": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
"integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
"dev": true
"integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4="
},
"to-object-path": {
"version": "0.3.0",
@ -28306,7 +28288,6 @@
"version": "3.0.11",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.0.11.tgz",
"integrity": "sha512-3/eUi4InQz8MPzruHYSTQPxtM3LdZ1/S/BvaU021zBnZi0laRUyH6pfuE4wtUeLvI8wmUNwj5wrZFvbHUXL9dw==",
"dev": true,
"requires": {
"@vue/compiler-dom": "3.0.11",
"@vue/runtime-dom": "3.0.11",
@ -28378,6 +28359,12 @@
}
}
},
"vuex": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-4.0.0.tgz",
"integrity": "sha512-56VPujlHscP5q/e7Jlpqc40sja4vOhC4uJD1llBCWolVI8ND4+VzisDVkUMl+z5y0MpIImW6HjhNc+ZvuizgOw==",
"requires": {}
},
"watchpack": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.1.1.tgz",

View File

@ -27,6 +27,7 @@
"vue-loader": "^16.1.2"
},
"dependencies": {
"vue-unicons": "^3.2.1"
"vue-unicons": "^3.2.1",
"vuex": "^4.0.0"
}
}

2064
public/js/app.js vendored

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,85 @@
<template>
<div class="sticky top-0 z-40">
<div class="w-full h-20 px-6 bg-gray-100 border-b flex items-center justify-between">
<!-- left navbar -->
<div class="flex">
<!-- mobile hamburger -->
<div class="inline-block lg:hidden flex items-center mr-4">
<button class="hover:text-blue-500 hover:border-white focus:outline-none navbar-burger" @click="toggleSidebar()">
<svg class="h-5 w-5" v-bind:style="{ fill: 'black' }" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><title>Menu</title><path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z"/></svg>
</button>
</div>
<slot></slot>
</div>
<!-- right navbar -->
<div class="flex items-center relative">
<jet-dropdown align="right" width="48">
<template #trigger>
<button v-if="$page.props.jetstream.managesProfilePhotos" class="flex text-sm border-2 border-transparent rounded-full focus:outline-none focus:border-gray-300 transition">
<img class="h-8 w-8 rounded-full object-cover" :src="$page.props.user.profile_photo_url" :alt="$page.props.user.name" />
</button>
<span v-else class="inline-flex rounded-md">
<button type="button" class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-gray-500 bg-white hover:text-gray-700 focus:outline-none transition">
{{ $page.props.user.name }}
<svg class="ml-2 -mr-0.5 h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" />
</svg>
</button>
</span>
</template>
<template #content>
<!-- Account Management -->
<div class="block px-4 py-2 text-xs text-gray-400">
Account verwalten
</div>
<jet-dropdown-link :href="route('profile.show')">
Profil
</jet-dropdown-link>
<div class="border-t border-gray-100"></div>
<!-- Authentication -->
<form @submit.prevent="logout">
<jet-dropdown-link as="button">
Abmelden
</jet-dropdown-link>
</form>
</template>
</jet-dropdown>
</div>
</div>
</div>
</template>
<script>
import JetDropdown from '@/Jetstream/Dropdown'
import JetDropdownLink from '@/Jetstream/DropdownLink'
import { mapState } from 'vuex'
export default {
components: {
JetDropdown,
JetDropdownLink,
},
computed: {
...mapState(['sideBarOpen'])
},
data() {
return {
dropDownOpen: false
}
},
methods: {
toggleSidebar() {
this.$store.dispatch('toggleSidebar')
}
}
}
</script>

View File

@ -0,0 +1,75 @@
<template>
<!-- give the sidebar z-50 class so its higher than the navbar if you want to see the logo -->
<!-- you will need to add a little "X" button next to the logo in order to close it though -->
<div class="w-1/2 md:w-1/3 lg:w-64 fixed md:top-0 md:left-0 h-screen lg:block bg-gray-100 border-r z-30" :class="sideBarOpen ? '' : 'hidden'" id="main-nav">
<div class="w-full h-20 border-b flex px-4 items-center mb-8">
<p class="font-semibold text-2xl text-blue-400 pl-4">Your SwissCar</p>
</div>
<div class="mb-4 px-4">
<jet-nav-link :href="route('dashboard')" :active="route().current('dashboard')">
<unicon class="mr-2" height="22" width="22" name="dashboard"></unicon>
Dashboard
</jet-nav-link>
</div>
<div class="mb-4 px-4">
<p class="text-sm font-semibold mb-1 text-gray-400 flex items-center">
Autos
</p>
<jet-nav-link :href="route('cars.create')" :active="route().current('cars.create')">
<unicon class="mr-2" height="22" width="22" name="plus-circle"></unicon>
Neues Auto
</jet-nav-link>
<jet-nav-link :href="route('cars')" :active="route().current('cars')">
<unicon class="mr-2" height="22" width="22" name="car-sideview"></unicon>
Alle Autos
</jet-nav-link>
<jet-nav-link :href="route('cars.unsold')" :active="route().current('cars.unsold')">
<unicon class="mr-2 ml-3" height="22" width="22" name="angle-right"></unicon>
Meine Autos
</jet-nav-link>
<jet-nav-link :href="route('cars.sold')" :active="route().current('cars.sold')">
<unicon class="mr-2 ml-3" height="22" width="22" name="angle-right"></unicon>
Verkaufte Autos
</jet-nav-link>
</div>
<div class="mb-4 px-4">
<p class="text-sm font-semibold mb-1 text-gray-400 flex items-center">
Kontakte
</p>
<jet-nav-link :href="route('contacts.create')" :active="route().current('contacts.create')">
<unicon class="mr-2" height="22" width="22" name="plus-circle"></unicon>
Neuer Kontakt
</jet-nav-link>
<jet-nav-link :href="route('contacts')" :active="route().current('contacts')">
<unicon class="mr-2" height="22" width="22" name="users-alt"></unicon>
Alle Kontakte
</jet-nav-link>
<jet-nav-link :href="route('contacts.buyers')" :active="route().current('contacts.buyers')">
<unicon class="mr-2 ml-3" height="22" width="22" name="angle-right"></unicon>
Käufer
</jet-nav-link>
<jet-nav-link :href="route('contacts.sellers')" :active="route().current('contacts.sellers')">
<unicon class="mr-2 ml-3" height="22" width="22" name="angle-right"></unicon>
Verkäufer
</jet-nav-link>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
import JetNavLink from '@/Jetstream/NavLink'
export default {
components: {
JetNavLink,
},
computed: {
...mapState(['sideBarOpen'])
}
}
</script>

View File

@ -11,8 +11,8 @@
computed: {
classes() {
return this.active
? 'inline-flex items-center px-1 pt-1 border-b-2 border-indigo-400 text-sm font-medium leading-5 text-gray-900 focus:outline-none focus:border-indigo-700 transition'
: 'inline-flex items-center px-1 pt-1 border-b-2 border-transparent text-sm font-medium leading-5 text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-none focus:text-gray-700 focus:border-gray-300 transition'
? 'w-full flex items-center text-blue-600 h-10 pl-4 bg-gray-200 hover:bg-gray-200 rounded-lg cursor-pointer'
: 'w-full flex items-center text-gray-800 h-10 pl-4 hover:bg-gray-200 rounded-lg cursor-pointer'
}
}
}

View File

@ -0,0 +1,33 @@
<template>
<div class="leading-normal tracking-normal" id="main-body">
<div class="flex flex-wrap">
<Sidebar />
<div class="w-full bg-gray-100 pl-0 lg:pl-64 min-h-screen" :class="sideBarOpen ? 'overlay' : ''" id="main-content">
<Navbar>
<slot name="header"></slot>
</Navbar>
<div class="p-6 bg-gray-100 mb-20">
<main>
<slot></slot>
</main>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
import Sidebar from "@/Components/Sidebar"
import Navbar from "@/Components/Navbar"
export default {
computed: {
...mapState(['sideBarOpen'])
},
components: {
Sidebar,
Navbar,
}
}
</script>

View File

@ -1,5 +1,5 @@
<template>
<app-layout>
<layout>
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
Autos
@ -9,19 +9,16 @@
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="mb-6 flex justify-between items-center">
<input type="text" ref="search" v-model="form.search" autofocus="true" name="search" placeholder="Suchen..." class="border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded-md shadow-sm block w-full" autocomplete="off">
<jet-button class="ml-4" @click="createCar">
Auto erfassen
</jet-button>
</div>
<simple-table :title="cars.total + ' Autos'" :data="cars" :columns="columns" :defaultSort="{ by: 'name', direction:'asc'}" />
</div>
</div>
</app-layout>
</layout>
</template>
<script>
import { pickBy, throttle, mapValues } from 'lodash'
import AppLayout from '@/Layouts/AppLayout'
import Layout from '@/Layouts/Layout'
import SimpleTable from '@/Components/SimpleTable.vue'
import SearchFilter from '@/Components/SearchFilter'
import JetButton from '@/Jetstream/Button'
@ -30,7 +27,7 @@ export default {
components: {
SearchFilter,
JetButton,
AppLayout,
Layout,
SimpleTable,
},
props: {
@ -63,9 +60,6 @@ export default {
reset() {
this.form = mapValues(this.form, () => null)
},
createCar() {
this.$inertia.visit(route('cars.create'), { method: 'get' })
},
},
}
</script>

View File

@ -1,5 +1,5 @@
<template>
<app-layout>
<layout>
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
<bread-crumb text="Kontakte" :href="route('contacts')" />
@ -8,7 +8,7 @@
</template>
<div>
<div class="max-w-7xl mx-auto py-10 sm:px-6 lg:px-8">
<div class="max-w-7xl py-10 sm:px-6 lg:px-8">
<jet-form-section @submitted="submitForm">
<template #title>
Kontaktinformationen
@ -103,18 +103,18 @@
</div>
</div>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="max-w-7xl sm:px-6 lg:px-8">
<simple-table :title="'An ' + title + ' verkaufte Autos'" :data="contact.bought_cars" :columns="boughtCarColumns" />
</div>
<div class="max-w-7xl pt-6 mx-auto sm:px-6 lg:px-8">
<div class="max-w-7xl pt-6 sm:px-6 lg:px-8">
<simple-table :title="'Von ' + title + ' gekaufte Autos'" :data="contact.sold_cars" :columns="soldCarColumns" />
</div>
</div>
</app-layout>
</layout>
</template>
<script>
import AppLayout from '@/Layouts/AppLayout'
import Layout from '@/Layouts/Layout'
import JetButton from '@/Jetstream/Button'
import BreadCrumb from '@/Components/BreadCrumb.vue'
import ContactCard from '@/Components/ContactCard.vue'
@ -129,7 +129,7 @@ export default {
components: {
JetButton,
JetFormSection,
AppLayout,
Layout,
BreadCrumb,
SimpleTable,
JetLabel,

View File

@ -1,28 +1,25 @@
<template>
<app-layout>
<layout>
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
Kontakte
</h2>
</template>
<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="w-full mx-auto sm:px-6 lg:px-8">
<div class="mb-6 flex justify-between items-center">
<!-- <search-filter ref="search" v-model="form.search" class="w-full max-w-md mr-4" @reset="reset"></search-filter> -->
<input type="text" ref="search" v-model="form.search" autofocus="true" name="search" placeholder="Suchen..." class="border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded-md shadow-sm block w-full" autocomplete="off">
<jet-button class="ml-4" @click="createContact">
Kontakt erfassen
</jet-button>
</div>
<simple-table :title="contacts.total + ' Kontakte'" :data="contacts" :columns="columns" :defaultSort="sort" />
</div>
</div>
</app-layout>
</layout>
</template>
<script>
import { pickBy, throttle, mapValues } from 'lodash'
import AppLayout from '@/Layouts/AppLayout'
import Layout from '@/Layouts/Layout'
import SimpleTable from '@/Components/SimpleTable.vue'
import SearchFilter from '@/Components/SearchFilter'
import JetButton from '@/Jetstream/Button'
@ -31,7 +28,7 @@ export default {
components: {
SearchFilter,
JetButton,
AppLayout,
Layout,
SimpleTable,
},
props: {
@ -48,7 +45,9 @@ export default {
columns: [
{key: 'name', value: 'Name', sortable: true},
{key: 'company', value: 'Firma', sortable: true},
{key: 'address', value: 'Adresse', sortable: true},
{key: 'fullCity', value: 'Ort', sortable: true},
{key: 'email', value: 'E-Mail', sortable: true},
{key: 'phone', value: 'Telefon'},
],
}
@ -65,9 +64,6 @@ export default {
reset() {
this.form = mapValues(this.form, () => null)
},
createContact() {
this.$inertia.visit(route('contacts.create'), { method: 'get' })
},
},
}
</script>

View File

@ -1,5 +1,5 @@
<template>
<app-layout>
<layout>
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
Dashboard
@ -13,15 +13,15 @@
</div>
</div>
</div>
</app-layout>
</layout>
</template>
<script>
import AppLayout from '@/Layouts/AppLayout'
import Layout from '@/Layouts/Layout'
export default {
components: {
AppLayout,
Layout,
},
}
</script>

View File

@ -1,5 +1,5 @@
<template>
<app-layout>
<layout>
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
Profile
@ -7,7 +7,7 @@
</template>
<div>
<div class="max-w-7xl mx-auto py-10 sm:px-6 lg:px-8">
<div class="max-w-7xl py-10 sm:px-6 lg:px-8">
<div v-if="$page.props.jetstream.canUpdateProfileInformation">
<update-profile-information-form :user="$page.props.user" />
@ -35,11 +35,11 @@
</template>
</div>
</div>
</app-layout>
</layout>
</template>
<script>
import AppLayout from '@/Layouts/AppLayout'
import Layout from '@/Layouts/Layout'
import DeleteUserForm from './DeleteUserForm'
import JetSectionBorder from '@/Jetstream/SectionBorder'
import LogoutOtherBrowserSessionsForm from './LogoutOtherBrowserSessionsForm'
@ -51,7 +51,7 @@
props: ['sessions'],
components: {
AppLayout,
Layout,
DeleteUserForm,
JetSectionBorder,
LogoutOtherBrowserSessionsForm,

30
resources/js/app.js vendored
View File

@ -5,11 +5,36 @@ import { createApp, h } from 'vue';
import { App as InertiaApp, plugin as InertiaPlugin } from '@inertiajs/inertia-vue3';
import { InertiaProgress } from '@inertiajs/progress';
import Unicon from 'vue-unicons';
import { uniMeh, uniUsersAlt, uniCarSideview, uniDashboard, uniSearch, uniFilter, uniFilterSlash, uniTrashAlt, uniPen, uniExclamationTriangle, uniMapMarker, uniPhone, uniEnvelope, uniFileDownload, uniArrowDown, uniArrowUp, uniArrowRight, uniAngleRight, uniAngleUp, uniAngleDown, uniAngleLeft, uniFileUploadAlt } from 'vue-unicons/dist/icons'
import { createStore } from 'vuex'
import { uniPlusCircle, uniMeh, uniUsersAlt, uniCarSideview, uniDashboard, uniSearch, uniFilter, uniFilterSlash, uniTrashAlt, uniPen, uniExclamationTriangle, uniMapMarker, uniPhone, uniEnvelope, uniFileDownload, uniArrowDown, uniArrowUp, uniArrowRight, uniAngleRight, uniAngleUp, uniAngleDown, uniAngleLeft, uniFileUploadAlt } from 'vue-unicons/dist/icons'
Unicon.add([uniMeh, uniUsersAlt, uniCarSideview, uniDashboard, uniSearch, uniFilter, uniFilterSlash, uniTrashAlt, uniPen, uniExclamationTriangle, uniMapMarker, uniPhone, uniEnvelope, uniFileDownload, uniArrowDown, uniArrowUp, uniArrowRight, uniAngleRight, uniAngleUp, uniAngleDown, uniAngleLeft, uniFileUploadAlt])
Unicon.add([uniPlusCircle, uniMeh, uniUsersAlt, uniCarSideview, uniDashboard, uniSearch, uniFilter, uniFilterSlash, uniTrashAlt, uniPen, uniExclamationTriangle, uniMapMarker, uniPhone, uniEnvelope, uniFileDownload, uniArrowDown, uniArrowUp, uniArrowRight, uniAngleRight, uniAngleUp, uniAngleDown, uniAngleLeft, uniFileUploadAlt])
// Create a new store instance.
const store = createStore({
state () {
return {
sideBarOpen: false
}
},
getters: {
sideBarOpen: state => {
return state.sideBarOpen
}
},
mutations: {
toggleSidebar (state) {
state.sideBarOpen = !state.sideBarOpen
}
},
actions: {
toggleSidebar(context) {
context.commit('toggleSidebar')
}
}
})
const el = document.getElementById('app');
createApp({
@ -21,6 +46,7 @@ createApp({
})
.mixin({ methods: { route } })
.use(InertiaPlugin)
.use(store)
.use(Unicon, {
fill: '#4B5563',
height: 32,

View File

@ -34,6 +34,14 @@ Route::get('contacts', [ContactController::class, 'index'])
->name('contacts')
->middleware(['auth:sanctum', 'verified']);
Route::post('contacts/buyers', [ContactController::class, 'index'])
->name('contacts.buyers')
->middleware(['auth:sanctum', 'verified']);
Route::post('contacts/sellers', [ContactController::class, 'index'])
->name('contacts.sellers')
->middleware(['auth:sanctum', 'verified']);
Route::get('contacts/create', [ContactController::class, 'create'])
->name('contacts.create')
->middleware(['auth:sanctum', 'verified']);
@ -62,10 +70,22 @@ Route::get('cars', [CarController::class, 'index'])
->name('cars')
->middleware(['auth:sanctum', 'verified']);
Route::get('cars/unsold', [CarController::class, 'index'])
->name('cars.unsold')
->middleware(['auth:sanctum', 'verified']);
Route::get('cars/sold', [CarController::class, 'index'])
->name('cars.sold')
->middleware(['auth:sanctum', 'verified']);
Route::get('cars/create', [ContactController::class, 'create'])
->name('cars.create')
->middleware(['auth:sanctum', 'verified']);
Route::get('cars/{contact}', [CarController::class, 'edit'])
->name('cars.edit')
->middleware(['auth:sanctum', 'verified']);
Route::get('cars/{car}', [CarController::class, 'edit'])
->name('cars.edit')
->middleware(['auth:sanctum', 'verified']);