From 3ea8245f859724b6b6eafabba4827b09d2cf0eae Mon Sep 17 00:00:00 2001 From: Masroor Ehsan Date: Wed, 29 Jan 2025 14:53:59 +0600 Subject: [PATCH] filament user --- app/Filament/Resources/UserResource.php | 196 ++++++++++++++++++ .../UserResource/Pages/CreateUser.php | 11 + .../Resources/UserResource/Pages/EditUser.php | 20 ++ .../UserResource/Pages/ListUsers.php | 19 ++ .../Resources/UserResource/Pages/ViewUser.php | 19 ++ app/Services/ACL/RoleService.php | 28 +++ 6 files changed, 293 insertions(+) create mode 100644 app/Filament/Resources/UserResource.php create mode 100644 app/Filament/Resources/UserResource/Pages/CreateUser.php create mode 100644 app/Filament/Resources/UserResource/Pages/EditUser.php create mode 100644 app/Filament/Resources/UserResource/Pages/ListUsers.php create mode 100644 app/Filament/Resources/UserResource/Pages/ViewUser.php create mode 100644 app/Services/ACL/RoleService.php diff --git a/app/Filament/Resources/UserResource.php b/app/Filament/Resources/UserResource.php new file mode 100644 index 0000000..3a2cb77 --- /dev/null +++ b/app/Filament/Resources/UserResource.php @@ -0,0 +1,196 @@ +getOperation() === 'create'; + + return $form + ->schema([ + Forms\Components\TextInput::make('guid') + ->label('Unique ID') + ->default(sprintf('USR-%s', Str::of(Uuid::uuid4())->lower())) + ->disabled() + ->dehydrated() + ->required() + ->maxLength(40) + ->unique(ignoreRecord: true), + Toggle::make('is_active') + ->required(), + TextInput::make('prefix') + ->maxLength(80), + TextInput::make('first_name') + ->required() + ->maxLength(120), + TextInput::make('last_name') + ->maxLength(120), + TextInput::make('display_name') + ->required() + ->maxLength(160), + TextInput::make('username') + ->unique(ignoreRecord: true) + ->required() + ->maxLength(24), + TextInput::make('password') + ->password() + ->revealable() + ->dehydrated(fn ($state) => filled($state)) + ->dehydrateStateUsing(fn ($state) => Hash::make($state)) + ->required(fn (string $context): bool => $context === 'create') + ->maxLength(32), + TextInput::make('phone') + ->unique(ignoreRecord: true) + ->tel() + ->telRegex('/^\+?[1-9]\d{8,14}$/') + ->maxLength(80), + TextInput::make('email') + ->unique(ignoreRecord: true) + ->email() + ->maxLength(80), + DateTimePicker::make('email_verified_at'), + TextInput::make('profile_photo_path') + ->maxLength(255), + FileUpload::make('signature_image_path') + ->disk('public') + ->visibility('public') + ->directory('signatures') + ->preserveFilenames() + ->getUploadedFileNameForStorageUsing( + function (TemporaryUploadedFile $file) { + return Str::of(pathinfo($file->getClientOriginalName(), PATHINFO_FILENAME)) + ->slug() + ->prepend(now()->timestamp . '_') + ->append('.' . $file->getClientOriginalExtension()); + } + ) + ->image(), + Textarea::make('signature_text') + ->columnSpanFull(), + Select::make('organization_id') + ->label('Organization') + ->live() + ->relationship('organization', 'name'), + Select::make('department_id') + ->label('Department') + ->options(function (Get $get) { + $organization_id = $get('organization_id'); + $result = []; + if ($organization_id != null) { + $result = Department::active()->organization($organization_id)->pluck('name', 'id')->toArray(); + } + + return $result; + }), + Select::make('roles') + ->relationship('roles', 'name') + ->multiple() + ->required(fn (string $context): bool => $context === 'create') + ->searchable() + // ->options(RoleService::select()) + ->afterStateUpdated(function ($state, User $user) { + $user->assignRole($state); + }), + Select::make('timezone') + ->options( + (new TimezoneList)->splitGroup(true)->toArray(false) + ) + ->required() + ->default('Asia/Dhaka'), + ]); + } + + public static function table(Table $table): Table + { + return $table + ->columns([ + Tables\Columns\IconColumn::make('is_active') + ->label('Active?') + ->boolean(), + TextColumn::make('display_name') + ->label('Name') + ->searchable(), + TextColumn::make('username') + ->searchable(), + TextColumn::make('email') + ->searchable(), + // ImageColumn::make('signature_image_path'), + TextColumn::make('organization.name') + ->label('Org') + ->badge() + ->sortable(), + TextColumn::make('department.name') + ->label('Dept') + ->sortable(), + TextColumn::make('created_at') + ->dateTime() + ->sortable() + ->toggleable(isToggledHiddenByDefault: true), + TextColumn::make('guid') + ->limit(16) + ->searchable(), + ]) + ->filters([ + // + ]) + ->actions([ + ViewAction::make(), + EditAction::make(), + ]) + ->bulkActions([ + 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'), + 'view' => Pages\ViewUser::route('/{record}'), + 'edit' => Pages\EditUser::route('/{record}/edit'), + ]; + } +} diff --git a/app/Filament/Resources/UserResource/Pages/CreateUser.php b/app/Filament/Resources/UserResource/Pages/CreateUser.php new file mode 100644 index 0000000..78a3894 --- /dev/null +++ b/app/Filament/Resources/UserResource/Pages/CreateUser.php @@ -0,0 +1,11 @@ +toArray(); + } + } + + public static function select(): array + { + // self::initCache(); + + return collect(Role::cases()) + // ->mapWithKeys(fn (Role $r) => [self::$roles[$r->value] => $r->name]) + ->mapWithKeys(fn (Role $r) => [$r->value => $r->name]) + ->toArray(); + } +}