Last active
September 14, 2024 13:08
-
-
Save ewilan-riviere/dfca491def1bb5aabf70e1649518b5f1 to your computer and use it in GitHub Desktop.
Revisions
-
ewilan-riviere revised this gist
Apr 27, 2023 . 1 changed file with 75 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,75 @@ <?php namespace App\View\Components\Field; use Illuminate\View\Component; use Illuminate\View\View; class UploadFile extends Component { public function __construct( public string $name = 'file', // name="avatar" public bool|int $multiple = false, // multiple public bool|int $validate = true, // validate for allowFileTypeValidation public bool|int $preview = true, // preview for allowImagePreview public bool|int $required = false, // required public bool|int $disabled = false, // disabled public int $previewMax = 200, // preview-max="200" for imagePreviewMaxHeight public array|string $accept = ['image/png', 'image/jpeg', 'image/webp', 'image/avif'], // accept="image/png, image/jpeg" for accept public string $size = '2MB', // size="4mb" for maxFileSize public int $number = 10, // number="4" for maxFiles public string $label = '', public string $sizeHuman = '', public array|string $acceptHuman = [], ) { } public function render(): View|string { if (! $this->multiple) { $this->multiple = 0; } if (! $this->validate) { $this->validate = 0; } if (! $this->preview) { $this->preview = 0; } if (! $this->required) { $this->required = 0; } if (! $this->disabled) { $this->disabled = 0; } if (is_string($this->accept)) { $this->accept = explode(',', $this->accept); } $this->accept = array_map('trim', $this->accept); $this->accept = array_filter($this->accept); $this->accept = array_unique($this->accept); $this->accept = array_values($this->accept); $this->accept = array_map('strtolower', $this->accept); $fileTypes = $this->accept; $this->accept = json_encode($this->accept); $this->sizeHuman = $this->size; foreach ($fileTypes as $type) { $new = explode('/', $type); if (array_key_exists(1, $new)) { $this->acceptHuman[] = ".{$new[1]}"; } } $this->acceptHuman = implode(', ', $this->acceptHuman); return view('components.field.upload-file'); } } -
ewilan-riviere created this gist
Apr 27, 2023 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,173 @@ @pushOnce('head') <link href="https://unpkg.com/filepond/dist/filepond.css" rel="stylesheet" > <link href="https://unpkg.com/filepond-plugin-image-preview/dist/filepond-plugin-image-preview.css" rel="stylesheet" > <style> .filepond--drop-label { background-color: white; border-width: 2px; border-style: dashed; border-color: lightgray; border-radius: 0.375rem; transition: background-color 0.1s ease; } .filepond--drop-label:hover { background-color: rgba(0, 0, 0, 0.01); } </style> @endPushOnce <div class="relative" wire:ignore x-data="{ model: @entangle($attributes->whereStartsWith('wire:model')->first()), isMultiple: {{ $multiple ? 'true' : 'false' }}, current: undefined, currentList: [], async URLtoFile(path) { let url = `${window.appUrlStorage}/${path}`; let name = url.split('/').pop(); const response = await fetch(url); const data = await response.blob(); const metadata = { name: name, size: data.size, type: data.type }; let file = new File([data], name, metadata); return { source: file, options: { type: 'local', metadata: { name: name, size: file.size, type: file.type } } } } }" x-cloak x-init="async () => { let picture = model let files = [] let exists = [] if (model) { if (isMultiple) { currentList = model.map((picture) => `${window.appUrlStorage}/${picture}`); await Promise.all(model.map(async (picture) => exists.push(await URLtoFile(picture)))) } else { if (picture) { exists.push(await URLtoFile(picture)) } } } files = exists let modelName = '{{ $attributes->whereStartsWith('wire:model')->first() }}' const notify = () => { new Notification() .title('File uploaded') .body(`You can save changes!`) .success() .seconds(1.5) .send() } const pond = FilePond.create($refs.{{ $attributes->get('ref') ?? 'input' }}); pond.setOptions({ allowMultiple: {{ $multiple ? 'true' : 'false' }}, server: { process: (fieldName, file, metadata, load, error, progress, abort, transfer, options) => { @this.upload(modelName, file, load, error, progress) }, revert: (filename, load) => { @this.removeUpload(modelName, filename, load) }, remove: (filename, load) => { @this.removeFile(modelName, filename.name) load(); }, }, allowImagePreview: {{ $preview ? 'true' : 'false' }}, imagePreviewMaxHeight: {{ $previewMax ? $previewMax : '256' }}, allowFileTypeValidation: {{ $validate ? 'true' : 'false' }}, acceptedFileTypes: {{ $accept ? $accept : 'null' }}, allowFileSizeValidation: {{ $validate ? 'true' : 'false' }}, maxFileSize: {!! $size ? "'" . $size . "'" : 'null' !!}, maxFiles: {{ $number ? $number : 'null' }}, required: {{ $required ? 'true' : 'false' }}, disabled: {{ $disabled ? 'true' : 'false' }}, onprocessfile: () => notify() }); pond.addFiles(files) pond.on('addfile', (error, file) => { if (error) { console.log('Oh no'); return; } }); }" > @if ($label) <div class="flex items-center justify-between"> <label class="block text-sm font-medium leading-6 text-gray-900 dark:text-gray-100" for="{{ $name }}" > {{ $label }} @if ($required) <span class="text-red-500" title="Required" >*</span> @endif </label> <div class="text-xs text-gray-400"> Size max: {{ $sizeHuman }} </div> </div> @endif <div class="flex items-center justify-between text-xs text-gray-400"> <div> Formats: {{ $acceptHuman }} </div> <div> {{ $multiple ? 'Multiple' : 'Single' }} @if ($multiple) <span>({{ $number }} files max)</span> @endif </div> </div> <div class="mt-5"> <input type="file" x-ref="{{ $attributes->get('ref') ?? 'input' }}" /> </div> @error('image') <p class="mt-2 text-sm text-red-600">{{ $message }}</p> @enderror </div> @pushOnce('scripts') <script src="https://unpkg.com/filepond-plugin-file-validate-type/dist/filepond-plugin-file-validate-type.js"></script> <script src="https://unpkg.com/filepond-plugin-file-validate-size/dist/filepond-plugin-file-validate-size.js"></script> <script src="https://unpkg.com/filepond-plugin-image-preview/dist/filepond-plugin-image-preview.js"></script> <script src="https://unpkg.com/filepond/dist/filepond.js"></script> <script> FilePond.registerPlugin(FilePondPluginFileValidateType); FilePond.registerPlugin(FilePondPluginFileValidateSize); FilePond.registerPlugin(FilePondPluginImagePreview); </script> @endPushOnce