feat: add notes management feature with CRUD operations
- Created Note model and controller for handling notes. - Added routes for notes CRUD operations. - Implemented notes index view with search and pinning functionality. - Created migration for notes table with necessary fields. - Developed event creation form with client and contract options.
This commit is contained in:
@@ -6,6 +6,29 @@
|
||||
|
||||
@section('content')
|
||||
|
||||
{{-- ── Video Player Modal ───────────────────────────────────── --}}
|
||||
<div id="video-player-modal"
|
||||
class="fixed inset-0 z-50 flex items-center justify-center bg-black/80 hidden"
|
||||
onclick="if(event.target===this)closeVideoModal()">
|
||||
<div class="relative w-full max-w-3xl mx-4">
|
||||
<div class="flex items-center justify-between mb-3 px-1">
|
||||
<p class="text-white text-sm font-semibold truncate" id="vpm-title"></p>
|
||||
<button onclick="closeVideoModal()"
|
||||
class="text-white/70 hover:text-white text-2xl leading-none ml-4 shrink-0">✕</button>
|
||||
</div>
|
||||
<video id="vpm-player"
|
||||
class="w-full rounded-2xl bg-black shadow-2xl"
|
||||
controls controlsList="nodownload"
|
||||
style="max-height:70vh">
|
||||
</video>
|
||||
<div class="flex items-center justify-between mt-3 px-1 text-xs text-white/60">
|
||||
<span id="vpm-meta"></span>
|
||||
<a id="vpm-dl" href="#" target="_blank"
|
||||
class="text-pink-300 hover:text-pink-200 font-medium">⬇️ Download</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- ── File Detail Popup Modal ──────────────────────────────── --}}
|
||||
<div id="file-detail-modal"
|
||||
class="fixed inset-0 z-50 flex items-end sm:items-center justify-center bg-black/40 hidden"
|
||||
@@ -191,17 +214,37 @@
|
||||
<div class="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-4 xl:grid-cols-5 gap-3">
|
||||
@endif
|
||||
|
||||
@php $fileData = ['name' => $file->name ?: $file->original_name, 'url' => $file->url, 'size' => $file->human_size, 'folder' => $file->folder, 'client' => $file->client?->name, 'is_image' => $file->is_image, 'is_video' => $file->is_video, 'icon' => $file->icon, 'created_at' => $file->created_at->format('d M Y')] @endphp
|
||||
<div class="cat-card p-3 flex flex-col gap-2">
|
||||
{{-- Preview / Icon --}}
|
||||
@if($file->is_image)
|
||||
<div class="w-full aspect-square rounded-2xl overflow-hidden bg-pink-50 cursor-pointer"
|
||||
onclick="showFileDetail({{ json_encode(['name' => $file->name ?: $file->original_name, 'url' => $file->url, 'size' => $file->human_size, 'folder' => $file->folder, 'client' => $file->client?->name, 'is_image' => $file->is_image, 'icon' => $file->icon, 'created_at' => $file->created_at->format('d M Y')]) }})">
|
||||
onclick="showFileDetail({{ json_encode($fileData) }})">
|
||||
<img src="{{ $file->url }}" alt="{{ $file->name }}"
|
||||
class="w-full h-full object-cover">
|
||||
</div>
|
||||
@elseif($file->is_video)
|
||||
<div class="w-full aspect-square rounded-2xl overflow-hidden bg-gray-900 relative cursor-pointer group"
|
||||
onclick="openVideoPlayer({{ json_encode($fileData) }})">
|
||||
{{-- Native video poster (browser generates a frame) --}}
|
||||
<video src="{{ $file->url }}"
|
||||
class="w-full h-full object-cover opacity-80"
|
||||
preload="metadata"
|
||||
muted playsinline
|
||||
style="pointer-events:none">
|
||||
</video>
|
||||
{{-- Play overlay --}}
|
||||
<div class="absolute inset-0 flex items-center justify-center
|
||||
bg-black/20 group-hover:bg-black/40 transition-colors">
|
||||
<div class="w-12 h-12 rounded-full bg-white/90 flex items-center justify-center shadow-lg
|
||||
group-hover:scale-110 transition-transform">
|
||||
<span class="text-gray-800 text-xl ml-0.5">▶</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@else
|
||||
<div class="w-full aspect-square rounded-2xl bg-pink-50 flex items-center justify-center text-4xl cursor-pointer"
|
||||
onclick="showFileDetail({{ json_encode(['name' => $file->name ?: $file->original_name, 'url' => $file->url, 'size' => $file->human_size, 'folder' => $file->folder, 'client' => $file->client?->name, 'is_image' => false, 'icon' => $file->icon, 'created_at' => $file->created_at->format('d M Y')]) }})">
|
||||
onclick="showFileDetail({{ json_encode($fileData) }})">
|
||||
{{ $file->icon }}
|
||||
</div>
|
||||
@endif
|
||||
@@ -256,7 +299,6 @@ function showFileDetail(file) {
|
||||
document.getElementById('fdm-name').textContent = file.name;
|
||||
document.getElementById('fdm-view-btn').href = file.url;
|
||||
|
||||
// Preview area
|
||||
const preview = document.getElementById('fdm-preview');
|
||||
if (file.is_image) {
|
||||
preview.innerHTML = `<img src="${file.url}" alt="${file.name}" class="max-h-48 rounded-2xl object-contain border border-pink-100">`;
|
||||
@@ -264,7 +306,6 @@ function showFileDetail(file) {
|
||||
preview.innerHTML = `<span class="text-6xl">${file.icon}</span>`;
|
||||
}
|
||||
|
||||
// Info rows
|
||||
const rows = [
|
||||
['Size', file.size],
|
||||
['Folder', file.folder],
|
||||
@@ -278,6 +319,32 @@ function showFileDetail(file) {
|
||||
|
||||
document.getElementById('file-detail-modal').classList.remove('hidden');
|
||||
}
|
||||
|
||||
function openVideoPlayer(file) {
|
||||
const player = document.getElementById('vpm-player');
|
||||
player.src = file.url;
|
||||
player.load();
|
||||
|
||||
document.getElementById('vpm-title').textContent = file.name;
|
||||
document.getElementById('vpm-meta').textContent = file.size + (file.client ? ' · ' + file.client : '');
|
||||
document.getElementById('vpm-dl').href = file.url;
|
||||
|
||||
document.getElementById('video-player-modal').classList.remove('hidden');
|
||||
document.body.style.overflow = 'hidden';
|
||||
}
|
||||
|
||||
function closeVideoModal() {
|
||||
const player = document.getElementById('vpm-player');
|
||||
player.pause();
|
||||
player.src = '';
|
||||
document.getElementById('video-player-modal').classList.add('hidden');
|
||||
document.body.style.overflow = '';
|
||||
}
|
||||
|
||||
// Close video modal on Escape
|
||||
document.addEventListener('keydown', e => {
|
||||
if (e.key === 'Escape') closeVideoModal();
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
|
||||
|
||||
Reference in New Issue
Block a user