made the video cards components

This commit is contained in:
ghassan committed 2026-03-02 02:16:28 +03:00
1 parent 3aa49d638d
commit 72e9439727
16 files changed
+3973 -250

No files matched your search

+141 -1
View File
@@ -398,6 +398,13 @@
background: var(--border-color);
color: var(--text-primary);
}
/* Modal input focus */
#deleteVideoInput:focus {
outline: none;
border-color: #ef4444 !important;
box-shadow: 0 0 0 2px rgba(239, 68, 68, 0.2);
}
</style>
@yield('extra_styles')
@@ -431,6 +438,54 @@
@auth
@include('layouts.partials.upload-modal')
@include('layouts.partials.edit-video-modal')
<!-- Delete Video Modal -->
<div class="modal fade" id="deleteVideoModal" tabindex="-1" aria-labelledby="deleteVideoModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content" style="background: #1a1a1a; border: 1px solid #3f3f3f; border-radius: 12px;">
<div class="modal-header" style="border-bottom: 1px solid #3f3f3f; padding: 20px 24px;">
<h5 class="modal-title" id="deleteVideoModalLabel" style="color: #fff; font-weight: 600; display: flex; align-items: center; gap: 10px;">
<i class="bi bi-exclamation-triangle-fill" style="color: #ef4444;"></i>
Delete Video
</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body" style="padding: 24px;">
<div style="background: #282828; border-radius: 8px; padding: 16px; margin-bottom: 20px;">
<p style="color: #fff; margin: 0; font-size: 14px; line-height: 1.6;">
<strong style="color: #ef4444;">Warning:</strong> This action is permanent and cannot be undone.
All data associated with this video will be lost, including:
</p>
<ul style="color: #aaa; margin: 12px 0 0; padding-left: 20px; font-size: 14px; line-height: 1.8;">
<li>View count</li>
<li>Comments</li>
<li>Likes</li>
<li>Thumbnail</li>
<li>Video file</li>
</ul>
</div>
<div>
<label for="deleteVideoInput" style="color: #aaa; font-size: 14px; margin-bottom: 8px; display: block;">
To confirm deletion, type <strong style="color: #fff;">"<span id="deleteVideoName"></span>"</strong> below:
</label>
<input type="text"
id="deleteVideoInput"
class="form-control"
style="background: #282828; border: 1px solid #3f3f3f; color: #fff; padding: 12px 16px; border-radius: 8px; font-size: 14px;"
placeholder="Enter video name">
</div>
</div>
<div class="modal-footer" style="border-top: 1px solid #3f3f3f; padding: 16px 24px; gap: 12px;">
<button type="button" class="btn" style="background: #3f3f3f; color: #fff; padding: 10px 20px; border-radius: 8px; font-weight: 500; border: none;" data-bs-dismiss="modal">
Cancel
</button>
<button type="button" id="confirmDeleteBtn" class="btn" style="background: #ef4444; color: #fff; padding: 10px 20px; border-radius: 8px; font-weight: 500; border: none; opacity: 0.5; cursor: not-allowed;" disabled onclick="confirmDeleteVideo()">
Delete Video
</button>
</div>
</div>
</div>
</div>
@endauth
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
@@ -531,9 +586,94 @@
restoreSidebarState();
}
});
// Delete video modal functions
let currentDeleteVideoId = null;
let currentDeleteVideoTitle = '';
function showDeleteModal(videoId, videoTitle) {
currentDeleteVideoId = videoId;
currentDeleteVideoTitle = videoTitle;
document.getElementById('deleteVideoName').textContent = videoTitle;
document.getElementById('deleteVideoInput').value = '';
const deleteBtn = document.getElementById('confirmDeleteBtn');
deleteBtn.disabled = true;
deleteBtn.style.opacity = '0.5';
deleteBtn.style.cursor = 'not-allowed';
// Close the dropdown first
const dropdown = document.querySelector('.dropdown-menu.show');
if (dropdown) {
dropdown.classList.remove('show');
}
// Show the modal
const modalElement = document.getElementById('deleteVideoModal');
const modal = new bootstrap.Modal(modalElement);
modal.show();
}
document.getElementById('deleteVideoInput').addEventListener('input', function(e) {
const deleteBtn = document.getElementById('confirmDeleteBtn');
if (e.target.value === currentDeleteVideoTitle) {
deleteBtn.disabled = false;
deleteBtn.style.opacity = '1';
deleteBtn.style.cursor = 'pointer';
} else {
deleteBtn.disabled = true;
deleteBtn.style.opacity = '0.5';
deleteBtn.style.cursor = 'not-allowed';
}
});
function confirmDeleteVideo() {
if (!currentDeleteVideoId || !currentDeleteVideoTitle) return;
const inputValue = document.getElementById('deleteVideoInput').value;
if (inputValue !== currentDeleteVideoTitle) {
alert('Video name does not match. Please try again.');
return;
}
fetch(`/videos/${currentDeleteVideoId}`, {
method: 'DELETE',
headers: {
'X-CSRF-TOKEN': '{{ csrf_token() }}',
'Accept': 'application/json'
}
})
.then(response => {
// Check for successful response
if (response.status === 200 || response.status === 302 || response.redirected) {
// Close modal first
const modalElement = document.getElementById('deleteVideoModal');
const modal = bootstrap.Modal.getInstance(modalElement);
if (modal) {
modal.hide();
}
// Reload the page
window.location.reload();
} else if (response.status === 403) {
alert('You do not have permission to delete this video.');
} else if (response.status === 404) {
alert('Video not found.');
} else {
response.json().then(data => {
alert(data.message || 'Failed to delete video. Please try again.');
}).catch(() => {
alert('Failed to delete video. Please try again.');
});
}
})
.catch(error => {
console.error('Error:', error);
alert('An error occurred while deleting the video.');
});
}
</script>
@yield('scripts')
</body>
</html>
@@ -83,6 +83,35 @@
class="form-textarea"
placeholder="Tell viewers about your video"></textarea>
</div>
<div class="form-group">
<label class="form-label">
<i class="bi bi-collection-play"></i> Video Type
</label>
<div class="video-type-options">
<label class="video-type-option" id="type-generic">
<input type="radio" name="type" value="generic" checked>
<div class="video-type-content">
<i class="bi bi-film"></i>
<span>Generic</span>
</div>
</label>
<label class="video-type-option" id="type-music">
<input type="radio" name="type" value="music">
<div class="video-type-content">
<i class="bi bi-music-note"></i>
<span>Music</span>
</div>
</label>
<label class="video-type-option" id="type-match">
<input type="radio" name="type" value="match">
<div class="video-type-content">
<i class="bi bi-trophy"></i>
<span>Match</span>
</div>
</label>
</div>
</div>
<div class="step-navigation">
<div></div>
@@ -486,6 +515,63 @@
color: #666;
}
/* Video Type Options */
.video-type-options {
display: flex;
gap: 12px;
}
.video-type-option {
flex: 1;
cursor: pointer;
}
.video-type-option input {
display: none;
}
.video-type-content {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
padding: 16px 12px;
background: #1a1a1a;
border: 2px solid #333;
border-radius: 12px;
transition: all 0.2s;
}
.video-type-option:hover .video-type-content {
border-color: #555;
background: #1f1f1f;
}
.video-type-option.active .video-type-content {
border-color: #e61e1e;
background: rgba(230, 30, 30, 0.1);
}
.video-type-content i {
font-size: 24px;
color: #666;
transition: color 0.2s;
}
.video-type-option.active .video-type-content i {
color: #e61e1e;
}
.video-type-content span {
font-size: 13px;
font-weight: 500;
color: #aaa;
}
.video-type-option.active .video-type-content span {
color: #e5e5e5;
}
/* Dropzone */
.dropzone-modal {
border: 2px dashed #404040;
@@ -777,6 +863,10 @@
width: 30px;
}
.video-type-options {
flex-direction: column;
}
.step-navigation {
flex-direction: column-reverse;
gap: 12px;
@@ -826,6 +916,17 @@ function openEditVideoModal(videoId) {
thumbnailWrapper.classList.remove('has-thumbnail');
}
// Set video type
const videoType = video.type || 'generic';
document.querySelectorAll('.video-type-option').forEach(opt => {
opt.classList.remove('active');
const radio = opt.querySelector('input[type="radio"]');
if (radio.value === videoType) {
radio.checked = true;
opt.classList.add('active');
}
});
// Set visibility
const visibility = video.visibility || 'public';
document.querySelectorAll('.visibility-option-modal').forEach(opt => {
@@ -987,6 +1088,16 @@ function removeEditThumbnail(e) {
document.getElementById('edit-thumbnail-info').classList.remove('active');
}
// Video type options
const videoTypeOptions = document.querySelectorAll('.video-type-option');
videoTypeOptions.forEach(option => {
const radio = option.querySelector('input[type="radio"]');
radio.addEventListener('change', function() {
videoTypeOptions.forEach(opt => opt.classList.remove('active'));
option.classList.add('active');
});
});
// Visibility options
const editVisibilityOptions = document.querySelectorAll('.visibility-option-modal');
editVisibilityOptions.forEach(option => {
@@ -1048,4 +1159,3 @@ document.getElementById('edit-video-form-modal').addEventListener('submit', func
});
});
</script>