This commit is contained in:
F4ilji
2026-04-07 17:54:26 +05:00
parent 04adba6682
commit 936b1fb5b0
468 changed files with 43498 additions and 4176 deletions
@@ -0,0 +1,57 @@
<?php
namespace App\Containers\Dashboard\Actions\Sliders;
use App\Containers\Dashboard\Tasks\Sliders\UploadSlideImageTask;
use App\Containers\Widget\Models\Slider;
use App\Containers\Widget\Models\Slide;
use Illuminate\Http\UploadedFile;
class CreateSlideAction
{
public function __construct(
private readonly UploadSlideImageTask $uploadImageTask,
) {}
public function run(Slider $slider, array $data): Slide
{
$maxSort = $slider->slides()->max('sort') ?? 0;
// Формируем структуру image как в Filament: {url, shading}
$imageData = [
'url' => null,
'shading' => $data['image_shading'] ?? '0.5',
];
// Обрабатываем изображение если это файл
if (isset($data['image']) && $data['image'] instanceof UploadedFile) {
$uploaded = $this->uploadImageTask->run($data['image']);
$imageData['url'] = $uploaded['url'];
}
$data['image'] = $imageData;
unset($data['image_shading']);
// Формируем settings как в Filament: только text_position и link_text
$data['settings'] = [
'text_position' => $data['settings']['text_position'] ?? 'left',
'link_text' => $data['settings']['link_text'] ?? 'Читать',
];
// active_button - отдельное поле в базе (не в settings!)
// Но Filament хранит его в settings, проверим структуру
$data['settings']['active_button'] = isset($data['active_button']) ? (bool) $data['active_button'] : true;
// Преобразуем is_active в boolean
if (isset($data['is_active'])) {
$data['is_active'] = (bool) $data['is_active'];
}
$slide = new Slide($data);
$slide->sort = $maxSort + 1;
$slider->slides()->save($slide);
return $slide;
}
}
@@ -0,0 +1,16 @@
<?php
namespace App\Containers\Dashboard\Actions\Sliders;
use App\Containers\Widget\Models\Slider;
use Illuminate\Support\Str;
class CreateSliderAction
{
public function run(array $data): Slider
{
$data['slug'] = $data['slug'] ?? Str::slug($data['title']);
return Slider::create($data);
}
}
@@ -0,0 +1,13 @@
<?php
namespace App\Containers\Dashboard\Actions\Sliders;
use App\Containers\Widget\Models\Slide;
class DeleteSlideAction
{
public function run(Slide $slide): bool
{
return $slide->delete();
}
}
@@ -0,0 +1,13 @@
<?php
namespace App\Containers\Dashboard\Actions\Sliders;
use App\Containers\Widget\Models\Slider;
class DeleteSliderAction
{
public function run(Slider $slider): bool
{
return $slider->delete();
}
}
@@ -0,0 +1,26 @@
<?php
namespace App\Containers\Dashboard\Actions\Sliders;
use App\Containers\Widget\Models\Slider;
use Illuminate\Pagination\LengthAwarePaginator;
class ListSlidersAction
{
public function run(array $filters = []): LengthAwarePaginator
{
$query = Slider::query()
->withCount('slides')
->when(isset($filters['is_active']), function ($query) use ($filters) {
$query->where('is_active', $filters['is_active']);
})
->when(isset($filters['search']), function ($query) use ($filters) {
$query->where(function ($q) use ($filters) {
$q->where('title', 'like', '%' . $filters['search'] . '%')
->orWhere('slug', 'like', '%' . $filters['search'] . '%');
});
});
return $query->orderBy('title', 'asc')->paginate(20);
}
}
@@ -0,0 +1,17 @@
<?php
namespace App\Containers\Dashboard\Actions\Sliders;
use App\Containers\Widget\Models\Slider;
use App\Containers\Widget\Models\Slide;
use Illuminate\Support\Collection;
class ListSlidesAction
{
public function run(Slider $slider): Collection
{
return $slider->slides()
->orderBy('sort')
->get();
}
}
@@ -0,0 +1,70 @@
<?php
namespace App\Containers\Dashboard\Actions\Sliders;
use App\Containers\Dashboard\Tasks\Sliders\UploadSlideImageTask;
use App\Containers\Widget\Models\Slide;
use Illuminate\Http\UploadedFile;
class UpdateSlideAction
{
public function __construct(
private readonly UploadSlideImageTask $uploadImageTask,
) {}
public function run(Slide $slide, array $data): Slide
{
// Формируем структуру image как в Filament: {url, shading}
$imageData = $slide->image ?? [];
if (!is_array($imageData)) {
$imageData = [];
}
// Обновляем shading если передан
if (isset($data['image_shading'])) {
$imageData['shading'] = $data['image_shading'];
unset($data['image_shading']);
}
// Обрабатываем новое изображение если это файл
if (isset($data['image']) && $data['image'] instanceof UploadedFile) {
$uploaded = $this->uploadImageTask->run($data['image']);
$imageData['url'] = $uploaded['url'];
}
// Сохраняем image
if (!empty($imageData)) {
$data['image'] = $imageData;
}
// Формируем settings
if (isset($data['settings'])) {
$settings = $slide->settings ?? [];
if (!is_array($settings)) {
$settings = [];
}
// Обновляем переданные поля
foreach ($data['settings'] as $key => $value) {
$settings[$key] = $value;
}
// active_button
if (isset($data['active_button'])) {
$settings['active_button'] = (bool) $data['active_button'];
unset($data['active_button']);
}
$data['settings'] = $settings;
}
// Преобразуем is_active в boolean
if (isset($data['is_active'])) {
$data['is_active'] = (bool) $data['is_active'];
}
$slide->update($data);
return $slide;
}
}
@@ -0,0 +1,15 @@
<?php
namespace App\Containers\Dashboard\Actions\Sliders;
use App\Containers\Widget\Models\Slider;
class UpdateSliderAction
{
public function run(Slider $slider, array $data): Slider
{
$slider->update($data);
return $slider;
}
}
@@ -0,0 +1,15 @@
<?php
namespace App\Containers\Dashboard\Actions\Sliders;
use App\Containers\Widget\Models\Slider;
class UpdateSlidesOrderAction
{
public function run(Slider $slider, array $slideIds): void
{
foreach ($slideIds as $index => $slideId) {
$slider->slides()->where('id', $slideId)->update(['sort' => $index + 1]);
}
}
}