Showing AI reviews for avriti-backend
Project AI Score ?
59%
Quality Avg ?
64%
Security Avg ?
45%
Reviews ?
57

Review Result ?

jattin01/avriti-backend · 4b2463d6
This commit adds functionality to manage product thumbnails in the backend and frontend with thumbnail preview, deletion, and lightbox features. It improves the UI for thumbnail management and sends thumbnail data on form submission, updating the backend to handle existing thumbnails. However, the commit message lacks detail. Some validation and security improvements could be made, such as sanitizing inputs and handling edge cases where thumbnails might be deleted asynchronously or maliciously.
Quality ?
75%
Security ?
60%
Business Value ?
80%
Maintainability ?
65%
Issues & Suggested Fixes ?
1AI detects the issue
2Shows file, line, or evidence
3Suggests the fix to apply
Issue
Where commit message
Issue / Evidence issue
Suggested Fix provide a more descriptive commit message summarizing key changes to improve code review and traceability
Missing Validation
Where app/Http/Controllers/AdminProductController.php:63
Issue / Evidence validation
Suggested Fix add explicit validation and sanitization for existing_thumbnails input to prevent potential malformed data issues
Potential Bug
Where app/Http/Controllers/AdminProductController.php:65
Issue / Evidence potential bug
Suggested Fix add error handling around deleteThumbnails() to manage failures during thumbnail deletion
Security Issue
Where resources/views/admin/partials/product-form.blade.php:282
Issue / Evidence UX/security
Suggested Fix add a confirmation dialog before allowing thumbnail deletions to prevent accidental removals
Robustness
Where resources/views/admin/products.blade.php:239
Issue / Evidence robustness
Suggested Fix add null checks and fallback for countEl in updateThumbCount to avoid potential JavaScript errors
Security Issue
Where resources/views/admin/products.blade.php:300
Issue / Evidence security
Suggested Fix validate image src URLs before using in the lightbox to mitigate injection risks
Code Change Preview · app/Http/Controllers/AdminProductController.php ?
Removed / Before Commit
- 
- $this->ensureSlugIsUnique($slug, $product->id);
- 
-         $thumbnailPaths = $this->productThumbnails($product);
- 
- if ($request->hasFile('thumbnail')) {
- $thumbnailPaths = array_merge($thumbnailPaths, $this->storeThumbnails($request));
- 'attributes.*.name' => ['nullable', 'string', 'max:255'],
- 'attributes.*.value' => ['nullable', 'string', 'max:255'],
- 'how_to_use' => ['nullable', 'string'],
- 'thumbnail' => ['nullable', 'array'],
- 'thumbnail.*' => ['image', 'mimes:jpg,jpeg,png,webp', 'max:2048'],
- 'featured' => ['nullable', 'boolean'],
Added / After Commit
+ 
+ $this->ensureSlugIsUnique($slug, $product->id);
+ 
+         $existingThumbnails = array_values(array_filter((array) $request->input('existing_thumbnails', [])));
+         $removedThumbnails = array_diff($this->productThumbnails($product), $existingThumbnails);
+         $this->deleteThumbnails($removedThumbnails);
+ 
+         $thumbnailPaths = $existingThumbnails;
+ 
+ if ($request->hasFile('thumbnail')) {
+ $thumbnailPaths = array_merge($thumbnailPaths, $this->storeThumbnails($request));
+ 'attributes.*.name' => ['nullable', 'string', 'max:255'],
+ 'attributes.*.value' => ['nullable', 'string', 'max:255'],
+ 'how_to_use' => ['nullable', 'string'],
+                 'existing_thumbnails' => ['nullable', 'array'],
+                 'existing_thumbnails.*' => ['nullable', 'string'],
+ 'thumbnail' => ['nullable', 'array'],
+ 'thumbnail.*' => ['image', 'mimes:jpg,jpeg,png,webp', 'max:2048'],
Removed / Before Commit
- 
- <div class="mt-4 grid grid-cols-2 gap-3 sm:grid-cols-4" data-thumbnail-preview>
- @forelse ($thumbnailRows as $thumbnail)
-         <img src="{{ asset($thumbnail) }}" alt="{{ $product?->title ?? 'Product thumbnail' }}" class="h-24 w-full rounded-2xl border-2 border-[#0b3dba] object-cover" />
- @empty
- @for ($thumbnailBox = 0; $thumbnailBox < 4; $thumbnailBox++)
- <div data-thumbnail-placeholder class="flex h-24 items-center justify-center rounded-2xl border-2 border-dashed border-[#0b3dba] bg-white text-[#0b3dba]">
- </div>
- 
- @if (count($thumbnailRows) > 0)
-       <p class="mt-2 text-xs text-gray-400">{{ count($thumbnailRows) }} {{ count($thumbnailRows) === 1 ? 'image' : 'images' }} uploaded.</p>
- @endif
- </div>
Added / After Commit
+ 
+ <div class="mt-4 grid grid-cols-2 gap-3 sm:grid-cols-4" data-thumbnail-preview>
+ @forelse ($thumbnailRows as $thumbnail)
+         <div class="relative group" data-thumb-item>
+           <input type="hidden" name="existing_thumbnails[]" value="{{ $thumbnail }}" data-existing-thumb />
+           <img src="{{ asset($thumbnail) }}" alt="{{ $product?->title ?? 'Product thumbnail' }}" class="h-24 w-full rounded-2xl border-2 border-[#0b3dba] object-cover" />
+           <div class="absolute inset-0 flex items-center justify-center gap-2 rounded-2xl bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity duration-200">
+             <button type="button" data-thumb-preview="{{ asset($thumbnail) }}" class="inline-flex h-8 w-8 items-center justify-center rounded-full bg-white text-[#0b3dba] hover:bg-blue-50 transition" title="Preview">
+               <i class="fa-solid fa-eye text-sm"></i>
+             </button>
+             <button type="button" data-thumb-delete class="inline-flex h-8 w-8 items-center justify-center rounded-full bg-white text-red-500 hover:bg-red-50 transition" title="Delete">
+               <i class="fa-solid fa-trash text-sm"></i>
+             </button>
+           </div>
+         </div>
+ @empty
+ @for ($thumbnailBox = 0; $thumbnailBox < 4; $thumbnailBox++)
+ <div data-thumbnail-placeholder class="flex h-24 items-center justify-center rounded-2xl border-2 border-dashed border-[#0b3dba] bg-white text-[#0b3dba]">
Removed / Before Commit
- </div>
- @endforeach
- 
- 
- @endsection
- 
- refreshRepeaterNumbers(repeater);
- };
- 
- const clearSelectedThumbnails = (preview) => {
- preview.querySelectorAll('[data-selected-thumbnail]').forEach((image) => image.remove());
- };
- const backdrop = event.target.matches('[data-modal]');
- const addRow = event.target.closest('[data-repeater-add]');
- const removeRow = event.target.closest('[data-repeater-remove]');
- 
- if (trigger) {
- openModal(document.getElementById(trigger.dataset.modalTarget));
Added / After Commit
+ </div>
+ @endforeach
+ 
+ {{-- Thumbnail lightbox --}}
+ <div id="thumbLightbox" class="hidden fixed inset-0 z-[9999] items-center justify-center bg-black/80 px-4 py-6">
+   <button type="button" data-lightbox-close class="absolute top-4 right-4 inline-flex h-10 w-10 items-center justify-center rounded-full bg-white/10 text-white hover:bg-white/20 transition">
+     <i class="fa-solid fa-xmark text-lg"></i>
+   </button>
+   <img id="thumbLightboxImg" src="" alt="Preview" class="max-h-[85vh] max-w-full rounded-2xl object-contain shadow-2xl" />
+ </div>
+ 
+ @endsection
+ 
+ refreshRepeaterNumbers(repeater);
+ };
+ 
+     const lightbox = document.getElementById('thumbLightbox');
+     const lightboxImg = document.getElementById('thumbLightboxImg');
Removed / Before Commit
- Route::get('/user', [AuthController::class, 'apiUser'])->name('api.user');
- Route::post('/logout', [AuthController::class, 'apiLogout'])->name('api.logout');
- });
Added / After Commit
+ Route::get('/user', [AuthController::class, 'apiUser'])->name('api.user');
+ Route::post('/logout', [AuthController::class, 'apiLogout'])->name('api.logout');
+ });
+ 
+