raffles document uploader added / Free Resource Completed
This commit is contained in:
25
.env.example
25
.env.example
@@ -4,48 +4,37 @@ APP_KEY=
|
||||
APP_DEBUG=true
|
||||
APP_TIMEZONE=UTC
|
||||
APP_URL=http://localhost
|
||||
|
||||
APP_LOCALE=en
|
||||
APP_FALLBACK_LOCALE=en
|
||||
APP_FAKER_LOCALE=en_US
|
||||
|
||||
APP_MAINTENANCE_DRIVER=file
|
||||
# APP_MAINTENANCE_STORE=database
|
||||
|
||||
BCRYPT_ROUNDS=12
|
||||
|
||||
LOG_CHANNEL=stack
|
||||
LOG_STACK=single
|
||||
LOG_DEPRECATIONS_CHANNEL=null
|
||||
LOG_LEVEL=debug
|
||||
|
||||
DB_CONNECTION=sqlite
|
||||
# DB_HOST=127.0.0.1
|
||||
# DB_PORT=3306
|
||||
# DB_DATABASE=laravel
|
||||
# DB_USERNAME=root
|
||||
# DB_PASSWORD=
|
||||
|
||||
DB_CONNECTION=mysql
|
||||
DB_HOST=127.0.0.1
|
||||
DB_PORT=3306
|
||||
DB_DATABASE=raffles
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=
|
||||
SESSION_DRIVER=database
|
||||
SESSION_LIFETIME=120
|
||||
SESSION_ENCRYPT=false
|
||||
SESSION_PATH=/
|
||||
SESSION_DOMAIN=null
|
||||
|
||||
BROADCAST_CONNECTION=log
|
||||
FILESYSTEM_DISK=local
|
||||
QUEUE_CONNECTION=database
|
||||
|
||||
CACHE_STORE=database
|
||||
CACHE_PREFIX=
|
||||
|
||||
MEMCACHED_HOST=127.0.0.1
|
||||
|
||||
REDIS_CLIENT=phpredis
|
||||
REDIS_HOST=127.0.0.1
|
||||
REDIS_PASSWORD=null
|
||||
REDIS_PORT=6379
|
||||
|
||||
MAIL_MAILER=log
|
||||
MAIL_HOST=127.0.0.1
|
||||
MAIL_PORT=2525
|
||||
@@ -54,11 +43,9 @@ MAIL_PASSWORD=null
|
||||
MAIL_ENCRYPTION=null
|
||||
MAIL_FROM_ADDRESS="hello@example.com"
|
||||
MAIL_FROM_NAME="${APP_NAME}"
|
||||
|
||||
AWS_ACCESS_KEY_ID=
|
||||
AWS_SECRET_ACCESS_KEY=
|
||||
AWS_DEFAULT_REGION=us-east-1
|
||||
AWS_BUCKET=
|
||||
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||
|
||||
VITE_APP_NAME="${APP_NAME}"
|
@@ -8,10 +8,12 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Modules\CCMS\Traits\UpdateCustomFields;
|
||||
use Modules\Document\Models\Document;
|
||||
use App\Traits\AddToDocumentCollection;
|
||||
|
||||
|
||||
class Country extends Model
|
||||
{
|
||||
use HasFactory, UpdateCustomFields, CreatedUpdatedBy;
|
||||
use HasFactory, AddToDocumentCollection, UpdateCustomFields, CreatedUpdatedBy;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
@@ -102,4 +104,5 @@ class Country extends Model
|
||||
{
|
||||
return $this->morphMany(Document::class, 'documentable');
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -8,10 +8,12 @@ use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Modules\CCMS\Traits\UpdateCustomFields;
|
||||
use Modules\Document\Models\Document;
|
||||
use App\Traits\AddToDocumentCollection;
|
||||
|
||||
|
||||
class Service extends Model
|
||||
{
|
||||
use HasFactory, UpdateCustomFields, CreatedUpdatedBy;
|
||||
use HasFactory, UpdateCustomFields, AddToDocumentCollection, CreatedUpdatedBy;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
|
@@ -8,12 +8,13 @@ use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Modules\CCMS\Traits\UpdateCustomFields;
|
||||
use Modules\Document\Models\Document;
|
||||
use App\Traits\AddToDocumentCollection;
|
||||
|
||||
// use Modules\CCMS\Database\Factories\TestFactory;
|
||||
|
||||
class Test extends Model
|
||||
{
|
||||
use HasFactory, UpdateCustomFields, CreatedUpdatedBy;
|
||||
use HasFactory, UpdateCustomFields, AddToDocumentCollection, CreatedUpdatedBy;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
|
@@ -6,10 +6,13 @@ use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Str;
|
||||
use Modules\CCMS\Models\Country;
|
||||
use Modules\Document\Models\Document;
|
||||
use Modules\CCMS\Models\Service;
|
||||
use Modules\CCMS\Models\Test;
|
||||
use Modules\Document\Services\DocumentService;
|
||||
use Yajra\DataTables\Facades\DataTables;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
|
||||
class DocumentController extends Controller
|
||||
{
|
||||
@@ -33,39 +36,151 @@ class DocumentController extends Controller
|
||||
}
|
||||
|
||||
|
||||
public function dropzoneUpload(Request $request)
|
||||
public function destroy($id)
|
||||
{
|
||||
$request->validate([
|
||||
'model' => 'required|string',
|
||||
'file' => 'required|array',
|
||||
'file.*' => 'file|mimes:pdf,doc,docx,jpg,png|max:5120',
|
||||
'title' => 'nullable|string',
|
||||
try {
|
||||
$document = Document::findOrFail($id);
|
||||
if (File::exists('storage/' . $document->document_path)) {
|
||||
File::delete('storage/' . $document->document_path);
|
||||
}
|
||||
|
||||
$document->delete();
|
||||
|
||||
session()->flash('Document Deleted');
|
||||
return response()->json(['status' => true, 'msg' => 'Document Deleted']);
|
||||
|
||||
} catch (\Throwable $th) {
|
||||
session()->flash('error', $th->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function uploadDocument(Request $request)
|
||||
{
|
||||
$isNumeric = is_numeric($request->title);
|
||||
|
||||
$validator = Validator::make($request->all(), [
|
||||
'title' => $isNumeric ? 'required|exists:required_documents,id' : 'required|string',
|
||||
'model' => 'required',
|
||||
'document' => 'required|array',
|
||||
], [
|
||||
'title.required' => 'Document title is required!',
|
||||
'title.exists' => 'Document does not exists in record!',
|
||||
'document' => 'Please upload document first!',
|
||||
'model' => 'Please Select Category'
|
||||
]);
|
||||
|
||||
$parts = explode(':', $request->model);
|
||||
|
||||
if (count($parts) !== 2) {
|
||||
return response()->json(['error' => 'Invalid model format.'], 422);
|
||||
if ($validator->fails()) {
|
||||
return response()->json(['status' => 422, 'errors' => $validator->errors()], 422);
|
||||
}
|
||||
|
||||
[$modelType, $modelId] = $parts;
|
||||
$modelClass = "App\\Models\\$modelType";
|
||||
try {
|
||||
|
||||
if (!class_exists($modelClass)) {
|
||||
return response()->json(['error' => 'Invalid model selected.'], 422);
|
||||
$modelValues = explode(':', $request->model);
|
||||
$modelClass = "Modules\\CCMS\\Models\\{$modelValues[0]}";
|
||||
|
||||
$model = $modelClass::findOrFail($modelValues[1]);
|
||||
|
||||
|
||||
foreach ($request->input('document', []) as $file) {
|
||||
$model->addToDocumentCollection(collectionName: 'uploads/document', file: $file, documentName: $request->title, referenceDocumentId: null);
|
||||
}
|
||||
|
||||
$model = $modelClass::findOrFail($modelId);
|
||||
return response()->json([
|
||||
'status' => true,
|
||||
'msg' => 'Document has been uploaded!',
|
||||
// 'view' => view('student::student.section.document.table', [
|
||||
// 'student' => $student,
|
||||
// ])->render(),
|
||||
], 200);
|
||||
} catch (\Throwable $th) {
|
||||
return response()->json([
|
||||
'status' => false,
|
||||
'msg' => $th->getMessage(),
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($request->file('file') as $uploadedFile) {
|
||||
$path = $uploadedFile->store('documents');
|
||||
public function store(Request $request)
|
||||
{
|
||||
$path = storage_path('tmp/uploads');
|
||||
|
||||
$model->documents()->create([
|
||||
'title' => $request->title ?? 'Untitled',
|
||||
'file_path' => $path,
|
||||
if (!file_exists($path)) {
|
||||
mkdir($path, 0777, true);
|
||||
}
|
||||
|
||||
$file = $request->file('file');
|
||||
|
||||
$name = uniqid() . '_' . trim($file->getClientOriginalName());
|
||||
|
||||
$file->move($path, $name);
|
||||
|
||||
return response()->json([
|
||||
'name' => $name,
|
||||
'original_name' => $file->getClientOriginalName(),
|
||||
]);
|
||||
}
|
||||
|
||||
return response()->json(['success' => 'Files uploaded successfully']);
|
||||
public function getAllDocuments()
|
||||
{
|
||||
$model = Document::query()->latest();
|
||||
return DataTables::eloquent($model)
|
||||
->setRowClass('tableRow')
|
||||
->addColumn('name', function (Document $document) {
|
||||
$extension = $document->getExtension();
|
||||
$assetUrl = $document->getUrl();
|
||||
$html = $document->isImageFile()
|
||||
? "<div class='flex-shrink-0'>
|
||||
<div class='avatar-sm bg-light rounded p-1'>
|
||||
<a href='{$assetUrl}' data-fancybox='gallery' data-caption='{$document->title}'>
|
||||
<img src='{$assetUrl}' alt='' class='avatar-sm img-fluid d-block'>
|
||||
</a>
|
||||
</div>
|
||||
</div>"
|
||||
: "<div class='flex-shrink-0'>
|
||||
<div class='avatar-sm'>
|
||||
<a href='{$assetUrl}' data-fancybox='gallery' data-caption='{$document->title}'>
|
||||
<div class='avatar-title bg-" . getFileIcon($extension)[1] . "-subtle text-" . getFileIcon($extension)[1] . " fs-20 material-shadow rounded'>
|
||||
<i class='" . getFileIcon($extension)[0] . "'></i>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>";
|
||||
|
||||
return "<div class='d-flex align-items-center'>
|
||||
{$html} <div class='flex-grow-1 ms-3'>
|
||||
<h6 class='fs-12 mb-0'>{$document->title}</h6>
|
||||
</div>
|
||||
</div>";
|
||||
})
|
||||
->addColumn('type', function (Document $document) {
|
||||
return $document->getExtension();
|
||||
})
|
||||
->addColumn('size', function (Document $document) {
|
||||
return $document->getSize();
|
||||
})
|
||||
->editColumn('created_at', function (Document $document) {
|
||||
return getFormatted($document->created_at);
|
||||
})
|
||||
->addColumn('action', function (Document $document) {
|
||||
return view('document::document.partials.action', ['document' => $document]);
|
||||
})
|
||||
->rawColumns(['action', 'name', 'size'])
|
||||
->toJson();
|
||||
}
|
||||
|
||||
public function reorder(Request $request)
|
||||
{
|
||||
Document::chunkById(100, function (Collection $documents) use ($request) {
|
||||
foreach ($documents as $document) {
|
||||
foreach ($request->order as $order) {
|
||||
if ($order['id'] == $document->id) {
|
||||
$document->update(['order' => $order['position']]);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return response(['status' => true, 'message' => 'Reordered successfully'], 200);
|
||||
}
|
||||
}
|
||||
|
@@ -13,9 +13,16 @@ class Document extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = ['title', 'file_path'];
|
||||
protected $fillable = ['title', 'file_path', 'collection_name', 'order'];
|
||||
|
||||
|
||||
protected static function booted()
|
||||
{
|
||||
static::creating(function ($model) {
|
||||
$model->order = ($model::max('order') ?? 0) + 1;
|
||||
});
|
||||
}
|
||||
|
||||
public function documentable(): MorphTo
|
||||
{
|
||||
return $this->morphTo();
|
||||
@@ -23,13 +30,13 @@ class Document extends Model
|
||||
|
||||
public function getUrl()
|
||||
{
|
||||
$path = $this->document_path;
|
||||
$path = $this->collection_name . '/' . $this->file_path;
|
||||
return Storage::disk('public')->url($path);
|
||||
}
|
||||
|
||||
public function getSize()
|
||||
{
|
||||
$path = $this->document_path;
|
||||
$path = $this->collection_name . '/' . $this->file_path;
|
||||
|
||||
if (Storage::disk('public')->exists($path)) {
|
||||
$sizeInBytes = Storage::disk('public')->size($path);
|
||||
@@ -41,13 +48,13 @@ class Document extends Model
|
||||
|
||||
public function getExtension()
|
||||
{
|
||||
return pathinfo($this->document_path, PATHINFO_EXTENSION);
|
||||
return pathinfo($this->file_path, PATHINFO_EXTENSION);
|
||||
}
|
||||
|
||||
public function isImageFile()
|
||||
{
|
||||
$imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg', 'webp', 'tiff', 'tif', 'ico'];
|
||||
$extension = pathinfo($this->document_path, PATHINFO_EXTENSION);
|
||||
$extension = pathinfo($this->file_path, PATHINFO_EXTENSION);
|
||||
return in_array(Str::lower($extension), $imageExtensions);
|
||||
}
|
||||
|
||||
@@ -56,7 +63,7 @@ class Document extends Model
|
||||
return Attribute::make(
|
||||
get: function (mixed $value, array $attributes) {
|
||||
$collectionName = $attributes['collection_name'];
|
||||
$path = $attributes['document_path'];
|
||||
$path = $attributes['file_path'];
|
||||
return "{$collectionName}/{$path}";
|
||||
}
|
||||
);
|
||||
|
@@ -13,11 +13,12 @@ return new class extends Migration
|
||||
{
|
||||
Schema::create('documents', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('title');
|
||||
$table->string('file_path');
|
||||
$table->string('title')->nullable();
|
||||
$table->string('file_path')->nullable();
|
||||
$table->string('collection_name')->default('uploads');
|
||||
$table->unsignedBigInteger('documentable_id');
|
||||
$table->string('documentable_type');
|
||||
$table->index(['documentable_type', 'documentable_id']);
|
||||
$table->unsignedBigInteger("order")->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
@@ -2,9 +2,7 @@
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
|
||||
<form method="POST" action="{{ route('documents.dropzone.upload') }}" class="dropzone" id="mainForm"
|
||||
enctype="multipart/form-data">
|
||||
@csrf
|
||||
{{ html()->form('POST', route('documents.upload'))->class(['needs-validation'])->attributes(['novalidate', 'enctype' => 'multipart/form-data', 'id' => 'documentForm'])->open() }}
|
||||
|
||||
<div class="mb-3">
|
||||
{{ html()->label('Title')->for('title') }}
|
||||
@@ -15,74 +13,102 @@
|
||||
<div class="mb-3">
|
||||
{{ html()->label('Select Model')->class('form-label')->for('model') }}
|
||||
{{ html()->span('*')->class('text-danger') }}
|
||||
{{ html()->select('model')->id('modelSelect')->class('form-select')->required()->options(['' => '-- Select --'] + $modelOptions->toArray()) }}
|
||||
{{ html()->select('model')->id('modelSelect')->class('form-select select2')->required()->options(['' => '-- Select --'] + $modelOptions->toArray()) }}
|
||||
</div>
|
||||
|
||||
<div class="dropzone-previews mb-3"></div>
|
||||
|
||||
<div class="dz-message mb-3">
|
||||
<p class="fs-14">Drop files here or click to upload.</p>
|
||||
<div class="mb-3">
|
||||
<x-document::file-upload :uploadUrl="route('documents.store')" dropzoneId="document-dropzone"
|
||||
formId="documentForm" message="Upload Document (PDF or Images Only)"
|
||||
inputName="document" />
|
||||
</div>
|
||||
|
||||
<button type="button" class="btn btn-primary" id="submitAll">Submit</button>
|
||||
</form>
|
||||
<div class="col-sm-12">
|
||||
<div class="hstack justify-content-end gap-2">
|
||||
<button type="submit" class="btn btn-primary upload-btn">Upload</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ html()->form()->close() }}
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@push('js')
|
||||
|
||||
@pushOnce('js')
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
Dropzone.autoDiscover = false;
|
||||
function clearDropzone(dropzoneIds = [], formId = '', fileFieldNames = []) {
|
||||
dropzoneIds.forEach(function(id) {
|
||||
const dropzoneElement = Dropzone.forElement(`#${id}`);
|
||||
if (dropzoneElement) {
|
||||
dropzoneElement.removeAllFiles(true);
|
||||
}
|
||||
});
|
||||
|
||||
const myDropzone = new Dropzone("#mainForm", {
|
||||
url: "{{ route('documents.dropzone.upload') }}",
|
||||
autoProcessQueue: false,
|
||||
uploadMultiple: true,
|
||||
parallelUploads: 5,
|
||||
maxFilesize: 5,
|
||||
addRemoveLinks: true,
|
||||
acceptedFiles: ".pdf,.doc,.docx,.jpg,.png",
|
||||
paramName: "file[]",
|
||||
fileFieldNames.forEach(function(field) {
|
||||
$(`#${formId} input[name="${field}[]"]`).remove();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
$(document).on('submit', '#documentForm', function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
const url = $(this).attr('action');
|
||||
const formData = new FormData(this);
|
||||
const button = $(this).find('button[type="submit"]');
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: url,
|
||||
data: formData,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': document.querySelector('input[name="_token"]').value
|
||||
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
|
||||
},
|
||||
init: function() {
|
||||
const dz = this;
|
||||
beforeSend: () => {
|
||||
button.text('Uploading...').prop('disabled', true);
|
||||
},
|
||||
success: (response) => {
|
||||
if (response.status == true) {
|
||||
$('#documentForm')[0].reset();
|
||||
|
||||
document.getElementById("submitAll").addEventListener("click", function(e) {
|
||||
const title = document.getElementById('docTitle').value;
|
||||
const model = document.getElementById('modelSelect').value;
|
||||
// if (DataTable.isDataTable("#documents-table")) {
|
||||
// $("#documents-table").DataTable().ajax.reload();
|
||||
// } else {
|
||||
// target.html(response.view);
|
||||
// }
|
||||
|
||||
clearDropzone(dropzoneIds = ["document-dropzone"],
|
||||
"documentForm", ["document"]);
|
||||
|
||||
button.text('Upload').prop('disabled', false);
|
||||
toastr.success(response.msg);
|
||||
|
||||
if (!title || !model) {
|
||||
alert("Please fill in both Title and Model.");
|
||||
return;
|
||||
}
|
||||
},
|
||||
error: (xhr) => {
|
||||
if (xhr.status === 422) {
|
||||
const errors = xhr.responseJSON.errors;
|
||||
$('.error-message').remove();
|
||||
|
||||
if (dz.getQueuedFiles().length > 0) {
|
||||
dz.processQueue();
|
||||
for (const [key, value] of Object.entries(errors)) {
|
||||
const errorMessage = $(
|
||||
'<p class="error-message text-danger mt-2"></p>').text(
|
||||
value[0]);
|
||||
$(`#${key}`).after(errorMessage);
|
||||
}
|
||||
} else {
|
||||
alert("Please select at least one file.");
|
||||
console.error(xhr);
|
||||
}
|
||||
});
|
||||
|
||||
dz.on("sending", function(file, xhr, formData) {
|
||||
formData.append("title", document.getElementById('docTitle').value);
|
||||
formData.append("model", document.getElementById('modelSelect').value);
|
||||
});
|
||||
|
||||
dz.on("successmultiple", function(files, response) {
|
||||
alert("Files uploaded successfully.");
|
||||
dz.removeAllFiles();
|
||||
document.getElementById('mainForm').reset();
|
||||
});
|
||||
|
||||
dz.on("errormultiple", function(files, response) {
|
||||
alert("An error occurred during upload.");
|
||||
console.error(response);
|
||||
});
|
||||
},
|
||||
complete: () => {
|
||||
button.text('Upload');
|
||||
button.prop('disabled', true);
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
@endPushOnce
|
||||
|
@@ -8,26 +8,17 @@
|
||||
@endif
|
||||
|
||||
<div class="row">
|
||||
<div class="col-lg-6 col-xl-6">
|
||||
<div class="col-lg-4 col-xl-4">
|
||||
<div class="card profile-card">
|
||||
@include('document::document.form')
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- <div class="col-lg-xl-8 col-lg-9">
|
||||
<div class="col-lg-xl-8 col-lg-8">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
@php
|
||||
$columns = [
|
||||
[
|
||||
'title' => '<input type="checkbox" id="select-all">',
|
||||
'data' => 'checkbox',
|
||||
'name' => 'checkbox',
|
||||
'orderable' => false,
|
||||
'searchable' => false,
|
||||
'printable' => false,
|
||||
'exportable' => false,
|
||||
],
|
||||
['title' => 'Document', 'data' => 'name', 'name' => 'name'],
|
||||
['title' => 'Type', 'data' => 'type', 'name' => 'type'],
|
||||
['title' => 'Size', 'data' => 'size', 'name' => 'size'],
|
||||
@@ -41,10 +32,11 @@
|
||||
];
|
||||
@endphp
|
||||
|
||||
<x-data-table-script :route="route('gallery.index')" :reorder="route('gallery.reorder')" :columns="$columns" />
|
||||
<x-data-table-script :route="route('documents.getAllDocuments')" :columns="$columns" id="documents-table" :reorder="route('documents.reorder')" />
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> --}}
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
@@ -0,0 +1,7 @@
|
||||
<div class="hstack flex-wrap gap-3 align-items-center">
|
||||
<a href="{{ $document->getUrl() }}" class="link-primary fs-15" download><i class="ri-download-2-line"></i></a>
|
||||
@can('documents.destroy')
|
||||
<a href="javascript:void(0);" data-link="{{ route('documents.destroy', $document->id) }}"
|
||||
class="link-danger fs-15 remove-item"><i class="ri-delete-bin-line"></i></a>
|
||||
@endcan
|
||||
</div>
|
@@ -15,6 +15,9 @@ use Modules\Document\Http\Controllers\DocumentController;
|
||||
*/
|
||||
|
||||
Route::group(['middleware' => ['web', 'auth', 'permission'], 'prefix' => 'admin/'], function () {
|
||||
Route::get('/documents', [DocumentController::class, 'index'])->name('documents.index');
|
||||
Route::post('/documents/dropzone-upload', [DocumentController::class, 'dropzoneUpload'])->name('documents.dropzone.upload');
|
||||
// Route::get('/documents', [DocumentController::class, 'index'])->name('documents.index');
|
||||
Route::post('documents/reorder', [DocumentController::class, 'reorder'])->name('documents.reorder');
|
||||
Route::resource('documents', DocumentController::class)->names('documents');
|
||||
Route::post('/documents/upload', [DocumentController::class, 'uploadDocument'])->name('documents.upload');
|
||||
Route::get('get-all-documents', [DocumentController::class, 'getAllDocuments'])->name('documents.getAllDocuments');
|
||||
});
|
||||
|
@@ -20,6 +20,49 @@ if (!function_exists('setting')) {
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('getFileIcon')) {
|
||||
|
||||
function getFileIcon($extension)
|
||||
{
|
||||
switch ($extension) {
|
||||
case 'pdf':
|
||||
return ['ri-file-pdf-line', 'danger'];
|
||||
case 'doc':
|
||||
case 'docx':
|
||||
return ['ri-file-word-line', 'primary'];
|
||||
case 'xls':
|
||||
case 'xlsx':
|
||||
return ['ri-file-excel-line', 'success'];
|
||||
case 'ppt':
|
||||
case 'pptx':
|
||||
return ['ri-file-powerpoint-line', 'danger'];
|
||||
case 'txt':
|
||||
return ['ri-file-alt-line', 'secondary'];
|
||||
case 'jpg':
|
||||
case 'jpeg':
|
||||
case 'png':
|
||||
case 'gif':
|
||||
return ['ri-file-image-line', 'info'];
|
||||
case 'zip':
|
||||
case 'rar':
|
||||
return ['ri-file-archive-line', 'warning'];
|
||||
case 'mp3':
|
||||
case 'wav':
|
||||
return ['ri-file-audio-line', 'warning'];
|
||||
case 'mp4':
|
||||
case 'mov':
|
||||
case 'avi':
|
||||
return ['ri-file-video-line', 'warning'];
|
||||
default:
|
||||
return ['ri-file-line', 'warning'];
|
||||
}
|
||||
// return collect([
|
||||
// 'icon' => $res[0],
|
||||
// 'color' => $res[1],
|
||||
// ]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!function_exists('uploadImage')) {
|
||||
function uploadImage($file, $path = 'uploads')
|
||||
{
|
||||
|
33
app/Traits/AddToDocumentCollection.php
Normal file
33
app/Traits/AddToDocumentCollection.php
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace App\Traits;
|
||||
|
||||
use Illuminate\Database\Eloquent\Relations\MorphMany;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Modules\Document\Models\Document;
|
||||
|
||||
trait AddToDocumentCollection
|
||||
{
|
||||
public function addToDocumentCollection(string $collectionName = 'uploads', string $file, ?string $documentName = null, ?int $referenceDocumentId = null)
|
||||
{
|
||||
if (!Storage::disk('public')->exists($collectionName)) {
|
||||
Storage::disk('public')->makeDirectory($collectionName);
|
||||
}
|
||||
|
||||
$targetFile = Storage::disk('public')->path("{$collectionName}/{$file}");
|
||||
|
||||
File::copy(storage_path("tmp/uploads/{$file}"), $targetFile);
|
||||
|
||||
$this->documents()->create([
|
||||
'title' => $documentName,
|
||||
'file_path' => $file,
|
||||
'collection_name' => $collectionName,
|
||||
]);
|
||||
}
|
||||
|
||||
public function documents(): MorphMany
|
||||
{
|
||||
return $this->morphMany(Document::class, 'documentable')->orderBy('order');
|
||||
}
|
||||
}
|
@@ -228,10 +228,10 @@ return [
|
||||
|
||||
[
|
||||
'text' => 'Documents',
|
||||
'url' => 'admin/document',
|
||||
'url' => 'admin/documents',
|
||||
'icon' => 'ri-file-text-line',
|
||||
'module' => 'Document',
|
||||
'can' => ['document.index'],
|
||||
'can' => ['documents.index'],
|
||||
],
|
||||
[
|
||||
'text' => 'Resume Builder',
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -31,7 +31,7 @@
|
||||
<link href="{{ asset('assets/css/custom.min.css') }}" rel="stylesheet" type="text/css" />
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.9.3/min/dropzone.min.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fancyapps/ui@5.0/dist/fancybox/fancybox.css" />
|
||||
|
||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css" rel="stylesheet" />
|
||||
@livewireStyles
|
||||
|
||||
@stack('css')
|
||||
@@ -119,6 +119,7 @@
|
||||
<script>
|
||||
const app_url = "{{ config('app.url') }}";
|
||||
</script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.9.3/min/dropzone.min.js"></script>
|
||||
<script src="{{ asset('assets/libs/jquery/jquery-3.7.1.min.js') }}"></script>
|
||||
<script src="{{ asset('assets/libs/bootstrap/js/bootstrap.bundle.min.js') }}"></script>
|
||||
|
BIN
storage/tmp/uploads/688e37041003e_Resume_Subash_PHP_1Yrs (1).pdf
Normal file
BIN
storage/tmp/uploads/688e37041003e_Resume_Subash_PHP_1Yrs (1).pdf
Normal file
Binary file not shown.
BIN
storage/tmp/uploads/688e386660f13_index.png
Normal file
BIN
storage/tmp/uploads/688e386660f13_index.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 MiB |
BIN
storage/tmp/uploads/688e38f9307e6_Resume_Subash_PHP_1Yrs (1).pdf
Normal file
BIN
storage/tmp/uploads/688e38f9307e6_Resume_Subash_PHP_1Yrs (1).pdf
Normal file
Binary file not shown.
BIN
storage/tmp/uploads/688e3b58d10f8_Resume_Subash_PHP_1Yrs (1).pdf
Normal file
BIN
storage/tmp/uploads/688e3b58d10f8_Resume_Subash_PHP_1Yrs (1).pdf
Normal file
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 67 KiB |
BIN
storage/tmp/uploads/688e438468483_report (15).pdf
Normal file
BIN
storage/tmp/uploads/688e438468483_report (15).pdf
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
storage/tmp/uploads/688e5589e5624_intern covers_removed.pdf
Normal file
BIN
storage/tmp/uploads/688e5589e5624_intern covers_removed.pdf
Normal file
Binary file not shown.
Reference in New Issue
Block a user