From 4a776a42e20c3175451d7628a63a96a8d5ad2c7d Mon Sep 17 00:00:00 2001 From: F4ilji Date: Fri, 18 Sep 2026 02:25:36 +0500 Subject: [PATCH] fix: resolve image upload issues in posts - Dashboard: disable submit button during uploads, show upload errors, guard against pending uploads - Filament: add maxParallelUploads(1) to fix race condition (filamentphp#13306) - Filament: add image/webp to gallery acceptedFileTypes, increase resize 30->50 - Dashboard: add image/webp to gallery input accept - Add missing notifications table migration for Filament databaseNotifications --- app/Filament/Components/Forms/PostForm.php | 7 +-- ...9_18_021743_create_notifications_table.php | 31 ++++++++++++ resources/js/Pages/Dashboard/Posts/Form.vue | 50 +++++++++++++++++-- 3 files changed, 81 insertions(+), 7 deletions(-) create mode 100644 database/migrations/2026_09_18_021743_create_notifications_table.php diff --git a/app/Filament/Components/Forms/PostForm.php b/app/Filament/Components/Forms/PostForm.php index 0afd189..d7e4008 100755 --- a/app/Filament/Components/Forms/PostForm.php +++ b/app/Filament/Components/Forms/PostForm.php @@ -160,7 +160,7 @@ class PostForm ->image() ->directory('posts/gallery') ->optimize('jpg') - ->resize(30) + ->resize(50) ->imageEditor() ->multiple() ->reorderable() @@ -168,8 +168,9 @@ class PostForm ->helperText('Загрузите дополнительные изображения для галереи') ->maxFiles(200) ->maxSize(20480) - ->acceptedFileTypes(['image/jpeg', 'image/png']) - ->imagePreviewHeight('150'), + ->acceptedFileTypes(['image/jpeg', 'image/png', 'image/webp']) + ->imagePreviewHeight('150') + ->maxParallelUploads(1), ]), Tabs\Tab::make('Слайдер') ->icon('heroicon-o-view-columns') diff --git a/database/migrations/2026_09_18_021743_create_notifications_table.php b/database/migrations/2026_09_18_021743_create_notifications_table.php new file mode 100644 index 0000000..d738032 --- /dev/null +++ b/database/migrations/2026_09_18_021743_create_notifications_table.php @@ -0,0 +1,31 @@ +uuid('id')->primary(); + $table->string('type'); + $table->morphs('notifiable'); + $table->text('data'); + $table->timestamp('read_at')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('notifications'); + } +}; diff --git a/resources/js/Pages/Dashboard/Posts/Form.vue b/resources/js/Pages/Dashboard/Posts/Form.vue index 68b6c59..e4c2c10 100644 --- a/resources/js/Pages/Dashboard/Posts/Form.vue +++ b/resources/js/Pages/Dashboard/Posts/Form.vue @@ -26,15 +26,15 @@ @@ -76,6 +76,28 @@ + + +
+
+ +
+ {{ uploadError }} +
+ +
+
+
+
@@ -497,7 +519,7 @@ ref="galleryInput" type="file" class="hidden" - accept="image/jpeg,image/png" + accept="image/jpeg,image/png,image/webp" multiple @change="handleGalleryFileSelect" /> @@ -596,6 +618,7 @@ export default { isDraggingPreview: false, isDraggingGallery: false, uploadingImages: false, + uploadError: null, newTag: '', newAuthor: '', PostStatus, @@ -698,6 +721,11 @@ export default { return null; }).filter(url => url !== null); }, + + uploadStatusText() { + if (this.uploadingImages) return 'Загрузка файлов...'; + return this.isEdit ? 'Сохранить' : 'Создать'; + }, }, beforeUnmount() { @@ -812,6 +840,7 @@ export default { if (!file) return; this.uploadingImages = true; + this.uploadError = null; try { const formData = new FormData(); @@ -830,9 +859,12 @@ export default { if (result.success && result.paths && result.paths.length > 0) { this.form.preview = result.paths[0]; + } else { + this.uploadError = result.error || 'Не удалось загрузить главное изображение'; } } catch (error) { console.error('Preview upload error:', error); + this.uploadError = 'Ошибка сети при загрузке главного изображения. Проверьте подключение.'; } finally { this.uploadingImages = false; } @@ -858,6 +890,7 @@ export default { if (files.length === 0) return; this.uploadingImages = true; + this.uploadError = null; try { const formData = new FormData(); @@ -880,9 +913,12 @@ export default { result.paths.forEach(path => { this.form.images.push(path); }); + } else { + this.uploadError = result.error || 'Не удалось загрузить изображения галереи'; } } catch (error) { console.error('Image upload error:', error); + this.uploadError = 'Ошибка сети при загрузке изображений. Проверьте подключение.'; } finally { this.uploadingImages = false; } @@ -951,8 +987,14 @@ export default { }, submitForm() { + if (this.uploadingImages) { + this.uploadError = 'Дождитесь завершения загрузки изображений перед сохранением.'; + return; + } + this.form.processing = true; this.form.errors = {}; + this.uploadError = null; // Фильтруем изображения - оставляем только строки (пути) this.form.images = this.form.images.filter(img => typeof img === 'string' && img.length > 0);