Skip to content

Commit 0c8138f

Browse files
committed
feat: media modal added on product and variation module for create and update
1 parent d6117a6 commit 0c8138f

File tree

10 files changed

+247
-94
lines changed

10 files changed

+247
-94
lines changed

app/Http/Controllers/Admin/ProductController.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ public function store(ProductRequest $request)
5252
try {
5353
DB::transaction(function () use ($request) {
5454
$data = $request->validated();
55-
if ($request->hasFile('image')) {
56-
$data['image'] = $this->uploadPhoto($request->file('image'));
57-
}
55+
// if ($request->hasFile('image')) {
56+
// $data['image'] = $this->uploadPhoto($request->file('image'));
57+
// }
5858
$product = Product::create($data);
5959
$this->service->storeCombinations($request, $product);
6060
});

app/Http/Controllers/Frontend/ProductController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class ProductController extends Controller
1111
{
1212
public function index()
1313
{
14-
$products = Product::where('type','simple')->with('category')->paginate(10);
14+
$products = Product::with('category')->paginate(10);
1515
return view('frontend.products.index', compact('products'));
1616
}
1717
}

app/Http/Requests/ProductRequest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public function rules(): array
3333
'category_id' => 'required',
3434
'type' => 'required',
3535
'price' => 'required|numeric',
36-
'image' => 'nullable|image|mimes:jpeg,png,jpg,gif,webp|max:2048',
36+
'image' => 'nullable|string',
3737
];
3838
}
3939
}

app/Services/ProductService.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ public function storeCombinations($request, Product $product, $oldVariants = [])
6767
if ($variant) {
6868
$image = $variant->image;
6969

70-
if (isset($combination['image']) && $combination['image'] instanceof \Illuminate\Http\UploadedFile) {
71-
$image = $this->uploadPhoto($combination['image'], $variant->image);
70+
if (isset($combination['image']) && is_string($combination['image'])) {
71+
$image = $combination['image'];
7272
}
7373

7474
$variant->update([
@@ -85,9 +85,11 @@ public function storeCombinations($request, Product $product, $oldVariants = [])
8585
}
8686

8787
$image = null;
88-
if (isset($combination['image']) && $combination['image'] instanceof \Illuminate\Http\UploadedFile) {
89-
$image = $this->uploadPhoto($combination['image']);
88+
if (!empty($combination['image']) && is_string($combination['image'])) {
89+
// Just store the image path from the selected gallery image
90+
$image = $combination['image'];
9091
} elseif ($oldVariants && isset($combination['variant_id'])) {
92+
// Use previous variant image if available
9193
$image = $oldVariants[$combination['variant_id']]->image ?? null;
9294
}
9395

resources/views/admin/components/media/popup.blade.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@
6060
</div>
6161

6262
<div class="position-relative flex-grow-1 px-3">
63-
<div class="loader custom"></div>
63+
<div class="loader custom" style="display: none"></div>
6464
<div class="row gutters-sm" id="ajax-container-{{ $modalId }}">
6565
{{-- Content loaded dynamically --}}
6666
</div>

resources/views/admin/components/modal-scripts.blade.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ function refreshUploadInput(form) {
5959
const saveBtn = e.target.closest('[id^="save-media-"]');
6060
if (!saveBtn) return;
6161
62-
const modalId = currentModalId;
62+
const modalId = saveBtn.closest('.offcanvas')?.id || currentModalId;
6363
const modal = document.getElementById(modalId);
6464
const inputName = modal.dataset.imageInput;
6565
const from = modal.dataset.from;
@@ -195,7 +195,7 @@ function setupMediaModal(modal) {
195195
}
196196
197197
function loadMedia(url, modalId, page = 1, folderId = null) {
198-
const loader = document.querySelector('.loader');
198+
const loader = document.querySelector(`#${modalId} .loader.custom`);
199199
const container = document.getElementById(`ajax-container-${modalId}`);
200200
const pagination = document.getElementById(`pagination-${modalId}`);
201201
if (loader) loader.style.display = 'block';
@@ -269,13 +269,17 @@ function loadMedia(url, modalId, page = 1, folderId = null) {
269269
});
270270
});
271271
}
272+
if (loader) loader.style.display = 'none';
272273
})
273274
.catch(() => {
274275
console.error("Failed to load media.");
276+
if (loader) loader.style.display = 'none';
275277
})
276278
.finally(() => {
277279
if (loader) loader.style.display = 'none';
278280
});
281+
282+
console.log(loader.style.display)
279283
}
280284
281285
@@ -296,7 +300,6 @@ function loadMedia(url, modalId, page = 1, folderId = null) {
296300
if (button) {
297301
e.preventDefault();
298302
const modal = button.closest('.modal');
299-
console.log(modal)
300303
const id = modal.querySelector('input[name="id"]').value;
301304
const isFile = modal.querySelector('input[name="is_file"]').value;
302305
const parent_id = modal.querySelector('select[name="folder_id"]').value;

resources/views/admin/components/scripts.blade.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,6 @@ function loadData(url, containerSelector, target = null) {
191191
return;
192192
}
193193
target?.classList.add("onLoading");
194-
195194
axios.get(url, {
196195
headers: {
197196
'X-Requested-With': 'XMLHttpRequest'
@@ -204,8 +203,9 @@ function loadData(url, containerSelector, target = null) {
204203
console.error("Failed to load data!", error);
205204
})
206205
.finally(() => {
207-
target.classList.remove("onLoading");
206+
target?.classList.remove("onLoading");
208207
});
208+
target?.classList.remove("onLoading");
209209
}
210210
</script>
211211

resources/views/admin/cruds/create.blade.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ class="btn btn-success">Save and create</button>
136136
</div>
137137
</div>
138138

139-
@include('admin.components.media.popup', [
139+
@include('admin.components.media.popup', [
140140
'modalId' => 'crud-offcanvas',
141141
'inputType' => 'single',
142142
'imageInputName' => 'media_input'

resources/views/admin/products/create.blade.php

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,14 @@
5555
<div class="mb-3 row">
5656
<div class="col-3 col-form-label required">Product Image</div>
5757
<div class="col">
58-
<input type="file" class="form-control" name="image"/>
58+
<button type="button" class="btn btn-primary" id="product-btn"
59+
data-bs-toggle="offcanvas" data-bs-target="#product"
60+
aria-controls="product" aria-expanded="false">
61+
Upload File
62+
</button>
63+
64+
<div id="product-wrapper">
65+
</div>
5966
<small class="form-hint">
6067
@error('image')
6168
<div class="text-danger mt-2">{{ $message }}</div>
@@ -196,6 +203,19 @@
196203
</form>
197204
</div>
198205

206+
@include('admin.components.media.popup', [
207+
'modalId' => 'product',
208+
'inputType' => 'single',
209+
'imageInputName' => 'image',
210+
])
211+
<template id="media-template">
212+
@include('admin.components.media.popup', [
213+
'modalId' => 'product-variant-__INDEX__',
214+
'inputType' => 'single',
215+
'imageInputName' => 'combinations[__INDEX__][image]',
216+
])
217+
</template>
218+
<div id="product-media-container"></div>
199219
@endsection
200220

201221

@@ -325,10 +345,40 @@ function generateVariantCombinations() {
325345
<input type="text" name="combinations[${index}][sku]" class="form-control" required>
326346
</td>
327347
<td>
328-
<input type="file" name="combinations[${index}][image]" class="form-control">
348+
<button type="button" class="btn btn-primary" id="product-variant-${index}-btn"
349+
data-bs-toggle="offcanvas" data-bs-target="#product-variant-${index}"
350+
aria-controls="product-variant-${index}" aria-expanded="false">
351+
Upload File
352+
</button>
353+
354+
<div id="product-variant-${index}-wrapper">
355+
</div>
329356
</td>
330357
`;
331358
359+
const mediaContainer = document.getElementById('product-media-container');
360+
const existingMedia = mediaContainer.querySelector(`#product-variant-${index}`);
361+
if (!existingMedia) {
362+
const template = document.getElementById('media-template').innerHTML;
363+
const rendered = template.replace(/__INDEX__/g, index);
364+
mediaContainer.insertAdjacentHTML('beforeend', rendered);
365+
366+
const newModal = document.getElementById(`product-variant-${index}`);
367+
if(newModal){
368+
const offcanvas = new tabler.Offcanvas(newModal);
369+
newModal.addEventListener('shown.bs.offcanvas', function() {
370+
const container = newModal.querySelector(`#ajax-container-${newModal.id}`);
371+
const route = newModal.getAttribute('data-route');
372+
if (container && route) {
373+
loadData(`${route}`, container);
374+
} else {
375+
console.error('Missing required elements or data for modal:', newModal.id, { container, route, folderId });
376+
}
377+
});
378+
}
379+
}
380+
381+
332382
wrapper.appendChild(row)
333383
});
334384
}

0 commit comments

Comments
 (0)