initial commit
This commit is contained in:
@@ -0,0 +1,357 @@
|
||||
@extends('layouts.backendTemplate')
|
||||
|
||||
@section('content')
|
||||
|
||||
<style>
|
||||
#progressBar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
width: 100%;
|
||||
height: 10px;
|
||||
border-radius: 5px;
|
||||
margin-top: 10px;
|
||||
appearance: none;
|
||||
}
|
||||
|
||||
.progress-bar::-webkit-progress-value {
|
||||
background-color: #4CAF50;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.progress-text {
|
||||
margin-top: 10px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
</style>
|
||||
|
||||
<!--begin::Main-->
|
||||
<div class="app-main flex-column flex-row-fluid" id="kt_app_main">
|
||||
|
||||
<div class="d-flex flex-column flex-column-fluid">
|
||||
|
||||
|
||||
@include('uc.admin.breadcrumb', [
|
||||
'title' => 'Video Add',
|
||||
'pageName' => 'Add',
|
||||
'pageParent' => 'Video Management',
|
||||
'pageParentLink' => url('video'),
|
||||
])
|
||||
|
||||
<div id="kt_app_content" class="app-content flex-column-fluid">
|
||||
<div id="kt_app_content_container" class="app-container container-xxl">
|
||||
|
||||
|
||||
|
||||
<form id="frmAdd" class="form d-flex flex-column flex-lg-row" method="post"
|
||||
enctype="multipart/form-data">
|
||||
|
||||
<input type="hidden" name="_method" value="POST">
|
||||
<input type="hidden" name="_token" value="{{ csrf_token() }}">
|
||||
|
||||
|
||||
<div class="d-flex flex-column flex-row-fluid gap-7 gap-lg-10">
|
||||
|
||||
<div class="card card-flush py-4">
|
||||
|
||||
|
||||
@if (Session::has('messageSuccess'))
|
||||
<div class="card-body">
|
||||
@include('uc/messageSuccess')
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if (Session::has('messageFail'))
|
||||
<div class="card-body">
|
||||
@include('uc/messageFail')
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="card-header">
|
||||
<div class="card-title">
|
||||
<h2>Overview</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body pt-0">
|
||||
|
||||
<div class="mb-10">
|
||||
<label class="form-label required">File Video</label>
|
||||
|
||||
<input class="fileInput file-input" type="file" id="fileInput" name="fileInput"
|
||||
multiple accept=".MP4, .MOV">
|
||||
|
||||
<progress id="progressBar" class="progress-bar" value="0"
|
||||
max="100"></progress>
|
||||
<div id="progressText" class="progress-text">0%</div>
|
||||
|
||||
<div class="text-muted fs-7">Allowed Types .MP4, .MOV</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end">
|
||||
|
||||
<a href="{{ url('video') }}" id="kt_ecommerce_add_product_cancel"
|
||||
class="btn btn-light me-5">Cancel</a>
|
||||
|
||||
<button type="button" id="btn_submit" class="btn btn-primary">
|
||||
<span class="indicator-label">Save</span>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@stop
|
||||
|
||||
|
||||
@section('script')
|
||||
|
||||
<script>
|
||||
const baseApiUrl = "{{ env('API_URL') }}";
|
||||
|
||||
|
||||
$(document).on("click", "#btn_submit", async function(e) {
|
||||
|
||||
e.preventDefault();
|
||||
|
||||
alertLoading("Loading")
|
||||
|
||||
await uploadFile();
|
||||
|
||||
});
|
||||
|
||||
|
||||
// Step 1
|
||||
async function uploadFile() {
|
||||
|
||||
const fileInput = document.getElementById("fileInput");
|
||||
|
||||
const progressBar = document.getElementById("progressBar");
|
||||
const progressText = document.getElementById("progressText");
|
||||
|
||||
if (!fileInput || fileInput.files.length === 0) {
|
||||
alertFail("Notice", "Please select one or more files.");
|
||||
hideLoading();
|
||||
return;
|
||||
}
|
||||
const files = Array.from(fileInput.files); // Get all selected files
|
||||
|
||||
$("#progressBar").show();
|
||||
|
||||
// Upload all files sequentially (or use Promise.all for parallel uploads)
|
||||
for (const file of files) {
|
||||
await uploadSingleFile(file, progressBar, progressText);
|
||||
}
|
||||
alertSuccessWithUrl("Notice", "All files uploaded successfully", "{{ url('video') }}");
|
||||
|
||||
}
|
||||
|
||||
async function uploadSingleFile(file, progressBar, progressText) {
|
||||
const uploadId = await initiateMultipartUpload(file.name);
|
||||
const partSize = 500 * 1024 * 1024; // 500 MB per part
|
||||
const parts = [];
|
||||
let uploadedSize = 0;
|
||||
|
||||
const uploadPromises = Array.from({
|
||||
length: Math.ceil(file.size / partSize)
|
||||
},
|
||||
(_, index) => {
|
||||
const partNumber = index + 1;
|
||||
const chunk = file.slice(index * partSize, (index + 1) * partSize);
|
||||
|
||||
return (async () => {
|
||||
const presignedUrl = await getPresignedUrl(uploadId, partNumber, file.name);
|
||||
const etag = await uploadPartToS3(presignedUrl, chunk);
|
||||
|
||||
parts.push({
|
||||
PartNumber: partNumber,
|
||||
ETag: etag
|
||||
});
|
||||
|
||||
uploadedSize += chunk.size;
|
||||
const finalPercent = Math.floor((uploadedSize / file.size) * 100);
|
||||
await animateProgress(progressBar, progressText, finalPercent);
|
||||
})();
|
||||
}
|
||||
);
|
||||
|
||||
await Promise.all(uploadPromises);
|
||||
await completeMultipartUpload(uploadId, parts, file.name);
|
||||
await saveFileNameToDB(file.name);
|
||||
}
|
||||
|
||||
// Step 2
|
||||
async function initiateMultipartUpload(fileName) {
|
||||
const urlUploadImage = `${baseApiUrl}/initiate-multipart-upload`;
|
||||
const response = await fetch(
|
||||
urlUploadImage, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
fileName
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
const {
|
||||
uploadId
|
||||
} = await response.json();
|
||||
|
||||
return uploadId;
|
||||
}
|
||||
|
||||
// Step 3
|
||||
async function getPresignedUrl(uploadId, partNumber, fileName) {
|
||||
|
||||
const urlPresigned = `${baseApiUrl}/get-presigned-url`
|
||||
const response = await fetch(
|
||||
urlPresigned, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
uploadId,
|
||||
partNumber,
|
||||
fileName
|
||||
}),
|
||||
}
|
||||
);
|
||||
const {
|
||||
url
|
||||
} = await response.json();
|
||||
return url;
|
||||
}
|
||||
|
||||
// Step 4
|
||||
async function uploadPartToS3(url, chunk) {
|
||||
const response = await fetch(url, {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/octet-stream",
|
||||
},
|
||||
body: chunk,
|
||||
});
|
||||
if (!response.ok) {
|
||||
alertFail("Notice", "Failed to upload part")
|
||||
hideLoading();
|
||||
//throw new Error("Failed to upload part");
|
||||
}
|
||||
|
||||
const etag = `${response.headers.get("ETag")}`.replace(/"/g, "");
|
||||
|
||||
if (!etag) {
|
||||
throw new Error("Failed to retrieve ETag from the response.");
|
||||
}
|
||||
|
||||
return etag;
|
||||
}
|
||||
|
||||
// Step 5
|
||||
async function completeMultipartUpload(uploadId, parts, fileName) {
|
||||
const urlUploadComplete = `${baseApiUrl}/complete-multipart-upload`;
|
||||
const response = await fetch(urlUploadComplete, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
uploadId,
|
||||
parts,
|
||||
fileName
|
||||
}),
|
||||
});
|
||||
if (response.ok) {
|
||||
//window.location.href = "{{ url('image') }}";
|
||||
} else {
|
||||
alertFail("Notice", "Failed to upload part");
|
||||
hideLoading();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Smoothly animates the progress bar and percentage text.
|
||||
*/
|
||||
async function animateProgress(progressBar, progressText, targetPercent) {
|
||||
const currentPercent = parseInt(progressBar.value) || 0;
|
||||
// Increment the percentage smoothly
|
||||
for (let percent = currentPercent + 1; percent <= targetPercent; percent++) {
|
||||
progressBar.value = percent;
|
||||
progressText.textContent = `${percent}%`;
|
||||
|
||||
// Add a small delay to make the increment visible (10ms delay)
|
||||
await new Promise((resolve) => setTimeout(resolve, 10));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the uploaded file name to the server using AJAX.
|
||||
*/
|
||||
function saveFileNameToDB(fileName) {
|
||||
initAjaxSetupToken();
|
||||
|
||||
const folderId = "{{ $folderIdView }}";
|
||||
const url = "{{ url('') }}";
|
||||
|
||||
return $.ajax({
|
||||
url: `${url}/video/insert`,
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify({
|
||||
fileName,
|
||||
folderId
|
||||
}),
|
||||
success: (response) => {
|
||||
console.log('File name saved:', response);
|
||||
},
|
||||
error: (err) => {
|
||||
console.error('Error saving file name:', err);
|
||||
alertFail("Notice", "There was an error saving the file name.");
|
||||
hideLoading();
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
$('.file-input').fileuploader({
|
||||
extensions: ['MP4', 'mp4', 'MOV', 'mov'],
|
||||
limit: null,
|
||||
fileMaxSize: null,
|
||||
changeInput: '<div class="fileuploader-input">' +
|
||||
'<div class="fileuploader-input-inner">' +
|
||||
'<p><i class="fileuploader-icon-main"></i></p>' +
|
||||
'<h6>Drag and drop files here</h6>' +
|
||||
'<p>or</p>' +
|
||||
'<br>' +
|
||||
'<button type="button" class="fileuploader-input-button"><span>${captions.button}</span></button>' +
|
||||
'</div>' +
|
||||
'</div>',
|
||||
theme: 'dragdrop',
|
||||
});
|
||||
</script>
|
||||
|
||||
@endsection
|
||||
@@ -0,0 +1,95 @@
|
||||
@extends('layouts.backendTemplate')
|
||||
|
||||
@section('content')
|
||||
|
||||
<!--begin::Main-->
|
||||
<div class="app-main flex-column flex-row-fluid" id="kt_app_main">
|
||||
|
||||
<div class="d-flex flex-column flex-column-fluid">
|
||||
|
||||
|
||||
@include('uc.admin.breadcrumb', [
|
||||
'title' => 'Video Create Folder',
|
||||
'pageName' => 'Create folder',
|
||||
'pageParent' => 'Video Management',
|
||||
'pageParentLink' => url('video'),
|
||||
])
|
||||
|
||||
<div id="kt_app_content" class="app-content flex-column-fluid">
|
||||
<div id="kt_app_content_container" class="app-container container-xxl">
|
||||
|
||||
<form id="frmAdd" action="{{ url('video/insert-folder') }}" class="form d-flex flex-column flex-lg-row"
|
||||
method="post" enctype="multipart/form-data">
|
||||
|
||||
<input type="hidden" name="_method" value="POST">
|
||||
<input type="hidden" name="_token" value="{{ csrf_token() }}">
|
||||
|
||||
|
||||
<div class="d-flex flex-column flex-row-fluid gap-7 gap-lg-10">
|
||||
|
||||
<div class="card card-flush py-4">
|
||||
|
||||
|
||||
@if (Session::has('messageSuccess'))
|
||||
<div class="card-body">
|
||||
@include('uc/messageSuccess')
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if (Session::has('messageFail'))
|
||||
<div class="card-body">
|
||||
@include('uc/messageFail')
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="card-header">
|
||||
<div class="card-title">
|
||||
<h2>Overview</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body pt-0">
|
||||
|
||||
<div class="mb-10 fv-row">
|
||||
<label class="required form-label">Name</label>
|
||||
<input type="text" name="name" class="form-control mb-2 col-6"
|
||||
value="{{ old('name') }}" />
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end">
|
||||
|
||||
<a href="{{ url('video') }}" id="kt_ecommerce_add_product_cancel"
|
||||
class="btn btn-light me-5">Cancel</a>
|
||||
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<span class="indicator-label">Save</span>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@stop
|
||||
|
||||
|
||||
@section('script')
|
||||
|
||||
<script></script>
|
||||
|
||||
@endsection
|
||||
@@ -0,0 +1,96 @@
|
||||
@extends('layouts.backendTemplate')
|
||||
|
||||
@section('content')
|
||||
|
||||
<!--begin::Main-->
|
||||
<div class="app-main flex-column flex-row-fluid" id="kt_app_main">
|
||||
|
||||
<div class="d-flex flex-column flex-column-fluid">
|
||||
|
||||
|
||||
@include('uc.admin.breadcrumb', [
|
||||
'title' => 'Video Edit Folder',
|
||||
'pageName' => 'Edit folder',
|
||||
'pageParent' => 'Video Management',
|
||||
'pageParentLink' => url('Video'),
|
||||
])
|
||||
|
||||
<div id="kt_app_content" class="app-content flex-column-fluid">
|
||||
<div id="kt_app_content_container" class="app-container container-xxl">
|
||||
|
||||
<form id="frmAdd" action="{{ url('video/update-folder') }}" class="form d-flex flex-column flex-lg-row"
|
||||
method="post" enctype="multipart/form-data">
|
||||
|
||||
<input type="hidden" name="id" value="{{ $idView }}">
|
||||
<input type="hidden" name="_method" value="POST">
|
||||
<input type="hidden" name="_token" value="{{ csrf_token() }}">
|
||||
|
||||
|
||||
<div class="d-flex flex-column flex-row-fluid gap-7 gap-lg-10">
|
||||
|
||||
<div class="card card-flush py-4">
|
||||
|
||||
|
||||
@if (Session::has('messageSuccess'))
|
||||
<div class="card-body">
|
||||
@include('uc/messageSuccess')
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if (Session::has('messageFail'))
|
||||
<div class="card-body">
|
||||
@include('uc/messageFail')
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="card-header">
|
||||
<div class="card-title">
|
||||
<h2>Overview</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card-body pt-0">
|
||||
|
||||
<div class="mb-10 fv-row">
|
||||
<label class="required form-label">Name</label>
|
||||
<input type="text" name="name" class="form-control mb-2 col-6"
|
||||
value="{{ $itemView->name }}" />
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end">
|
||||
|
||||
<a href="{{ url('video') }}" id="kt_ecommerce_add_product_cancel"
|
||||
class="btn btn-light me-5">Cancel</a>
|
||||
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<span class="indicator-label">Save</span>
|
||||
</button>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@stop
|
||||
|
||||
|
||||
@section('script')
|
||||
|
||||
<script></script>
|
||||
|
||||
@endsection
|
||||
@@ -0,0 +1,305 @@
|
||||
@extends('layouts.backendTemplate')
|
||||
|
||||
@section('content')
|
||||
|
||||
<style>
|
||||
.link-container {
|
||||
display: flex;
|
||||
/* Use flexbox for alignment */
|
||||
align-items: center;
|
||||
/* Center items vertically */
|
||||
justify-content: space-between;
|
||||
/* Space between the URL and button */
|
||||
}
|
||||
|
||||
.file-url {
|
||||
flex: 1;
|
||||
/* Allow the URL to take up available space */
|
||||
color: #007bff;
|
||||
/* Link color */
|
||||
text-decoration: none;
|
||||
/* Remove underline */
|
||||
overflow: hidden;
|
||||
/* Hide overflow */
|
||||
white-space: nowrap;
|
||||
/* Prevent text wrapping */
|
||||
text-overflow: ellipsis;
|
||||
/* Add ellipsis for overflow */
|
||||
margin-right: 10px;
|
||||
/* Space between text and button */
|
||||
}
|
||||
</style>
|
||||
|
||||
<!--begin::Main-->
|
||||
<div class="app-main flex-column flex-row-fluid" id="kt_app_main">
|
||||
|
||||
<div class="d-flex flex-column flex-column-fluid">
|
||||
|
||||
|
||||
@include('uc.breadcrumbList', [
|
||||
'title' => 'Video Management Folder ' . $folderView->name,
|
||||
'pageName' => 'Video Management',
|
||||
])
|
||||
|
||||
|
||||
<div id="kt_app_content" class="app-content flex-column-fluid">
|
||||
|
||||
<div id="kt_app_content_container" class="app-container container-xxl">
|
||||
|
||||
<div class="card">
|
||||
|
||||
@if (Session::has('messageSuccess'))
|
||||
<div class="card-body">
|
||||
@include('uc/messageSuccess')
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if (Session::has('messageFail'))
|
||||
<div class="card-body">
|
||||
@include('uc/messageFail')
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
<div class="card-header border-0 pt-6">
|
||||
<div class="d-flex align-items-center position-relative my-1">
|
||||
</div>
|
||||
|
||||
@if (Auth::user()->role != 2)
|
||||
<div class="card-toolbar">
|
||||
<div class="d-flex justify-content-end" data-kt-customer-table-toolbar="base">
|
||||
<a href="{{ url('video/add/' . $folderView->id) }}" class="btn btn-primary">Add
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="card-header border-0 pt-5">
|
||||
|
||||
<div class="card-title">
|
||||
<div class="d-flex align-items-center position-relative my-1">
|
||||
<span class="svg-icon svg-icon-1 position-absolute ms-4">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<rect opacity="0.5" x="17.0365" y="15.1223" width="8.15546" height="2"
|
||||
rx="1" transform="rotate(45 17.0365 15.1223)" fill="currentColor">
|
||||
</rect>
|
||||
<path
|
||||
d="M11 19C6.55556 19 3 15.4444 3 11C3 6.55556 6.55556 3 11 3C15.4444 3 19 6.55556 19 11C19 15.4444 15.4444 19 11 19ZM11 5C7.53333 5 5 7.53333 5 11C5 14.4667 7.53333 17 11 17C14.4667 17 17 14.4667 17 11C17 7.53333 14.4667 5 11 5Z"
|
||||
fill="currentColor"></path>
|
||||
</svg>
|
||||
</span>
|
||||
|
||||
<input type="text" table-filter="search"
|
||||
class="form-control form-control-solid w-250px ps-15" placeholder="Search" />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="card-body py-4">
|
||||
<!--begin::Table-->
|
||||
<table class="table align-middle table-row-dashed fs-6 gy-5" id="data-table">
|
||||
<!--begin::Table head-->
|
||||
<thead>
|
||||
<!--begin::Table row-->
|
||||
<tr class="text-start text-muted fw-bold fs-7 text-uppercase gs-0">
|
||||
<th class="min-w-125px">Name</th>
|
||||
<th class="min-w-125px">Created</th>
|
||||
<th class="text-end min-w-100px">Manage</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody class="text-gray-600 fw-semibold">
|
||||
|
||||
@foreach ($itemView as $obj)
|
||||
<tr>
|
||||
<td>
|
||||
<div class="d-flex flex-column">
|
||||
<a href="#" class="text-gray-800 text-hover-primary mb-1">
|
||||
<video controls class="h-100px" style="height: 150px!important;">
|
||||
<source src="{{ env('R2_SCHEMA_URL') . $obj['name'] }}"
|
||||
type="video/mp4">
|
||||
Your browser does not support the video element.
|
||||
</video>
|
||||
</a>
|
||||
<span>{{ $obj['name'] }}</span>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
|
||||
<td>
|
||||
{{ Carbon\Carbon::parse($obj['created_at'])->format('d, M Y') }}
|
||||
</td>
|
||||
|
||||
<td class="min-w-100px text-end">
|
||||
|
||||
{{-- Download --}}
|
||||
<a href="{{ env('R2_SCHEMA_URL') . $obj['name'] }}" target="_blank"
|
||||
class="btn btn-sm btn-icon btn-light btn-active-light-primary"
|
||||
type="button" data-bs-toggle="tooltip" aria-label="Coming soon"
|
||||
data-bs-original-title="Coming soon" data-kt-initialized="1">
|
||||
<i class="bi bi-download fs-3"></i>
|
||||
</a>
|
||||
|
||||
{{-- Copy --}}
|
||||
<button type="button" data-action="copy"
|
||||
data-url="{{ env('R2_SCHEMA_URL') . $obj['name'] }}"
|
||||
class="btn btn-sm btn-icon btn-light btn-active-light-primary copy-button">
|
||||
<span class="svg-icon svg-icon-2">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24"
|
||||
fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.5"
|
||||
d="M18 2H9C7.34315 2 6 3.34315 6 5H8C8 4.44772 8.44772 4 9 4H18C18.5523 4 19 4.44772 19 5V16C19 16.5523 18.5523 17 18 17V19C19.6569 19 21 17.6569 21 16V5C21 3.34315 19.6569 2 18 2Z"
|
||||
fill="currentColor"></path>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M14.7857 7.125H6.21429C5.62255 7.125 5.14286 7.6007 5.14286 8.1875V18.8125C5.14286 19.3993 5.62255 19.875 6.21429 19.875H14.7857C15.3774 19.875 15.8571 19.3993 15.8571 18.8125V8.1875C15.8571 7.6007 15.3774 7.125 14.7857 7.125ZM6.21429 5C4.43908 5 3 6.42709 3 8.1875V18.8125C3 20.5729 4.43909 22 6.21429 22H14.7857C16.5609 22 18 20.5729 18 18.8125V8.1875C18 6.42709 16.5609 5 14.7857 5H6.21429Z"
|
||||
fill="currentColor"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<!--end::Svg Icon-->
|
||||
</button>
|
||||
|
||||
|
||||
{{-- Delete --}}
|
||||
@if (Auth::user()->role != 2)
|
||||
<a href="#" data-id="{{ $obj['id'] }}"
|
||||
class="btn btn-icon btn-bg-light btn-active-color-primary btn-sm delete-item">
|
||||
<span class="svg-icon svg-icon-3">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24"
|
||||
fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M5 9C5 8.44772 5.44772 8 6 8H18C18.5523 8 19 8.44772 19 9V18C19 19.6569 17.6569 21 16 21H8C6.34315 21 5 19.6569 5 18V9Z"
|
||||
fill="currentColor" />
|
||||
<path opacity="0.5"
|
||||
d="M5 5C5 4.44772 5.44772 4 6 4H18C18.5523 4 19 4.44772 19 5V5C19 5.55228 18.5523 6 18 6H6C5.44772 6 5 5.55228 5 5V5Z"
|
||||
fill="currentColor" />
|
||||
<path opacity="0.5"
|
||||
d="M9 4C9 3.44772 9.44772 3 10 3H14C14.5523 3 15 3.44772 15 4V4H9V4Z"
|
||||
fill="currentColor" />
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
@endif
|
||||
</td>
|
||||
|
||||
|
||||
</tr>
|
||||
@endforeach
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@stop
|
||||
|
||||
|
||||
@section('script')
|
||||
|
||||
<script type="text/javascript">
|
||||
const baseUrl = "{{ url('video') }}";
|
||||
var datatable;
|
||||
datatable = $("#data-table").DataTable({
|
||||
"info": false,
|
||||
"order": []
|
||||
});
|
||||
|
||||
// Filter by search
|
||||
const filterSearch = document.querySelector('[table-filter="search"]');
|
||||
filterSearch.addEventListener('keyup', function(e) {
|
||||
datatable.search(e.target.value).draw();
|
||||
});
|
||||
|
||||
// filter by status
|
||||
const filterStatus = document.querySelector('[table-filter="status"]');
|
||||
$(filterStatus).on('change', e => {
|
||||
let value = e.target.value;
|
||||
if (value === 'all') {
|
||||
value = '';
|
||||
}
|
||||
datatable.column(4).search(value).draw();
|
||||
});
|
||||
|
||||
|
||||
// Remove
|
||||
$(document).on('click', '.delete-item', function() {
|
||||
swal.fire({
|
||||
allowOutsideClick: false,
|
||||
text: "Are you sure you would like to Delete?",
|
||||
icon: "warning",
|
||||
buttonsStyling: false,
|
||||
showDenyButton: true,
|
||||
confirmButtonText: "Yes",
|
||||
denyButtonText: 'No',
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
denyButton: "btn btn-light-danger"
|
||||
}
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
|
||||
alertLoading("Loading")
|
||||
|
||||
// set up ajax
|
||||
initAjaxSetupToken();
|
||||
|
||||
const ajaxProp = {
|
||||
url: "{{ url('video/delete') }}",
|
||||
type: 'POST',
|
||||
data: {
|
||||
item_id: $(this).data('id')
|
||||
},
|
||||
};
|
||||
|
||||
//const id = $(this).data('id');
|
||||
const id = "{{ $folderView->id }}";
|
||||
|
||||
$.ajax(ajaxProp).done(function(res) {
|
||||
if (res.status) {
|
||||
const url = "{{ url('video/folder') }}/" + id;
|
||||
alertSuccessWithUrl('Notice', "Delete success", url);
|
||||
hideLoading();
|
||||
} else {
|
||||
alertFail('Notice', res.message ?? "Unsuccessfully");
|
||||
hideLoading();
|
||||
}
|
||||
}).fail(function(xhr, status, error) {
|
||||
logAjaxError(xhr, status, error);
|
||||
alertFail('Notice', error.message ?? "Unsuccessfully");
|
||||
hideLoading();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const copyButtons = document.querySelectorAll('.copy-button');
|
||||
|
||||
copyButtons.forEach(button => {
|
||||
button.addEventListener('click', function() {
|
||||
const urlToCopy = button.getAttribute('data-url');
|
||||
|
||||
// Copy the URL to the clipboard
|
||||
navigator.clipboard.writeText(urlToCopy).then(() => {
|
||||
alert(
|
||||
'Link copied to clipboard!'
|
||||
); // You can change this to a toast notification
|
||||
}).catch(err => {
|
||||
console.error('Could not copy text: ', err);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@endsection
|
||||
@@ -0,0 +1,426 @@
|
||||
@extends('layouts.backendTemplate')
|
||||
|
||||
@section('content')
|
||||
|
||||
<style>
|
||||
.link-container {
|
||||
display: flex;
|
||||
/* Use flexbox for alignment */
|
||||
align-items: center;
|
||||
/* Center items vertically */
|
||||
justify-content: space-between;
|
||||
/* Space between the URL and button */
|
||||
}
|
||||
|
||||
.file-url {
|
||||
flex: 1;
|
||||
/* Allow the URL to take up available space */
|
||||
color: #007bff;
|
||||
/* Link color */
|
||||
text-decoration: none;
|
||||
/* Remove underline */
|
||||
overflow: hidden;
|
||||
/* Hide overflow */
|
||||
white-space: nowrap;
|
||||
/* Prevent text wrapping */
|
||||
text-overflow: ellipsis;
|
||||
/* Add ellipsis for overflow */
|
||||
margin-right: 10px;
|
||||
/* Space between text and button */
|
||||
}
|
||||
</style>
|
||||
|
||||
<!--begin::Main-->
|
||||
<div class="app-main flex-column flex-row-fluid" id="kt_app_main">
|
||||
|
||||
<div class="d-flex flex-column flex-column-fluid">
|
||||
|
||||
|
||||
@include('uc.breadcrumbList', [
|
||||
'title' => 'Video Management',
|
||||
'pageName' => 'Video Management',
|
||||
])
|
||||
|
||||
|
||||
<div id="kt_app_content" class="app-content flex-column-fluid">
|
||||
|
||||
<div id="kt_app_content_container" class="app-container container-xxl">
|
||||
|
||||
<div class="card">
|
||||
|
||||
@if (Session::has('messageSuccess'))
|
||||
<div class="card-body">
|
||||
@include('uc/messageSuccess')
|
||||
</div>
|
||||
@endif
|
||||
|
||||
@if (Session::has('messageFail'))
|
||||
<div class="card-body">
|
||||
@include('uc/messageFail')
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
<div class="card-header border-0 pt-6">
|
||||
<div class="d-flex align-items-center position-relative my-1">
|
||||
</div>
|
||||
|
||||
@if (Auth::user()->role != 2)
|
||||
<div class="card-toolbar">
|
||||
|
||||
<div class="d-flex justify-content-end" style="margin-right: 5px;"
|
||||
data-kt-customer-table-toolbar="base">
|
||||
<a href="{{ url('video/add-folder') }}" class="btn btn-light-primary me-3"
|
||||
id="kt_file_manager_new_folder">New
|
||||
Folder</a>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end" data-kt-customer-table-toolbar="base">
|
||||
<a href="{{ url('video/add') }}" class="btn btn-primary">Add </a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<div class="card-header border-0 pt-5">
|
||||
|
||||
<div class="card-title">
|
||||
<div class="d-flex align-items-center position-relative my-1">
|
||||
<span class="svg-icon svg-icon-1 position-absolute ms-4">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg">
|
||||
<rect opacity="0.5" x="17.0365" y="15.1223" width="8.15546" height="2"
|
||||
rx="1" transform="rotate(45 17.0365 15.1223)" fill="currentColor">
|
||||
</rect>
|
||||
<path
|
||||
d="M11 19C6.55556 19 3 15.4444 3 11C3 6.55556 6.55556 3 11 3C15.4444 3 19 6.55556 19 11C19 15.4444 15.4444 19 11 19ZM11 5C7.53333 5 5 7.53333 5 11C5 14.4667 7.53333 17 11 17C14.4667 17 17 14.4667 17 11C17 7.53333 14.4667 5 11 5Z"
|
||||
fill="currentColor"></path>
|
||||
</svg>
|
||||
</span>
|
||||
|
||||
<input type="text" table-filter="search"
|
||||
class="form-control form-control-solid w-250px ps-15" placeholder="Search" />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="card-body py-4">
|
||||
<!--begin::Table-->
|
||||
<table class="table align-middle table-row-dashed fs-6 gy-5" id="data-table">
|
||||
<!--begin::Table head-->
|
||||
<thead>
|
||||
<!--begin::Table row-->
|
||||
<tr class="text-start text-muted fw-bold fs-7 text-uppercase gs-0">
|
||||
<th class="min-w-125px">Name</th>
|
||||
<th class="min-w-125px">Created</th>
|
||||
<th class="text-end min-w-100px">Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody class="text-gray-600 fw-semibold">
|
||||
|
||||
@foreach ($folderView as $obj)
|
||||
<tr>
|
||||
<td>
|
||||
<div class="d-flex align-items-center">
|
||||
<span class="svg-icon svg-icon-2x svg-icon-primary me-4">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24"
|
||||
fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.3" d="M10 4H21C21.6 4 22 4.4 22 5V7H10V4Z"
|
||||
fill="currentColor"></path>
|
||||
<path
|
||||
d="M9.2 3H3C2.4 3 2 3.4 2 4V19C2 19.6 2.4 20 3 20H21C21.6 20 22 19.6 22 19V7C22 6.4 21.6 6 21 6H12L10.4 3.60001C10.2 3.20001 9.7 3 9.2 3Z"
|
||||
fill="currentColor"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<a href="{{ url('video/folder/' . $obj->id) }}"
|
||||
class="text-gray-800 text-hover-primary">
|
||||
{{ $obj->name }}</a>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{ Carbon\Carbon::parse($obj['created_at'])->format('d, M Y') }}
|
||||
</td>
|
||||
|
||||
<td class="min-w-100px text-end">
|
||||
|
||||
{{-- Edit --}}
|
||||
<a href="{{ url('video/edit-folder/' . $obj['id']) }}"
|
||||
class="btn btn-icon btn-bg-light btn-active-color-primary btn-sm me-1">
|
||||
<span class="svg-icon svg-icon-3">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24"
|
||||
fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.3"
|
||||
d="M21.4 8.35303L19.241 10.511L13.485 4.755L15.643 2.59595C16.0248 2.21423 16.5426 1.99988 17.0825 1.99988C17.6224 1.99988 18.1402 2.21423 18.522 2.59595L21.4 5.474C21.7817 5.85581 21.9962 6.37355 21.9962 6.91345C21.9962 7.45335 21.7817 7.97122 21.4 8.35303ZM3.68699 21.932L9.88699 19.865L4.13099 14.109L2.06399 20.309C1.98815 20.5354 1.97703 20.7787 2.03189 21.0111C2.08674 21.2436 2.2054 21.4561 2.37449 21.6248C2.54359 21.7934 2.75641 21.9115 2.989 21.9658C3.22158 22.0201 3.4647 22.0084 3.69099 21.932H3.68699Z"
|
||||
fill="currentColor" />
|
||||
<path
|
||||
d="M5.574 21.3L3.692 21.928C3.46591 22.0032 3.22334 22.0141 2.99144 21.9594C2.75954 21.9046 2.54744 21.7864 2.3789 21.6179C2.21036 21.4495 2.09202 21.2375 2.03711 21.0056C1.9822 20.7737 1.99289 20.5312 2.06799 20.3051L2.696 18.422L5.574 21.3ZM4.13499 14.105L9.891 19.861L19.245 10.507L13.489 4.75098L4.13499 14.105Z"
|
||||
fill="currentColor" />
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
{{-- Delete --}}
|
||||
<a href="#" data-id="{{ $obj['id'] }}"
|
||||
class="btn btn-icon btn-bg-light btn-active-color-primary btn-sm delete-folder-item">
|
||||
<span class="svg-icon svg-icon-3">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24"
|
||||
fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M5 9C5 8.44772 5.44772 8 6 8H18C18.5523 8 19 8.44772 19 9V18C19 19.6569 17.6569 21 16 21H8C6.34315 21 5 19.6569 5 18V9Z"
|
||||
fill="currentColor" />
|
||||
<path opacity="0.5"
|
||||
d="M5 5C5 4.44772 5.44772 4 6 4H18C18.5523 4 19 4.44772 19 5V5C19 5.55228 18.5523 6 18 6H6C5.44772 6 5 5.55228 5 5V5Z"
|
||||
fill="currentColor" />
|
||||
<path opacity="0.5"
|
||||
d="M9 4C9 3.44772 9.44772 3 10 3H14C14.5523 3 15 3.44772 15 4V4H9V4Z"
|
||||
fill="currentColor" />
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
</td>
|
||||
|
||||
|
||||
</tr>
|
||||
@endforeach
|
||||
|
||||
|
||||
@foreach ($itemView as $obj)
|
||||
<tr>
|
||||
|
||||
<td class="d-flex align-items-center">
|
||||
<div class="d-flex flex-column">
|
||||
<a href="#" class="text-gray-800 text-hover-primary mb-1">
|
||||
<video controls class="h-100px" style="height: 150px!important;">
|
||||
<source src="{{ env('R2_SCHEMA_URL') . $obj['name'] }}"
|
||||
type="video/mp4">
|
||||
Your browser does not support the video element.
|
||||
</video>
|
||||
</a>
|
||||
<span>{{ $obj['name'] }}</span>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{{ Carbon\Carbon::parse($obj['created_at'])->format('d, M Y') }}
|
||||
</td>
|
||||
|
||||
<td class="min-w-100px text-end">
|
||||
|
||||
{{-- Download --}}
|
||||
<a href="{{ env('R2_SCHEMA_URL') . $obj['name'] }}" target="_blank"
|
||||
class="btn btn-sm btn-icon btn-light btn-active-light-primary"
|
||||
type="button" data-bs-toggle="tooltip" aria-label="Coming soon"
|
||||
data-bs-original-title="Coming soon" data-kt-initialized="1">
|
||||
<i class="bi bi-download fs-3"></i>
|
||||
</a>
|
||||
|
||||
{{-- Copy --}}
|
||||
<button type="button" data-action="copy"
|
||||
data-url="{{ env('R2_SCHEMA_URL') . $obj['name'] }}"
|
||||
class="btn btn-sm btn-icon btn-light btn-active-light-primary copy-button">
|
||||
<span class="svg-icon svg-icon-2">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24"
|
||||
fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path opacity="0.5"
|
||||
d="M18 2H9C7.34315 2 6 3.34315 6 5H8C8 4.44772 8.44772 4 9 4H18C18.5523 4 19 4.44772 19 5V16C19 16.5523 18.5523 17 18 17V19C19.6569 19 21 17.6569 21 16V5C21 3.34315 19.6569 2 18 2Z"
|
||||
fill="currentColor"></path>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M14.7857 7.125H6.21429C5.62255 7.125 5.14286 7.6007 5.14286 8.1875V18.8125C5.14286 19.3993 5.62255 19.875 6.21429 19.875H14.7857C15.3774 19.875 15.8571 19.3993 15.8571 18.8125V8.1875C15.8571 7.6007 15.3774 7.125 14.7857 7.125ZM6.21429 5C4.43908 5 3 6.42709 3 8.1875V18.8125C3 20.5729 4.43909 22 6.21429 22H14.7857C16.5609 22 18 20.5729 18 18.8125V8.1875C18 6.42709 16.5609 5 14.7857 5H6.21429Z"
|
||||
fill="currentColor"></path>
|
||||
</svg>
|
||||
</span>
|
||||
<!--end::Svg Icon-->
|
||||
</button>
|
||||
|
||||
{{-- Delete --}}
|
||||
@if (Auth::user()->role != 2)
|
||||
<a href="#" data-id="{{ $obj['id'] }}"
|
||||
class="btn btn-sm btn-icon btn-light btn-active-light-primary delete-item">
|
||||
<span class="svg-icon svg-icon-3">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24"
|
||||
fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M5 9C5 8.44772 5.44772 8 6 8H18C18.5523 8 19 8.44772 19 9V18C19 19.6569 17.6569 21 16 21H8C6.34315 21 5 19.6569 5 18V9Z"
|
||||
fill="currentColor" />
|
||||
<path opacity="0.5"
|
||||
d="M5 5C5 4.44772 5.44772 4 6 4H18C18.5523 4 19 4.44772 19 5V5C19 5.55228 18.5523 6 18 6H6C5.44772 6 5 5.55228 5 5V5Z"
|
||||
fill="currentColor" />
|
||||
<path opacity="0.5"
|
||||
d="M9 4C9 3.44772 9.44772 3 10 3H14C14.5523 3 15 3.44772 15 4V4H9V4Z"
|
||||
fill="currentColor" />
|
||||
</svg>
|
||||
</span>
|
||||
</a>
|
||||
@endif
|
||||
</td>
|
||||
|
||||
|
||||
</tr>
|
||||
@endforeach
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@stop
|
||||
|
||||
|
||||
@section('script')
|
||||
|
||||
<script type="text/javascript">
|
||||
const baseUrl = "{{ url('video') }}";
|
||||
var datatable;
|
||||
datatable = $("#data-table").DataTable({
|
||||
"info": false,
|
||||
"order": []
|
||||
});
|
||||
|
||||
// Filter by search
|
||||
const filterSearch = document.querySelector('[table-filter="search"]');
|
||||
filterSearch.addEventListener('keyup', function(e) {
|
||||
datatable.search(e.target.value).draw();
|
||||
});
|
||||
|
||||
// filter by status
|
||||
const filterStatus = document.querySelector('[table-filter="status"]');
|
||||
$(filterStatus).on('change', e => {
|
||||
let value = e.target.value;
|
||||
if (value === 'all') {
|
||||
value = '';
|
||||
}
|
||||
datatable.column(4).search(value).draw();
|
||||
});
|
||||
|
||||
|
||||
// Remove
|
||||
$(document).on('click', '.delete-item', function() {
|
||||
swal.fire({
|
||||
allowOutsideClick: false,
|
||||
text: "Are you sure you would like to Delete?",
|
||||
icon: "warning",
|
||||
buttonsStyling: false,
|
||||
showDenyButton: true,
|
||||
confirmButtonText: "Yes",
|
||||
denyButtonText: 'No',
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
denyButton: "btn btn-light-danger"
|
||||
}
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
|
||||
alertLoading("Loading")
|
||||
|
||||
// set up ajax
|
||||
initAjaxSetupToken();
|
||||
|
||||
const ajaxProp = {
|
||||
url: "{{ url('video/delete') }}",
|
||||
type: 'POST',
|
||||
data: {
|
||||
item_id: $(this).data('id')
|
||||
},
|
||||
};
|
||||
|
||||
$.ajax(ajaxProp).done(function(res) {
|
||||
if (res.status) {
|
||||
const url = "{{ url('video') }}";
|
||||
alertSuccessWithUrl('Notice', "Delete success", url);
|
||||
hideLoading();
|
||||
} else {
|
||||
alertFail('Notice', res.message ?? "Unsuccessfully");
|
||||
hideLoading();
|
||||
}
|
||||
}).fail(function(xhr, status, error) {
|
||||
logAjaxError(xhr, status, error);
|
||||
alertFail('Notice', error.message ?? "Unsuccessfully");
|
||||
hideLoading();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const copyButtons = document.querySelectorAll('.copy-button');
|
||||
|
||||
copyButtons.forEach(button => {
|
||||
button.addEventListener('click', function() {
|
||||
const urlToCopy = button.getAttribute('data-url');
|
||||
|
||||
// Copy the URL to the clipboard
|
||||
navigator.clipboard.writeText(urlToCopy).then(() => {
|
||||
alert(
|
||||
'Link copied to clipboard!'
|
||||
); // You can change this to a toast notification
|
||||
}).catch(err => {
|
||||
console.error('Could not copy text: ', err);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Delete folder
|
||||
$(document).on('click', '.delete-folder-item', function() {
|
||||
swal.fire({
|
||||
allowOutsideClick: false,
|
||||
text: "Are you sure you would like to Delete?",
|
||||
icon: "warning",
|
||||
buttonsStyling: false,
|
||||
showDenyButton: true,
|
||||
confirmButtonText: "Yes",
|
||||
denyButtonText: 'No',
|
||||
customClass: {
|
||||
confirmButton: "btn btn-primary",
|
||||
denyButton: "btn btn-light-danger"
|
||||
}
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
|
||||
alertLoading("Loading")
|
||||
|
||||
// set up ajax
|
||||
initAjaxSetupToken();
|
||||
|
||||
const ajaxProp = {
|
||||
url: "{{ url('video/delete-folder') }}",
|
||||
type: 'POST',
|
||||
data: {
|
||||
item_id: $(this).data('id')
|
||||
},
|
||||
};
|
||||
|
||||
$.ajax(ajaxProp).done(function(res) {
|
||||
if (res.status) {
|
||||
const url = "{{ url('video') }}";
|
||||
alertSuccessWithUrl('Notice', "Delete success", url);
|
||||
hideLoading();
|
||||
} else {
|
||||
alertFail('Notice', res.message ?? "Unsuccessfully");
|
||||
hideLoading();
|
||||
}
|
||||
}).fail(function(xhr, status, error) {
|
||||
logAjaxError(xhr, status, error);
|
||||
alertFail('Notice', error.message ?? "Unsuccessfully");
|
||||
hideLoading();
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@endsection
|
||||
Reference in New Issue
Block a user