Cari Halaman

Pengenalan Filament

Sarah Johnson
1 January 0001
4-5 jam

Pengenalan Filament - Laravel Admin Panel

Filament adalah framework admin panel yang powerful dan modern untuk Laravel. Mari kita mulai dengan dasar-dasar Filament.

Apa itu Filament?

Filament adalah framework admin panel yang dibangun di atas Laravel dan TALL stack (Tailwind CSS, Alpine.js, Laravel, Livewire). Filament menyediakan interface yang modern dan powerful untuk mengelola data aplikasi Laravel.

Keunggulan Filament

  • Modern UI: Interface yang modern dengan Tailwind CSS
  • Laravel Integration: Terintegrasi sempurna dengan Laravel
  • Livewire: Real-time interactions tanpa JavaScript
  • Customizable: Sangat mudah untuk dikustomisasi
  • Developer Experience: Developer-friendly dengan fitur yang intuitif
  • Rich Components: Komponen UI yang lengkap
  • Form Builder: Form builder yang powerful
  • Table Builder: Table builder yang fleksibel

Persiapan Development Environment

1. Prerequisites

1
2
3
4
5
# Pastikan sudah menginstall:
# - PHP >= 8.1
# - Laravel >= 10.0
# - Composer
# - Node.js & NPM

2. Install Filament

1
2
3
4
5
6
7
8
# Install Filament via Composer
composer require filament/filament

# Publish Filament assets
php artisan filament:install

# Create admin user
php artisan make:filament-user

3. Configure Filament

1
2
3
4
5
# Publish config files
php artisan vendor:publish --tag=filament-config

# Run migrations
php artisan migrate

Struktur Filament

1. Directory Structure

1
2
3
4
5
6
7
8
9
app/
├── Filament/
│   ├── Resources/
│   │   ├── UserResource.php
│   │   └── PostResource.php
│   ├── Pages/
│   │   └── Dashboard.php
│   └── Widgets/
│       └── StatsOverview.php

2. Configuration

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
// config/filament.php
return [
    'path' => env('FILAMENT_PATH', 'admin'),
    'domain' => env('FILAMENT_DOMAIN'),
    'home_url' => '/',
    'auth' => [
        'guard' => env('FILAMENT_AUTH_GUARD', 'web'),
    ],
    'pages' => [
        'namespace' => 'App\\Filament\\Pages',
        'path' => app_path('Filament/Pages'),
        'register' => [
            \App\Filament\Pages\Dashboard::class,
        ],
    ],
];

Creating Your First Resource

1. Generate Resource

1
2
3
4
5
# Create a resource for User model
php artisan make:filament-resource User

# Create a resource with all CRUD operations
php artisan make:filament-resource Post --generate

2. Basic Resource Structure

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<?php

namespace App\Filament\Resources;

use App\Filament\Resources\UserResource\Pages;
use App\Models\User;
use Filament\Forms;
use Filament\Forms\Form;
use Filament\Resources\Resource;
use Filament\Tables;
use Filament\Tables\Table;

class UserResource extends Resource
{
    protected static ?string $model = User::class;

    protected static ?string $navigationIcon = 'heroicon-o-users';

    public static function form(Form $form): Form
    {
        return $form
            ->schema([
                Forms\Components\TextInput::make('name')
                    ->required()
                    ->maxLength(255),
                Forms\Components\TextInput::make('email')
                    ->email()
                    ->required()
                    ->maxLength(255),
                Forms\Components\TextInput::make('password')
                    ->password()
                    ->required()
                    ->hiddenOn('edit'),
            ]);
    }

    public static function table(Table $table): Table
    {
        return $table
            ->columns([
                Tables\Columns\TextColumn::make('name')
                    ->searchable(),
                Tables\Columns\TextColumn::make('email')
                    ->searchable(),
                Tables\Columns\TextColumn::make('created_at')
                    ->dateTime()
                    ->sortable()
                    ->toggleable(isToggledHiddenByDefault: true),
            ])
            ->filters([
                //
            ])
            ->actions([
                Tables\Actions\EditAction::make(),
                Tables\Actions\DeleteAction::make(),
            ])
            ->bulkActions([
                Tables\Actions\BulkActionGroup::make([
                    Tables\Actions\DeleteBulkAction::make(),
                ]),
            ]);
    }

    public static function getRelations(): array
    {
        return [
            //
        ];
    }

    public static function getPages(): array
    {
        return [
            'index' => Pages\ListUsers::route('/'),
            'create' => Pages\CreateUser::route('/create'),
            'edit' => Pages\EditUser::route('/{record}/edit'),
        ];
    }
}

Form Components

1. Basic Form Fields

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
public static function form(Form $form): Form
{
    return $form
        ->schema([
            // Text Input
            Forms\Components\TextInput::make('name')
                ->label('Full Name')
                ->required()
                ->maxLength(255)
                ->placeholder('Enter your full name'),

            // Email Input
            Forms\Components\TextInput::make('email')
                ->email()
                ->required()
                ->unique(ignoreRecord: true),

            // Password Input
            Forms\Components\TextInput::make('password')
                ->password()
                ->required()
                ->hiddenOn('edit')
                ->confirmed(),

            // Password Confirmation
            Forms\Components\TextInput::make('password_confirmation')
                ->password()
                ->required()
                ->hiddenOn('edit'),

            // Select Dropdown
            Forms\Components\Select::make('role')
                ->options([
                    'admin' => 'Administrator',
                    'user' => 'User',
                    'moderator' => 'Moderator',
                ])
                ->required(),

            // Checkbox
            Forms\Components\Toggle::make('is_active')
                ->label('Active User')
                ->default(true),

            // Date Picker
            Forms\Components\DatePicker::make('birth_date')
                ->label('Date of Birth'),

            // File Upload
            Forms\Components\FileUpload::make('avatar')
                ->image()
                ->directory('avatars')
                ->maxSize(5120), // 5MB

            // Rich Text Editor
            Forms\Components\RichEditor::make('bio')
                ->label('Biography')
                ->columnSpanFull(),
        ]);
}

2. Advanced Form Components

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public static function form(Form $form): Form
{
    return $form
        ->schema([
            // Tabs
            Forms\Components\Tabs::make('User Information')
                ->tabs([
                    'basic' => Forms\Components\Tabs\Tab::make('Basic Info')
                        ->schema([
                            Forms\Components\TextInput::make('name'),
                            Forms\Components\TextInput::make('email'),
                        ]),
                    'advanced' => Forms\Components\Tabs\Tab::make('Advanced')
                        ->schema([
                            Forms\Components\Select::make('role'),
                            Forms\Components\Toggle::make('is_active'),
                        ]),
                ]),

            // Grid Layout
            Forms\Components\Grid::make(2)
                ->schema([
                    Forms\Components\TextInput::make('first_name'),
                    Forms\Components\TextInput::make('last_name'),
                ]),

            // Section
            Forms\Components\Section::make('Contact Information')
                ->schema([
                    Forms\Components\TextInput::make('phone'),
                    Forms\Components\TextInput::make('address'),
                ])
                ->collapsible(),

            // Repeater
            Forms\Components\Repeater::make('social_links')
                ->schema([
                    Forms\Components\TextInput::make('platform'),
                    Forms\Components\TextInput::make('url'),
                ])
                ->columns(2),
        ]);
}

Table Components

1. Basic Table Columns

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public static function table(Table $table): Table
{
    return $table
        ->columns([
            // Text Column
            Tables\Columns\TextColumn::make('name')
                ->label('Full Name')
                ->searchable()
                ->sortable(),

            // Email Column
            Tables\Columns\TextColumn::make('email')
                ->searchable()
                ->sortable(),

            // Image Column
            Tables\Columns\ImageColumn::make('avatar')
                ->circular(),

            // Badge Column
            Tables\Columns\BadgeColumn::make('role')
                ->colors([
                    'danger' => 'admin',
                    'warning' => 'moderator',
                    'success' => 'user',
                ]),

            // Toggle Column
            Tables\Columns\ToggleColumn::make('is_active')
                ->label('Active'),

            // Date Column
            Tables\Columns\TextColumn::make('created_at')
                ->dateTime()
                ->sortable()
                ->toggleable(isToggledHiddenByDefault: true),
        ]);
}

2. Advanced Table Features

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
public static function table(Table $table): Table
{
    return $table
        ->columns([
            // Select Column
            Tables\Columns\TextColumn::make('name')
                ->searchable()
                ->sortable()
                ->selectable(),

            // Action Column
            Tables\Columns\TextColumn::make('email')
                ->searchable()
                ->copyable()
                ->copyMessage('Email copied!'),

            // Status Column
            Tables\Columns\BadgeColumn::make('status')
                ->colors([
                    'success' => 'active',
                    'danger' => 'inactive',
                ]),

            // Progress Column
            Tables\Columns\ProgressColumn::make('completion_rate')
                ->label('Completion Rate'),
        ])
        ->filters([
            // Select Filter
            Tables\Filters\SelectFilter::make('role')
                ->options([
                    'admin' => 'Administrator',
                    'user' => 'User',
                    'moderator' => 'Moderator',
                ]),

            // Date Filter
            Tables\Filters\Filter::make('created_at')
                ->form([
                    Forms\Components\DatePicker::make('created_from'),
                    Forms\Components\DatePicker::make('created_until'),
                ])
                ->query(function (Builder $query, array $data): Builder {
                    return $query
                        ->when(
                            $data['created_from'],
                            fn (Builder $query, $date): Builder => $query->whereDate('created_at', '>=', $date),
                        )
                        ->when(
                            $data['created_until'],
                            fn (Builder $query, $date): Builder => $query->whereDate('created_at', '<=', $date),
                        );
                }),
        ])
        ->actions([
            Tables\Actions\ViewAction::make(),
            Tables\Actions\EditAction::make(),
            Tables\Actions\DeleteAction::make(),
        ])
        ->bulkActions([
            Tables\Actions\BulkActionGroup::make([
                Tables\Actions\DeleteBulkAction::make(),
            ]),
        ]);
}

Custom Pages

1. Create Custom Page

1
2
# Generate custom page
php artisan make:filament-page Settings

2. Custom Page Structure

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php

namespace App\Filament\Pages;

use Filament\Pages\Page;

class Settings extends Page
{
    protected static ?string $navigationIcon = 'heroicon-o-cog-6-tooth';

    protected static string $view = 'filament.pages.settings';

    protected static ?int $navigationSort = 10;

    public function getTitle(): string
    {
        return 'Settings';
    }

    public function getHeading(): string
    {
        return 'Application Settings';
    }
}

3. Custom Page View

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// resources/views/filament/pages/settings.blade.php
<x-filament-panels::page>
    <x-filament-panels::form wire:submit="save">
        {{ $this->form }}
        
        <x-filament-panels::form.actions
            :actions="$this->getCachedFormActions()"
            :full-width="$this->hasFullWidthFormActions()"
        />
    </x-filament-panels::form>
</x-filament-panels::page>

Widgets

1. Create Widget

1
2
# Generate stats widget
php artisan make:filament-widget StatsOverview

2. Stats Widget

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php

namespace App\Filament\Widgets;

use App\Models\User;
use App\Models\Post;
use Filament\Widgets\StatsOverviewWidget as BaseWidget;
use Filament\Widgets\StatsOverviewWidget\Stat;

class StatsOverview extends BaseWidget
{
    protected function getStats(): array
    {
        return [
            Stat::make('Total Users', User::count())
                ->description('32k increase')
                ->descriptionIcon('heroicon-m-arrow-trending-up')
                ->color('success'),

            Stat::make('Total Posts', Post::count())
                ->description('3% decrease')
                ->descriptionIcon('heroicon-m-arrow-trending-down')
                ->color('danger'),

            Stat::make('Active Users', User::where('is_active', true)->count())
                ->description('7% increase')
                ->descriptionIcon('heroicon-m-arrow-trending-up')
                ->color('success'),
        ];
    }
}

Customization

1. Theme Customization

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// config/filament.php
'layout' => [
    'sidebar' => [
        'is_collapsible_on_desktop' => true,
        'groups' => [
            'are_collapsible' => true,
        ],
    ],
],

'brand' => [
    'logo' => asset('images/logo.png'),
    'logoHeight' => '2rem',
],

2. Custom CSS

1
2
3
4
5
6
7
/* resources/css/filament/admin/theme.css */
@import '../../../../vendor/filament/filament/resources/css/theme.css';

/* Custom styles */
.filament-sidebar {
    @apply bg-gradient-to-b from-emerald-600 to-emerald-800;
}

Next Steps

Di modul selanjutnya, kita akan mempelajari:

  • Advanced resource customization
  • Custom actions dan bulk actions
  • Relationship management
  • Custom widgets dan charts
  • API integration
  • Deployment strategies

Mari lanjutkan ke modul berikutnya!

Modul Sebelumnya
Modul Selanjutnya

Progress Seri

Lanjutkan pembelajaran Anda

1/12
Modul
8%
Sedang Berjalan