frontend work

shift-build-2464
Nadim Salloum 2021-05-18 11:14:03 +02:00
parent f642c9c555
commit 417760182e
18 changed files with 2312 additions and 870 deletions

View File

@ -3,36 +3,44 @@
namespace App\Http\Controllers; namespace App\Http\Controllers;
use App\Models\Car; use App\Models\Car;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Validation\Rule;
use Inertia\Inertia; use Inertia\Inertia;
use App\Enums\InsuranceType;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Redirect;
class CarController extends Controller class CarController extends Controller
{ {
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $request) public function index(Request $request)
{ {
return $this->renderCarsList($request, Car::query(), 'Cars/Index');
}
public function unsold(Request $request)
{
return $this->renderCarsList($request, Car::unsoldCars(), 'Cars/Unsold');
}
public function sold(Request $request)
{
return $this->renderCarsList($request, Car::soldCars(), 'Cars/Sold');
}
private function renderCarsList(Request $request, $cars, string $renderPage) {
$direction = $this->getDirection($request); $direction = $this->getDirection($request);
$sortBy = $this->getSortBy($request); $sortBy = $this->getSortBy($request);
$cars = $this->getWithCustomSort($sortBy, $direction); $cars = $this->getWithCustomSort($cars, $sortBy, $direction);
return Inertia::render('Cars/Index', [ return Inertia::render($renderPage, [
'filters' => $request->all('search', 'trashed'), 'filters' => $request->all('search', 'trashed'),
'sort' => [ 'sort' => [
'by' => $sortBy, 'by' => $sortBy,
'direction' => $direction, 'direction' => $direction,
], ],
'cars' => $cars->filter($request->only('search', 'trashed')) 'cars' => $cars->filter($request->only('search', 'trashed'))
->orderByInitialDate()
->paginate(50) ->paginate(50)
->withQueryString() ->withQueryString()
->through(function ($car) { ->through(fn ($car) => [
return [
'id' => $car->id, 'id' => $car->id,
'stammnummer' => $car->stammnummer, 'stammnummer' => $car->stammnummer,
'vin' => $car->vin, 'vin' => $car->vin,
@ -44,21 +52,21 @@ class CarController extends Controller
'name' => $car->name, 'name' => $car->name,
'initial_date' => $car->initial_date, 'initial_date' => $car->initial_date,
'deleted_at' => $car->deleted_at, 'deleted_at' => $car->deleted_at,
]; 'link' => route('cars.edit', $car),
}), ]),
]); ]);
} }
private function getWithCustomSort(string $sortBy, string $direction) private function getWithCustomSort($cars, string $sortBy, string $direction)
{ {
switch($sortBy) { switch($sortBy) {
case 'initial_date': case 'initial_date':
return Car::orderBy('initial_date', $direction); return $cars->orderBy('initial_date', $direction);
case 'stammnummer': case 'stammnummer':
return Car::orderBy('stammnummer', $direction); return $cars->orderBy('stammnummer', $direction);
default: default:
//return Car::orderByName($direction); //return $cars->orderByName($direction);
return Car::orderBy('initial_date', $direction); return $cars->orderBy('initial_date', $direction);
} }
} }
@ -100,18 +108,20 @@ class CarController extends Controller
*/ */
public function store(Request $request) public function store(Request $request)
{ {
// $car = Car::create(
} $request->validate([
'stammnummer' => ['unique', 'max:11'],
'vin' => ['max:17'],
'initial_date' => ['nullable', 'date'],
'last_check_date' => ['nullable', 'date'],
'colour' => ['nullable', 'max:75'],
// 'model_id' => ['nullable', 'max:150'],
'kilometers' => ['nullable', 'max:75'],
])
);
return Redirect::route('cars.edit', $car)->with('success', 'Kontakt erstellt.');
/**
* Display the specified resource.
*
* @param \App\Models\Car $car
* @return \Illuminate\Http\Response
*/
public function show(Car $car)
{
//
} }
/** /**
@ -122,7 +132,39 @@ class CarController extends Controller
*/ */
public function edit(Car $car) public function edit(Car $car)
{ {
// return Inertia::render('Cars/Edit', [
'car' => [
'id' => $car->id,
'stammnummer' => $car->stammnummer,
'vin' => $car->vin,
'car_model' => $car->carModel->only('name'),
'name' => $car->name,
'initial_date' => $car->initial_date,
'colour' => $car->colour,
'last_check_date' => $car->last_check_date,
'kilometers' => $car->kilometers,
'known_damage' => $car->known_damage,
'notes' => $car->notes,
'deleted_at' => $car->deleted_at,
// 'buy_contracts' => $car->buyContracts()
// // ->with('contact')
// ->through(fn ($contract) => [
// 'date' => $contract->date,
// 'price' => $contract->price,
// 'buyer' => 'aaa', // $contract->contact->name,
// 'link' => route('cars.edit', $car),
// ]),
// 'sell_contracts' => $car->sellContracts()
// // ->with('contact')
// ->through(fn ($contract) => [
// 'date' => $contract->date,
// 'price' => $contract->price,
// 'seller' => 'bbb', // $contract->seller->name,
// 'link' => route('cars.edit', $car),
// 'insurance_type' => InsuranceType::fromValue((int)$contract->insurance_type)->key,
// ]),
]
]);
} }
/** /**
@ -134,7 +176,19 @@ class CarController extends Controller
*/ */
public function update(Request $request, Car $car) public function update(Request $request, Car $car)
{ {
// $car->update(
$request->validate([
'stammnummer' => ['unique', 'max:11'],
'vin' => ['max:17'],
'initial_date' => ['nullable', 'date'],
'last_check_date' => ['nullable', 'date'],
'colour' => ['nullable', 'max:75'],
// 'model_id' => ['nullable', 'max:150'],
'kilometers' => ['nullable', 'max:75'],
])
);
return Redirect::back()->with('success', 'Auto geändert.');
} }
/** /**

View File

@ -19,11 +19,25 @@ class ContactController extends Controller
*/ */
public function index(Request $request) public function index(Request $request)
{ {
return $this->renderContactsList($request, Contact::query(), 'Contacts/Index');
}
public function sellers(Request $request)
{
return $this->renderContactsList($request, Contact::has('buyContracts'), 'Contacts/Sellers');
}
public function buyers(Request $request)
{
return $this->renderContactsList($request, Contact::has('sellContracts'), 'Contacts/Buyers');
}
private function renderContactsList(Request $request, $contacts, string $renderPage) {
$direction = $this->getDirection($request); $direction = $this->getDirection($request);
$sortBy = $this->getSortBy($request); $sortBy = $this->getSortBy($request);
$contacts = $this->getWithCustomSort($sortBy, $direction); $contacts = $this->getWithCustomSort($contacts, $sortBy, $direction);
return Inertia::render('Contacts/Index', [ return Inertia::render($renderPage, [
'filters' => $request->all('search', 'trashed'), 'filters' => $request->all('search', 'trashed'),
'sort' => [ 'sort' => [
'by' => $sortBy, 'by' => $sortBy,
@ -46,19 +60,19 @@ class ContactController extends Controller
]); ]);
} }
private function getWithCustomSort(string $sortBy, string $direction) private function getWithCustomSort($contacts, string $sortBy, string $direction)
{ {
switch($sortBy) { switch($sortBy) {
case 'company': case 'company':
return Contact::orderBy('company', $direction); return $contacts->orderBy('company', $direction);
case 'fullCity': case 'fullCity':
return Contact::orderBy('city', $direction); return $contacts->orderBy('city', $direction);
case 'email': case 'email':
return Contact::orderBy('email', $direction); return $contacts->orderBy('email', $direction);
case 'address': case 'address':
return Contact::orderBy('address', $direction); return $contacts->orderBy('address', $direction);
default: default:
return Contact::orderByName($direction); return $contacts->orderByName($direction);
} }
} }
@ -100,12 +114,12 @@ class ContactController extends Controller
*/ */
public function store(Request $request) public function store(Request $request)
{ {
Contact::create( $contact = Contact::create(
$request->validate([ $request->validate([
'firstname' => ['max:75'], 'firstname' => ['max:75'],
'lastname' => ['max:75'], 'lastname' => ['max:75'],
'email' => ['nullable', 'max:75', 'email'], 'email' => ['nullable', 'max:75', 'email'],
'phone' => ['max:75'], 'phone' => ['required', 'max:75'],
'address' => ['nullable', 'max:150'], 'address' => ['nullable', 'max:150'],
'zip' => ['nullable', 'max:6'], 'zip' => ['nullable', 'max:6'],
'city' => ['nullable', 'max:75'], 'city' => ['nullable', 'max:75'],
@ -114,7 +128,7 @@ class ContactController extends Controller
]) ])
); );
return Redirect::route('contacts/1')->with('success', 'Kontakt erstellt.'); return Redirect::route('contacts.edit', $contact)->with('success', 'Kontakt erstellt.');
} }
/** /**

View File

@ -88,12 +88,12 @@ class Car extends Model
public function buyContracts() public function buyContracts()
{ {
return $this->hasMany(buyContract::class); return $this->hasMany(BuyContract::class);
} }
public function sellContracts() public function sellContracts()
{ {
return $this->hasMany(sellContract::class); return $this->hasMany(SellContract::class);
} }
public function carPayment() public function carPayment()
@ -106,21 +106,21 @@ class Car extends Model
// return $query->whereDate('sold_at', '>=', Carbon::today()->format('Y')); // return $query->whereDate('sold_at', '>=', Carbon::today()->format('Y'));
// } // }
// public function scopeSoldCars($query)
// {
// return $query->whereDate('sold_at', '>=', Carbon::today()->format('Y'));
// }
// public function scopeUnsoldCars($query)
// {
// return $query->whereDate('sold_at', );
// }
public function scopeOrderByInitialDate($query) public function scopeOrderByInitialDate($query)
{ {
$query->orderBy('initial_date'); $query->orderBy('initial_date');
} }
public function scopeSoldCars($query)
{
$query->withCount(['buyContracts', 'sellContracts'])->having('buy_contracts_count', '=', 'sell_contracts_count');
}
public function scopeUnsoldCars($query)
{
$query->withCount(['buyContracts', 'sellContracts'])->having('buy_contracts_count', '>', 'sell_contracts_count');
}
public function scopeFilter($query, array $filters) public function scopeFilter($query, array $filters)
{ {
$query->when($filters['search'] ?? null, function ($query, $search) { $query->when($filters['search'] ?? null, function ($query, $search) {

2231
public/js/app.js vendored

File diff suppressed because it is too large Load Diff

View File

@ -70,6 +70,7 @@ export default {
data: Object, data: Object,
columns: Array, columns: Array,
title: String, title: String,
currentRoute: String,
defaultSort: Object, defaultSort: Object,
filters: Object, filters: Object,
}, },
@ -102,7 +103,9 @@ export default {
this.form = mapValues(this.form, () => null) this.form = mapValues(this.form, () => null)
}, },
refreshTable() { refreshTable() {
this.$inertia.get(this.route('contacts'), pickBy(this.form), { preserveState: true }) if (this.currentRoute) {
this.$inertia.get(this.route(this.currentRoute), pickBy(this.form), { preserveState: true })
}
}, },
isActiveSort(col, dir) { isActiveSort(col, dir) {
return col == this.sort.by && dir == this.sort.direction; return col == this.sort.by && dir == this.sort.direction;

View File

@ -0,0 +1,126 @@
<template>
<div class="max-w-7xl py-10 sm:px-6 lg:px-8">
<jet-form-section @submitted="submitForm">
<template #title>
<slot name="title"></slot>
</template>
<template #description>
<slot name="description"></slot>
</template>
<template #form>
<div class="col-span-6 sm:col-span-4">
<jet-label for="car_model_id" value="Modell" />
<jet-input id="car_model_id" type="text" class="mt-1 block w-full" v-model="form.car_model_id" ref="car_model_id" autocomplete="car_model_id" />
<jet-input-error :message="form.errors.car_model_id" class="mt-2" />
</div>
<div class="col-span-6 sm:col-span-4">
<div class="grid grid-cols-12 gap-6">
<div class="col-span-12 sm:col-span-5">
<jet-label for="stammnummer" value="Stammnummer" />
<jet-input id="stammnummer" type="text" class="mt-1 block w-full" v-model="form.stammnummer" ref="stammnummer" autocomplete="stammnummer" />
<jet-input-error :message="form.errors.stammnummer" class="mt-2" />
</div>
<div class="col-span-12 sm:col-span-7">
<jet-label for="vin" value="Chassisnummer" />
<jet-input id="vin" type="text" class="mt-1 block w-full" v-model="form.vin" ref="vin" autocomplete="vin" />
<jet-input-error :message="form.errors.vin" class="mt-2" />
</div>
</div>
</div>
<div class="col-span-6 sm:col-span-4">
<div class="grid grid-cols-12 gap-6">
<div class="col-span-6 sm:col-span-6">
<jet-label for="initial_date" value="Inverkehrssetzung" />
<jet-input id="initial_date" type="text" class="mt-1 block w-full" v-model="form.initial_date" ref="initial_date" autocomplete="initial_date" />
<jet-input-error :message="form.errors.initial_date" class="mt-2" />
</div>
<div class="col-span-6 sm:col-span-6">
<jet-label for="last_check_date" value="Letzte Prüfung" />
<jet-input id="last_check_date" type="text" class="mt-1 block w-full" v-model="form.last_check_date" ref="last_check_date" autocomplete="last_check_date" />
<jet-input-error :message="form.errors.last_check_date" class="mt-2" />
</div>
</div>
</div>
<div class="col-span-6 sm:col-span-4">
<jet-label for="kilometers" value="Kilometerstand" />
<jet-input id="kilometers" type="text" class="mt-1 block w-full" v-model="form.kilometers" ref="kilometers" autocomplete="kilometers" />
<jet-input-error :message="form.errors.kilometers" class="mt-2" />
</div>
<div class="col-span-6 sm:col-span-4">
<jet-label for="colour" value="Farbe" />
<jet-input id="colour" type="text" class="mt-1 block w-full" v-model="form.colour" ref="colour" autocomplete="colour" />
<jet-input-error :message="form.errors.colour" class="mt-2" />
</div>
<div class="col-span-6 sm:col-span-4">
<jet-label for="known_damage" value="Bekannter Schaden" />
<textarea class="mt-1 block w-full border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded-md shadow-sm" v-model="form.known_damage" ref="input">
</textarea>
<jet-input-error :message="form.errors.known_damage" class="mt-2" />
</div>
<div class="col-span-6 sm:col-span-4">
<jet-label for="notes" value="Bemerkungen" />
<textarea class="mt-1 block w-full border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded-md shadow-sm" v-model="form.notes" ref="input">
</textarea>
<jet-input-error :message="form.errors.notes" class="mt-2" />
</div>
</template>
<template #actions>
<jet-action-message :on="form.recentlySuccessful" class="mr-3">
{{ meta.on_success }}
</jet-action-message>
<jet-button :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
{{ meta.button_text }}
</jet-button>
</template>
</jet-form-section>
</div>
</template>
<script>
import JetButton from '@/Jetstream/Button'
import JetLabel from '@/Jetstream/Label.vue'
import JetInput from '@/Jetstream/Input.vue'
import Modal from '@/Jetstream/Modal.vue'
import JetActionMessage from '@/Jetstream/ActionMessage'
import JetInputError from '@/Jetstream/InputError'
import JetFormSection from '@/Jetstream/FormSection'
export default {
components: {
JetButton,
JetFormSection,
JetLabel,
Modal,
JetInput,
JetInputError,
JetActionMessage,
},
props: {
form: Object,
meta: Object,
},
data() {
return {
}
},
methods: {
submitForm() {
this.form.post(route(this.meta.link, this.form.data()), {
preserveScroll: true,
});
},
},
}
</script>

View File

@ -0,0 +1,53 @@
<template>
<layout>
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
<bread-crumb text="Autos" :href="route('cars')" />
Neues Auto erfassen
</h2>
</template>
<div>
<car-form :form="form" :meta="meta">
<template #title>Neues Auto erfassen</template>
<template #description>...</template>
</car-form>
</div>
</layout>
</template>
<script>
import Layout from '@/Layouts/Layout'
import BreadCrumb from '@/Components/BreadCrumb.vue'
import CarForm from './Components/CarForm.vue'
export default {
components: {
Layout,
BreadCrumb,
CarForm,
},
data() {
return {
meta: {
link: 'cars.store',
button_text: 'Auto speichern',
on_success: 'Auto gespeichert',
},
form: this.$inertia.form({
_method: 'POST',
id: null,
stammnummer: null,
vin: null,
colour: null,
model_id: null,
initial_date: null,
last_check_date: null,
kilometers: null,
known_damage: null,
notes: null,
}),
}
},
}
</script>

View File

@ -0,0 +1,86 @@
<template>
<layout>
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
<bread-crumb text="Autos" :href="route('cars')" />
{{ car.name }}
</h2>
</template>
<div>
<div class="max-w-7xl py-10 sm:px-6 lg:px-8">
<contact-form :form="form" :meta="meta">
<template #title>Autoangaben</template>
<template #description>
Autodetails anschauen &amp; anpassen.
</template>
</contact-form>
</div>
</div>
</layout>
</template>
<script>
import Layout from '@/Layouts/Layout'
import BreadCrumb from '@/Components/BreadCrumb.vue'
import SimpleTable from '@/Components/SimpleTable.vue'
import CarForm from './Components/CarForm.vue'
export default {
components: {
BreadCrumb,
Layout,
SimpleTable,
CarForm,
},
props: {
car: Object,
},
computed: {
title: function () {
// if (this.form.company) {
// return this.form.company;
// }
// return this.form.lastname + ' ' + this.form.firstname;
},
computedCar: function () {
return {
// firstname: this.form.firstname,
// lastname: this.form.lastname,
// company: this.form.company,
// email: this.form.email,
// phone: this.form.phone,
// address: this.form.address,
// zip: this.form.zip,
// city: this.form.city,
// country: this.form.country,
}
}
},
data() {
return {
currentRoute: 'car.edit',
meta: {
link: 'cars.update',
button_text: 'Änderungen speichern',
on_success: 'Änderungen gespeichert',
},
form: this.$inertia.form({
_method: 'PUT',
id: this.car.id,
stammnummer: this.car.stammnummer,
vin: this.car.vin,
initial_date: this.car.initial_date,
colour: this.car.colour,
notes: this.car.notes,
model_id: this.car.model_id,
last_check_date: this.car.last_check_date,
kilometers: this.car.kilometers,
known_damage: this.car.known_damage,
notes: this.car.notes,
}),
}
},
}
</script>

View File

@ -2,44 +2,37 @@
<layout> <layout>
<template #header> <template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight"> <h2 class="font-semibold text-xl text-gray-800 leading-tight">
Autos <bread-crumb text="Autos" :href="route('cars')" />
Alle Autos
</h2> </h2>
</template> </template>
<div class="py-12"> <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"> <simple-table :title="cars.total + ' Autos'" :data="cars" :columns="columns" :defaultSort="sort" :filters="filters" :currentRoute="currentRoute" />
<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">
</div>
<simple-table :title="cars.total + ' Autos'" :data="cars" :columns="columns" :defaultSort="{ by: 'name', direction:'asc'}" />
</div> </div>
</div> </div>
</layout> </layout>
</template> </template>
<script> <script>
import { pickBy, throttle, mapValues } from 'lodash'
import Layout from '@/Layouts/Layout' import Layout from '@/Layouts/Layout'
import BreadCrumb from '@/Components/BreadCrumb.vue'
import SimpleTable from '@/Components/SimpleTable.vue' import SimpleTable from '@/Components/SimpleTable.vue'
import SearchFilter from '@/Components/SearchFilter'
import JetButton from '@/Jetstream/Button'
export default { export default {
components: { components: {
SearchFilter, BreadCrumb,
JetButton,
Layout, Layout,
SimpleTable, SimpleTable,
}, },
props: { props: {
filters: Object, filters: Object,
sort: Object,
cars: Object, cars: Object,
}, },
data() { data() {
return { return {
form: { currentRoute: 'cars',
search: this.filters.search,
trashed: this.filters.trashed,
},
columns: [ columns: [
{key: 'name', value: 'Name', sortable: true}, {key: 'name', value: 'Name', sortable: true},
{key: 'stammnummer', value: 'Stammummer', sortable: true}, {key: 'stammnummer', value: 'Stammummer', sortable: true},
@ -48,18 +41,5 @@ export default {
], ],
} }
}, },
watch: {
form: {
deep: true,
handler: throttle(function() {
this.$inertia.get(this.route('cars'), pickBy(this.form), { preserveState: false })
}, 300),
},
},
methods: {
reset() {
this.form = mapValues(this.form, () => null)
},
},
} }
</script> </script>

View File

@ -0,0 +1,45 @@
<template>
<layout>
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
<bread-crumb text="Autos" :href="route('cars')" />
Verkaufte Autos
</h2>
</template>
<div class="py-12">
<div class="w-full mx-auto sm:px-6 lg:px-8">
<simple-table :title="cars.total + ' Autos'" :data="cars" :columns="columns" :defaultSort="sort" :filters="filters" :currentRoute="currentRoute" />
</div>
</div>
</layout>
</template>
<script>
import Layout from '@/Layouts/Layout'
import BreadCrumb from '@/Components/BreadCrumb.vue'
import SimpleTable from '@/Components/SimpleTable.vue'
export default {
components: {
BreadCrumb,
Layout,
SimpleTable,
},
props: {
filters: Object,
sort: Object,
cars: Object,
},
data() {
return {
currentRoute: 'cars.sold',
columns: [
{key: 'name', value: 'Name', sortable: true},
{key: 'stammnummer', value: 'Stammummer', sortable: true},
{key: 'buy_price', value: 'Kaufpreis', sortable: true},
{key: 'initial_date', value: 'Inverkehrssetzung', sortable: true},
],
}
},
}
</script>

View File

@ -0,0 +1,45 @@
<template>
<layout>
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
<bread-crumb text="Autos" :href="route('cars')" />
Meine Autos
</h2>
</template>
<div class="py-12">
<div class="w-full mx-auto sm:px-6 lg:px-8">
<simple-table :title="cars.total + ' Autos'" :data="cars" :columns="columns" :defaultSort="sort" :filters="filters" :currentRoute="currentRoute" />
</div>
</div>
</layout>
</template>
<script>
import Layout from '@/Layouts/Layout'
import BreadCrumb from '@/Components/BreadCrumb.vue'
import SimpleTable from '@/Components/SimpleTable.vue'
export default {
components: {
BreadCrumb,
Layout,
SimpleTable,
},
props: {
filters: Object,
sort: Object,
cars: Object,
},
data() {
return {
currentRoute: 'cars.unsold',
columns: [
{key: 'name', value: 'Name', sortable: true},
{key: 'stammnummer', value: 'Stammummer', sortable: true},
{key: 'buy_price', value: 'Kaufpreis', sortable: true},
{key: 'initial_date', value: 'Inverkehrssetzung', sortable: true},
],
}
},
}
</script>

View File

@ -0,0 +1,47 @@
<template>
<layout>
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
<bread-crumb text="Kontakte" :href="route('contacts')" />
Käufer
</h2>
</template>
<div class="py-12">
<div class="w-full mx-auto sm:px-6 lg:px-8">
<simple-table :title="contacts.total + ' Käufer'" :data="contacts" :columns="columns" :defaultSort="sort" :filters="filters" :currentRoute="currentRoute" />
</div>
</div>
</layout>
</template>
<script>
import Layout from '@/Layouts/Layout'
import BreadCrumb from '@/Components/BreadCrumb.vue'
import SimpleTable from '@/Components/SimpleTable.vue'
export default {
components: {
BreadCrumb,
Layout,
SimpleTable,
},
props: {
filters: Object,
sort: Object,
contacts: Object,
},
data() {
return {
currentRoute: 'contacts.buyers',
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'},
],
}
},
}
</script>

View File

@ -95,8 +95,6 @@
<script> <script>
import JetButton from '@/Jetstream/Button' import JetButton from '@/Jetstream/Button'
import BreadCrumb from '@/Components/BreadCrumb.vue'
import SimpleTable from '@/Components/SimpleTable.vue'
import JetLabel from '@/Jetstream/Label.vue' import JetLabel from '@/Jetstream/Label.vue'
import JetInput from '@/Jetstream/Input.vue' import JetInput from '@/Jetstream/Input.vue'
import JetActionMessage from '@/Jetstream/ActionMessage' import JetActionMessage from '@/Jetstream/ActionMessage'
@ -107,8 +105,6 @@ export default {
components: { components: {
JetButton, JetButton,
JetFormSection, JetFormSection,
BreadCrumb,
SimpleTable,
JetLabel, JetLabel,
JetInput, JetInput,
JetInputError, JetInputError,
@ -116,30 +112,31 @@ export default {
}, },
props: { props: {
contact: Object, form: Object,
meta: Object, meta: Object,
}, },
data() {
computed: {
contact: function () {
return { return {
form: this.$inertia.form({ id: this.form.id,
_method: 'PUT', firstname: this.form.firstname,
firstname: this.contact.firstname, lastname: this.form.lastname,
lastname: this.contact.lastname, company: this.form.company,
company: this.contact.company, email: this.form.email,
email: this.contact.email, phone: this.form.phone,
phone: this.contact.phone, address: this.form.address,
address: this.contact.address, zip: this.form.zip,
zip: this.contact.zip, city: this.form.city,
city: this.contact.city, country: this.form.country,
country: this.contact.country, notes: this.form.notes,
notes: this.contact.notes,
}),
} }
}, },
},
methods: { methods: {
submitForm() { submitForm() {
this.form.post(route(this.meta.link, this.form), { this.form.post(route(this.meta.link, this.contact), {
preserveScroll: true, preserveScroll: true,
}); });
}, },

View File

@ -8,7 +8,7 @@
</template> </template>
<div> <div>
<contact-form :contact="form" :meta="meta"> <contact-form :form="form" :meta="meta">
<template #title>Neuen Kontakt erfassen</template> <template #title>Neuen Kontakt erfassen</template>
<template #description>Anschliessend können mit dem neuen Kontakt Verträge abgeschlossen werden.</template> <template #description>Anschliessend können mit dem neuen Kontakt Verträge abgeschlossen werden.</template>
</contact-form> </contact-form>
@ -27,9 +27,6 @@ export default {
BreadCrumb, BreadCrumb,
ContactForm, ContactForm,
}, },
props: {
},
data() { data() {
return { return {
meta: { meta: {
@ -38,7 +35,8 @@ export default {
on_success: 'Kontakt gespeichert', on_success: 'Kontakt gespeichert',
}, },
form: this.$inertia.form({ form: this.$inertia.form({
_method: 'PUT', _method: 'POST',
id: null,
firstname: null, firstname: null,
lastname: null, lastname: null,
company: null, company: null,

View File

@ -9,97 +9,13 @@
<div> <div>
<div class="max-w-7xl 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"> <contact-form :form="form" :meta="meta">
<template #title> <template #title>Kontaktinformationen</template>
Kontaktinformationen
</template>
<template #description> <template #description>
Kontaktinformationen anschauen &amp; anpassen. Kontaktinformationen anschauen &amp; anpassen.
<contact-card :contact="computedContact" /> <contact-card :contact="computedContact" />
</template> </template>
</contact-form>
<template #form>
<div class="col-span-6 sm:col-span-4">
<div class="grid grid-cols-6 gap-6">
<div class="col-span-6 sm:col-span-3">
<jet-label for="firstname" value="Vorname" />
<jet-input id="firstname" type="text" class="mt-1 block w-full" v-model="form.firstname" ref="firstname" autocomplete="firstname" />
<jet-input-error :message="form.errors.firstname" class="mt-2" />
</div>
<div class="col-span-6 sm:col-span-3">
<jet-label for="lastname" value="Nachname" />
<jet-input id="lastname" type="text" class="mt-1 block w-full" v-model="form.lastname" ref="lastname" autocomplete="lastname" />
<jet-input-error :message="form.errors.lastname" class="mt-2" />
</div>
</div>
</div>
<div class="col-span-6 sm:col-span-4">
<jet-label for="company" value="Firma" />
<jet-input id="company" type="text" class="mt-1 block w-full" v-model="form.company" ref="company" autocomplete="company" />
<jet-input-error :message="form.errors.company" class="mt-2" />
</div>
<div class="col-span-6 sm:col-span-4">
<jet-label for="address" value="Strasse" />
<jet-input id="address" type="text" class="mt-1 block w-full" v-model="form.address" ref="address" autocomplete="address" />
<jet-input-error :message="form.errors.address" class="mt-2" />
</div>
<div class="col-span-6 sm:col-span-4">
<div class="grid grid-cols-6 gap-6">
<div class="col-span-6 sm:col-span-2">
<jet-label for="zip" value="PLZ" />
<jet-input id="zip" type="text" class="mt-1 block w-full" v-model="form.zip" ref="zip" autocomplete="zip" />
<jet-input-error :message="form.errors.zip" class="mt-2" />
</div>
<div class="col-span-6 sm:col-span-3">
<jet-label for="city" value="Ort" />
<jet-input id="city" type="text" class="mt-1 block w-full" v-model="form.city" ref="city" autocomplete="city" />
<jet-input-error :message="form.errors.city" class="mt-2" />
</div>
<div class="col-span-6 sm:col-span-1">
<jet-label for="country" value="Land" />
<jet-input id="country" type="text" class="mt-1 block w-full" v-model="form.country" ref="country" autocomplete="country" />
<jet-input-error :message="form.errors.country" class="mt-2" />
</div>
</div>
</div>
<div class="col-span-6 sm:col-span-4">
<div class="grid grid-cols-6 gap-6">
<div class="col-span-6 sm:col-span-3">
<jet-label for="email" value="E-Mail" />
<jet-input id="email" type="email" class="mt-1 block w-full" v-model="form.email" ref="email" autocomplete="email" />
<jet-input-error :message="form.errors.email" class="mt-2" />
</div>
<div class="col-span-6 sm:col-span-3">
<jet-label for="phone" value="Telefon" />
<jet-input id="phone" type="text" class="mt-1 block w-full" v-model="form.phone" ref="phone" autocomplete="phone" />
<jet-input-error :message="form.errors.phone" class="mt-2" />
</div>
</div>
</div>
<div class="col-span-6 sm:col-span-4">
<jet-label for="notes" value="Bemerkungen" />
<textarea class="mt-1 block w-full border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded-md shadow-sm" v-model="form.notes" ref="input">
</textarea>
<jet-input-error :message="form.errors.notes" class="mt-2" />
</div>
</template>
<template #actions>
<jet-action-message :on="form.recentlySuccessful" class="mr-3">
Änderungen gespeichert.
</jet-action-message>
<jet-button :class="{ 'opacity-25': form.processing }" :disabled="form.processing">
Änderungen speichern
</jet-button>
</template>
</jet-form-section>
</div> </div>
</div> </div>
<div class="py-12"> <div class="py-12">
@ -115,27 +31,17 @@
<script> <script>
import Layout from '@/Layouts/Layout' import Layout from '@/Layouts/Layout'
import JetButton from '@/Jetstream/Button'
import BreadCrumb from '@/Components/BreadCrumb.vue' import BreadCrumb from '@/Components/BreadCrumb.vue'
import ContactCard from '@/Components/ContactCard.vue' import ContactCard from '@/Components/ContactCard.vue'
import SimpleTable from '@/Components/SimpleTable.vue' import SimpleTable from '@/Components/SimpleTable.vue'
import JetLabel from '@/Jetstream/Label.vue' import ContactForm from './Components/ContactForm.vue'
import JetInput from '@/Jetstream/Input.vue'
import JetActionMessage from '@/Jetstream/ActionMessage'
import JetInputError from '@/Jetstream/InputError'
import JetFormSection from '@/Jetstream/FormSection'
export default { export default {
components: { components: {
JetButton,
JetFormSection,
Layout, Layout,
BreadCrumb, BreadCrumb,
SimpleTable, SimpleTable,
JetLabel, ContactForm,
JetInput,
JetInputError,
JetActionMessage,
ContactCard, ContactCard,
}, },
@ -144,8 +50,14 @@ export default {
}, },
data() { data() {
return { return {
meta: {
link: 'contacts.update',
button_text: 'Änderungen speichern',
on_success: 'Änderungen gespeichert',
},
form: this.$inertia.form({ form: this.$inertia.form({
_method: 'PUT', _method: 'PUT',
id: this.contact.id,
firstname: this.contact.firstname, firstname: this.contact.firstname,
lastname: this.contact.lastname, lastname: this.contact.lastname,
company: this.contact.company, company: this.contact.company,
@ -192,13 +104,5 @@ export default {
} }
} }
}, },
methods: {
submitForm() {
this.form.post(route('contacts.update', this.contact), {
preserveScroll: true,
});
},
},
} }
</script> </script>

View File

@ -2,12 +2,13 @@
<layout> <layout>
<template #header> <template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight"> <h2 class="font-semibold text-xl text-gray-800 leading-tight">
Kontakte <bread-crumb text="Kontakte" :href="route('contacts')" />
Alle Kontakte
</h2> </h2>
</template> </template>
<div class="py-12"> <div class="py-12">
<div class="w-full mx-auto sm:px-6 lg:px-8"> <div class="w-full mx-auto sm:px-6 lg:px-8">
<simple-table :title="contacts.total + ' Kontakte'" :data="contacts" :columns="columns" :defaultSort="sort" :filters="filters" /> <simple-table :title="contacts.total + ' Kontakte'" :data="contacts" :columns="columns" :defaultSort="sort" :filters="filters" :currentRoute="currentRoute" />
</div> </div>
</div> </div>
</layout> </layout>
@ -15,14 +16,12 @@
<script> <script>
import Layout from '@/Layouts/Layout' import Layout from '@/Layouts/Layout'
import BreadCrumb from '@/Components/BreadCrumb.vue'
import SimpleTable from '@/Components/SimpleTable.vue' import SimpleTable from '@/Components/SimpleTable.vue'
import SearchFilter from '@/Components/SearchFilter'
import JetButton from '@/Jetstream/Button'
export default { export default {
components: { components: {
SearchFilter, BreadCrumb,
JetButton,
Layout, Layout,
SimpleTable, SimpleTable,
}, },
@ -33,6 +32,7 @@ export default {
}, },
data() { data() {
return { return {
currentRoute: 'contacts',
columns: [ columns: [
{key: 'name', value: 'Name', sortable: true}, {key: 'name', value: 'Name', sortable: true},
{key: 'company', value: 'Firma', sortable: true}, {key: 'company', value: 'Firma', sortable: true},

View File

@ -0,0 +1,47 @@
<template>
<layout>
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
<bread-crumb text="Kontakte" :href="route('contacts')" />
Käufer
</h2>
</template>
<div class="py-12">
<div class="w-full mx-auto sm:px-6 lg:px-8">
<simple-table :title="contacts.total + ' Verkäufer'" :data="contacts" :columns="columns" :defaultSort="sort" :filters="filters" :currentRoute="currentRoute" />
</div>
</div>
</layout>
</template>
<script>
import Layout from '@/Layouts/Layout'
import BreadCrumb from '@/Components/BreadCrumb.vue'
import SimpleTable from '@/Components/SimpleTable.vue'
export default {
components: {
BreadCrumb,
Layout,
SimpleTable,
},
props: {
filters: Object,
sort: Object,
contacts: Object,
},
data() {
return {
currentRoute: 'contacts.sellers',
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'},
],
}
},
}
</script>

View File

@ -34,11 +34,11 @@ Route::get('contacts', [ContactController::class, 'index'])
->name('contacts') ->name('contacts')
->middleware(['auth:sanctum', 'verified']); ->middleware(['auth:sanctum', 'verified']);
Route::get('contacts/buyers', [ContactController::class, 'index']) Route::get('contacts/buyers', [ContactController::class, 'buyers'])
->name('contacts.buyers') ->name('contacts.buyers')
->middleware(['auth:sanctum', 'verified']); ->middleware(['auth:sanctum', 'verified']);
Route::get('contacts/sellers', [ContactController::class, 'index']) Route::get('contacts/sellers', [ContactController::class, 'sellers'])
->name('contacts.sellers') ->name('contacts.sellers')
->middleware(['auth:sanctum', 'verified']); ->middleware(['auth:sanctum', 'verified']);
@ -70,22 +70,26 @@ Route::get('cars', [CarController::class, 'index'])
->name('cars') ->name('cars')
->middleware(['auth:sanctum', 'verified']); ->middleware(['auth:sanctum', 'verified']);
Route::get('cars/unsold', [CarController::class, 'index']) Route::get('cars/unsold', [CarController::class, 'unsold'])
->name('cars.unsold') ->name('cars.unsold')
->middleware(['auth:sanctum', 'verified']); ->middleware(['auth:sanctum', 'verified']);
Route::get('cars/sold', [CarController::class, 'index']) Route::get('cars/sold', [CarController::class, 'sold'])
->name('cars.sold') ->name('cars.sold')
->middleware(['auth:sanctum', 'verified']); ->middleware(['auth:sanctum', 'verified']);
Route::get('cars/create', [ContactController::class, 'create']) Route::get('cars/create', [CarController::class, 'create'])
->name('cars.create') ->name('cars.create')
->middleware(['auth:sanctum', 'verified']); ->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']) Route::get('cars/{car}', [CarController::class, 'edit'])
->name('cars.edit') ->name('cars.edit')
->middleware(['auth:sanctum', 'verified']); ->middleware(['auth:sanctum', 'verified']);
Route::put('cars/{car}', [CarController::class, 'update'])
->name('cars.update')
->middleware(['auth:sanctum', 'verified']);
Route::post('cars', [CarController::class, 'store'])
->name('cars.store')
->middleware(['auth:sanctum', 'verified']);