<?php $__env->startSection('title', 'Image Gallery'); ?>
<?php $__env->startPush('styles'); ?>
<style>
.media-upload-zone {
border: 2px dashed #d1d5db; border-radius: 10px;
padding: 36px 20px; text-align: center; cursor: pointer;
transition: border-color .2s, background .2s; background: #fafafa;
}
.media-upload-zone.drag-over { border-color: #4f46e5; background: #f5f3ff; }
.media-upload-zone i { font-size: 2.5rem; color: #9ca3af; display: block; margin-bottom: 10px; }
.media-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 12px;
}
.media-card {
position: relative; border: 1px solid #e5e7eb; border-radius: 8px;
overflow: hidden; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.06);
transition: box-shadow .2s, transform .15s;
}
.media-card:hover { box-shadow: 0 4px 16px rgba(0,0,0,.12); transform: translateY(-2px); }
.media-card-img {
width: 100%; aspect-ratio: 1; object-fit: cover;
display: block; background: #f9fafb; cursor: zoom-in;
}
.media-card-body { padding: 7px 8px; }
.media-card-title { font-size: .72rem; font-weight: 600; color: #374151; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.media-card-meta { font-size: .62rem; color: #9ca3af; margin-top: 2px; }
.media-card-actions { display: flex; gap: 4px; margin-top: 6px; }
.media-card-actions .btn { font-size: .65rem; padding: 2px 7px; }
/* Copy URL button */
.btn-copy { cursor: pointer; }
.btn-copy.copied { background: #10b981 !important; border-color: #10b981 !important; color: #fff !important; }
/* Progress bar */
.upload-progress { display: none; margin-top: 12px; }
.progress-bar-wrap { background: #e5e7eb; border-radius: 999px; height: 8px; overflow: hidden; margin-top: 6px; }
.progress-bar-fill { height: 100%; background: #4f46e5; width: 0%; transition: width .3s; border-radius: 999px; }
/* Lightbox */
#mediaLightbox {
display: none; position: fixed; inset: 0; z-index: 9999;
background: rgba(0,0,0,.92); align-items: center; justify-content: center;
flex-direction: column; gap: 12px;
}
#mediaLightbox.open { display: flex; }
#mediaLightbox img { max-width: 90vw; max-height: 80vh; border-radius: 6px; box-shadow: 0 8px 40px rgba(0,0,0,.5); }
#mediaLightbox .lb-bar {
background: rgba(255,255,255,.1); border-radius: 8px; padding: 10px 16px;
display: flex; gap: 12px; align-items: center; flex-wrap: wrap; max-width: 90vw;
}
#mediaLightbox .lb-url {
font-family: monospace; font-size: .8rem; color: #e0e0e0;
background: rgba(0,0,0,.4); padding: 6px 10px; border-radius: 5px;
word-break: break-all; flex: 1;
}
#mediaLightbox .lb-close {
position: fixed; top: 16px; right: 20px;
background: rgba(255,255,255,.15); border: none; color: #fff;
font-size: 1.4rem; width: 36px; height: 36px; border-radius: 50%;
cursor: pointer; display: flex; align-items: center; justify-content: center;
transition: background .15s;
}
#mediaLightbox .lb-close:hover { background: rgba(192,57,43,.8); }
</style>
<?php $__env->stopPush(); ?>
<?php $__env->startSection('content'); ?>
<div class="d-flex align-items-center justify-content-between mb-3">
<h5 class="mb-0"><i class="bi bi-images me-2"></i>Image Gallery</h5>
<form method="GET" class="d-flex gap-2">
<input type="text" name="q" value="<?php echo e(request('q')); ?>" class="form-control form-control-sm"
placeholder="নাম দিয়ে খুঁজুন..." style="width:200px">
<button class="btn btn-sm btn-outline-secondary">খুঁজুন</button>
<?php if(request('q')): ?>
<a href="<?php echo e(route('admin.media.index')); ?>" class="btn btn-sm btn-outline-danger">✕</a>
<?php endif; ?>
</form>
</div>
<div class="card mb-4">
<div class="card-header py-3 px-4"><i class="bi bi-cloud-upload me-2"></i>ছবি আপলোড করুন</div>
<div class="card-body p-4">
<div class="media-upload-zone" id="uploadZone">
<i class="bi bi-file-earmark-image"></i>
<div class="fw-semibold" style="font-size:.95rem">এখানে ছবি ড্রপ করুন অথবা ক্লিক করুন</div>
<div class="text-muted mt-1" style="font-size:.8rem">JPG, PNG, WEBP, GIF, SVG — সর্বোচ্চ 10MB প্রতিটি, একসাথে ২০টি পর্যন্ত</div>
<input type="file" id="fileInput" multiple accept="image/*" class="d-none">
</div>
<div class="upload-progress" id="uploadProgress">
<div class="d-flex justify-content-between" style="font-size:.8rem">
<span id="progressText">আপলোড হচ্ছে...</span>
<span id="progressPct">0%</span>
</div>
<div class="progress-bar-wrap">
<div class="progress-bar-fill" id="progressFill"></div>
</div>
</div>
<div id="uploadResult" class="mt-2"></div>
</div>
</div>
<div class="card">
<div class="card-header py-3 px-4 d-flex align-items-center justify-content-between">
<span><i class="bi bi-grid me-2"></i>সব ছবি (<?php echo e($media->total()); ?>টি)</span>
<span class="text-muted" style="font-size:.78rem">যেকোনো ছবিতে ক্লিক করলে বড় দেখাবে ও URL পাবেন</span>
</div>
<div class="card-body p-3">
<?php if($media->count()): ?>
<div class="media-grid" id="mediaGrid">
<?php $__currentLoopData = $media; $__env->addLoop($__currentLoopData); foreach($__currentLoopData as $item): $__env->incrementLoopIndices(); $loop = $__env->getLastLoop(); ?>
<?php echo $__env->make('admin.media._card', ['item' => $item], \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?>
<?php endforeach; $__env->popLoop(); $loop = $__env->getLastLoop(); ?>
</div>
<div class="mt-3"><?php echo e($media->links()); ?></div>
<?php endif; ?>
</div>
</div>
<div id="mediaLightbox">
<button class="lb-close" id="lbClose">✕</button>
<img id="lbImage" src="" alt="">
<div class="lb-bar">
<span class="lb-url" id="lbUrl"></span>
<button class="btn btn-sm btn-light btn-copy" id="lbCopyBtn" onclick="lbCopy()">
<i class="bi bi-clipboard me-1"></i>URL কপি
</button>
<a id="lbOpenBtn" href="#" target="_blank" class="btn btn-sm btn-outline-light">
<i class="bi bi-box-arrow-up-right me-1"></i>খুলুন
</a>
</div>
</div>
<?php $__env->stopSection(); ?>
<?php $__env->startPush('scripts'); ?>
<script>
var uploadUrl = '<?php echo e(route("admin.media.store")); ?>';
var csrfToken = '<?php echo e(csrf_token()); ?>';
/* ── Upload zone ─────────────────────────────────── */
var zone = document.getElementById('uploadZone');
var input = document.getElementById('fileInput');
zone.addEventListener('click', function () { input.click(); });
zone.addEventListener('dragover', function (e) { e.preventDefault(); zone.classList.add('drag-over'); });
zone.addEventListener('dragleave', function () { zone.classList.remove('drag-over'); });
zone.addEventListener('drop', function (e) { e.preventDefault(); zone.classList.remove('drag-over'); uploadFiles(e.dataTransfer.files); });
input.addEventListener('change', function () { uploadFiles(this.files); this.value = ''; });
function uploadFiles(files) {
if (!files.length) return;
var fd = new FormData();
Array.from(files).forEach(function (f) { fd.append('files[]', f); });
fd.append('_token', csrfToken);
var prog = document.getElementById('uploadProgress');
var fill = document.getElementById('progressFill');
var pct = document.getElementById('progressPct');
var text = document.getElementById('progressText');
var result = document.getElementById('uploadResult');
prog.style.display = 'block';
result.innerHTML = '';
var xhr = new XMLHttpRequest();
xhr.open('POST', uploadUrl);
xhr.setRequestHeader('X-CSRF-TOKEN', csrfToken);
xhr.setRequestHeader('Accept', 'application/json');
xhr.upload.addEventListener('progress', function (e) {
if (!e.lengthComputable) return;
var p = Math.round(e.loaded / e.total * 100);
fill.style.width = p + '%';
pct.textContent = p + '%';
text.textContent = p < 100 ? 'আপলোড হচ্ছে...' : 'প্রসেস হচ্ছে...';
});
xhr.addEventListener('load', function () {
prog.style.display = 'none';
fill.style.width = '0%';
try {
var res = JSON.parse(xhr.responseText);
if (res.success) {
result.innerHTML = '<div class="alert alert-success py-2 mb-0">' +
'<i class="bi bi-check-circle me-1"></i>' + res.count + 'টি ছবি সফলভাবে আপলোড হয়েছে।</div>';
prependCards(res.items);
} else {
result.innerHTML = '<div class="alert alert-danger py-2 mb-0">আপলোড ব্যর্থ হয়েছে।</div>';
}
} catch (e) {
result.innerHTML = '<div class="alert alert-danger py-2 mb-0">সার্ভার এরর।</div>';
}
});
xhr.addEventListener('error', function () {
prog.style.display = 'none';
result.innerHTML = '<div class="alert alert-danger py-2 mb-0">নেটওয়ার্ক সমস্যা।</div>';
});
xhr.send(fd);
}
function prependCards(items) {
var grid = document.getElementById('mediaGrid');
if (!grid) { location.reload(); return; }
items.reverse().forEach(function (item) {
var div = document.createElement('div');
div.className = 'media-card';
div.dataset.id = item.id;
div.dataset.url = item.url;
div.innerHTML = cardHtml(item);
grid.prepend(div);
});
}
function cardHtml(item) {
return '<img class="media-card-img" src="' + item.url + '" alt="" onclick="openLightbox(\'' + item.url + '\')">' +
'<div class="media-card-body">' +
'<div class="media-card-title">' + (item.title || '—') + '</div>' +
'<div class="media-card-actions">' +
'<button class="btn btn-xs btn-outline-primary btn-copy" onclick="copyUrl(\'' + item.url + '\', this)" style="font-size:.63rem;padding:2px 7px"><i class="bi bi-clipboard me-1"></i>URL</button>' +
'<button class="btn btn-xs btn-outline-danger" onclick="deleteMedia(' + item.id + ', this)" style="font-size:.63rem;padding:2px 7px"><i class="bi bi-trash"></i></button>' +
'</div></div>';
}
/* ── Copy URL ─────────────────────────────────────── */
function copyUrl(url, btn) {
navigator.clipboard.writeText(url).then(function () {
var orig = btn.innerHTML;
btn.innerHTML = '<i class="bi bi-check me-1"></i>কপি!';
btn.classList.add('copied');
setTimeout(function () { btn.innerHTML = orig; btn.classList.remove('copied'); }, 2000);
});
}
/* ── Delete ───────────────────────────────────────── */
function deleteMedia(id, btn) {
if (!confirm('এই ছবিটি স্থায়ীভাবে মুছে ফেলবেন?')) return;
var card = btn.closest('.media-card');
fetch('<?php echo e(url("/admin/media")); ?>/' + id, {
method: 'DELETE',
headers: { 'X-CSRF-TOKEN': csrfToken, 'Accept': 'application/json' }
}).then(function (r) { return r.json(); }).then(function (res) {
if (res.success) {
card.style.transition = 'opacity .3s, transform .3s';
card.style.opacity = '0';
card.style.transform = 'scale(.8)';
setTimeout(function () { card.remove(); }, 300);
}
});
}
/* ── Lightbox ─────────────────────────────────────── */
function openLightbox(url) {
document.getElementById('lbImage').src = url;
document.getElementById('lbUrl').textContent = url;
document.getElementById('lbOpenBtn').href = url;
document.getElementById('mediaLightbox').classList.add('open');
}
function lbCopy() {
var url = document.getElementById('lbUrl').textContent;
navigator.clipboard.writeText(url).then(function () {
var btn = document.getElementById('lbCopyBtn');
btn.innerHTML = '<i class="bi bi-check me-1"></i>কপি হয়েছে!';
btn.classList.add('copied');
setTimeout(function () {
btn.innerHTML = '<i class="bi bi-clipboard me-1"></i>URL কপি';
btn.classList.remove('copied');
}, 2000);
});
}
document.getElementById('lbClose').addEventListener('click', function () {
document.getElementById('mediaLightbox').classList.remove('open');
});
document.getElementById('mediaLightbox').addEventListener('click', function (e) {
if (e.target === this) this.classList.remove('open');
});
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape') document.getElementById('mediaLightbox').classList.remove('open');
});
/* ── Existing card buttons (server-rendered) ─────── */
document.querySelectorAll('.media-card').forEach(function (card) {
var img = card.querySelector('.media-card-img');
if (img) img.addEventListener('click', function () { openLightbox(img.src); });
});
</script>
<?php $__env->stopPush(); ?>
<?php echo $__env->make('layouts.admin', \Illuminate\Support\Arr::except(get_defined_vars(), ['__data', '__path']))->render(); ?><?php /**PATH /home/boguraj1/public_html/epaper/resources/views/admin/media/index.blade.php ENDPATH**/ ?>