From 1e6fa0183046ab7c775cbdd0661fb3b86008fc0e Mon Sep 17 00:00:00 2001 From: aleksandar kocev <aleks15kocev@gmail.com> Date: Sat, 17 Feb 2024 16:15:30 +0100 Subject: [PATCH 1/3] working on edit product --- .../Controllers/Admin/ProductController.php | 29 +---- AdminPanel-Marinov/resources/js/app.js | 6 +- .../views/products/edit-product.blade.php | 107 ++++++++++++++++++ AdminPanel-Marinov/routes/api.php | 10 +- AdminPanel-Marinov/routes/web.php | 3 +- 5 files changed, 124 insertions(+), 31 deletions(-) create mode 100644 AdminPanel-Marinov/resources/views/products/edit-product.blade.php diff --git a/AdminPanel-Marinov/app/Http/Controllers/Admin/ProductController.php b/AdminPanel-Marinov/app/Http/Controllers/Admin/ProductController.php index 30ace2f..4db4a55 100644 --- a/AdminPanel-Marinov/app/Http/Controllers/Admin/ProductController.php +++ b/AdminPanel-Marinov/app/Http/Controllers/Admin/ProductController.php @@ -13,8 +13,6 @@ class ProductController extends Controller { - - public function index() { $product = Product::all(); @@ -59,29 +57,12 @@ class ProductController extends Controller return 'success'; } - public function updateProduct(Request $request, $id) - { + public function edit(string $id){ + $categories = Category::all(); + $materials = Material::all(); + $maintenances = Maintenance::all(); $product = Product::findOrFail($id); - - $validated = $request->validate([ - 'title' => 'sometimes|string|max:255', - 'description' => 'sometimes|string', - 'price' => 'sometimes|numeric', - 'quantity' => 'sometimes|integer', - 'category_id' => 'sometimes|integer|exists:categories,id', - 'type_id' => 'sometimes|integer|exists:types,id', - 'discount' => 'sometimes|numeric|min:0|max:100', - 'is_featured' => 'sometimes|boolean', - 'weight' => 'sometimes|numeric', - 'dimensions' => 'sometimes|string', - 'date' => 'sometimes|date', - ]); - - - $product->update($validated); - - - return response()->json($product, 200); + return view('products.edit-product', compact('product','categories', 'materials','maintenances')); } diff --git a/AdminPanel-Marinov/resources/js/app.js b/AdminPanel-Marinov/resources/js/app.js index 49b6093..5bdfab3 100644 --- a/AdminPanel-Marinov/resources/js/app.js +++ b/AdminPanel-Marinov/resources/js/app.js @@ -41,4 +41,8 @@ $('#categories').on('change', function () { }); } }) -}) \ No newline at end of file +}) +//edit-product panel +$(document).load(function(){ + +}); \ No newline at end of file diff --git a/AdminPanel-Marinov/resources/views/products/edit-product.blade.php b/AdminPanel-Marinov/resources/views/products/edit-product.blade.php new file mode 100644 index 0000000..6257fa2 --- /dev/null +++ b/AdminPanel-Marinov/resources/views/products/edit-product.blade.php @@ -0,0 +1,107 @@ +@extends('layouts.app') + +@section('content') +<div class="w-4/12 m-12"> + <h1 class="text-2xl text-center ">Add new product</h1> + <form action="{{route('product.store')}}" method="POST"> + @csrf + <!-- Name --> + <div class="mt-4"> + <x-input-label for="title" :value="__('Title')" /> + <x-text-input id="title" class="block mt-1 w-full" type="text" name="title" :value="old('title')" required /> + <x-input-error :messages="$errors->get('title')" class="mt-2" /> + </div> + <!-- Category and type --> + <div class="mt-4"> + <x-input-label for="category" :value="__('Category')" class="inline-block me-1" /> + <select name="categories" id="categories" + class="mt-1 border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm"> + <option value="" selected disabled>Choose a category</option> + @foreach($categories as $category) + <option value="{{$category->id}}">{{$category->name}}</option> + @endforeach + </select> + <select name="types" id="types" class="mt-1 border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm"> + </select> + <x-input-error :messages="$errors->get('categories')" class="mt-2" /> + <x-input-error :messages="$errors->get('types')" class="mt-2" /> + </div> + <!-- Materials--> + <x-input-label :value="__('Materials')" /> + @foreach($materials as $material) + <label for="{{$material->id}}" class="font-medium text-sm text-gray-700 dark:text-gray-300">{{$material->name}}</label> + <input type="checkbox" name="materials[]" id="{{$material->id}}" value="{{$material->id}}" class="mt-1 border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm me-2"> + @endforeach + <x-input-error :messages="$errors->get('materials')" class="mt-2" /> + <!-- maintenances --> + <x-input-label :value="__('Maintenances')" /> + @foreach($maintenances as $maintenance) + <label for="{{$maintenance->id}}" class="font-medium text-sm text-gray-700 dark:text-gray-300">{{$maintenance->title}}</label> + <input type="checkbox" name="maintenances[]" id="{{$maintenance->id}}" value="{{$maintenance->id}}" class="mt-1 border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm me-2"> + @endforeach + <x-input-error :messages="$errors->get('maintenances')" class="mt-2" /> + <!-- Description --> + <div class="mt-4"> + <x-input-label for="desc" :value="__('Description')" /> + <textarea name="desc" id="desc" + class="block mt-1 w-full border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm">{{old('desc')}}</textarea> + <x-input-error :messages="$errors->get('desc')" class="mt-2" /> + </div> + <!-- Price --> + <div class="mt-4"> + <x-input-label for="price" :value="__('Price')" /> + <x-text-input id="price" class="block mt-1 w-full" type="number" name="price" :value="old('price')" + min="0.5" step="0.5" required /> + <x-input-error :messages="$errors->get('price')" class="mt-2" /> + </div> + <!-- Quantity --> + <div class="mt-4"> + <x-input-label for="quantity" :value="__('Quantity')" /> + <x-text-input id="quantity" class="block mt-1 w-full" type="number" name="quantity" :value="old('quantity')" + min="0" required /> + <x-input-error :messages="$errors->get('quantity')" class="mt-2" /> + </div> + <!-- weight --> + <div class="mt-4"> + <x-input-label for="weight" :value="__('Weight')" /> + <x-text-input id="weight" class="block mt-1 w-full" type="text" name="weight" :value="old('weight')" + required /> + <x-input-error :messages="$errors->get('weight')" class="mt-2" /> + </div> + <!-- Dimensions --> + <div class="mt-4"> + <x-input-label for="dimensions" :value="__('Dimensions')" /> + <x-text-input id="dimensions" class="block mt-1 w-full" type="text" name="dimensions" + :value="old('dimensions')" required /> + <x-input-error :messages="$errors->get('dimensions')" class="mt-2" /> + </div> + <!-- Images --> + <div class="mt-4"> + <x-input-label for="main_img" :value="__('Main Image')" class="inline-block me-1 mt-2" /> + <input type="file" name="main_img" id="main_img" > + <x-input-error :messages="$errors->get('main_img')" class="mt-2" /> + <x-input-label for="img_1" :value="__('Image 1')" class="inline-block me-1 mt-2" /> + <input type="file" name="img_1" id="img_1" > + <x-input-label for="img_2" :value="__('Image 2')" class="inline-block me-1 mt-2" /> + <input type="file" name="img_2" id="img_2" > + <x-input-label for="img_3" :value="__('Image 3')" class="inline-block me-1 mt-2" /> + <input type="file" name="img_3" id="img_3" > + </div> + <!-- Featured --> + <div class="mt-4"> + <x-input-label for="is_featured" :value="__('Featured')" class="inline-block me-3" /> + <x-text-input id="is_featured" class="inline-block" type="checkbox" name="is_featured" checked value="1" /> + </div> + <!-- Discount --> + <div class="mt-4"> + <x-input-label for="discount" :value="__('Discount')" /> + <x-text-input id="discount" class="block mt-1 w-full" type="number" name="discount" min="1" /> + </div> + <x-primary-button class="my-5"> + {{ __('Add') }} + </x-primary-button> + + </form> +</div> + +@endsection \ No newline at end of file diff --git a/AdminPanel-Marinov/routes/api.php b/AdminPanel-Marinov/routes/api.php index 75a22a2..b4b831b 100644 --- a/AdminPanel-Marinov/routes/api.php +++ b/AdminPanel-Marinov/routes/api.php @@ -1,10 +1,10 @@ <?php -use App\Http\Controllers\CategoryController; -use App\Http\Controllers\TypeController; +use App\Http\Controllers\Admin\CategoryController; +use App\Http\Controllers\Admin\TypeController; use App\Http\Controllers\Admin\ProductController; -use App\Http\Controllers\MaterialController; -use App\Http\Controllers\MaintenanceController; -use App\Http\Controllers\ImageController; +use App\Http\Controllers\Admin\MaterialController; +use App\Http\Controllers\Admin\MaintenanceController; +use App\Http\Controllers\Admin\ImageController; use App\Models\Type; /* |-------------------------------------------------------------------------- diff --git a/AdminPanel-Marinov/routes/web.php b/AdminPanel-Marinov/routes/web.php index 53f4b9b..c8edfd7 100644 --- a/AdminPanel-Marinov/routes/web.php +++ b/AdminPanel-Marinov/routes/web.php @@ -38,8 +38,9 @@ Route::prefix('admin')->middleware('auth')->group(function () { Route::get('/types', [TypeController::class, 'index'])->name('types.index'); Route::get('/materials', [MaterialController::class, 'index'])->name('materials.index'); Route::get('/maintenances', [MaintenanceController::class, 'index'])->name('maintenances.index'); - Route::get('/product/add', [ProductController::class, 'create'])->name('product.add'); + Route::get('/product/add', [ProductController::class, 'create'])->name('product.create'); Route::post('/product/store',[ProductController::class,'store'])->name('product.store'); + Route::get('/product/edit/{id}',[ProductController::class,'edit'])->name('product.edit'); Route::put('/product/update/{id}', [ProductController::class, 'updateProduct'])->name('admin.product.update'); Route::delete('/product/delete/{id}', [ProductController::class, 'deleteProduct'])->name('admin.product.delete'); }); -- GitLab From b85d154b9dd8ba6f49a4dd3080f3ca5fd4061a8a Mon Sep 17 00:00:00 2001 From: aleksandar kocev <aleks15kocev@gmail.com> Date: Sat, 17 Feb 2024 19:01:49 +0100 Subject: [PATCH 2/3] finishing edit product form --- .../Controllers/Admin/ProductController.php | 8 +- AdminPanel-Marinov/resources/js/app.js | 51 +++++++- .../views/products/add-product.blade.php | 10 +- .../views/products/edit-product.blade.php | 123 ++++++++++++------ AdminPanel-Marinov/routes/api.php | 6 + 5 files changed, 144 insertions(+), 54 deletions(-) diff --git a/AdminPanel-Marinov/app/Http/Controllers/Admin/ProductController.php b/AdminPanel-Marinov/app/Http/Controllers/Admin/ProductController.php index 4db4a55..229f533 100644 --- a/AdminPanel-Marinov/app/Http/Controllers/Admin/ProductController.php +++ b/AdminPanel-Marinov/app/Http/Controllers/Admin/ProductController.php @@ -2,10 +2,11 @@ namespace App\Http\Controllers\Admin; +use App\Models\Image; +use App\Models\Product; use App\Models\Category; -use App\Models\Maintenance; use App\Models\Material; -use App\Models\Product; +use App\Models\Maintenance; use Illuminate\Http\Request; use App\Http\Controllers\Controller; @@ -62,7 +63,8 @@ class ProductController extends Controller $materials = Material::all(); $maintenances = Maintenance::all(); $product = Product::findOrFail($id); - return view('products.edit-product', compact('product','categories', 'materials','maintenances')); + $images = Image::where('product_id',$id)->get(); + return view('products.edit-product', compact('product','categories', 'materials','maintenances','images')); } diff --git a/AdminPanel-Marinov/resources/js/app.js b/AdminPanel-Marinov/resources/js/app.js index 5bdfab3..5e96428 100644 --- a/AdminPanel-Marinov/resources/js/app.js +++ b/AdminPanel-Marinov/resources/js/app.js @@ -7,19 +7,19 @@ window.Alpine = Alpine; Alpine.start(); // admin nav-bar -$('#nav_products').click((e)=>{ +$('#nav_products').click((e) => { $('#product_items').toggle(); }) -$('#nav_orders').click((e)=>{ +$('#nav_orders').click((e) => { $('#orders_items').toggle(); }) -$('#nav_responsive_products').click((e)=>{ +$('#nav_responsive_products').click((e) => { $('#product_responsive_items').toggle(); }) -$('#nav_responsive_orders').click((e)=>{ +$('#nav_responsive_orders').click((e) => { $('#orders_responsive_items').toggle(); }) @@ -31,7 +31,6 @@ $('#categories').on('change', function () { url: `/api/category/types/${$(categories).val()}`, method: 'GET', success: function (response) { - console.log(response) $('#types').show(); $('#types').html('<option value="" selected disabled>Choose Type</option>'); response.forEach(type => { @@ -43,6 +42,44 @@ $('#categories').on('change', function () { }) }) //edit-product panel -$(document).load(function(){ - +$(function () { + // Your code here + if (window.location.href.indexOf("/product/edit") > -1) { + let userId = $('#id').val(); + $.ajax({ + url: `/api/category/types/${$('#edit_categories').val()}/${userId}`, + method: 'GET', + success: function (response) { + $('#edit_types').show(); + $('#edit_types').html('<option value="" selected disabled>Choose Type</option>'); + response.types.forEach(type => { + if (type['id'] == response.product['type_id']) { + $('#edit_types').append(` + <option value="${type['id']}" selected>${type['name']}</option> + `); + } else { + $('#edit_types').append(` + <option value="${type['id']}">${type['name']}</option> + `); + } + + }); + } + }); + $('#edit_categories').on('change', function () { + $.ajax({ + url: `/api/category/types/${$('#edit_categories').val()}`, + method: 'GET', + success: function (response) { + $('#edit_types').show(); + $('#edit_types').html('<option value="" selected disabled>Choose Type</option>'); + response.forEach(type => { + $('#edit_types').append(` + <option value="${type['id']}">${type['name']}</option> + `); + }); + } + }) + }) + } }); \ No newline at end of file diff --git a/AdminPanel-Marinov/resources/views/products/add-product.blade.php b/AdminPanel-Marinov/resources/views/products/add-product.blade.php index b9340d8..0a402d6 100644 --- a/AdminPanel-Marinov/resources/views/products/add-product.blade.php +++ b/AdminPanel-Marinov/resources/views/products/add-product.blade.php @@ -13,7 +13,7 @@ </div> <!-- Category and type --> <div class="mt-4"> - <x-input-label for="category" :value="__('Category')" class="inline-block me-1" /> + <x-input-label for="categories" :value="__('Category')" class="inline-block me-1" /> <select name="categories" id="categories" class="mt-1 border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm"> <option value="" selected disabled>Choose a category</option> @@ -77,14 +77,14 @@ </div> <!-- Images --> <div class="mt-4"> - <x-input-label for="main_img" :value="__('Main Image')" class="inline-block me-1 mt-2" /> + <x-input-label for="main_img" :value="__('Main Image')" class="mt-2" /> <input type="file" name="main_img" id="main_img" > <x-input-error :messages="$errors->get('main_img')" class="mt-2" /> - <x-input-label for="img_1" :value="__('Image 1')" class="inline-block me-1 mt-2" /> + <x-input-label for="img_1" :value="__('Image 1')" class="mt-2" /> <input type="file" name="img_1" id="img_1" > - <x-input-label for="img_2" :value="__('Image 2')" class="inline-block me-1 mt-2" /> + <x-input-label for="img_2" :value="__('Image 2')" class="mt-2" /> <input type="file" name="img_2" id="img_2" > - <x-input-label for="img_3" :value="__('Image 3')" class="inline-block me-1 mt-2" /> + <x-input-label for="img_3" :value="__('Image 3')" class="mt-2" /> <input type="file" name="img_3" id="img_3" > </div> <!-- Featured --> diff --git a/AdminPanel-Marinov/resources/views/products/edit-product.blade.php b/AdminPanel-Marinov/resources/views/products/edit-product.blade.php index 6257fa2..2f91887 100644 --- a/AdminPanel-Marinov/resources/views/products/edit-product.blade.php +++ b/AdminPanel-Marinov/resources/views/products/edit-product.blade.php @@ -2,69 +2,104 @@ @section('content') <div class="w-4/12 m-12"> - <h1 class="text-2xl text-center ">Add new product</h1> + <h1 class="text-2xl text-center ">Edit product</h1> <form action="{{route('product.store')}}" method="POST"> @csrf + <input type="number" name="id" id="id" hidden value="{{$product->id}}"> <!-- Name --> <div class="mt-4"> - <x-input-label for="title" :value="__('Title')" /> - <x-text-input id="title" class="block mt-1 w-full" type="text" name="title" :value="old('title')" required /> + <x-input-label for="edit_title" :value="__('Title')" /> + <x-text-input id="edit_title" class="block mt-1 w-full" type="text" name="title" :value="$product->title" + required /> <x-input-error :messages="$errors->get('title')" class="mt-2" /> </div> <!-- Category and type --> <div class="mt-4"> - <x-input-label for="category" :value="__('Category')" class="inline-block me-1" /> - <select name="categories" id="categories" + <x-input-label for="edit_categories" :value="__('Category')" class="inline-block me-1" /> + <select name="categories" id="edit_categories" class="mt-1 border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm"> <option value="" selected disabled>Choose a category</option> @foreach($categories as $category) + @if($category->id == $product->category_id) + <option value="{{$category->id}}" selected>{{$category->name}}</option> + @else <option value="{{$category->id}}">{{$category->name}}</option> + @endif @endforeach </select> - <select name="types" id="types" class="mt-1 border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm"> + <select name="types" id="edit_types" + class="mt-1 border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm"> </select> <x-input-error :messages="$errors->get('categories')" class="mt-2" /> <x-input-error :messages="$errors->get('types')" class="mt-2" /> </div> <!-- Materials--> - <x-input-label :value="__('Materials')" /> - @foreach($materials as $material) - <label for="{{$material->id}}" class="font-medium text-sm text-gray-700 dark:text-gray-300">{{$material->name}}</label> - <input type="checkbox" name="materials[]" id="{{$material->id}}" value="{{$material->id}}" class="mt-1 border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm me-2"> - @endforeach - <x-input-error :messages="$errors->get('materials')" class="mt-2" /> + <div class="mt-4"> + <x-input-label :value="__('Materials')" /> + @foreach($materials as $material) + @php + $checked = false; + foreach ($product->materials as $productMaterial) { + if ($productMaterial->id == $material->id) { + $checked = true; + break; + } + } + @endphp + <label for="{{ $material->id }}" class="font-medium text-sm text-gray-700 dark:text-gray-300"> + {{ $material->name }} + </label> + <input type="checkbox" name="materials[]" id="{{ $material->id }}" value="{{ $material->id }}" + class="border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm me-2" + @if($checked) checked @endif> + @endforeach + <x-input-error :messages="$errors->get('materials')" class="mt-2" /> + </div> + <!-- maintenances --> - <x-input-label :value="__('Maintenances')" /> - @foreach($maintenances as $maintenance) - <label for="{{$maintenance->id}}" class="font-medium text-sm text-gray-700 dark:text-gray-300">{{$maintenance->title}}</label> - <input type="checkbox" name="maintenances[]" id="{{$maintenance->id}}" value="{{$maintenance->id}}" class="mt-1 border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm me-2"> - @endforeach - <x-input-error :messages="$errors->get('maintenances')" class="mt-2" /> - <!-- Description --> <div class="mt-4"> - <x-input-label for="desc" :value="__('Description')" /> - <textarea name="desc" id="desc" - class="block mt-1 w-full border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm">{{old('desc')}}</textarea> - <x-input-error :messages="$errors->get('desc')" class="mt-2" /> + <x-input-label :value="__('Maintenances')" /> + + @foreach($maintenances as $maintenance) + @php + $checkedMaintenance = false; + foreach ($product->maintenances as $productMaintenance) { + if ($productMaintenance->id == $maintenance->id) { + $checkedMaintenance = true; + break; + } + } + @endphp + + <label for="{{ $maintenance->id }}" class="font-medium text-sm text-gray-700 dark:text-gray-300"> + {{ $maintenance->title }} + </label> + + <input type="checkbox" name="maintenances[]" id="{{ $maintenance->id }}" value="{{ $maintenance->id }}" + class="mt-1 border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm me-2" + @if($checkedMaintenance) checked @endif> + @endforeach + + <x-input-error :messages="$errors->get('maintenances')" class="mt-2" /> </div> <!-- Price --> <div class="mt-4"> <x-input-label for="price" :value="__('Price')" /> - <x-text-input id="price" class="block mt-1 w-full" type="number" name="price" :value="old('price')" + <x-text-input id="price" class="block mt-1 w-full" type="number" name="price" :value="$product->price" min="0.5" step="0.5" required /> <x-input-error :messages="$errors->get('price')" class="mt-2" /> </div> <!-- Quantity --> <div class="mt-4"> <x-input-label for="quantity" :value="__('Quantity')" /> - <x-text-input id="quantity" class="block mt-1 w-full" type="number" name="quantity" :value="old('quantity')" - min="0" required /> + <x-text-input id="quantity" class="block mt-1 w-full" type="number" name="quantity" + :value="$product->quantity" min="0" required /> <x-input-error :messages="$errors->get('quantity')" class="mt-2" /> </div> <!-- weight --> <div class="mt-4"> <x-input-label for="weight" :value="__('Weight')" /> - <x-text-input id="weight" class="block mt-1 w-full" type="text" name="weight" :value="old('weight')" + <x-text-input id="weight" class="block mt-1 w-full" type="text" name="weight" :value="$product->weight" required /> <x-input-error :messages="$errors->get('weight')" class="mt-2" /> </div> @@ -72,30 +107,40 @@ <div class="mt-4"> <x-input-label for="dimensions" :value="__('Dimensions')" /> <x-text-input id="dimensions" class="block mt-1 w-full" type="text" name="dimensions" - :value="old('dimensions')" required /> + :value="$product->dimensions" required /> <x-input-error :messages="$errors->get('dimensions')" class="mt-2" /> </div> <!-- Images --> - <div class="mt-4"> - <x-input-label for="main_img" :value="__('Main Image')" class="inline-block me-1 mt-2" /> - <input type="file" name="main_img" id="main_img" > + @foreach($images as $image) + @dd($image) + <x-input-label for="main_img" :value="__('Main Image')" class="mt-2" /> + <input type="file" name="main_img" id="main_img" value="{{$image->iamge_url}}"> + @endforeach + <!-- <div class="mt-4"> + <x-input-label for="main_img" :value="__('Main Image')" class="mt-2" /> + <input type="file" name="main_img" id="main_img"> <x-input-error :messages="$errors->get('main_img')" class="mt-2" /> - <x-input-label for="img_1" :value="__('Image 1')" class="inline-block me-1 mt-2" /> - <input type="file" name="img_1" id="img_1" > - <x-input-label for="img_2" :value="__('Image 2')" class="inline-block me-1 mt-2" /> - <input type="file" name="img_2" id="img_2" > - <x-input-label for="img_3" :value="__('Image 3')" class="inline-block me-1 mt-2" /> - <input type="file" name="img_3" id="img_3" > - </div> + <x-input-label for="img_1" :value="__('Image 1')" class="mt-2" /> + <input type="file" name="img_1" id="img_1"> + <x-input-label for="img_2" :value="__('Image 2')" class="mt-2" /> + <input type="file" name="img_2" id="img_2"> + <x-input-label for="img_3" :value="__('Image 3')" class="mt-2" /> + <input type="file" name="img_3" id="img_3"> + </div> --> <!-- Featured --> <div class="mt-4"> <x-input-label for="is_featured" :value="__('Featured')" class="inline-block me-3" /> + @if($product->is_featured) <x-text-input id="is_featured" class="inline-block" type="checkbox" name="is_featured" checked value="1" /> + @else + <x-text-input id="is_featured" class="inline-block" type="checkbox" name="is_featured" value="1" /> + @endif </div> <!-- Discount --> <div class="mt-4"> <x-input-label for="discount" :value="__('Discount')" /> - <x-text-input id="discount" class="block mt-1 w-full" type="number" name="discount" min="1" /> + <x-text-input id="discount" class="block mt-1 w-full" type="number" name="discount" min="1" + :value="$product->discount" /> </div> <x-primary-button class="my-5"> {{ __('Add') }} diff --git a/AdminPanel-Marinov/routes/api.php b/AdminPanel-Marinov/routes/api.php index b4b831b..99efe64 100644 --- a/AdminPanel-Marinov/routes/api.php +++ b/AdminPanel-Marinov/routes/api.php @@ -5,6 +5,7 @@ use App\Http\Controllers\Admin\ProductController; use App\Http\Controllers\Admin\MaterialController; use App\Http\Controllers\Admin\MaintenanceController; use App\Http\Controllers\Admin\ImageController; +use App\Models\Product; use App\Models\Type; /* |-------------------------------------------------------------------------- @@ -34,3 +35,8 @@ Route::get('/category/types/{categoryId}',function($categoryId){ $types = Type::where('category_id', $categoryId)->get(); return response()->json($types); }); +Route::get('/category/types/{categoryId}/{productId}',function($categoryId,$productId){ + $types = Type::where('category_id', $categoryId)->get(); + $product = Product::find($productId); + return response()->json(['types' => $types,'product' => $product]); +}); \ No newline at end of file -- GitLab From 2fb0c17fc87fba7b9bfbafad2dbef1c1c0ef2d10 Mon Sep 17 00:00:00 2001 From: aleksandar kocev <aleks15kocev@gmail.com> Date: Sat, 17 Feb 2024 20:26:40 +0100 Subject: [PATCH 3/3] completed edit for products --- .../Controllers/Admin/ProductController.php | 231 ++++++++++-------- ...024_02_16_134554_create_products_table.php | 2 +- AdminPanel-Marinov/resources/js/app.js | 34 +-- .../views/products/edit-product.blade.php | 60 +++-- AdminPanel-Marinov/routes/web.php | 11 +- 5 files changed, 177 insertions(+), 161 deletions(-) diff --git a/AdminPanel-Marinov/app/Http/Controllers/Admin/ProductController.php b/AdminPanel-Marinov/app/Http/Controllers/Admin/ProductController.php index d44d837..5f38354 100644 --- a/AdminPanel-Marinov/app/Http/Controllers/Admin/ProductController.php +++ b/AdminPanel-Marinov/app/Http/Controllers/Admin/ProductController.php @@ -5,17 +5,14 @@ namespace App\Http\Controllers\Admin; use ImageKit\ImageKit; use App\Models\Product; use App\Models\Image; -use App\Models\Product; use App\Models\Category; use App\Models\Material; use App\Models\Maintenance; use Illuminate\Http\Request; use App\Http\Controllers\Controller; -use App\Models\Image; - -class ProductController extends Controller +class ProductController extends Controller { public function index() { @@ -24,130 +21,152 @@ class ProductController extends Controller } public function create() { + $product = Product::first(); + dd($product->images); $categories = Category::all(); $materials = Material::all(); $maintenances = Maintenance::all(); - return view('products.add-product', compact('categories', 'materials','maintenances')); + return view('products.add-product', compact('categories', 'materials', 'maintenances')); } public function store(Request $request) -{ - $request->validate([ - 'title' => 'required', - 'categories' => 'required', - 'types' => 'required', - 'materials' => 'required|array|min:1', - 'desc' => 'required', - 'price' => 'required|numeric', - 'quantity' => 'required|integer', - 'is_featured' => 'boolean', - 'weight' => 'required', - 'dimensions' => 'required|string', - 'main_img' => 'required', - 'maintenances' => 'required|array|min:1', - ]); - - $product = Product::create([ - 'title' => $request->input('title'), - 'description' => $request->input('desc'), - 'price' => $request->input('price'), - 'quantity' => $request->input('quantity'), - 'is_featured' => $request->input('is_featured'), - 'weight' => $request->input('weight'), - 'dimensions' => $request->input('dimensions'), - 'category_id' => $request->input('categories'), - 'type_id' => $request->input('types') - ]); - - - $imageKit=new ImageKit( - "public_yHkkydctuDLQxoy5zFiseD9ZiW0=" - , - - "private_yPLFIGZ49woAFKkKT8eyt2yriCE=" - , - "https://ik.imagekit.io/hx2cyuc3r" - ); - - if($_FILES['main_img']['tmp_name']){ - $fileTypeMain = mime_content_type($_FILES['main_img']['tmp_name']); - - $file = $imageKit->uploadFile([ - 'file' => 'data:' . $fileTypeMain . ';base64,' . base64_encode(file_get_contents($_FILES['main_img']['tmp_name'])), - 'fileName' => 'picture', + { + $request->validate([ + 'title' => 'required', + 'categories' => 'required', + 'types' => 'required', + 'materials' => 'required|array|min:1', + 'desc' => 'required', + 'price' => 'required|numeric', + 'quantity' => 'required|integer', + 'is_featured' => 'boolean', + 'weight' => 'required', + 'dimensions' => 'required|string', + 'main_img' => 'required', + 'maintenances' => 'required|array|min:1', ]); - Image::create([ - 'image_url'=> $file->result->url, - 'product_id'=>$product->id + $product = Product::create([ + 'title' => $request->input('title'), + 'description' => $request->input('desc'), + 'price' => $request->input('price'), + 'quantity' => $request->input('quantity'), + 'is_featured' => $request->input('is_featured'), + 'weight' => $request->input('weight'), + 'dimensions' => $request->input('dimensions'), + 'category_id' => $request->input('categories'), + 'type_id' => $request->input('types') ]); - } - if($_FILES['img_1']['tmp_name']){ - $fileType1 = mime_content_type($_FILES['img_1']['tmp_name']); - $file1 = $imageKit->uploadFile([ - 'file' => 'data:' . $fileType1 . ';base64,' . base64_encode(file_get_contents($_FILES['img_1']['tmp_name'])), - 'fileName' => 'picture', - ]); + $imageKit = new ImageKit( + "public_yHkkydctuDLQxoy5zFiseD9ZiW0=" + , - Image::create([ - 'image_url'=> $file1->result->url, - 'product_id'=>$product->id - ]); - } - if($_FILES['img_2']['tmp_name']){ - $fileType2 = mime_content_type($_FILES['img_2']['tmp_name']); + "private_yPLFIGZ49woAFKkKT8eyt2yriCE=" + , + "https://ik.imagekit.io/hx2cyuc3r" + ); - $file2 = $imageKit->uploadFile([ - 'file' => 'data:' . $fileType2 . ';base64,' . base64_encode(file_get_contents($_FILES['img_2']['tmp_name'])), - 'fileName' => 'picture', - ]); - Image::create([ - 'image_url'=> $file2->result->url, - 'product_id'=>$product->id - ]); - - } - if($_FILES['img_3']['tmp_name']){ - $fileType3 = mime_content_type($_FILES['img_3']['tmp_name']); - - $file3 = $imageKit->uploadFile([ - 'file' => 'data:' . $fileType3 . ';base64,' . base64_encode(file_get_contents($_FILES['img_3']['tmp_name'])), - 'fileName' => 'picture', - ]); - Image::create([ - 'image_url'=> $file3->result->url, - 'product_id'=>$product->id - ]); -} + if ($_FILES['main_img']['tmp_name']) { + $fileTypeMain = mime_content_type($_FILES['main_img']['tmp_name']); - $product->materials()->sync($request->input('materials', [])); - $product->maintenances()->sync($request->input('maintenances', [])); - return redirect()->route('products.index')->with('message',"product added"); -} + $file = $imageKit->uploadFile([ + 'file' => 'data:' . $fileTypeMain . ';base64,' . base64_encode(file_get_contents($_FILES['main_img']['tmp_name'])), + 'fileName' => 'picture', + ]); + + Image::create([ + 'image_url' => $file->result->url, + 'product_id' => $product->id + ]); + + } + if ($_FILES['img_1']['tmp_name']) { + $fileType1 = mime_content_type($_FILES['img_1']['tmp_name']); + + $file1 = $imageKit->uploadFile([ + 'file' => 'data:' . $fileType1 . ';base64,' . base64_encode(file_get_contents($_FILES['img_1']['tmp_name'])), + 'fileName' => 'picture', + ]); + + Image::create([ + 'image_url' => $file1->result->url, + 'product_id' => $product->id + ]); + } + if ($_FILES['img_2']['tmp_name']) { + $fileType2 = mime_content_type($_FILES['img_2']['tmp_name']); + + $file2 = $imageKit->uploadFile([ + 'file' => 'data:' . $fileType2 . ';base64,' . base64_encode(file_get_contents($_FILES['img_2']['tmp_name'])), + 'fileName' => 'picture', + ]); + Image::create([ + 'image_url' => $file2->result->url, + 'product_id' => $product->id + ]); + + } + if ($_FILES['img_3']['tmp_name']) { + $fileType3 = mime_content_type($_FILES['img_3']['tmp_name']); + + $file3 = $imageKit->uploadFile([ + 'file' => 'data:' . $fileType3 . ';base64,' . base64_encode(file_get_contents($_FILES['img_3']['tmp_name'])), + 'fileName' => 'picture', + ]); + Image::create([ + 'image_url' => $file3->result->url, + 'product_id' => $product->id + ]); + } - public function edit(string $id){ + $product->materials()->sync($request->input('materials', [])); + $product->maintenances()->sync($request->input('maintenances', [])); + return redirect()->route('products.index')->with('message', "product added"); + } + + public function edit(string $id) + { $categories = Category::all(); $materials = Material::all(); $maintenances = Maintenance::all(); $product = Product::findOrFail($id); - $images = Image::where('product_id',$id)->get(); - return view('products.edit-product', compact('product','categories', 'materials','maintenances','images')); + $mainImage = Image::where('product_id', $id)->first(); + $images = Image::where('product_id', $id)->get()->skip(1); + return view('products.edit-product', compact('product', 'categories', 'materials', 'maintenances', 'mainImage', 'images')); } - public function deleteProductByTitle(Request $request) + public function update(Request $request) { - $productTitle = $request->title; - - - $product = Product::where('title', $productTitle)->first(); + $request->validate([ + 'title' => 'required', + 'categories' => 'required', + 'types' => 'required', + 'materials' => 'required|array|min:1', + 'desc' => 'required', + 'price' => 'required|numeric', + 'quantity' => 'required|integer', + 'is_featured' => 'boolean', + 'weight' => 'required', + 'dimensions' => 'required|string', + 'maintenances' => 'required|array|min:1', + ]); - if ($product) { - $product->delete(); - return response()->json('Product successfully deleted', 200); - } else { - return response()->json(['message' => 'Product not found'], 404); - } + $product = Product::find($request->id); + $product->update([ + 'title' => $request->input('title'), + 'description' => $request->input('desc'), + 'price' => $request->input('price'), + 'quantity' => $request->input('quantity'), + 'is_featured' => $request->input('is_featured'), + 'weight' => $request->input('weight'), + 'dimensions' => $request->input('dimensions'), + 'category_id' => $request->input('categories'), + 'type_id' => $request->input('types') + ]); + $product->materials()->sync($request->input('materials', [])); + $product->maintenances()->sync($request->input('maintenances', [])); + return 'success'; } } diff --git a/AdminPanel-Marinov/database/migrations/2024_02_16_134554_create_products_table.php b/AdminPanel-Marinov/database/migrations/2024_02_16_134554_create_products_table.php index f418af3..7f93b7b 100644 --- a/AdminPanel-Marinov/database/migrations/2024_02_16_134554_create_products_table.php +++ b/AdminPanel-Marinov/database/migrations/2024_02_16_134554_create_products_table.php @@ -20,7 +20,7 @@ return new class extends Migration $table->foreignId('category_id')->constrained('categories'); $table->foreignId('type_id')->constrained('types'); $table->integer('discount')->nullable(); - $table->boolean('is_featured'); + $table->boolean('is_featured')->nullable()->default(0); $table->string('weight', 255); $table->string('dimensions', 255); $table->softDeletes(); diff --git a/AdminPanel-Marinov/resources/js/app.js b/AdminPanel-Marinov/resources/js/app.js index cdd0ee7..930502d 100644 --- a/AdminPanel-Marinov/resources/js/app.js +++ b/AdminPanel-Marinov/resources/js/app.js @@ -5,12 +5,8 @@ window.Alpine = Alpine; Alpine.start(); -<<<<<<< HEAD -$('#nav_products').click((e) => { -======= -// admin nav-bar +// admin nav-bar $('#nav_products').click((e)=>{ ->>>>>>> 3de133d66b9eb7cee852913c485c83109df6ed9f $('#product_items').toggle(); }); @@ -33,10 +29,7 @@ $('#categories').on('change', function () { url: `/api/category/types/${$(categories).val()}`, method: 'GET', success: function (response) { -<<<<<<< HEAD -======= console.log(response); ->>>>>>> 3de133d66b9eb7cee852913c485c83109df6ed9f $('#types').show(); $('#types').html('<option value="" selected disabled>Choose Type</option>'); response.forEach(type => { @@ -45,7 +38,6 @@ $('#categories').on('change', function () { `); }); } -<<<<<<< HEAD }) }) //edit-product panel @@ -90,13 +82,12 @@ $(function () { }) } }); -======= - }); -}); + + // Delete maintenance -$(document).ready(function() { - $('.btn-maintenance-delete').on('click', function() { +$(document).ready(function () { + $('.btn-maintenance-delete').on('click', function () { let maintenanceId = $(this).data('maintenance-id'); $.ajax({ @@ -105,10 +96,10 @@ $(document).ready(function() { headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }, - success: function(response) { + success: function (response) { location.reload(); }, - error: function(error) { + error: function (error) { console.error('Error deleting maintenance:', error); } }); @@ -116,14 +107,14 @@ $(document).ready(function() { }); // Edit maintenance -$(document).ready(function() { - $('.btn-maintenance-edit').on('click', function() { +$(document).ready(function () { + $('.btn-maintenance-edit').on('click', function () { var maintenanceId = $(this).data('maintenance-id'); window.location.href = '/admin/maintenances/update/' + maintenanceId; }); // Update maintenance - $('#maintenanceBtn').on('click', function() { + $('#maintenanceBtn').on('click', function () { let maintenanceId = $('#maintenanceForm').data('maintenance-id'); let formData = $('#maintenanceForm').serialize(); let url = maintenanceId ? '/admin/maintenances/update/' + maintenanceId : '/admin/maintenances/store'; @@ -135,10 +126,10 @@ $(document).ready(function() { headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }, - success: function(response) { + success: function (response) { window.location.href = '/admin/maintenances'; }, - error: function(xhr, status, error) { + error: function (xhr, status, error) { alert('Error: ' + xhr.responseText); } }); @@ -146,4 +137,3 @@ $(document).ready(function() { }); ->>>>>>> 3de133d66b9eb7cee852913c485c83109df6ed9f diff --git a/AdminPanel-Marinov/resources/views/products/edit-product.blade.php b/AdminPanel-Marinov/resources/views/products/edit-product.blade.php index 2f91887..2bbff11 100644 --- a/AdminPanel-Marinov/resources/views/products/edit-product.blade.php +++ b/AdminPanel-Marinov/resources/views/products/edit-product.blade.php @@ -3,7 +3,7 @@ @section('content') <div class="w-4/12 m-12"> <h1 class="text-2xl text-center ">Edit product</h1> - <form action="{{route('product.store')}}" method="POST"> + <form action="{{route('product.update')}}" method="POST"> @csrf <input type="number" name="id" id="id" hidden value="{{$product->id}}"> <!-- Name --> @@ -82,51 +82,61 @@ <x-input-error :messages="$errors->get('maintenances')" class="mt-2" /> </div> + <!-- Description --> + <div class="mt-4"> + <x-input-label for="edit_desc" :value="__('Description')" /> + <textarea name="desc" id="edit_desc" + class="block mt-1 w-full border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm">{{$product->description}}</textarea> + <x-input-error :messages="$errors->get('desc')" class="mt-2" /> + </div> <!-- Price --> <div class="mt-4"> <x-input-label for="price" :value="__('Price')" /> <x-text-input id="price" class="block mt-1 w-full" type="number" name="price" :value="$product->price" - min="0.5" step="0.5" required /> + min="0.5" step="0.01" required /> <x-input-error :messages="$errors->get('price')" class="mt-2" /> </div> <!-- Quantity --> <div class="mt-4"> - <x-input-label for="quantity" :value="__('Quantity')" /> - <x-text-input id="quantity" class="block mt-1 w-full" type="number" name="quantity" + <x-input-label for="edit_quantity" :value="__('Quantity')" /> + <x-text-input id="edit_quantity" class="block mt-1 w-full" type="number" name="quantity" :value="$product->quantity" min="0" required /> <x-input-error :messages="$errors->get('quantity')" class="mt-2" /> </div> <!-- weight --> <div class="mt-4"> - <x-input-label for="weight" :value="__('Weight')" /> - <x-text-input id="weight" class="block mt-1 w-full" type="text" name="weight" :value="$product->weight" + <x-input-label for="edit_weight" :value="__('Weight')" /> + <x-text-input id="edit_weight" class="block mt-1 w-full" type="text" name="weight" :value="$product->weight" required /> <x-input-error :messages="$errors->get('weight')" class="mt-2" /> </div> <!-- Dimensions --> <div class="mt-4"> - <x-input-label for="dimensions" :value="__('Dimensions')" /> - <x-text-input id="dimensions" class="block mt-1 w-full" type="text" name="dimensions" + <x-input-label for="edit_edit_dimensions" :value="__('Dimensions')" /> + <x-text-input id="edit_edit_dimensions" class="block mt-1 w-full" type="text" name="dimensions" :value="$product->dimensions" required /> <x-input-error :messages="$errors->get('dimensions')" class="mt-2" /> </div> <!-- Images --> - @foreach($images as $image) - @dd($image) - <x-input-label for="main_img" :value="__('Main Image')" class="mt-2" /> - <input type="file" name="main_img" id="main_img" value="{{$image->iamge_url}}"> - @endforeach - <!-- <div class="mt-4"> - <x-input-label for="main_img" :value="__('Main Image')" class="mt-2" /> - <input type="file" name="main_img" id="main_img"> + <div class="mt-4"> + <label for="main_img" class="font-medium text-sm text-gray-700 dark:text-gray-300 mt-2 block">Main + Image</label> + <img src="{{$mainImage->image_url}}" alt="product_image" class="w-2/12"> + <input type="file" name="main_img" id="main_img" value="{{$mainImage->iamge_url}}"> <x-input-error :messages="$errors->get('main_img')" class="mt-2" /> - <x-input-label for="img_1" :value="__('Image 1')" class="mt-2" /> - <input type="file" name="img_1" id="img_1"> - <x-input-label for="img_2" :value="__('Image 2')" class="mt-2" /> - <input type="file" name="img_2" id="img_2"> - <x-input-label for="img_3" :value="__('Image 3')" class="mt-2" /> - <input type="file" name="img_3" id="img_3"> - </div> --> + @php + $i= 1 + @endphp + @foreach($images as $image) + <label for="img_{{$i}}" class="font-medium text-sm text-gray-700 dark:text-gray-300 mt-2 block">Image + {{$i}}</label> + <img src="{{$image->image_url}}" alt="product_image" class="w-2/12"> + <input type="file" name="img_{{$i}}" id="img_{{$i}}"> + @php + $i++; + @endphp + @endforeach + </div> <!-- Featured --> <div class="mt-4"> <x-input-label for="is_featured" :value="__('Featured')" class="inline-block me-3" /> @@ -138,8 +148,8 @@ </div> <!-- Discount --> <div class="mt-4"> - <x-input-label for="discount" :value="__('Discount')" /> - <x-text-input id="discount" class="block mt-1 w-full" type="number" name="discount" min="1" + <x-input-label for="edit_discount" :value="__('Discount')" /> + <x-text-input id="edit_discount" class="block mt-1 w-full" type="number" name="discount" min="1" :value="$product->discount" /> </div> <x-primary-button class="my-5"> diff --git a/AdminPanel-Marinov/routes/web.php b/AdminPanel-Marinov/routes/web.php index ae5b7c2..90a4bef 100644 --- a/AdminPanel-Marinov/routes/web.php +++ b/AdminPanel-Marinov/routes/web.php @@ -38,10 +38,8 @@ Route::prefix('admin')->middleware('auth')->group(function () { // Types routes Route::get('/types', [TypeController::class, 'index'])->name('types.index'); - // Materials routes - Route::get('/materials', [MaterialController::class, 'index'])->name('materials.index'); - Route::get('/materials/create', [MaterialController::class, 'create'])->name('materials.create'); - Route::get('/materials/{id}/edit', [MaterialController::class, 'edit'])->name('materials.edit'); + + // Products routes Route::get('/products', [ProductController::class, 'index'])->name('products.index'); @@ -51,11 +49,10 @@ Route::prefix('admin')->middleware('auth')->group(function () { Route::post('/materials', [MaterialController::class, 'store'])->name('materials.store'); Route::put('/materials/{id}', [MaterialController::class, 'update'])->name('materials.update'); - Route::get('/maintenances', [MaintenanceController::class, 'index'])->name('maintenances.index'); Route::get('/product/add', [ProductController::class, 'create'])->name('product.create'); Route::post('/product/store', [ProductController::class, 'store'])->name('product.store'); - Route::get('/product/edit/{id}',[ProductController::class,'edit'])->name('product.edit'); - Route::put('/product/update/{id}', [ProductController::class, 'updateProduct'])->name('admin.product.update'); + Route::get('/product/edit/{id}', [ProductController::class, 'edit'])->name('product.edit'); + Route::post('/product/update', [ProductController::class, 'update'])->name('product.update'); Route::delete('/product/delete/{id}', [ProductController::class, 'deleteProduct'])->name('admin.product.delete'); // Maintenances routes -- GitLab