Skip to content

Commit b5d3e25

Browse files
committed
Update dependencies and boilerplate changes
1 parent a5c302a commit b5d3e25

File tree

8 files changed

+456
-1
lines changed

8 files changed

+456
-1
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace App\Filament\Admin\Resources\Users\Pages;
4+
5+
use App\Filament\Admin\Resources\Users\UserResource;
6+
use Filament\Resources\Pages\CreateRecord;
7+
8+
class CreateUser extends CreateRecord
9+
{
10+
protected static string $resource = UserResource::class;
11+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace App\Filament\Admin\Resources\Users\Pages;
4+
5+
use App\Filament\Admin\Resources\Users\UserResource;
6+
use Filament\Actions\DeleteAction;
7+
use Filament\Resources\Pages\EditRecord;
8+
9+
class EditUser extends EditRecord
10+
{
11+
protected static string $resource = UserResource::class;
12+
13+
protected function getHeaderActions(): array
14+
{
15+
return [
16+
DeleteAction::make(),
17+
];
18+
}
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace App\Filament\Admin\Resources\Users\Pages;
4+
5+
use App\Filament\Admin\Resources\Users\UserResource;
6+
use Filament\Actions\CreateAction;
7+
use Filament\Resources\Pages\ListRecords;
8+
9+
class ListUsers extends ListRecords
10+
{
11+
protected static string $resource = UserResource::class;
12+
13+
protected function getHeaderActions(): array
14+
{
15+
return [
16+
CreateAction::make(),
17+
];
18+
}
19+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
<?php
2+
3+
namespace App\Filament\Admin\Resources\Users\Pages;
4+
5+
use App\Filament\Admin\Resources\Users\UserResource;
6+
use Filament\Actions\EditAction;
7+
use Filament\Resources\Pages\ViewRecord;
8+
use Filament\Infolists\Infolist;
9+
use Filament\Infolists\Components\TextEntry;
10+
use Filament\Infolists\Components\ImageEntry;
11+
use Filament\Infolists\Components\IconEntry;
12+
use Filament\Schemas\Components\Section;
13+
use Filament\Schemas\Schema;
14+
15+
class ViewUser extends ViewRecord
16+
{
17+
protected static string $resource = UserResource::class;
18+
19+
protected function getHeaderActions(): array
20+
{
21+
return [
22+
EditAction::make(),
23+
];
24+
}
25+
26+
public function infolist(Schema $schema): Schema
27+
{
28+
return $schema
29+
->components([
30+
Section::make('User Profile')
31+
->columns(2)
32+
->schema([
33+
ImageEntry::make('profile_photo_url')
34+
->label('Profile Photo')
35+
->circular()
36+
->defaultImageUrl(fn ($record) => 'https://ui-avatars.com/api/?name=' . urlencode($record->name) . '&color=7F9CF5&background=EBF4FF')
37+
->columnSpanFull(),
38+
39+
TextEntry::make('name')
40+
->label('Full Name')
41+
->size('lg')
42+
->weight('bold'),
43+
44+
TextEntry::make('email')
45+
->label('Email Address')
46+
->copyable()
47+
->icon('heroicon-o-envelope'),
48+
49+
IconEntry::make('email_verified_at')
50+
->label('Email Verified')
51+
->boolean()
52+
->trueIcon('heroicon-o-check-badge')
53+
->falseIcon('heroicon-o-x-circle')
54+
->trueColor('success')
55+
->falseColor('danger'),
56+
57+
TextEntry::make('email_verified_at')
58+
->label('Verified At')
59+
->dateTime('M d, Y H:i')
60+
->placeholder('Not verified'),
61+
]),
62+
63+
Section::make('Roles & Permissions')
64+
->columns(2)
65+
->schema([
66+
TextEntry::make('roles.name')
67+
->label('Assigned Roles')
68+
->badge()
69+
->color('success')
70+
->formatStateUsing(fn ($state) => ucfirst($state))
71+
->placeholder('No roles assigned')
72+
->columnSpanFull(),
73+
74+
TextEntry::make('permissions.name')
75+
->label('Direct Permissions')
76+
->badge()
77+
->color('info')
78+
->placeholder('No direct permissions')
79+
->columnSpanFull(),
80+
]),
81+
82+
Section::make('Team Information')
83+
->columns(2)
84+
->schema([
85+
TextEntry::make('teams.name')
86+
->label('Teams')
87+
->badge()
88+
->color('primary')
89+
->placeholder('No teams')
90+
->columnSpanFull(),
91+
92+
TextEntry::make('currentTeam.name')
93+
->label('Current Team')
94+
->placeholder('No current team'),
95+
96+
TextEntry::make('ownedTeams.name')
97+
->label('Owned Teams')
98+
->badge()
99+
->color('warning')
100+
->placeholder('No owned teams'),
101+
]),
102+
103+
Section::make('Account Information')
104+
->columns(2)
105+
->schema([
106+
TextEntry::make('created_at')
107+
->label('Account Created')
108+
->dateTime('M d, Y H:i')
109+
->icon('heroicon-o-calendar'),
110+
111+
TextEntry::make('updated_at')
112+
->label('Last Updated')
113+
->dateTime('M d, Y H:i')
114+
->since()
115+
->icon('heroicon-o-clock'),
116+
117+
TextEntry::make('two_factor_confirmed_at')
118+
->label('Two-Factor Enabled')
119+
->formatStateUsing(fn ($state) => $state ? 'Yes' : 'No')
120+
->badge()
121+
->color(fn ($state) => $state ? 'success' : 'gray'),
122+
123+
TextEntry::make('profile_photo_path')
124+
->label('Profile Photo Path')
125+
->placeholder('No custom photo')
126+
->limit(50),
127+
]),
128+
]);
129+
}
130+
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<?php
2+
3+
namespace App\Filament\Admin\Resources\Users\Schemas;
4+
5+
use Filament\Forms\Components\DateTimePicker;
6+
use Filament\Forms\Components\FileUpload;
7+
use Filament\Forms\Components\Select;
8+
use Filament\Forms\Components\TextInput;
9+
use Filament\Forms\Components\Toggle;
10+
use Filament\Forms\Components\Textarea;
11+
use Filament\Schemas\Components\Section;
12+
use Filament\Schemas\Components\Tabs;
13+
use Filament\Schemas\Components\Tabs\Tab;
14+
use Filament\Schemas\Schema;
15+
use Illuminate\Support\Facades\Hash;
16+
17+
class UserForm
18+
{
19+
public static function configure(Schema $schema): Schema
20+
{
21+
return $schema
22+
->components([
23+
Tabs::make('User Management')
24+
->columnSpanFull()
25+
->tabs([
26+
Tab::make('Basic Information')
27+
->schema([
28+
Section::make('Personal Details')
29+
->description('Basic user information and profile settings')
30+
->columns(2)
31+
->schema([
32+
TextInput::make('name')
33+
->required()
34+
->maxLength(255)
35+
->columnSpanFull()
36+
->placeholder('Enter full name'),
37+
38+
TextInput::make('email')
39+
->label('Email Address')
40+
->email()
41+
->required()
42+
->unique(ignoreRecord: true)
43+
->maxLength(255)
44+
->placeholder('user@example.com'),
45+
46+
TextInput::make('password')
47+
->password()
48+
->dehydrateStateUsing(fn ($state) => filled($state) ? Hash::make($state) : null)
49+
->dehydrated(fn ($state) => filled($state))
50+
->required(fn (string $context): bool => $context === 'create')
51+
->maxLength(255)
52+
->placeholder('Enter password')
53+
->helperText('Leave blank to keep current password (when editing)'),
54+
55+
FileUpload::make('profile_photo_path')
56+
->label('Profile Photo')
57+
->image()
58+
->imageEditor()
59+
->maxSize(2048)
60+
->directory('profile-photos')
61+
->columnSpanFull()
62+
->helperText('Upload a profile photo (max 2MB)')
63+
]),
64+
]),
65+
66+
Tab::make('Roles & Permissions')
67+
->schema([
68+
Section::make('Role Assignment')
69+
->description('Assign roles to control user access and permissions')
70+
->schema([
71+
Select::make('roles')
72+
->relationship('roles', 'name')
73+
->multiple()
74+
->preload()
75+
->searchable()
76+
->placeholder('Select roles')
77+
->helperText('Users inherit all permissions from their assigned roles')
78+
->columnSpanFull(),
79+
]),
80+
]),
81+
82+
Tab::make('Account Settings')
83+
->schema([
84+
Section::make('Account Status')
85+
->description('Manage account verification and security settings')
86+
->columns(2)
87+
->schema([
88+
DateTimePicker::make('email_verified_at')
89+
->label('Email Verified At')
90+
->placeholder('Not verified')
91+
->helperText('Mark as verified to enable full account access')
92+
->native(false),
93+
94+
TextInput::make('current_team_id')
95+
->label('Current Team ID')
96+
->numeric()
97+
->placeholder('Default team')
98+
->helperText('The user\'s active team context'),
99+
]),
100+
]),
101+
]),
102+
]);
103+
}
104+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<?php
2+
3+
namespace App\Filament\Admin\Resources\Users\Tables;
4+
5+
use Filament\Actions\BulkActionGroup;
6+
use Filament\Actions\DeleteBulkAction;
7+
use Filament\Actions\EditAction;
8+
use Filament\Actions\ViewAction;
9+
use Filament\Tables\Columns\IconColumn;
10+
use Filament\Tables\Columns\ImageColumn;
11+
use Filament\Tables\Columns\TextColumn;
12+
use Filament\Tables\Filters\Filter;
13+
use Filament\Tables\Filters\SelectFilter;
14+
use Filament\Tables\Table;
15+
use Illuminate\Database\Eloquent\Builder;
16+
17+
class UsersTable
18+
{
19+
public static function configure(Table $table): Table
20+
{
21+
return $table
22+
->columns([
23+
ImageColumn::make('profile_photo_url')
24+
->label('Photo')
25+
->circular()
26+
->defaultImageUrl(fn ($record) => 'https://ui-avatars.com/api/?name=' . urlencode($record->name) . '&color=7F9CF5&background=EBF4FF'),
27+
28+
TextColumn::make('name')
29+
->searchable()
30+
->sortable()
31+
->weight('medium')
32+
->description(fn ($record) => $record->email, position: 'below'),
33+
34+
TextColumn::make('roles.name')
35+
->label('Roles')
36+
->badge()
37+
->color('success')
38+
->searchable()
39+
->sortable()
40+
->formatStateUsing(fn ($state) => ucfirst($state))
41+
->placeholder('No roles assigned'),
42+
43+
IconColumn::make('email_verified_at')
44+
->label('Verified')
45+
->boolean()
46+
->trueIcon('heroicon-o-check-badge')
47+
->falseIcon('heroicon-o-x-circle')
48+
->trueColor('success')
49+
->falseColor('danger')
50+
->sortable()
51+
->tooltip(fn ($record) => $record->email_verified_at
52+
? 'Verified on ' . $record->email_verified_at->format('M d, Y')
53+
: 'Not verified'),
54+
55+
TextColumn::make('teams_count')
56+
->label('Teams')
57+
->counts('teams')
58+
->badge()
59+
->color('info')
60+
->sortable(),
61+
62+
TextColumn::make('created_at')
63+
->label('Joined')
64+
->dateTime('M d, Y')
65+
->sortable()
66+
->toggleable(isToggledHiddenByDefault: true),
67+
68+
TextColumn::make('updated_at')
69+
->label('Last Updated')
70+
->dateTime('M d, Y H:i')
71+
->sortable()
72+
->toggleable(isToggledHiddenByDefault: true),
73+
])
74+
->filters([
75+
SelectFilter::make('roles')
76+
->relationship('roles', 'name')
77+
->multiple()
78+
->preload()
79+
->searchable()
80+
->placeholder('Filter by role'),
81+
82+
Filter::make('verified')
83+
->label('Email Verified')
84+
->query(fn (Builder $query): Builder => $query->whereNotNull('email_verified_at')),
85+
86+
Filter::make('unverified')
87+
->label('Email Unverified')
88+
->query(fn (Builder $query): Builder => $query->whereNull('email_verified_at')),
89+
90+
Filter::make('created_at')
91+
->label('Recently Joined')
92+
->query(fn (Builder $query): Builder => $query->where('created_at', '>=', now()->subDays(30))),
93+
])
94+
->recordActions([
95+
ViewAction::make(),
96+
EditAction::make(),
97+
])
98+
->toolbarActions([
99+
BulkActionGroup::make([
100+
DeleteBulkAction::make(),
101+
]),
102+
])
103+
->defaultSort('created_at', 'desc');
104+
}
105+
}

0 commit comments

Comments
 (0)