Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Member Laravel Package

alessandronuunes/filament-member

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup Steps

  1. Installation

    composer require alessandronuunes/filament-member
    php artisan filament-member:install
    php artisan migrate
    
  2. Configure User Model Add HasTenantRelations trait and HasTenants contract to your User model:

    use AlessandroNuunes\FilamentMember\Traits\HasTenantRelations;
    use Filament\Models\Contracts\HasTenants;
    
    class User extends Authenticatable implements FilamentUser, HasTenants
    {
        use HasTenantRelations;
        // ...
    }
    
  3. Register Plugin Add to your Filament panel configuration:

    public function panel(Panel $panel): Panel
    {
        return $panel->plugins([
            MemberPlugin::make(),
        ]);
    }
    

First Use Case

Invite a new member to your tenant:

  1. Navigate to the "Members" page in your Filament panel.
  2. Click "Invite Members" and enter up to 5 email addresses.
  3. Assign roles (Owner, Admin, Member) and send invitations.
  4. Verify the invitation email or link is received by the recipient.

Implementation Patterns

Core Workflows

1. Member Management Workflow

// Invite members via API (if needed)
$invites = TenantInvite::create([
    'tenant_id' => $tenant->id,
    'email' => 'user@example.com',
    'role' => TenantRole::Admin,
]);

// Bulk invite (via Filament UI)
$emails = ['user1@example.com', 'user2@example.com'];
$roles = [TenantRole::Member, TenantRole::Member];
MemberInvitation::bulkInvite($tenant, $emails, $roles);

2. Role Assignment & Updates

// Change a member's role
$member->updateRole(TenantRole::Admin);

// Check if user can access a tenant
if ($user->canAccessTenant($tenant)) {
    // Grant access
}

3. Tenant Ownership & Access Control

// Get all tenants a user owns or is a member of
$tenants = $user->getTenants($panel);

// Check if user is an owner of a tenant
if ($user->isOwnerOf($tenant)) {
    // Owner-specific logic
}

4. Customizing Invitation Logic

// Override default invite behavior (e.g., require registration)
event(new TenantInviteCreated($invite));

Integration Tips

Filament Panel Integration

  • Navigation: The plugin auto-registers a "Members" page under the tenant context.
  • Tenancy: Works seamlessly with Filament’s built-in tenancy system. Ensure your User model implements HasTenants.

Event-Driven Extensions

Listen to events for custom logic:

// Listen for new invitations
TenantInviteCreated::subscribe(function (TenantInviteCreated $event) {
    // Custom logic (e.g., log, audit, or trigger workflows)
});

API Endpoints for Invitations

Expose an API endpoint to accept invitations:

Route::get('/invite/{token}/accept', [InviteController::class, 'accept'])
    ->middleware(['signed', 'throttle:60']);

Customizing Notifications

Extend the default notification logic:

// Override the notification sender
TenantInviteCreated::subscribe(function (TenantInviteCreated $event) {
    TenantInviteNotification::send($event->invite);
});

Bulk Operations

Leverage the built-in bulk invite feature:

// In a Filament action or API endpoint
MemberInvitation::bulkInvite($tenant, $emails, $roles);

Gotchas and Tips

Pitfalls

1. Tenant Model Mismatch

  • Issue: If your tenant model isn’t App\Models\Tenant, update config/filament-member.php:
    'models' => [
        'tenant' => App\Models\Organization::class,
    ],
    
  • Debug: Check ConfigHelper::getTenantModel() to verify the correct model is loaded.

2. Missing HasTenants Contract

  • Issue: Forgetting to implement HasTenants on the User model will break tenancy.
  • Fix: Add the contract and trait:
    use Filament\Models\Contracts\HasTenants;
    use AlessandroNuunes\FilamentMember\Traits\HasTenantRelations;
    
    class User extends Authenticatable implements FilamentUser, HasTenants
    {
        use HasTenantRelations;
    }
    

3. Role Enum Conflicts

  • Issue: Custom role enums must use string backing values (e.g., 'owner' not 1).
  • Fix: Ensure your enum implements HasLabel and HasColor:
    enum TenantRole: string
    {
        case Owner = 'owner';
        case Admin = 'admin';
        case Member = 'member';
    
        public function label(): string
        {
            return match ($this) {
                self::Owner => 'Owner',
                self::Admin => 'Admin',
                self::Member => 'Member',
            };
        }
    
        public function color(): string
        {
            return match ($this) {
                self::Owner => 'danger',
                self::Admin => 'warning',
                self::Member => 'info',
            };
        }
    }
    

4. Invitation Token Expiration

  • Issue: Invitations expire after invite_expiration_days (default: 7). Set to null for no expiration:
    'invites' => [
        'expire_after_days' => null,
    ],
    

5. Duplicate Invitation Validation

  • Issue: The AlreadyMember validation rule prevents re-inviting existing members.
  • Workaround: Use MemberInvitation::inviteIfNotMember($tenant, $email, $role).

6. Theme/Styling Issues

  • Issue: Plugin styles not loading due to missing @source directive.
  • Fix: Add to resources/css/filament/admin/theme.css:
    @source '../../../../vendor/alessandronuunes/filament-member/resources/views/filament/**/*';
    

Debugging Tips

1. Check Published Config

Verify your config/filament-member.php matches expectations:

php artisan config:clear

2. Log Invitation Events

Debug invitation creation:

TenantInviteCreated::subscribe(function (TenantInviteCreated $event) {
    \Log::info('Invite created', ['invite' => $event->invite]);
});

3. Validate Tenant Relationships

Ensure relationships are correctly set up:

// Check if a user can access a tenant
if (!$user->canAccessTenant($tenant)) {
    \Log::error('User cannot access tenant', [
        'user_id' => $user->id,
        'tenant_id' => $tenant->id,
    ]);
}

4. Test Invitation Acceptance

Manually test the invitation flow:

  1. Generate a token: $invite->token.
  2. Visit /invite/{token}/accept (or custom path).
  3. Verify the accepted_at timestamp updates.

Extension Points

1. Custom Invitation Logic

Override the default invite creation:

// In a service provider
TenantInvite::creating(function ($invite) {
    $invite->custom_field = 'value';
});

2. Extend Member Table Columns

Add custom columns to the Filament table:

use AlessandroNuunes\FilamentMember\Tables\MemberTable;

MemberTable::modify(function (Table $table) {
    $table->addColumns([
        Tables\Columns\TextColumn::make('custom_field')
            ->label('Custom Data'),
    ]);
});

3. Hook into Tenant Creation

Listen for tenant creation to auto-invite owners:

TenantCreated::subscribe(function ($tenant) {
    $owner = auth()->user();
    $tenant->members()->attach($owner->id, ['role' => TenantRole::Owner]);
});

4. Customize Notifications

Extend the default notification:

// Publish and override the notification view
php artisan vendor:publish --tag=filament-member-views
// Then edit `resources/views/vendor/filament-member/email/invite.blade.php`

5. Add Custom Member Actions

Extend the member table with custom actions:

MemberTable::modify(function (Table $table) {
    $table->actions([
        Tables\Actions\Action::make('customAction')
            ->action(function (Member $member) {
                // Custom logic
            }),
    ]);
});

6. Localize Additional Languages

Add translations for unsupported locales:

php artisan vendor:publish --tag=filament-member-translations
// Edit `lang/vendor/filament-member/es/default.php`
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor