Prečo Filament, nie vlastný admin
Každý projekt s backoffice potrebuje admin rozhranie. Väčšina vývojárov ho stavia na mieru — tabuľky, formuláre, filtrovanie, paginovanie, oprávnenia. Trvá to dni a výsledok vyzerá rovnako: šedé tabuľky bez vizuálnej identity.
Filament 3 je open-source admin framework postavený priamo na Laraveli, Livewire a Alpine.js. Nedostanete generický SaaS — dostanete PHP knižnicu, ktorú vlastníte, modifikujete a nasadzujete bez mesačných poplatkov.
| Prístup | Čas vývoja | Údržba | Cena |
|---|---|---|---|
| Custom admin (Blade + Bootstrap) | 3–5 dní | Vysoká | Len čas vývojára |
| Nova (Laravel official) | 2–4 hod. | Nízka | 99 USD/projekt |
| Filament 3 | 2–3 hod. | Nízka | Zdarma (MIT) |
Z krabice dostanete: tabuľky s vyhľadávaním, triedením a filtráciou, formuláre s validáciou, nahrávanie súborov, rich-text editor, sofistikovaný systém oprávnení, dark mode a responzívny dizajn — bez jediného riadku vlastného CSS.
Inštalácia za 3 príkazy
Filament vyžaduje Laravel 11+ a PHP 8.2+. Viac o základoch Laravelu nájdete v článku Prečo Laravel 12 v roku 2026 stále vyhráva.
# 1. Nainštalovanie balíka
composer require filament/filament:"^3.3"
# 2. Inicializácia admin panelu
php artisan filament:install --panels
# 3. Prvý admin používateľ
php artisan make:filament-user
Po týchto troch príkazoch máte funkčný admin panel na adrese /admin. Prihlasovací formulár, dashboard a navigácia — všetko okamžite.
filament:install --panels vytvorí súbor app/Providers/Filament/AdminPanelProvider.php. Tu neskôr nastavíte logo, farebnú tému, navigáciu, middleware a ďalšie globálne nastavenia celého admin panelu.
Prvý Resource — správa produktov
Resource je základ Filamentu — spája Eloquent model s tabuľkou a formulárom v adminu. Jeden príkaz vygeneruje všetko potrebné:
php artisan make:filament-resource Product --generate
Voľba --generate automaticky prečíta stĺpce z databázy a vytvorí základnú schému. Výsledný súbor app/Filament/Resources/ProductResource.php upravíte podľa potreby:
// app/Filament/Resources/ProductResource.php
public static function form(Form $form): Form
{
return $form->schema([
Forms\Components\TextInput::make('name')
->label('Názov produktu')
->required()
->maxLength(255),
Forms\Components\TextInput::make('price')
->label('Cena (EUR)')
->numeric()
->prefix('€')
->required(),
Forms\Components\Select::make('category_id')
->label('Kategória')
->relationship('category', 'name')
->searchable()
->preload()
->required(),
Forms\Components\Toggle::make('is_active')
->label('Aktívny produkt')
->default(true),
Forms\Components\FileUpload::make('image')
->label('Obrázok produktu')
->image()
->directory('products')
->maxSize(2048),
]);
}
Tabuľka s filtráciou a vyhľadávaním
public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\ImageColumn::make('image')->label(''),
Tables\Columns\TextColumn::make('name')
->label('Názov')
->searchable()
->sortable(),
Tables\Columns\TextColumn::make('price')
->label('Cena')
->money('EUR')
->sortable(),
Tables\Columns\TextColumn::make('category.name')
->label('Kategória')
->badge(),
Tables\Columns\ToggleColumn::make('is_active')
->label('Aktívny'),
])
->filters([
Tables\Filters\SelectFilter::make('category')
->relationship('category', 'name'),
Tables\Filters\TernaryFilter::make('is_active')
->label('Stav produktu'),
])
->defaultSort('created_at', 'desc');
}
Výsledok: plnohodnotná správa produktov s vyhľadávaním, filtráciou, obrázkami a prepínačom aktivity — bez jediného riadku vlastného HTML.
Vlastné Actions
Actions sú tlačidlá s logikou — na riadku tabuľky, nad tabuľkou alebo hromadne pre viacero záznamov. Filament ich stavia cez fluent API.
Action na riadku: schválenie objednávky
// V metóde table() pridajte do ->actions([]):
Tables\Actions\Action::make('approve')
->label('Schváliť')
->icon('heroicon-o-check-circle')
->color('success')
->requiresConfirmation()
->modalHeading('Schváliť objednávku?')
->modalDescription('Zákazník dostane potvrdzovací e-mail.')
->action(function (Order $record): void {
$record->update(['status' => 'approved']);
$record->customer->notify(new OrderApprovedNotification($record));
Notification::make()
->title('Objednávka schválená')
->success()
->send();
})
BulkAction: hromadný export
// V metóde table() pridajte do ->bulkActions([]):
Tables\Actions\BulkAction::make('export')
->label('Exportovať do CSV')
->icon('heroicon-o-arrow-down-tray')
->action(function (Collection $records) {
return response()->streamDownload(function () use ($records) {
$csv = Writer::createFromString();
$csv->insertOne(['ID', 'Meno', 'Email', 'Suma']);
$records->each(fn($r) => $csv->insertOne([
$r->id, $r->customer_name, $r->email, $r->total
]));
echo $csv->toString();
}, 'objednavky.csv');
})
requiresConfirmation() je pri deštruktívnych akciách (zmazanie, zmena stavu) povinné — ochrana pred náhodným kliknutím. Filament zobrazí modal automaticky, bez vlastného JavaScriptu.
Widgety na dashboarde
Dashboard bez čísel je prázdny panel. Filament má vstavaný systém widgetov — generujete ich príkazom a vypĺňate dátami z Eloquentu.
StatsOverviewWidget: kľúčové metriky
php artisan make:filament-widget StatsOverview --stats-overview
// app/Filament/Widgets/StatsOverview.php
class StatsOverview extends BaseWidget
{
protected function getStats(): array
{
return [
Stat::make('Tržby dnes', '€ ' . number_format(
Order::whereDate('created_at', today())->sum('total'), 2
))
->description('Oproti včerajšku')
->descriptionIcon('heroicon-m-arrow-trending-up')
->color('success'),
Stat::make('Nové objednávky', Order::whereDate('created_at', today())->count())
->description('Čakajú na vybavenie')
->color('warning'),
Stat::make('Aktívni zákazníci', Customer::where('is_active', true)->count())
->color('primary'),
];
}
}
LineChartWidget: objednávky za 30 dní
php artisan make:filament-widget OrdersChart --chart
// app/Filament/Widgets/OrdersChart.php
class OrdersChart extends ChartWidget
{
protected static ?string $heading = 'Objednávky — posledných 30 dní';
protected static string $color = 'primary';
protected function getData(): array
{
$data = Order::selectRaw('DATE(created_at) as date, COUNT(*) as count')
->where('created_at', '>=', now()->subDays(30))
->groupBy('date')
->orderBy('date')
->pluck('count', 'date');
return [
'datasets' => [['label' => 'Objednávky', 'data' => $data->values()->toArray()]],
'labels' => $data->keys()->toArray(),
];
}
protected function getType(): string { return 'line'; }
}
Roly a oprávnenia cez Shield
Filament nemá vstavaný systém rolí — namiesto toho sa skvele integruje so Filament Shield, ktorý je postavený na spatie/laravel-permission.
composer require bezhansalleh/filament-shield
php artisan shield:install --fresh
php artisan shield:generate --all
Shield automaticky vygeneruje oprávnenia pre každý Resource: view_product, create_product, update_product, delete_product. Potom priradíte roly používateľom:
// Vytvorenie rolí
php artisan shield:super-admin --user=1 // superadmin
// V kóde — priradenie role
$user->assignRole('editor');
// Filament automaticky skryje/zablokuje Resources podľa oprávnení
// Ak chcete manuálnu kontrolu:
public static function canCreate(): bool
{
return auth()->user()->hasRole(['admin', 'manager']);
}
public static function canDeleteAny(): bool
{
return auth()->user()->hasRole('admin');
}
Záver: checklist pred odovzdaním
- Resources vytvorené pre všetky hlavné modely (
--generateušetrí čas) - Tabuľky majú
searchable()aspoň na meno/e-mail stĺpcoch - Deštruktívne Actions majú
requiresConfirmation() - Dashboard má aspoň jeden StatsOverview widget
- Shield nainštalovaný, roly definované
- Admin URL zmenená z
/adminna niečo neočakávané (bezpečnosť) - Middleware
auth+ prípadneverifiedna admin panel - Testovanie: každá role odskúšaná v prehliadači
Čo ďalej: pokročilé možnosti
Filament 3 toho vie oveľa viac. Ďalšie kroky podľa projektu:
- Multi-tenancy — jeden Filament panel pre viacero zákazníkov (SaaS)
- Vlastné Pages — ľubovoľná Livewire stránka v admin paneli
- Relation Managers — správa vzťahov (napr. položky objednávky) priamo na detaile záznamu
- AI widget — kombinácia s OpenAI API pre inteligentný asistent priamo v adminu
Filament som použil na viacerých projektoch — CRM pre výrobnú firmu, rezervačný systém aj e-commerce backend. Vo všetkých prípadoch skrátil vývoj admin časti o viac ako 70 %. Ak budujete systém na mieru v Laraveli, Filament je prvá vec, ktorú inštalujem. Viac o tom, prečo Laravel stále vyhráva, nájdete v článku Ako navrhnúť REST API, ktoré nevyhorí o rok.