update car create form

shift-build-2464
Nadim Salloum 2021-05-18 16:31:32 +02:00
parent 417760182e
commit 5ef66366ca
11 changed files with 2073 additions and 90 deletions

View File

@ -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;
}
/**

View File

@ -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,

View File

@ -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;
}
/**

View File

@ -10,7 +10,7 @@ class CarModel extends Model
use HasFactory;
protected $fillable = [
'car_model',
'name',
'brand_id',
];

15
package-lock.json generated
View File

@ -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",

View File

@ -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"
}

1998
public/js/app.js vendored

File diff suppressed because one or more lines are too long

View File

@ -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>

View File

@ -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: {

View File

@ -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 &amp; anpassen.
<contact-card :contact="computedContact" />
</template>
</contact-form>
</div>
<contact-form :form="form" :meta="meta">
<template #title>Kontaktinformationen</template>
<template #description>
Kontaktinformationen anschauen &amp; anpassen.
<contact-card :contact="computedContact" />
</template>
</contact-form>
</div>
<div class="py-12">
<div class="max-w-7xl sm:px-6 lg:px-8">

View File

@ -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']);