1096 lines
38 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@extends('layouts.app')
@section('main_class', 'upload-page-only upload-page-responsive')
@section('title', 'Upload Video | ' . config('app.name'))
@section('extra_styles')
<style>
/* Mobile: Full page view */
@media (max-width: 991px) {
.upload-page-only .yt-header,
.upload-page-only .yt-sidebar {
display: block !important;
}
.upload-page-only .yt-main {
display: block !important;
margin-left: 0;
}
.upload-page-only.upload-page-responsive {
display: block;
background: transparent;
padding: 0;
}
.upload-page-only.upload-page-responsive .upload-page-standalone {
max-width: 100%;
border-radius: 0;
box-shadow: none;
background: transparent;
border: none;
}
.upload-page-only.upload-page-responsive .upload-page-header {
border-radius: 0;
margin: -16px -16px 16px -16px;
padding: 16px;
}
.upload-page-only.upload-page-responsive .upload-page-body {
padding: 0;
background: transparent;
}
.upload-page-only.upload-page-responsive .form-input,
.upload-page-only.upload-page-responsive .form-textarea {
background: var(--bg-secondary);
border-color: var(--border-color);
color: var(--text-primary);
}
.upload-page-only.upload-page-responsive .form-label {
color: var(--text-primary);
}
.upload-page-only.upload-page-responsive .visibility-content-modal {
background: var(--bg-secondary);
border-color: var(--border-color);
}
.upload-page-only.upload-page-responsive .visibility-title {
color: var(--text-primary);
}
.upload-page-only.upload-page-responsive .visibility-desc {
color: var(--text-secondary);
}
}
/* Desktop: Modal view */
@media (min-width: 992px) {
.upload-page-only {
min-height: auto;
display: block;
padding: 20px;
background: #121212;
}
}
/* Common Modal Styles */
/* Full Page Styles */
.upload-page-standalone {
background: #1a1a1a;
border: none;
border-radius: 0;
box-shadow: none;
overflow: hidden;
width: 100%;
max-width: 800px;
margin: 0 auto;
padding: 20px;
}
}
@keyframes modalPopIn {
0% {
transform: scale(0.8) translateY(20px);
opacity: 0;
}
60% {
transform: scale(1.02) translateY(-5px);
}
100% {
transform: scale(1) translateY(0);
opacity: 1;
}
}
.upload-page-header {
background: #1a1a1a;
border-bottom: none;
padding: 20px 24px;
position: relative;
overflow: hidden;
}
.upload-page-header::before {
content: '';
position: absolute;
top: -50%;
right: -50%;
width: 100%;
height: 200%;
background: radial-gradient(circle, rgba(255,255,255,0.1) 0%, transparent 70%);
pointer-events: none;
}
.upload-icon-wrapper {
width: 48px;
height: 48px;
background: rgba(255, 255, 255, 0.2);
border-radius: 14px;
display: flex;
align-items: center;
justify-content: center;
font-size: 22px;
color: white;
backdrop-filter: blur(10px);
}
.upload-page-header .modal-title {
font-size: 20px;
font-weight: 600;
color: white;
margin: 0;
}
.upload-subtitle {
font-size: 13px;
color: rgba(255, 255, 255, 0.8);
}
.upload-page-body {
padding: 24px;
background: #1a1a1a;
}
/* Container for mobile */
.upload-container {
max-width: 600px;
margin: 0 auto;
}
.form-group {
margin-bottom: 20px;
}
.form-label {
display: block;
margin-bottom: 8px;
font-weight: 500;
}
.form-input, .form-select, .form-textarea {
width: 100%;
background: #121212;
border: 1px solid var(--border-color);
border-radius: 8px;
padding: 12px 16px;
color: var(--text-primary);
font-size: 14px;
}
.form-input:focus, .form-select:focus, .form-textarea:focus {
outline: none;
border-color: var(--brand-red);
}
.form-textarea {
resize: vertical;
min-height: 100px;
}
/* Dropzone */
#dropzone, #thumbnail-dropzone {
border: 2px dashed var(--border-color);
border-radius: 12px;
padding: 40px 20px;
text-align: center;
cursor: pointer;
transition: all 0.2s;
}
/* Hide file input */
#video, #thumbnail {
display: none;
}
#dropzone:hover, #dropzone.dragover,
#thumbnail-dropzone:hover, #thumbnail-dropzone.dragover {
border-color: var(--brand-red);
background: rgba(230, 30, 30, 0.05);
}
#dropzone .icon, #thumbnail-dropzone .icon {
font-size: 48px;
color: var(--text-secondary);
margin-bottom: 16px;
}
#dropzone p, #thumbnail-dropzone p {
color: var(--text-secondary);
margin: 8px 0;
}
#dropzone .hint, #thumbnail-dropzone .hint {
font-size: 12px;
color: var(--text-secondary);
opacity: 0.7;
}
#file-info, #thumbnail-info {
display: none;
}
#file-info.active, #thumbnail-info.active {
display: block;
}
#file-info .filename, #thumbnail-info .filename {
color: var(--brand-red);
font-weight: 500;
}
/* Upload Row - Side by Side */
.upload-row {
display: flex;
gap: 20px;
margin-bottom: 20px;
}
.upload-row .form-group {
flex: 1;
margin-bottom: 0;
}
/* Progress Bar */
#progress-container {
display: none;
margin: 20px 0;
}
#progress-container.active {
display: block;
}
.progress-bar-wrapper {
background: var(--border-color);
border-radius: 4px;
height: 8px;
overflow: hidden;
}
.progress-bar-fill {
background: var(--brand-red);
height: 100%;
width: 0%;
transition: width 0.3s;
}
.progress-text {
text-align: center;
color: var(--text-secondary);
font-size: 14px;
margin-top: 8px;
}
/* Status Message */
#status-message {
display: none;
padding: 16px;
border-radius: 8px;
margin-bottom: 20px;
}
#status-message.success {
display: block;
background: rgba(34, 197, 94, 0.2);
color: #22c55e;
border: 1px solid #22c55e;
}
#status-message.error {
display: block;
background: rgba(239, 68, 68, 0.2);
color: #ef4444;
border: 1px solid #ef4444;
}
/* Submit Button */
.btn-submit {
width: 100%;
background: var(--brand-red);
color: white;
border: none;
padding: 14px 24px;
border-radius: 8px;
font-size: 16px;
font-weight: 500;
cursor: pointer;
transition: background 0.2s;
}
.btn-submit:hover {
background: #cc1a1a;
}
.btn-submit:disabled {
background: #555;
cursor: not-allowed;
}
/* Upload Page Layout */
.upload-page .yt-main {
display: block;
margin-left: 0;
}
/* Visibility Options */
.visibility-options {
display: flex;
flex-direction: column;
gap: 12px;
}
.visibility-option {
display: block;
cursor: pointer;
}
.visibility-option input {
display: none;
}
.visibility-content {
display: flex;
align-items: center;
gap: 16px;
padding: 16px;
background: #1a1a1a;
border: 2px solid var(--border-color);
border-radius: 12px;
transition: all 0.2s;
}
.visibility-option:hover .visibility-content {
border-color: var(--text-secondary);
}
.visibility-option.active .visibility-content {
border-color: var(--brand-red);
background: rgba(230, 30, 30, 0.1);
}
.visibility-content i {
font-size: 24px;
color: var(--text-secondary);
}
.visibility-option.active .visibility-content i {
color: var(--brand-red);
}
.visibility-title {
font-weight: 500;
font-size: 16px;
}
.visibility-desc {
color: var(--text-secondary);
font-size: 14px;
}
@media (min-width: 992px) {
.upload-page .yt-main {
margin-left: 240px;
}
}
/* Desktop Modal Form Styles */
@media (min-width: 992px) {
.upload-page-body .form-group {
margin-bottom: 20px;
}
.upload-page-body .form-label {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 10px;
font-weight: 500;
font-size: 14px;
color: #e5e5e5;
}
.upload-page-body .form-label i {
color: #e63030;
font-size: 16px;
}
.upload-page-body .form-input,
.upload-page-body .form-textarea {
width: 100%;
background: #121212;
border: 1px solid #333;
border-radius: 12px;
padding: 14px 16px;
color: #f1f1f1;
font-size: 14px;
transition: all 0.2s;
}
.upload-page-body .form-input:focus,
.upload-page-body .form-textarea:focus {
outline: none;
border-color: #e63030;
box-shadow: 0 0 0 3px rgba(230, 30, 30, 0.15);
}
.upload-page-body .dropzone-modal {
border: 2px dashed #404040;
border-radius: 12px;
padding: 20px;
text-align: center;
cursor: pointer;
transition: all 0.3s;
position: relative;
background: #151515;
}
.upload-page-body .dropzone-modal:hover {
border-color: #e63030;
background: rgba(230, 30, 30, 0.05);
}
.upload-page-body .dropzone-modal.dragover {
border-color: #e63030;
background: rgba(230, 30, 30, 0.1);
}
.upload-page-body .dropzone-modal input[type="file"] {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
opacity: 0;
cursor: pointer;
}
.upload-page-body .dropzone-icon {
font-size: 36px;
color: #e63030;
margin-bottom: 8px;
}
.upload-page-body .dropzone-title {
color: #e5e5e5;
font-size: 14px;
font-weight: 500;
margin: 6px 0;
}
.upload-page-body .dropzone-hint {
color: #666;
font-size: 12px;
margin: 0;
}
.upload-page-body .visibility-options-modal {
display: flex;
flex-direction: column;
gap: 10px;
}
.upload-page-body .visibility-option-modal {
cursor: pointer;
}
.upload-page-body .visibility-option-modal input {
display: none;
}
.upload-page-body .visibility-content-modal {
display: flex;
align-items: center;
gap: 14px;
padding: 14px;
background: #1a1a1a;
border: 2px solid #333;
border-radius: 12px;
transition: all 0.2s;
}
.upload-page-body .visibility-option-modal:hover .visibility-content-modal {
border-color: #555;
background: #1f1f1f;
}
.upload-page-body .visibility-option-modal.active .visibility-content-modal {
border-color: #e63030;
background: rgba(230, 30, 30, 0.1);
}
.upload-page-body .visibility-content-modal i {
font-size: 20px;
color: #666;
width: 28px;
text-align: center;
}
.upload-page-body .visibility-option-modal.active .visibility-content-modal i {
color: #e63030;
}
.upload-page-body .visibility-text {
display: flex;
flex-direction: column;
gap: 2px;
}
.upload-page-body .visibility-title {
font-weight: 500;
font-size: 14px;
color: #e5e5e5;
}
.upload-page-body .visibility-desc {
color: #777;
font-size: 12px;
}
.upload-page-actions {
display: flex;
justify-content: flex-end;
gap: 12px;
margin-top: 24px;
padding-top: 20px;
border-top: 1px solid #2a2a2a;
}
.upload-page-actions .btn-cancel,
.upload-page-actions .btn-submit {
display: flex;
align-items: center;
gap: 8px;
padding: 12px 20px;
border-radius: 10px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
border: none;
}
.upload-page-actions .btn-cancel {
background: transparent;
border: 1px solid #404040;
color: #aaa;
text-decoration: none;
}
.upload-page-actions .btn-cancel:hover {
border-color: #666;
color: #fff;
}
.upload-page-actions .btn-submit {
background: #1a1a1a;
color: white;
box-shadow: 0 4px 15px rgba(230, 30, 30, 0.3);
}
.upload-page-actions .btn-submit:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(230, 30, 30, 0.4);
}
.upload-page-actions .btn-submit:disabled {
background: #555;
cursor: not-allowed;
transform: none;
box-shadow: none;
}
}
</style>
@endsection
@section('content')
<div class="upload-page-standalone">
<!-- Header -->
<div class="upload-page-header">
<div class="upload-icon-wrapper">
<i class="bi bi-cloud-arrow-up-fill"></i>
</div>
<a href="{{ route("videos.index") }}" class="btn-close btn-close-white" style="position: relative; z-index: 1; text-decoration: none;">×</a>
</div>
<!-- Body -->
<div class="upload-page-body">
<form id="upload-form" enctype="multipart/form-data">
@csrf
<div class="form-group">
<label class="form-label">
<i class="bi bi-card-heading"></i> Title *
</label>
<input type="text" name="title" required
class="form-input"
placeholder="Enter video title">
</div>
<div class="form-group">
<label class="form-label">
<i class="bi bi-text-paragraph"></i> Description
</label>
<textarea name="description" rows="3"
class="form-textarea"
placeholder="Tell viewers about your video"></textarea>
</div>
<div class="form-group">
<label class="form-label">
<i class="bi bi-camera-video"></i> Video File *
</label>
<div id="dropzone" class="dropzone-modal">
<input type="file" name="video" id="video" accept="video/*" required>
<div id="dropzone-default">
<div class="dropzone-icon">
<i class="bi bi-cloud-arrow-up"></i>
</div>
<p class="dropzone-title">Click to select or drag video here</p>
<p class="dropzone-hint">MP4, MOV, AVI, WebM up to 512MB</p>
</div>
<div id="file-info">
<div class="file-preview">
<i class="bi bi-film"></i>
</div>
<div class="file-details">
<p class="filename" id="filename"></p>
<p id="filesize"></p>
</div>
<button type="button" class="btn-remove-file" onclick="removeVideo(event)">
<i class="bi bi-x-lg"></i>
</button>
</div>
</div>
</div>
<div class="form-group">
<label class="form-label">
<i class="bi bi-image"></i> Thumbnail (optional)
</label>
<div id="thumbnail-dropzone" class="dropzone-modal">
<input type="file" name="thumbnail" id="thumbnail" accept="image/*">
<div id="thumbnail-default">
<div class="dropzone-icon">
<i class="bi bi-card-image"></i>
</div>
<p class="dropzone-title">Click to select or drag thumbnail</p>
<p class="dropzone-hint">JPG, PNG, WebP up to 5MB</p>
</div>
<div id="thumbnail-info">
<div class="file-preview thumbnail-preview">
<img id="thumbnail-preview-img" src="" alt="Thumbnail preview">
</div>
<div class="file-details">
<p class="filename" id="thumbnail-filename"></p>
<p id="thumbnail-filesize"></p>
</div>
<button type="button" class="btn-remove-file" onclick="removeThumbnail(event)">
<i class="bi bi-x-lg"></i>
</button>
</div>
</div>
</div>
<div class="form-group">
<label class="form-label">
<i class="bi bi-collection-play"></i> Video Type
</label>
<div class="visibility-options-modal" id="type-options">
<label class="visibility-option-modal active">
<input type="radio" name="type" value="generic" checked>
<div class="visibility-content-modal">
<i class="bi bi-film"></i>
<div class="visibility-text">
<span class="visibility-title">Generic</span>
<span class="visibility-desc">Standard video</span>
</div>
</div>
</label>
<label class="visibility-option-modal">
<input type="radio" name="type" value="music">
<div class="visibility-content-modal">
<i class="bi bi-music-note"></i>
<div class="visibility-text">
<span class="visibility-title">Music</span>
<span class="visibility-desc">Music video or song</span>
</div>
</div>
</label>
<label class="visibility-option-modal">
<input type="radio" name="type" value="match">
<div class="visibility-content-modal">
<i class="bi bi-trophy"></i>
<div class="visibility-text">
<span class="visibility-title">Match</span>
<span class="visibility-desc">Sports match or competition</span>
</div>
</div>
</label>
</div>
</div>
<div class="form-group">
<label class="form-label">
<i class="bi bi-shield-lock"></i> Privacy Setting
</label>
<div class="visibility-options-modal" id="visibility-options" style="margin-top: 15px;">
<label class="visibility-option-modal active">
<input type="radio" name="visibility" value="public" checked>
<div class="visibility-content-modal">
<i class="bi bi-globe"></i>
<div class="visibility-text">
<span class="visibility-title">Public</span>
<span class="visibility-desc">Everyone can see this video</span>
</div>
</div>
</label>
<label class="visibility-option-modal">
<input type="radio" name="visibility" value="unlisted">
<div class="visibility-content-modal">
<i class="bi bi-link-45deg"></i>
<div class="visibility-text">
<span class="visibility-title">Unlisted</span>
<span class="visibility-desc">Only people with the link</span>
</div>
</div>
</label>
<label class="visibility-option-modal">
<input type="radio" name="visibility" value="private">
<div class="visibility-content-modal">
<i class="bi bi-lock"></i>
<div class="visibility-text">
<span class="visibility-title">Private</span>
<span class="visibility-desc">Only you can see</span>
</div>
</div>
</label>
</div>
</div>
<!-- Progress Bar -->
<div id="progress-container">
<div class="progress-bar-wrapper">
<div id="progress-bar" class="progress-bar-fill"></div>
</div>
<p id="progress-text" class="progress-text">Uploading... 0%</p>
</div>
<!-- Status Message -->
<div id="status-message"></div>
<div class="upload-page-actions">
<button type="button" class="btn-cancel" onclick="window.location='{{ route('videos.index') }}'">
Cancel
</button>
<button type="submit" id="submit-btn" class="btn-submit">
<i class="bi bi-cloud-arrow-up-fill"></i> Upload Video
</button>
</div>
</form>
</div>
</div>
<!-- Desktop only: modal overlay styles -->
<style>
@media (min-width: 992px) {
.file-preview {
width: 56px;
height: 56px;
background: #1a1a1a;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
color: white;
flex-shrink: 0;
}
.file-preview.thumbnail-preview {
background: none;
overflow: hidden;
}
.file-preview.thumbnail-preview img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 12px;
}
.file-details {
flex: 1;
text-align: left;
}
.file-details .filename {
color: #e5e5e5;
font-weight: 500;
font-size: 14px;
margin: 0 0 4px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 200px;
}
.file-details p {
color: #888;
font-size: 13px;
margin: 0;
}
.btn-remove-file {
width: 32px;
height: 32px;
border-radius: 50%;
background: #333;
border: none;
color: #888;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s;
}
.btn-remove-file:hover {
background: #1a1a1a;
color: white;
}
#file-info, #thumbnail-info {
display: none;
align-items: center;
gap: 12px;
padding: 12px;
background: #1f1f1f;
border-radius: 12px;
border: 1px solid #333;
}
#file-info.active, #thumbnail-info.active {
display: flex;
}
#dropzone, #thumbnail-dropzone {
padding: 0;
border: 2px dashed #404040;
}
#dropzone-default, #thumbnail-default {
padding: 32px 20px;
}
}
</style>
@endsection
@section('scripts')
<script>
// Video Dropzone
const dropzone = document.getElementById('dropzone');
const fileInput = document.getElementById('video');
fileInput.addEventListener('change', function() {
handleFileSelect(this);
});
dropzone.addEventListener('click', function(e) {
if (e.target.classList.contains('btn-remove-file')) return;
fileInput.click();
});
dropzone.addEventListener('dragover', (e) => {
e.preventDefault();
dropzone.classList.add('dragover');
});
dropzone.addEventListener('dragleave', () => {
dropzone.classList.remove('dragover');
});
dropzone.addEventListener('drop', (e) => {
e.preventDefault();
dropzone.classList.remove('dragover');
if (e.dataTransfer.files.length) {
fileInput.files = e.dataTransfer.files;
handleFileSelect(fileInput);
}
});
function handleFileSelect(input) {
if (input.files && input.files[0]) {
const file = input.files[0];
const maxSize = 512 * 1024 * 1024;
const validTypes = ['video/mp4', 'video/webm', 'video/ogg', 'video/quicktime', 'video/x-msvideo', 'video/x-flv', 'video/x-matroska'];
const validExtensions = ['.mp4', '.webm', '.ogg', '.mov', '.avi', '.wmv', '.flv', '.mkv'];
let isValidType = validTypes.includes(file.type);
let fileExtension = '.' + file.name.split('.').pop().toLowerCase();
if (!isValidType) {
isValidType = validExtensions.includes(fileExtension);
}
if (!isValidType) {
alert('Invalid video format. Please select a valid video file (MP4, MOV, AVI, WebM, OGG, WMV, FLV, MKV).');
input.value = '';
return;
}
if (file.size > maxSize) {
alert('File size exceeds 512MB limit. Please select a smaller video file.');
input.value = '';
return;
}
document.getElementById('filename').textContent = file.name;
document.getElementById('filesize').textContent = (file.size / 1024 / 1024).toFixed(2) + ' MB';
document.getElementById('dropzone-default').style.display = 'none';
document.getElementById('file-info').classList.add('active');
}
}
function removeVideo(e) {
e.preventDefault();
e.stopPropagation();
fileInput.value = '';
document.getElementById('dropzone-default').style.display = 'block';
document.getElementById('file-info').classList.remove('active');
}
// Thumbnail Dropzone
const thumbnailDropzone = document.getElementById('thumbnail-dropzone');
const thumbnailInput = document.getElementById('thumbnail');
thumbnailDropzone.addEventListener('click', function(e) {
if (e.target.classList.contains('btn-remove-file')) return;
thumbnailInput.click();
});
thumbnailDropzone.addEventListener('dragover', (e) => {
e.preventDefault();
thumbnailDropzone.classList.add('dragover');
});
thumbnailDropzone.addEventListener('dragleave', () => {
thumbnailDropzone.classList.remove('dragover');
});
thumbnailDropzone.addEventListener('drop', (e) => {
e.preventDefault();
thumbnailDropzone.classList.remove('dragover');
if (e.dataTransfer.files.length) {
thumbnailInput.files = e.dataTransfer.files;
handleThumbnailSelect(thumbnailInput);
}
});
thumbnailInput.addEventListener('change', function() {
handleThumbnailSelect(this);
});
function handleThumbnailSelect(input) {
if (input.files && input.files[0]) {
const file = input.files[0];
document.getElementById('thumbnail-filename').textContent = file.name;
document.getElementById('thumbnail-filesize').textContent = (file.size / 1024 / 1024).toFixed(2) + ' MB';
const reader = new FileReader();
reader.onload = function(e) {
document.getElementById('thumbnail-preview-img').src = e.target.result;
};
reader.readAsDataURL(file);
document.getElementById('thumbnail-default').style.display = 'none';
document.getElementById('thumbnail-info').classList.add('active');
}
}
function removeThumbnail(e) {
e.preventDefault();
e.stopPropagation();
thumbnailInput.value = '';
document.getElementById('thumbnail-default').style.display = 'block';
document.getElementById('thumbnail-info').classList.remove('active');
}
// Visibility option handling
const typeOptions = document.querySelectorAll('#type-options .visibility-option-modal');
typeOptions.forEach(option => {
const radio = option.querySelector('input[type="radio"]');
radio.addEventListener('change', function() {
typeOptions.forEach(opt => opt.classList.remove('active'));
option.classList.add('active');
});
});
const visibilityOptions = document.querySelectorAll('#visibility-options .visibility-option-modal');
visibilityOptions.forEach(option => {
const radio = option.querySelector('input[type="radio"]');
radio.addEventListener('change', function() {
visibilityOptions.forEach(opt => opt.classList.remove('active'));
option.classList.add('active');
});
});
document.getElementById('upload-form').addEventListener('submit', function(e) {
e.preventDefault();
const formData = new FormData(this);
const xhr = new XMLHttpRequest();
document.getElementById('progress-container').classList.add('active');
document.getElementById('submit-btn').disabled = true;
document.getElementById('submit-btn').innerHTML = '<i class="bi bi-arrow-repeat"></i> Uploading...';
document.getElementById('status-message').className = '';
xhr.upload.addEventListener('progress', function(e) {
if (e.lengthComputable) {
const percent = Math.round((e.loaded / e.total) * 100);
document.getElementById('progress-bar').style.width = percent + '%';
document.getElementById('progress-text').textContent = 'Uploading... ' + percent + '%';
}
});
xhr.addEventListener('load', function() {
document.getElementById('progress-bar').style.width = '100%';
document.getElementById('progress-text').textContent = 'Processing...';
try {
const response = JSON.parse(xhr.responseText);
if (response.success) {
document.getElementById('progress-text').textContent = 'Done! Redirecting...';
window.location.href = response.redirect;
} else {
showError(response.message || 'Upload failed');
}
} catch(e) {
showError('Invalid response from server');
}
});
xhr.addEventListener('error', function() {
showError('Upload failed. Please try again.');
});
xhr.open('POST', '{{ route("videos.store") }}');
xhr.setRequestHeader('X-CSRF-TOKEN', '{{ csrf_token() }}');
xhr.send(formData);
});
function showError(message) {
const status = document.getElementById('status-message');
status.innerHTML = '<i class="bi bi-exclamation-circle-fill"></i> ' + message;
status.className = 'error';
document.getElementById('submit-btn').disabled = false;
document.getElementById('submit-btn').innerHTML = '<i class="bi bi-cloud-arrow-up-fill"></i> Upload Video';
}
</script>
@endsection