This is a fork of Filament Breezy by Jeff Greco designed for internal HydePHP use.
You are free to use the package yourself, but there are no stability guarantees (unless the package somehow becomes popular enough for people to desire that).
First, add the following to your composer.json
"repositories": [
{
"type": "vcs",
"url": "https://github.com/hydephp/filament-breezier.git"
}
]
Next, install the package via Composer:
composer require hydephp/filament-breezier
php artisan breezy:install
Optionally, you can publish the views using:
php artisan vendor:publish --tag="filament-breezy-views"
- Changes the root namespace and vendor name to HydePHP and resets versioning to
v0.1.0
- Requires a
composer.json
repository configuration (package not published to Packagist) - Does not guarantee package stability as it is designed for internal use
- Adds feature to ignore MyProfile components
#306
- Formats the code style, making it easier to read
- Removes test scaffolding as there are no tests
- Removes language files other than English
My Profile - Personal info with avatar support Update password with customizable validation rules Protected sensitive actions with a password confirmation modal Action Two factor authentication with recovery codes Force the user to enable two factor authentication before they can use the app Create and manage Sanctum personal access tokens
You must enable Breezy by adding the class to your Filament Panel's plugin()
or plugins([])
method:
use HydePHP\FilamentBreezy\BreezyCore;
class CustomersPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
return $panel
...
->plugin(
BreezyCore::make()
)
}
}
Breezy will use the authGuard
set on the Filament Panel that you create. You may update the authGuard as you please:
use HydePHP\FilamentBreezy\BreezyCore;
class CustomersPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
return $panel
...
->authGuard('customers')
->plugin(
BreezyCore::make()
)
}
}
NOTE: you must ensure that the model used in your Guard extends the Authenticatable class.
Enable the My Profile page with configuration options.
NOTE: if you are using avatars,
BreezyCore::make()
->myProfile(
shouldRegisterUserMenu: true, // Sets the 'account' link in the panel User Menu (default = true)
shouldRegisterNavigation: false, // Adds a main navigation item for the My Profile page (default = false)
navigationGroup: 'Settings', // Sets the navigation group for the My Profile page (default = null)
hasAvatars: false, // Enables the avatar upload form component (default = false)
slug: 'my-profile' // Sets the slug for the profile page (default = 'my-profile')
)
The instructions for using custom avatars is found in the Filament v3 docs under Setting up user avatars.
Here is a possible implementation using the example from the docs:
use Illuminate\Support\Facades\Storage;
use Filament\Models\Contracts\HasAvatar;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable implements FilamentUser, HasAvatar
{
// ...
public function getFilamentAvatarUrl(): ?string
{
return $this->avatar_url ? Storage::url($this->avatar_url) : null ;
}
}
use Filament\Forms\Components\FileUpload;
BreezyCore::make()
->avatarUploadComponent(fn($fileUpload) => $fileUpload->disableLabel())
// OR, replace with your own component
->avatarUploadComponent(fn() => FileUpload::make('avatar_url')->disk('profile-photos'))
If you wish to have your own avatar, you need to create a column on the users table named avatar_url
. It is reccomended that you create a new migration for it, and add the column there:
php artisan make:migration add_avatar_url_column_to_users_table
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('users', function (Blueprint $table) {
$table->string('avatar_url')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('avatar_url');
});
}
};
protected $fillable = [
...
'avatar_url',
...
];
You can customize the validation rules for the update password component by passing an array of validation strings, or an instance of the Illuminate\Validation\Rules\Password
class.
use Illuminate\Validation\Rules\Password;
BreezyCore::make()
->passwordUpdateRules(
rules: [Password::default()->mixedCase()->uncompromised(3)], // you may pass an array of validation rules as well. (default = ['min:8'])
requiresCurrentPassword: true, // when false, the user can update their password without entering their current password. (default = true)
)
In Breezy v2, you can now create custom Livewire components for the My Profile page and append them easily.
- Create a new Livewire component in your project using:
php artisan make:livewire MyCustomComponent
- Extend the
MyProfileComponent
class included with Breezy. This class implements Actions and Forms.
use HydePHP\FilamentBreezy\Livewire\MyProfileComponent;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
class MyCustomComponent extends MyProfileComponent
{
protected string $view = "livewire.my-custom-component";
//
public array $data;
public function form(Form $form): Form
{
return $form
->schema([
TextInput::make('name')
->required()
])
->statePath('data');
}
}
- Within your Livewire component's view, you can use Breezy's
grid-section
blade component to match the style:
<x-filament-breezy::grid-section md=2 title="Your title" description="This is the description">
<x-filament::card>
<form wire:submit.prevent="submit" class="space-y-6">
{{ $this->form }}
<div class="text-right">
<x-filament::button type="submit" form="submit" class="align-right">
Submit!
</x-filament::button>
</div>
</form>
</x-filament::card>
</x-filament-breezy::grid-section>
- Finally, register your new component with Breezy:
use App\Livewire\MyCustomComponent;
BreezyCore::make()
->myProfileComponents([MyCustomComponent::class])
You may override the existing MyProfile components to replace them with your own:
use App\Livewire\MyCustomComponent;
BreezyCore::make()
->myProfileComponents([
// 'personal_info' => ,
'update_password' => MyCustomComponent::class, // replaces UpdatePassword component with your own.
// 'two_factor_authentication' => ,
// 'sanctum_tokens' =>
])
If you want to customize only the fields and notification in the personal info component, you can extend the original breezy component:
namespace App\Livewire;
use Filament\Forms;
use Filament\Notifications\Notification;
use HydePHP\FilamentBreezy\PersonalInfo;
class CustomPersonalInfo extends PersonalInfo
{
protected function getNameComponent(): Forms\Components\TextInput
{
return Forms\Components\TextInput::make('custom_name_field')
->required();
}
protected function getEmailComponent(): Forms\Components\TextInput
{
return Forms\Components\TextInput::make('custom_email_field')
->required();
}
protected function sendNotification(): void
{
Notification::make()
->success()
->title('Saved Data!')
->send();
}
}
Now, as mentioned above, give this component to BreezyCore::make()->myProfileComponents
to override the original and use your custom component.
Custom MyProfile components can be sorted by setting their static $sort
property. This property can be set for existing MyProfile components in any service provider:
TwoFactorAuthentication::setSort(4);
A lot of the time this won't be necessary, though, as the default sort order is spaced out in steps of 10, so there should be enough numbers to place any custom components in between.
- Add
HydePHP\FilamentBreezy\Traits\TwoFactorAuthenticatable
to your Authenticatable model:
use HydePHP\FilamentBreezy\Traits\TwoFactorAuthenticatable;
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable, TwoFactorAuthenticatable;
// ...
}
- Enable Two Factory Authentication using the
enableTwoFactorAuthentication()
method on the Breezy plugin.
BreezyCore::make()
->enableTwoFactorAuthentication(
force: false, // force the user to enable 2FA before they can use the application (default = false)
action: CustomTwoFactorPage::class // optionally, use a custom 2FA page
)
- Adjust the 2FA page
The Breezy 2FA page can be swapped for a custom implementation (see above), same as the Filament auth pages. This allows, for example, to define a custom auth layout like so:
use HydePHP\FilamentBreezy\Pages\TwoFactorPage;
class CustomTwoFactorPage extends TwoFactorPage
{
protected static string $layout = 'custom.auth.layout.view';
}
As of Laravel 8.x Sanctum is included with Laravel, but if you don't already have the package follow the installation instructions here.
Enable the Sanctum token management component:
BreezyCore::make()
->enableSanctumTokens(
permissions: ['my','custom','permissions'] // optional, customize the permissions (default = ["create", "view", "update", "delete"])
)
This button action will prompt the user to enter their password for sensitive actions (eg. delete). This action uses the same 'password_timeout'
number of seconds found in config/auth.php
.
use HydePHP\FilamentBreezy\Actions\PasswordButtonAction;
PasswordButtonAction::make('secure_action')->action('doSecureAction')
// Customize the icon, action, modalHeading and anything else.
PasswordButtonAction::make('secure_action')->label('Delete')->icon('heroicon-s-shield-check')->modalHeading('Confirmation')->action(fn()=>$this->doAction())
How the 2FA session work across multiple panels?
By default, Breezy uses the same guard as defined on your Panel. The default is 'web'. Only panels that have registered the BreezyCore plugin will have access to 2FA. If multiple panels use 2FA, and share the same guard, the User only has to enter the OTP once for the duration of the session.
How does 2FA interact with MustVerifyEmail?
When 2FA is properly configured, and the User is prompted for the OTP code before email verification.
How long does the 2FA session last?
The 2FA session is the same as the Laravel session lifetime. Once the user is logged out, or the session expires, they will need to enter the OTP code again.
composer test
Please see CHANGELOG for more information on what has changed recently.
Please see CONTRIBUTING for details.
Please review our security policy on how to report security vulnerabilities.
The MIT License (MIT). Please see License File for more information.