update car create form
parent
417760182e
commit
5ef66366ca
|
|
@ -4,6 +4,7 @@ namespace App\Http\Controllers;
|
|||
|
||||
use App\Models\Brand;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Redirect;
|
||||
|
||||
class BrandController extends Controller
|
||||
{
|
||||
|
|
@ -31,11 +32,16 @@ class BrandController extends Controller
|
|||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
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 Inertia\Inertia;
|
||||
use App\Models\Brand;
|
||||
use App\Enums\InsuranceType;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
|
@ -97,7 +98,21 @@ class CarController extends Controller
|
|||
*/
|
||||
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(
|
||||
$request->validate([
|
||||
'stammnummer' => ['unique', 'max:11'],
|
||||
'vin' => ['max:17'],
|
||||
'stammnummer' => ['required', 'unique:cars', 'string', 'size:11', 'regex:/[0-9]{3}[.][0-9]{3}[.][0-9]{3}/i'],
|
||||
'vin' => ['required', 'unique:cars', 'string', 'size:17'],
|
||||
'initial_date' => ['nullable', 'date'],
|
||||
'last_check_date' => ['nullable', 'date'],
|
||||
'colour' => ['nullable', 'max:75'],
|
||||
// 'model_id' => ['nullable', 'max:150'],
|
||||
'car_model_id' => ['required', 'exists:App\Models\CarModel,id'],
|
||||
'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,
|
||||
'stammnummer' => $car->stammnummer,
|
||||
'vin' => $car->vin,
|
||||
'car_model' => $car->carModel->only('name'),
|
||||
'car_model' => $car->carModel,
|
||||
'brand' => $car->brand,
|
||||
'name' => $car->name,
|
||||
'initial_date' => $car->initial_date,
|
||||
'colour' => $car->colour,
|
||||
|
|
|
|||
|
|
@ -35,7 +35,14 @@ class CarModelController extends Controller
|
|||
*/
|
||||
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;
|
||||
|
||||
protected $fillable = [
|
||||
'car_model',
|
||||
'name',
|
||||
'brand_id',
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
"packages": {
|
||||
"": {
|
||||
"dependencies": {
|
||||
"vue-multiselect": "^3.0.0-alpha.2",
|
||||
"vue-unicons": "^3.2.1",
|
||||
"vuex": "^4.0.0"
|
||||
},
|
||||
|
|
@ -15389,6 +15390,15 @@
|
|||
"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": {
|
||||
"version": "4.1.3",
|
||||
"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": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz",
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
"vue-loader": "^16.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"vue-multiselect": "^3.0.0-alpha.2",
|
||||
"vue-unicons": "^3.2.1",
|
||||
"vuex": "^4.0.0"
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -11,10 +11,29 @@
|
|||
|
||||
<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" />
|
||||
<jet-label for="brand" value="Marke" />
|
||||
<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">
|
||||
<template v-slot:noResult>
|
||||
<span @click="addBrand">
|
||||
<b>{{ brandSearch }}</b> als neue Marke speichern?
|
||||
</span>
|
||||
</template>
|
||||
</multiselect>
|
||||
</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="grid grid-cols-12 gap-6">
|
||||
<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 JetInputError from '@/Jetstream/InputError'
|
||||
import JetFormSection from '@/Jetstream/FormSection'
|
||||
import Multiselect from 'vue-multiselect'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
|
@ -104,23 +124,60 @@ export default {
|
|||
JetInput,
|
||||
JetInputError,
|
||||
JetActionMessage,
|
||||
Multiselect,
|
||||
},
|
||||
|
||||
props: {
|
||||
form: Object,
|
||||
brands: Array,
|
||||
meta: Object,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
brand: this.form.brand,
|
||||
brandSearch: null,
|
||||
modelSearch: null,
|
||||
carModels: [],
|
||||
model: this.form.model,
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
submitForm() {
|
||||
this.form.post(route(this.meta.link, this.form.data()), {
|
||||
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>
|
||||
|
||||
<div>
|
||||
<car-form :form="form" :meta="meta">
|
||||
<car-form :form="form" :meta="meta" :brands="brands">
|
||||
<template #title>Neues Auto erfassen</template>
|
||||
<template #description>...</template>
|
||||
</car-form>
|
||||
|
|
@ -27,6 +27,9 @@ export default {
|
|||
BreadCrumb,
|
||||
CarForm,
|
||||
},
|
||||
props: {
|
||||
brands: Array,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
meta: {
|
||||
|
|
|
|||
|
|
@ -8,15 +8,13 @@
|
|||
</template>
|
||||
|
||||
<div>
|
||||
<div class="max-w-7xl py-10 sm:px-6 lg:px-8">
|
||||
<contact-form :form="form" :meta="meta">
|
||||
<template #title>Kontaktinformationen</template>
|
||||
<template #description>
|
||||
Kontaktinformationen anschauen & anpassen.
|
||||
<contact-card :contact="computedContact" />
|
||||
</template>
|
||||
</contact-form>
|
||||
</div>
|
||||
<contact-form :form="form" :meta="meta">
|
||||
<template #title>Kontaktinformationen</template>
|
||||
<template #description>
|
||||
Kontaktinformationen anschauen & anpassen.
|
||||
<contact-card :contact="computedContact" />
|
||||
</template>
|
||||
</contact-form>
|
||||
</div>
|
||||
<div class="py-12">
|
||||
<div class="max-w-7xl sm:px-6 lg:px-8">
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
use Illuminate\Foundation\Application;
|
||||
use App\Http\Controllers\ContactController;
|
||||
use App\Http\Controllers\CarController;
|
||||
use App\Http\Controllers\BrandController;
|
||||
use App\Http\Controllers\CarModelController;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Inertia\Inertia;
|
||||
|
||||
|
|
@ -92,4 +94,12 @@ Route::put('cars/{car}', [CarController::class, 'update'])
|
|||
|
||||
Route::post('cars', [CarController::class, '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']);
|
||||
Loading…
Reference in New Issue