feat: implement Spatie Media Library integration
with CRUD operations and media management UI
This commit is contained in:
parent
d40b87438d
commit
02884d4e2b
11 changed files with 499 additions and 4 deletions
|
|
@ -2,13 +2,16 @@
|
|||
|
||||
namespace App\Filament\Resources\Entries\Schemas;
|
||||
|
||||
use Filament\Actions\Action;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Forms\Components\RichEditor;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Select;
|
||||
use Filament\Forms\Components\Textarea;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Forms\Components\Toggle;
|
||||
use Filament\Schemas\Schema;
|
||||
use Illuminate\Support\Str;
|
||||
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
||||
|
||||
class EntryForm
|
||||
{
|
||||
|
|
@ -18,13 +21,14 @@ class EntryForm
|
|||
->components([
|
||||
TextInput::make('title')
|
||||
->required()
|
||||
->reactive()
|
||||
->live(onBlur: true)
|
||||
->afterStateUpdated(function ($state, $set): void {
|
||||
$set('slug', Str::slug((string) $state));
|
||||
}),
|
||||
TextInput::make('slug')
|
||||
->required()
|
||||
->disabled(),
|
||||
->dehydrated()
|
||||
->readOnly(),
|
||||
Textarea::make('description')
|
||||
->columnSpanFull(),
|
||||
Toggle::make('is_published')
|
||||
|
|
@ -33,7 +37,45 @@ class EntryForm
|
|||
->required(),
|
||||
DatePicker::make('published_at'),
|
||||
RichEditor::make('content')
|
||||
->columnSpanFull(),
|
||||
->columnSpanFull()
|
||||
->hintAction(
|
||||
Action::make('picker')
|
||||
->label('Gallery Picker')
|
||||
->icon('heroicon-m-photo')
|
||||
->schema([
|
||||
Select::make('image_url')
|
||||
->label('Select an existing image')
|
||||
->allowHtml()
|
||||
->options(function () {
|
||||
// We must 'get' the collection first so we can call getUrl()
|
||||
// because 'url' is not a column in the Spatie database table.
|
||||
return Media::latest()
|
||||
->get()
|
||||
->mapWithKeys(function (Media $item) {
|
||||
$url = $item->getUrl();
|
||||
|
||||
$fileName = e($item->file_name);
|
||||
$name = e($item->name ?? '');
|
||||
|
||||
$html = "<div class='flex items-center gap-2 w-full'>".
|
||||
"<img src=\"{$url}\" class=\"rounded\" style=\"max-width:200px;max-height:200px;object-fit:cover;width:auto;height:auto;\" alt=\"{$fileName}\"/>".
|
||||
"<span class=\"ml-2 truncate\">{$name} — {$fileName}</span></div>";
|
||||
|
||||
return [$url => $html];
|
||||
})->toArray();
|
||||
})
|
||||
->searchable()
|
||||
->required(),
|
||||
])
|
||||
->action(function (array $data, RichEditor $component) {
|
||||
// We dispatch the URL to the browser to be inserted into TipTap
|
||||
$component->getLivewire()->dispatch('insert-editor-content', [
|
||||
'statePath' => $component->getStatePath(),
|
||||
'html' => "<img src='{$data['image_url']}' alt=''>",
|
||||
]);
|
||||
})
|
||||
),
|
||||
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ use Filament\Actions\DeleteBulkAction;
|
|||
use Filament\Actions\EditAction;
|
||||
use Filament\Actions\ViewAction;
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
use Filament\Tables\Columns\SpatieMediaLibraryImageColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
|
|
@ -16,6 +17,11 @@ class EntriesTable
|
|||
{
|
||||
return $table
|
||||
->columns([
|
||||
SpatieMediaLibraryImageColumn::make('featured_image')
|
||||
->collection('featured')
|
||||
->circular()
|
||||
->stacked()
|
||||
->limit(3),
|
||||
TextColumn::make('title')
|
||||
->searchable(),
|
||||
TextColumn::make('slug')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue