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;
use App\Models\Car;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Validation\Rule;
use Inertia\Inertia;
use App\Enums\InsuranceType;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Redirect;
class CarController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
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);
$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'),
'sort' => [
'by' => $sortBy,
'direction' => $direction,
],
'cars' => $cars->filter($request->only('search', 'trashed'))
->orderByInitialDate()
->paginate(50)
->withQueryString()
->through(function ($car) {
return [
->through(fn ($car) => [
'id' => $car->id,
'stammnummer' => $car->stammnummer,
'vin' => $car->vin,
@ -44,21 +52,21 @@ class CarController extends Controller
'name' => $car->name,
'initial_date' => $car->initial_date,
'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) {
case 'initial_date':
return Car::orderBy('initial_date', $direction);
return $cars->orderBy('initial_date', $direction);
case 'stammnummer':
return Car::orderBy('stammnummer', $direction);
return $cars->orderBy('stammnummer', $direction);
default:
//return Car::orderByName($direction);
return Car::orderBy('initial_date', $direction);
//return $cars->orderByName($direction);
return $cars->orderBy('initial_date', $direction);
}
}
@ -100,18 +108,20 @@ class CarController extends Controller
*/
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)
{
//
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)
{
//
$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)
{
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);
$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'),
'sort' => [
'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) {
case 'company':
return Contact::orderBy('company', $direction);
return $contacts->orderBy('company', $direction);
case 'fullCity':
return Contact::orderBy('city', $direction);
return $contacts->orderBy('city', $direction);
case 'email':
return Contact::orderBy('email', $direction);
return $contacts->orderBy('email', $direction);
case 'address':
return Contact::orderBy('address', $direction);
return $contacts->orderBy('address', $direction);
default:
return Contact::orderByName($direction);
return $contacts->orderByName($direction);
}
}
@ -100,12 +114,12 @@ class ContactController extends Controller
*/
public function store(Request $request)
{
Contact::create(
$contact = Contact::create(
$request->validate([
'firstname' => ['max:75'],
'lastname' => ['max:75'],
'email' => ['nullable', 'max:75', 'email'],
'phone' => ['max:75'],
'phone' => ['required', 'max:75'],
'address' => ['nullable', 'max:150'],
'zip' => ['nullable', 'max:6'],
'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()
{
return $this->hasMany(buyContract::class);
return $this->hasMany(BuyContract::class);
}
public function sellContracts()
{
return $this->hasMany(sellContract::class);
return $this->hasMany(SellContract::class);
}
public function carPayment()
@ -106,21 +106,21 @@ class Car extends Model
// 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)
{
$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)
{
$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,
columns: Array,
title: String,
currentRoute: String,
defaultSort: Object,
filters: Object,
},
@ -102,7 +103,9 @@ export default {
this.form = mapValues(this.form, () => null)
},
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) {
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>
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
Autos
<bread-crumb text="Autos" :href="route('cars')" />
Alle Autos
</h2>
</template>
<div class="py-12">
<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">
</div>
<simple-table :title="cars.total + ' Autos'" :data="cars" :columns="columns" :defaultSort="{ by: 'name', direction:'asc'}" />
<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 { pickBy, throttle, mapValues } from 'lodash'
import Layout from '@/Layouts/Layout'
import BreadCrumb from '@/Components/BreadCrumb.vue'
import SimpleTable from '@/Components/SimpleTable.vue'
import SearchFilter from '@/Components/SearchFilter'
import JetButton from '@/Jetstream/Button'
export default {
components: {
SearchFilter,
JetButton,
BreadCrumb,
Layout,
SimpleTable,
},
props: {
filters: Object,
sort: Object,
cars: Object,
},
data() {
return {
form: {
search: this.filters.search,
trashed: this.filters.trashed,
},
currentRoute: 'cars',
columns: [
{key: 'name', value: 'Name', 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>

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

View File

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

View File

@ -9,97 +9,13 @@
<div>
<div class="max-w-7xl py-10 sm:px-6 lg:px-8">
<jet-form-section @submitted="submitForm">
<template #title>
Kontaktinformationen
</template>
<contact-form :form="form" :meta="meta">
<template #title>Kontaktinformationen</template>
<template #description>
Kontaktinformationen anschauen &amp; anpassen.
<contact-card :contact="computedContact" />
</template>
<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>
</contact-form>
</div>
</div>
<div class="py-12">
@ -115,27 +31,17 @@
<script>
import Layout from '@/Layouts/Layout'
import JetButton from '@/Jetstream/Button'
import BreadCrumb from '@/Components/BreadCrumb.vue'
import ContactCard from '@/Components/ContactCard.vue'
import SimpleTable from '@/Components/SimpleTable.vue'
import JetLabel from '@/Jetstream/Label.vue'
import JetInput from '@/Jetstream/Input.vue'
import JetActionMessage from '@/Jetstream/ActionMessage'
import JetInputError from '@/Jetstream/InputError'
import JetFormSection from '@/Jetstream/FormSection'
import ContactForm from './Components/ContactForm.vue'
export default {
components: {
JetButton,
JetFormSection,
Layout,
BreadCrumb,
SimpleTable,
JetLabel,
JetInput,
JetInputError,
JetActionMessage,
ContactForm,
ContactCard,
},
@ -144,8 +50,14 @@ export default {
},
data() {
return {
meta: {
link: 'contacts.update',
button_text: 'Änderungen speichern',
on_success: 'Änderungen gespeichert',
},
form: this.$inertia.form({
_method: 'PUT',
id: this.contact.id,
firstname: this.contact.firstname,
lastname: this.contact.lastname,
company: this.contact.company,
@ -192,13 +104,5 @@ export default {
}
}
},
methods: {
submitForm() {
this.form.post(route('contacts.update', this.contact), {
preserveScroll: true,
});
},
},
}
</script>

View File

@ -2,12 +2,13 @@
<layout>
<template #header>
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
Kontakte
<bread-crumb text="Kontakte" :href="route('contacts')" />
Alle Kontakte
</h2>
</template>
<div class="py-12">
<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>
</layout>
@ -15,14 +16,12 @@
<script>
import Layout from '@/Layouts/Layout'
import BreadCrumb from '@/Components/BreadCrumb.vue'
import SimpleTable from '@/Components/SimpleTable.vue'
import SearchFilter from '@/Components/SearchFilter'
import JetButton from '@/Jetstream/Button'
export default {
components: {
SearchFilter,
JetButton,
BreadCrumb,
Layout,
SimpleTable,
},
@ -33,6 +32,7 @@ export default {
},
data() {
return {
currentRoute: 'contacts',
columns: [
{key: 'name', value: 'Name', 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')
->middleware(['auth:sanctum', 'verified']);
Route::get('contacts/buyers', [ContactController::class, 'index'])
Route::get('contacts/buyers', [ContactController::class, 'buyers'])
->name('contacts.buyers')
->middleware(['auth:sanctum', 'verified']);
Route::get('contacts/sellers', [ContactController::class, 'index'])
Route::get('contacts/sellers', [ContactController::class, 'sellers'])
->name('contacts.sellers')
->middleware(['auth:sanctum', 'verified']);
@ -70,22 +70,26 @@ Route::get('cars', [CarController::class, 'index'])
->name('cars')
->middleware(['auth:sanctum', 'verified']);
Route::get('cars/unsold', [CarController::class, 'index'])
Route::get('cars/unsold', [CarController::class, 'unsold'])
->name('cars.unsold')
->middleware(['auth:sanctum', 'verified']);
Route::get('cars/sold', [CarController::class, 'index'])
Route::get('cars/sold', [CarController::class, 'sold'])
->name('cars.sold')
->middleware(['auth:sanctum', 'verified']);
Route::get('cars/create', [ContactController::class, 'create'])
Route::get('cars/create', [CarController::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']);
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']);