update car create form
parent
417760182e
commit
5ef66366ca
|
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\Brand;
|
use App\Models\Brand;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Redirect;
|
||||||
|
|
||||||
class BrandController extends Controller
|
class BrandController extends Controller
|
||||||
{
|
{
|
||||||
|
|
@ -31,11 +32,16 @@ class BrandController extends Controller
|
||||||
* Store a newly created resource in storage.
|
* Store a newly created resource in storage.
|
||||||
*
|
*
|
||||||
* @param \Illuminate\Http\Request $request
|
* @param \Illuminate\Http\Request $request
|
||||||
* @return \Illuminate\Http\Response
|
|
||||||
*/
|
*/
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
//
|
$brand = Brand::create(
|
||||||
|
$request->validate([
|
||||||
|
'name' => ['required', 'string', 'max:255'],
|
||||||
|
])
|
||||||
|
)->only('id', 'name');
|
||||||
|
|
||||||
|
return $brand;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
||||||
|
|
||||||
use App\Models\Car;
|
use App\Models\Car;
|
||||||
use Inertia\Inertia;
|
use Inertia\Inertia;
|
||||||
|
use App\Models\Brand;
|
||||||
use App\Enums\InsuranceType;
|
use App\Enums\InsuranceType;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Validation\Rule;
|
use Illuminate\Validation\Rule;
|
||||||
|
|
@ -97,7 +98,21 @@ class CarController extends Controller
|
||||||
*/
|
*/
|
||||||
public function create()
|
public function create()
|
||||||
{
|
{
|
||||||
return Inertia::render('Cars/Create');
|
return Inertia::render('Cars/Create', [
|
||||||
|
'brands' => Brand::all()->map(function ($brand) {
|
||||||
|
return [
|
||||||
|
'id' => $brand->id,
|
||||||
|
'name' => $brand->name,
|
||||||
|
'models' => $brand->carModels()->get()
|
||||||
|
->map(function ($carModel) {
|
||||||
|
return [
|
||||||
|
'id' => $carModel->id,
|
||||||
|
'name' => $carModel->name,
|
||||||
|
];
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
}),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -110,17 +125,17 @@ class CarController extends Controller
|
||||||
{
|
{
|
||||||
$car = Car::create(
|
$car = Car::create(
|
||||||
$request->validate([
|
$request->validate([
|
||||||
'stammnummer' => ['unique', 'max:11'],
|
'stammnummer' => ['required', 'unique:cars', 'string', 'size:11', 'regex:/[0-9]{3}[.][0-9]{3}[.][0-9]{3}/i'],
|
||||||
'vin' => ['max:17'],
|
'vin' => ['required', 'unique:cars', 'string', 'size:17'],
|
||||||
'initial_date' => ['nullable', 'date'],
|
'initial_date' => ['nullable', 'date'],
|
||||||
'last_check_date' => ['nullable', 'date'],
|
'last_check_date' => ['nullable', 'date'],
|
||||||
'colour' => ['nullable', 'max:75'],
|
'colour' => ['nullable', 'max:75'],
|
||||||
// 'model_id' => ['nullable', 'max:150'],
|
'car_model_id' => ['required', 'exists:App\Models\CarModel,id'],
|
||||||
'kilometers' => ['nullable', 'max:75'],
|
'kilometers' => ['nullable', 'max:75'],
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
|
||||||
return Redirect::route('cars.edit', $car)->with('success', 'Kontakt erstellt.');
|
return Redirect::route('cars.edit', $car);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -137,7 +152,8 @@ class CarController extends Controller
|
||||||
'id' => $car->id,
|
'id' => $car->id,
|
||||||
'stammnummer' => $car->stammnummer,
|
'stammnummer' => $car->stammnummer,
|
||||||
'vin' => $car->vin,
|
'vin' => $car->vin,
|
||||||
'car_model' => $car->carModel->only('name'),
|
'car_model' => $car->carModel,
|
||||||
|
'brand' => $car->brand,
|
||||||
'name' => $car->name,
|
'name' => $car->name,
|
||||||
'initial_date' => $car->initial_date,
|
'initial_date' => $car->initial_date,
|
||||||
'colour' => $car->colour,
|
'colour' => $car->colour,
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,14 @@ class CarModelController extends Controller
|
||||||
*/
|
*/
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
//
|
$model = CarModel::create(
|
||||||
|
$request->validate([
|
||||||
|
'name' => ['required', 'string', 'max:255'],
|
||||||
|
'brand_id' => ['required', 'exists:App\Models\Brand,id'],
|
||||||
|
])
|
||||||
|
)->only('id', 'name');
|
||||||
|
|
||||||
|
return $model;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ class CarModel extends Model
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'car_model',
|
'name',
|
||||||
'brand_id',
|
'brand_id',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"vue-multiselect": "^3.0.0-alpha.2",
|
||||||
"vue-unicons": "^3.2.1",
|
"vue-unicons": "^3.2.1",
|
||||||
"vuex": "^4.0.0"
|
"vuex": "^4.0.0"
|
||||||
},
|
},
|
||||||
|
|
@ -15389,6 +15390,15 @@
|
||||||
"node": ">=8.9.0"
|
"node": ">=8.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vue-multiselect": {
|
||||||
|
"version": "3.0.0-alpha.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-multiselect/-/vue-multiselect-3.0.0-alpha.2.tgz",
|
||||||
|
"integrity": "sha512-Xp9fGJECns45v+v8jXbCIsAkCybYkEg0lNwr7Z6HDUSMyx2TEIK2giipPE+qXiShEc1Ipn+ZtttH2iq9hwXP4Q==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 4.0.0",
|
||||||
|
"npm": ">= 3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/vue-style-loader": {
|
"node_modules/vue-style-loader": {
|
||||||
"version": "4.1.3",
|
"version": "4.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz",
|
||||||
|
|
@ -28323,6 +28333,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"vue-multiselect": {
|
||||||
|
"version": "3.0.0-alpha.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-multiselect/-/vue-multiselect-3.0.0-alpha.2.tgz",
|
||||||
|
"integrity": "sha512-Xp9fGJECns45v+v8jXbCIsAkCybYkEg0lNwr7Z6HDUSMyx2TEIK2giipPE+qXiShEc1Ipn+ZtttH2iq9hwXP4Q=="
|
||||||
|
},
|
||||||
"vue-style-loader": {
|
"vue-style-loader": {
|
||||||
"version": "4.1.3",
|
"version": "4.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz",
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
"vue-loader": "^16.1.2"
|
"vue-loader": "^16.1.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"vue-multiselect": "^3.0.0-alpha.2",
|
||||||
"vue-unicons": "^3.2.1",
|
"vue-unicons": "^3.2.1",
|
||||||
"vuex": "^4.0.0"
|
"vuex": "^4.0.0"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -11,10 +11,29 @@
|
||||||
|
|
||||||
<template #form>
|
<template #form>
|
||||||
<div class="col-span-6 sm:col-span-4">
|
<div class="col-span-6 sm:col-span-4">
|
||||||
<jet-label for="car_model_id" value="Modell" />
|
<jet-label for="brand" value="Marke" />
|
||||||
<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" />
|
<multiselect v-model="brand" @SearchChange="updateBrandSearch" @select="updateCarModelsList" label="name" track-by="id" :options="brands" class="mt-1 block w-full" placeholder="Marke auswählen">
|
||||||
<jet-input-error :message="form.errors.car_model_id" class="mt-2" />
|
<template v-slot:noResult>
|
||||||
|
<span @click="addBrand">
|
||||||
|
<b>{{ brandSearch }}</b> als neue Marke speichern?
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</multiselect>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div v-if="brand" class="col-span-6 sm:col-span-4">
|
||||||
|
<jet-label for="model" value="Modell" />
|
||||||
|
<multiselect label="name" track-by="id" v-model="model" @SearchChange="updateCarModelSearch" :options="carModels" class="mt-1 block w-full" placeholder="Modell auswählen">
|
||||||
|
<template v-slot:noResult>
|
||||||
|
<span @click="addCarModel">
|
||||||
|
<b>{{ modelSearch }}</b> als neues {{ brand.name }}-Modell speichern?
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</multiselect>
|
||||||
|
<jet-input-error :message="form.errors.model" class="mt-2" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="col-span-6 sm:col-span-4">
|
<div class="col-span-6 sm:col-span-4">
|
||||||
<div class="grid grid-cols-12 gap-6">
|
<div class="grid grid-cols-12 gap-6">
|
||||||
<div class="col-span-12 sm:col-span-5">
|
<div class="col-span-12 sm:col-span-5">
|
||||||
|
|
@ -94,6 +113,7 @@ import Modal from '@/Jetstream/Modal.vue'
|
||||||
import JetActionMessage from '@/Jetstream/ActionMessage'
|
import JetActionMessage from '@/Jetstream/ActionMessage'
|
||||||
import JetInputError from '@/Jetstream/InputError'
|
import JetInputError from '@/Jetstream/InputError'
|
||||||
import JetFormSection from '@/Jetstream/FormSection'
|
import JetFormSection from '@/Jetstream/FormSection'
|
||||||
|
import Multiselect from 'vue-multiselect'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -104,23 +124,60 @@ export default {
|
||||||
JetInput,
|
JetInput,
|
||||||
JetInputError,
|
JetInputError,
|
||||||
JetActionMessage,
|
JetActionMessage,
|
||||||
|
Multiselect,
|
||||||
},
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
form: Object,
|
form: Object,
|
||||||
|
brands: Array,
|
||||||
meta: Object,
|
meta: Object,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
brand: this.form.brand,
|
||||||
|
brandSearch: null,
|
||||||
|
modelSearch: null,
|
||||||
|
carModels: [],
|
||||||
|
model: this.form.model,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
submitForm() {
|
submitForm() {
|
||||||
this.form.post(route(this.meta.link, this.form.data()), {
|
this.form.post(route(this.meta.link, this.form.data()), {
|
||||||
preserveScroll: true,
|
preserveScroll: true,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
updateCarModelsList(brand) {
|
||||||
|
this.carModels = brand.models ?? [];
|
||||||
|
this.model = null;
|
||||||
|
},
|
||||||
|
updateBrandSearch(searchQuery, id) {
|
||||||
|
this.brandSearch = searchQuery
|
||||||
|
},
|
||||||
|
addBrand() {
|
||||||
|
axios.post(this.route('brands.store'), {
|
||||||
|
name: this.brandSearch,
|
||||||
|
}).then((response) => {
|
||||||
|
let newBrand = response.data;
|
||||||
|
this.brands.push(newBrand);
|
||||||
|
this.brand = newBrand;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updateCarModelSearch(searchQuery, id) {
|
||||||
|
this.modelSearch = searchQuery
|
||||||
|
},
|
||||||
|
addCarModel() {
|
||||||
|
axios.post(this.route('models.store'), {
|
||||||
|
name: this.modelSearch,
|
||||||
|
brand_id: this.brand.id,
|
||||||
|
}).then((response) => {
|
||||||
|
let newModel = response.data;
|
||||||
|
this.carModels.push(newModel);
|
||||||
|
this.model = newModel;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
<style src="vue-multiselect/dist/vue-multiselect.css"></style>
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<car-form :form="form" :meta="meta">
|
<car-form :form="form" :meta="meta" :brands="brands">
|
||||||
<template #title>Neues Auto erfassen</template>
|
<template #title>Neues Auto erfassen</template>
|
||||||
<template #description>...</template>
|
<template #description>...</template>
|
||||||
</car-form>
|
</car-form>
|
||||||
|
|
@ -27,6 +27,9 @@ export default {
|
||||||
BreadCrumb,
|
BreadCrumb,
|
||||||
CarForm,
|
CarForm,
|
||||||
},
|
},
|
||||||
|
props: {
|
||||||
|
brands: Array,
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
meta: {
|
meta: {
|
||||||
|
|
|
||||||
|
|
@ -8,15 +8,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<div class="max-w-7xl py-10 sm:px-6 lg:px-8">
|
<contact-form :form="form" :meta="meta">
|
||||||
<contact-form :form="form" :meta="meta">
|
<template #title>Kontaktinformationen</template>
|
||||||
<template #title>Kontaktinformationen</template>
|
<template #description>
|
||||||
<template #description>
|
Kontaktinformationen anschauen & anpassen.
|
||||||
Kontaktinformationen anschauen & anpassen.
|
<contact-card :contact="computedContact" />
|
||||||
<contact-card :contact="computedContact" />
|
</template>
|
||||||
</template>
|
</contact-form>
|
||||||
</contact-form>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="py-12">
|
<div class="py-12">
|
||||||
<div class="max-w-7xl sm:px-6 lg:px-8">
|
<div class="max-w-7xl sm:px-6 lg:px-8">
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@
|
||||||
use Illuminate\Foundation\Application;
|
use Illuminate\Foundation\Application;
|
||||||
use App\Http\Controllers\ContactController;
|
use App\Http\Controllers\ContactController;
|
||||||
use App\Http\Controllers\CarController;
|
use App\Http\Controllers\CarController;
|
||||||
|
use App\Http\Controllers\BrandController;
|
||||||
|
use App\Http\Controllers\CarModelController;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
use Inertia\Inertia;
|
use Inertia\Inertia;
|
||||||
|
|
||||||
|
|
@ -92,4 +94,12 @@ Route::put('cars/{car}', [CarController::class, 'update'])
|
||||||
|
|
||||||
Route::post('cars', [CarController::class, 'store'])
|
Route::post('cars', [CarController::class, 'store'])
|
||||||
->name('cars.store')
|
->name('cars.store')
|
||||||
|
->middleware(['auth:sanctum', 'verified']);
|
||||||
|
|
||||||
|
Route::post('brands', [BrandController::class, 'store'])
|
||||||
|
->name('brands.store')
|
||||||
|
->middleware(['auth:sanctum', 'verified']);
|
||||||
|
|
||||||
|
Route::post('models', [CarModelController::class, 'store'])
|
||||||
|
->name('models.store')
|
||||||
->middleware(['auth:sanctum', 'verified']);
|
->middleware(['auth:sanctum', 'verified']);
|
||||||
Loading…
Reference in New Issue