Add NAS file manager integration and all pending platform changes
- Installed p7h/nas-file-manager package via private VCS repo - Published config/nas-file-manager.php with super_admin middleware restriction - Added NAS env vars to .env.example - Created admin/nas-storage page with connection info panel and file browser widget - Added NAS Storage link to admin sidebar (super_admin only) - Added SuperAdminController@nasStorage method and admin.nas-storage route - Includes all accumulated branch changes: profile wall, 2FA, audit logs, settings panel, country/phone/timezone components, posts, slideshow, playlist shares, video downloads/shares, comment likes, notifications, social links, and more Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
1 parent
d44490dfe0
commit
0b2e95ea65
161 files changed
+27496
-7250
No files matched your search
@@ -3,164 +3,312 @@
|
||||
@section('title', 'Edit Video')
|
||||
@section('page_title', 'Edit Video')
|
||||
|
||||
@section('extra_styles')
|
||||
<style>
|
||||
.ef-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 300px;
|
||||
gap: 20px;
|
||||
align-items: start;
|
||||
}
|
||||
@media (max-width: 900px) {
|
||||
.ef-grid { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
||||
/* ── Form fields ── */
|
||||
.ef-field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 18px; }
|
||||
.ef-field:last-of-type { margin-bottom: 0; }
|
||||
.ef-label {
|
||||
font-size: 12px; font-weight: 600; color: var(--text-2);
|
||||
text-transform: uppercase; letter-spacing: .04em;
|
||||
}
|
||||
.ef-input, .ef-select, .ef-textarea {
|
||||
width: 100%;
|
||||
background: var(--bg-2);
|
||||
border: 1px solid var(--border);
|
||||
color: var(--text);
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
outline: none;
|
||||
transition: border-color .15s;
|
||||
font-family: inherit;
|
||||
}
|
||||
.ef-input, .ef-select { height: 38px; padding: 0 12px; }
|
||||
.ef-select { cursor: pointer; appearance: none;
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='%23888' viewBox='0 0 16 16'%3E%3Cpath d='M7.247 11.14L2.451 5.658C1.885 5.013 2.345 4 3.204 4h9.592a1 1 0 0 1 .753 1.659l-4.796 5.48a1 1 0 0 1-1.506 0z'/%3E%3C/svg%3E");
|
||||
background-repeat: no-repeat; background-position: right 12px center; padding-right: 32px;
|
||||
}
|
||||
.ef-textarea { height: 100px; padding: 10px 12px; resize: vertical; }
|
||||
.ef-input:focus, .ef-select:focus, .ef-textarea:focus { border-color: var(--brand); }
|
||||
.ef-input.is-invalid, .ef-select.is-invalid, .ef-textarea.is-invalid { border-color: #f87171; }
|
||||
.ef-error { font-size: 12px; color: #f87171; margin-top: 2px; }
|
||||
|
||||
.ef-row-3 { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 14px; }
|
||||
@media (max-width: 600px) { .ef-row-3 { grid-template-columns: 1fr; } }
|
||||
|
||||
/* ── Actions ── */
|
||||
.ef-actions { display: flex; gap: 10px; margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--border); }
|
||||
|
||||
/* ── Sidebar stats ── */
|
||||
.ef-thumb {
|
||||
width: 100%; border-radius: 10px; object-fit: cover; display: block;
|
||||
background: var(--bg-2);
|
||||
}
|
||||
.ef-thumb-placeholder {
|
||||
width: 100%; height: 160px; border-radius: 10px;
|
||||
background: var(--bg-2); border: 1px solid var(--border);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
color: var(--text-3); font-size: 36px;
|
||||
}
|
||||
.ef-stat-row {
|
||||
display: flex; justify-content: space-between; align-items: center;
|
||||
padding: 9px 0; border-bottom: 1px solid rgba(255,255,255,.04);
|
||||
font-size: 13px;
|
||||
}
|
||||
.ef-stat-row:last-child { border-bottom: none; padding-bottom: 0; }
|
||||
.ef-stat-label { color: var(--text-2); }
|
||||
.ef-stat-val { font-weight: 600; color: var(--text); }
|
||||
|
||||
/* ── Danger zone ── */
|
||||
.ef-danger-zone {
|
||||
padding: 16px;
|
||||
border: 1px solid rgba(248,113,113,.25);
|
||||
border-radius: 10px;
|
||||
background: rgba(248,113,113,.05);
|
||||
}
|
||||
.ef-danger-title { font-size: 12px; font-weight: 700; color: #f87171; margin-bottom: 10px; text-transform: uppercase; letter-spacing: .05em; }
|
||||
</style>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<!-- Alerts -->
|
||||
|
||||
{{-- ── Page header ── --}}
|
||||
<div class="adm-page-header" style="margin-bottom:20px;">
|
||||
<div style="display:flex;align-items:center;gap:12px;">
|
||||
<a href="{{ route('admin.videos') }}" class="adm-btn adm-btn-sm">
|
||||
<i class="bi bi-arrow-left"></i>
|
||||
</a>
|
||||
<h1 class="adm-page-title" style="margin:0;">
|
||||
<i class="bi bi-pencil-square"></i> Edit Video
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- ── Alerts ── --}}
|
||||
@if(session('success'))
|
||||
<div class="alert alert-success alert-dismissible fade show" role="alert">
|
||||
{{ session('success') }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
<div class="adm-alert adm-alert-success" style="margin-bottom:16px;">
|
||||
<i class="bi bi-check-circle-fill"></i>
|
||||
<span>{{ session('success') }}</span>
|
||||
<button class="adm-alert-close"><i class="bi bi-x"></i></button>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if(session('error'))
|
||||
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
||||
{{ session('error') }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
<div class="adm-alert adm-alert-error" style="margin-bottom:16px;">
|
||||
<i class="bi bi-exclamation-circle-fill"></i>
|
||||
<span>{{ session('error') }}</span>
|
||||
<button class="adm-alert-close"><i class="bi bi-x"></i></button>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-8">
|
||||
<!-- Edit Video Form -->
|
||||
<div class="admin-card">
|
||||
<div class="admin-card-header">
|
||||
<h5 class="admin-card-title">Edit Video</h5>
|
||||
<a href="{{ route('admin.videos') }}" class="btn btn-outline-light btn-sm">
|
||||
<i class="bi bi-arrow-left"></i> Back to Videos
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<form method="POST" action="{{ route('admin.videos.update', $video->id) }}">
|
||||
<div class="ef-grid">
|
||||
|
||||
{{-- ── Left: form ── --}}
|
||||
<div class="adm-card">
|
||||
<div class="adm-card-header">
|
||||
<div class="adm-card-title"><i class="bi bi-film"></i> Video Details</div>
|
||||
</div>
|
||||
<div class="adm-card-body">
|
||||
<form method="POST" action="{{ route('admin.videos.update', $video) }}">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="title" class="form-label">Title</label>
|
||||
<input type="text" class="form-control @error('title') is-invalid @enderror" id="title" name="title" value="{{ old('title', $video->title) }}" required>
|
||||
@error('title')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
|
||||
{{-- Title --}}
|
||||
<div class="ef-field">
|
||||
<label class="ef-label" for="title">Title</label>
|
||||
<input class="ef-input @error('title') is-invalid @enderror"
|
||||
id="title" name="title" type="text"
|
||||
value="{{ old('title', $video->title) }}" required>
|
||||
@error('title')<div class="ef-error">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="description" class="form-label">Description</label>
|
||||
<textarea class="form-control @error('description') is-invalid @enderror" id="description" name="description" rows="4">{{ old('description', $video->description) }}</textarea>
|
||||
@error('description')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
|
||||
{{-- Description --}}
|
||||
<div class="ef-field">
|
||||
<label class="ef-label" for="description">Description</label>
|
||||
<textarea class="ef-textarea @error('description') is-invalid @enderror"
|
||||
id="description" name="description">{{ old('description', $video->description) }}</textarea>
|
||||
@error('description')<div class="ef-error">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
|
||||
<div class="row mb-3">
|
||||
<div class="col-md-4">
|
||||
<label for="visibility" class="form-label">Visibility</label>
|
||||
<select class="form-select @error('visibility') is-invalid @enderror" id="visibility" name="visibility" required>
|
||||
<option value="public" {{ old('visibility', $video->visibility) == 'public' ? 'selected' : '' }}>Public</option>
|
||||
<option value="unlisted" {{ old('visibility', $video->visibility) == 'unlisted' ? 'selected' : '' }}>Unlisted</option>
|
||||
<option value="private" {{ old('visibility', $video->visibility) == 'private' ? 'selected' : '' }}>Private</option>
|
||||
|
||||
{{-- Visibility / Type / Status --}}
|
||||
<div class="ef-row-3">
|
||||
<div class="ef-field" style="margin-bottom:0;">
|
||||
<label class="ef-label" for="visibility">Visibility</label>
|
||||
<select class="ef-select @error('visibility') is-invalid @enderror" id="visibility" name="visibility">
|
||||
<option value="public" {{ old('visibility', $video->visibility) === 'public' ? 'selected' : '' }}>Public</option>
|
||||
<option value="unlisted" {{ old('visibility', $video->visibility) === 'unlisted' ? 'selected' : '' }}>Unlisted</option>
|
||||
<option value="private" {{ old('visibility', $video->visibility) === 'private' ? 'selected' : '' }}>Private</option>
|
||||
</select>
|
||||
@error('visibility')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
@error('visibility')<div class="ef-error">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<label for="type" class="form-label">Type</label>
|
||||
<select class="form-select @error('type') is-invalid @enderror" id="type" name="type" required>
|
||||
<option value="generic" {{ old('type', $video->type) == 'generic' ? 'selected' : '' }}>Generic</option>
|
||||
<option value="music" {{ old('type', $video->type) == 'music' ? 'selected' : '' }}>Music</option>
|
||||
<option value="match" {{ old('type', $video->type) == 'match' ? 'selected' : '' }}>Match</option>
|
||||
<div class="ef-field" style="margin-bottom:0;">
|
||||
<label class="ef-label" for="type">Type</label>
|
||||
<select class="ef-select @error('type') is-invalid @enderror" id="type" name="type">
|
||||
<option value="generic" {{ old('type', $video->type) === 'generic' ? 'selected' : '' }}>Generic</option>
|
||||
<option value="music" {{ old('type', $video->type) === 'music' ? 'selected' : '' }}>Music</option>
|
||||
<option value="match" {{ old('type', $video->type) === 'match' ? 'selected' : '' }}>Match</option>
|
||||
</select>
|
||||
@error('type')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
@error('type')<div class="ef-error">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<label for="status" class="form-label">Status</label>
|
||||
<select class="form-select @error('status') is-invalid @enderror" id="status" name="status" required>
|
||||
<option value="pending" {{ old('status', $video->status) == 'pending' ? 'selected' : '' }}>Pending</option>
|
||||
<option value="processing" {{ old('status', $video->status) == 'processing' ? 'selected' : '' }}>Processing</option>
|
||||
<option value="ready" {{ old('status', $video->status) == 'ready' ? 'selected' : '' }}>Ready</option>
|
||||
<option value="failed" {{ old('status', $video->status) == 'failed' ? 'selected' : '' }}>Failed</option>
|
||||
<div class="ef-field" style="margin-bottom:0;">
|
||||
<label class="ef-label" for="status">Status</label>
|
||||
<select class="ef-select @error('status') is-invalid @enderror" id="status" name="status">
|
||||
<option value="pending" {{ old('status', $video->status) === 'pending' ? 'selected' : '' }}>Pending</option>
|
||||
<option value="processing" {{ old('status', $video->status) === 'processing' ? 'selected' : '' }}>Processing</option>
|
||||
<option value="ready" {{ old('status', $video->status) === 'ready' ? 'selected' : '' }}>Ready</option>
|
||||
<option value="failed" {{ old('status', $video->status) === 'failed' ? 'selected' : '' }}>Failed</option>
|
||||
</select>
|
||||
@error('status')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
@error('status')<div class="ef-error">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex gap-2">
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="bi bi-check-circle"></i> Update Video
|
||||
|
||||
{{-- Download Access --}}
|
||||
<div class="ef-field" style="margin-top:18px;">
|
||||
<label class="ef-label" for="download_access">Who Can Download</label>
|
||||
<select class="ef-select @error('download_access') is-invalid @enderror" id="download_access" name="download_access">
|
||||
<option value="disabled" {{ old('download_access', $video->download_access) === 'disabled' ? 'selected' : '' }}>No one (disabled)</option>
|
||||
<option value="everyone" {{ old('download_access', $video->download_access) === 'everyone' ? 'selected' : '' }}>Everyone (guests too)</option>
|
||||
<option value="registered" {{ old('download_access', $video->download_access) === 'registered' ? 'selected' : '' }}>Registered members</option>
|
||||
<option value="subscribers" {{ old('download_access', $video->download_access) === 'subscribers' ? 'selected' : '' }}>Subscribers only</option>
|
||||
</select>
|
||||
@error('download_access')<div class="ef-error">{{ $message }}</div>@enderror
|
||||
</div>
|
||||
|
||||
<div class="ef-actions">
|
||||
<button type="submit" class="adm-btn adm-btn-primary">
|
||||
<i class="bi bi-check-circle-fill"></i> Save Changes
|
||||
</button>
|
||||
<a href="{{ route('admin.videos') }}" class="btn btn-outline-light">Cancel</a>
|
||||
<a href="{{ route('admin.videos') }}" class="adm-btn">Cancel</a>
|
||||
<a href="{{ route('videos.show', $video) }}" target="_blank" class="adm-btn" style="margin-left:auto;">
|
||||
<i class="bi bi-play-circle"></i> View Video
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4">
|
||||
<!-- Video Info -->
|
||||
<div class="admin-card">
|
||||
<div class="admin-card-header">
|
||||
<h5 class="admin-card-title">Video Info</h5>
|
||||
|
||||
{{-- ── Right: sidebar ── --}}
|
||||
<div style="display:flex;flex-direction:column;gap:16px;">
|
||||
|
||||
{{-- Thumbnail --}}
|
||||
<div class="adm-card">
|
||||
<div class="adm-card-body">
|
||||
@if($video->thumbnail)
|
||||
<img src="{{ asset('storage/thumbnails/' . $video->thumbnail) }}"
|
||||
alt="{{ $video->title }}" class="ef-thumb">
|
||||
@else
|
||||
<div class="ef-thumb-placeholder"><i class="bi bi-play-circle"></i></div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@if($video->thumbnail)
|
||||
<img src="{{ asset('storage/thumbnails/' . $video->thumbnail) }}" alt="{{ $video->title }}" class="img-fluid rounded mb-3" style="width: 100%;">
|
||||
@else
|
||||
<div class="bg-secondary rounded d-flex align-items-center justify-content-center mb-3" style="height: 180px;">
|
||||
<i class="bi bi-play-circle text-white" style="font-size: 3rem;"></i>
|
||||
</div>
|
||||
|
||||
{{-- Stats --}}
|
||||
<div class="adm-card">
|
||||
<div class="adm-card-header">
|
||||
<div class="adm-card-title"><i class="bi bi-info-circle"></i> Video Info</div>
|
||||
</div>
|
||||
<div class="adm-card-body">
|
||||
<div class="ef-stat-row">
|
||||
<span class="ef-stat-label">Owner</span>
|
||||
<a href="{{ route('channel', $video->user->channel) }}" target="_blank"
|
||||
style="color:var(--brand);font-weight:600;font-size:13px;text-decoration:none;">
|
||||
{{ $video->user->name }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="ef-stat-row">
|
||||
<span class="ef-stat-label">Uploaded</span>
|
||||
<span class="ef-stat-val">{{ $video->created_at->format('M d, Y') }}</span>
|
||||
</div>
|
||||
<div class="ef-stat-row">
|
||||
<span class="ef-stat-label">Views</span>
|
||||
<span class="ef-stat-val" style="color:#22d3ee;">
|
||||
{{ number_format(\DB::table('video_views')->where('video_id', $video->id)->count()) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="ef-stat-row">
|
||||
<span class="ef-stat-label">Likes</span>
|
||||
<span class="ef-stat-val" style="color:#f472b6;">
|
||||
{{ number_format(\DB::table('video_likes')->where('video_id', $video->id)->count()) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="ef-stat-row">
|
||||
<span class="ef-stat-label">Duration</span>
|
||||
<span class="ef-stat-val">{{ $video->duration ? gmdate('H:i:s', $video->duration) : '—' }}</span>
|
||||
</div>
|
||||
<div class="ef-stat-row">
|
||||
<span class="ef-stat-label">Dimensions</span>
|
||||
<span class="ef-stat-val">{{ $video->width ?? '—' }} × {{ $video->height ?? '—' }}</span>
|
||||
</div>
|
||||
<div class="ef-stat-row">
|
||||
<span class="ef-stat-label">File size</span>
|
||||
<span class="ef-stat-val">{{ $video->size ? number_format($video->size / 1024 / 1024, 1) . ' MB' : '—' }}</span>
|
||||
</div>
|
||||
<div class="ef-stat-row">
|
||||
<span class="ef-stat-label">Orientation</span>
|
||||
<span class="ef-stat-val" style="text-transform:capitalize;">{{ $video->orientation ?? '—' }}</span>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<hr style="border-color: var(--border-color);">
|
||||
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span class="text-secondary">Video ID</span>
|
||||
<span>#{{ $video->id }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span class="text-secondary">Owner</span>
|
||||
<a href="{{ route('channel', $video->user->id) }}" target="_blank">{{ $video->user->name }}</a>
|
||||
</div>
|
||||
|
||||
{{-- Danger zone --}}
|
||||
<div class="ef-danger-zone">
|
||||
<div class="ef-danger-title"><i class="bi bi-exclamation-triangle-fill me-1"></i> Danger Zone</div>
|
||||
<button type="button" class="adm-btn adm-btn-danger" style="width:100%;"
|
||||
onclick="openDelDialog()">
|
||||
<i class="bi bi-trash3-fill"></i> Delete This Video
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- ── Delete confirmation dialog ── --}}
|
||||
<div class="adm-dialog-overlay" id="delDialog">
|
||||
<div class="adm-dialog">
|
||||
<div class="adm-dialog-header">
|
||||
<div class="adm-dialog-title">
|
||||
<i class="bi bi-exclamation-triangle-fill"></i> Delete Video
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span class="text-secondary">Uploaded</span>
|
||||
<span>{{ $video->created_at->format('M d, Y') }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span class="text-secondary">File Size</span>
|
||||
<span>{{ number_format($video->size / 1024 / 1024, 2) }} MB</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span class="text-secondary">Duration</span>
|
||||
<span>{{ $video->duration ? gmdate('H:i:s', $video->duration) : 'N/A' }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span class="text-secondary">Orientation</span>
|
||||
<span class="text-capitalize">{{ $video->orientation }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span class="text-secondary">Dimensions</span>
|
||||
<span>{{ $video->width ?? 'N/A' }} x {{ $video->height ?? 'N/A' }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between mb-2">
|
||||
<span class="text-secondary">Views</span>
|
||||
<span>{{ number_format(\DB::table('video_views')->where('video_id', $video->id)->count()) }}</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between">
|
||||
<span class="text-secondary">Likes</span>
|
||||
<span>{{ number_format(\DB::table('video_likes')->where('video_id', $video->id)->count()) }}</span>
|
||||
</div>
|
||||
|
||||
<hr style="border-color: var(--border-color);">
|
||||
|
||||
<div class="d-grid gap-2">
|
||||
<a href="{{ route('videos.show', $video->id) }}" target="_blank" class="btn btn-outline-light btn-sm">
|
||||
<i class="bi bi-play-circle"></i> View Video
|
||||
</a>
|
||||
<button type="button" class="adm-btn adm-btn-sm" onclick="closeDelDialog()"
|
||||
style="border:none;background:none;color:var(--text-2);">
|
||||
<i class="bi bi-x-lg"></i>
|
||||
</button>
|
||||
</div>
|
||||
<div class="adm-dialog-body">
|
||||
<p>You are about to permanently delete <strong>{{ $video->title }}</strong>.</p>
|
||||
<div class="adm-dialog-warning">
|
||||
<i class="bi bi-info-circle-fill" style="flex-shrink:0;margin-top:1px;"></i>
|
||||
The video file, thumbnail, and all associated data will be removed. This cannot be undone.
|
||||
</div>
|
||||
</div>
|
||||
<div class="adm-dialog-footer">
|
||||
<button type="button" class="adm-btn" onclick="closeDelDialog()">Cancel</button>
|
||||
<form method="POST" action="{{ route('admin.videos.delete', $video) }}">
|
||||
@csrf @method('DELETE')
|
||||
<button type="submit" class="adm-btn adm-btn-danger" style="height:36px;">
|
||||
<i class="bi bi-trash3-fill"></i> Delete Permanently
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@section('scripts')
|
||||
<script>
|
||||
function openDelDialog() { document.getElementById('delDialog').classList.add('open'); }
|
||||
function closeDelDialog() { document.getElementById('delDialog').classList.remove('open'); }
|
||||
document.getElementById('delDialog').addEventListener('click', e => { if (e.target === document.getElementById('delDialog')) closeDelDialog(); });
|
||||
document.addEventListener('keydown', e => { if (e.key === 'Escape') closeDelDialog(); });
|
||||
</script>
|
||||
@endsection
|
||||
Reference in new issue
Block a user