feat: replace raw image path input with interactive visual gallery and multi-image manager in admin and shop
This commit is contained in:
@@ -5,6 +5,7 @@ namespace App\Http\Controllers\Admin;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Category;
|
||||
use App\Models\Product;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
@@ -84,7 +85,9 @@ class ProductController extends Controller
|
||||
'base_price' => 'required|numeric|min:0.01',
|
||||
'short_description' => 'nullable|string|max:500',
|
||||
'description' => 'required|string',
|
||||
'image_url' => 'nullable|string|max:500',
|
||||
'image_url' => 'nullable|string|max:2048',
|
||||
'gallery_images' => 'nullable|array',
|
||||
'gallery_images.*' => 'nullable|string|max:2048',
|
||||
'dimensions' => 'nullable|string|max:100',
|
||||
'weight_grams' => 'nullable|integer|min:0',
|
||||
'print_time_hours' => 'nullable|numeric|min:0',
|
||||
@@ -95,6 +98,7 @@ class ProductController extends Controller
|
||||
$validated['slug'] = Str::slug($validated['name']);
|
||||
$validated['is_featured'] = $request->boolean('is_featured');
|
||||
$validated['is_active'] = $request->boolean('is_active');
|
||||
$validated['gallery_images'] = $this->cleanGalleryImages($request->input('gallery_images', []), $validated['image_url'] ?? null);
|
||||
$validated['available_materials'] = ['pla', 'petg', 'silk', 'tpu'];
|
||||
$validated['available_colors'] = [
|
||||
'Zon Geel (Pikachu)', 'Vurig Rood (Charizard)', 'Hemelsblauw (Squirtle)',
|
||||
@@ -129,7 +133,9 @@ class ProductController extends Controller
|
||||
'base_price' => 'required|numeric|min:0.01',
|
||||
'short_description' => 'nullable|string|max:500',
|
||||
'description' => 'required|string',
|
||||
'image_url' => 'nullable|string|max:500',
|
||||
'image_url' => 'nullable|string|max:2048',
|
||||
'gallery_images' => 'nullable|array',
|
||||
'gallery_images.*' => 'nullable|string|max:2048',
|
||||
'dimensions' => 'nullable|string|max:100',
|
||||
'weight_grams' => 'nullable|integer|min:0',
|
||||
'print_time_hours' => 'nullable|numeric|min:0',
|
||||
@@ -139,6 +145,7 @@ class ProductController extends Controller
|
||||
|
||||
$validated['is_featured'] = $request->boolean('is_featured');
|
||||
$validated['is_active'] = $request->boolean('is_active');
|
||||
$validated['gallery_images'] = $this->cleanGalleryImages($request->input('gallery_images', []), $validated['image_url'] ?? null);
|
||||
|
||||
$product->update($validated);
|
||||
|
||||
@@ -146,6 +153,43 @@ class ProductController extends Controller
|
||||
->with('success', "Product '{$product->name}' is succesvol bijgewerkt!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle image upload for product gallery / cover.
|
||||
*/
|
||||
public function uploadImage(Request $request): JsonResponse
|
||||
{
|
||||
$request->validate([
|
||||
'image' => 'required|image|mimes:jpeg,png,jpg,webp,gif|max:8192',
|
||||
]);
|
||||
|
||||
$path = $request->file('image')->store('products', 'public');
|
||||
$url = '/storage/'.$path;
|
||||
|
||||
return response()->json([
|
||||
'success' => true,
|
||||
'url' => $url,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitize and filter gallery images.
|
||||
*
|
||||
* @param array<int, mixed> $images
|
||||
* @return array<int, string>
|
||||
*/
|
||||
protected function cleanGalleryImages(array $images, ?string $coverUrl = null): array
|
||||
{
|
||||
$clean = [];
|
||||
foreach ($images as $img) {
|
||||
$img = trim((string) $img);
|
||||
if ($img !== '' && $img !== $coverUrl && ! in_array($img, $clean, true)) {
|
||||
$clean[] = $img;
|
||||
}
|
||||
}
|
||||
|
||||
return $clean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified product from storage.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user