DEV Community

Cover image for Email verification in Filament: UserResource filters and actions
yebor974 for Filament Mastery

Posted on • Originally published at filamentmastery.com on

Email verification in Filament: UserResource filters and actions

Managing users effectively is at the heart of many applications. Filament provides powerful tools to create and customize resources. In this article, we will focus on:

  1. Enabling Email Verification on User
  2. Setting up a User resource.
  3. Adding filter and action for email verification.

Step 1: Enable email verification on User model and Filament panel

You need to implement MustVerifyEmail on your User model and add emailVerification on your Filament Panel Provider.

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Filament\Models\Contracts\FilamentUser;

class User extends Authenticatable implements FilamentUser, MustVerifyEmail
{
    ...
}


class AdminPanelProvider extends PanelProvider
{
    public function panel(Panel $panel): Panel
    {
         return $panel
             ...
             ->login()
             ->registration()
             ->emailVerification()
             ...
    }
}

Enter fullscreen mode Exit fullscreen mode

With this, when a user registers a new account, they will be asked to verify their email address. An email is automatically sent to them.

Step 2: Define the UserResource

Generate a resource for your User model:

php artisan make:filament-resource User

Enter fullscreen mode Exit fullscreen mode

If you have more than one panel, you will be prompted to choose which one you want to create it in.

Update the resource configuration to include only the most relevant columns:

public static function table(Table $table): Table
{
    return $table
        ->columns([
            Tables\Columns\TextColumn::make('name')
                ->sortable()
                ->searchable(),
            Tables\Columns\TextColumn::make('email')
                ->sortable()
                ->searchable(),
            Tables\Columns\TextColumn::make('email_verified_at')
                ->label('Email Verified')
                ->dateTime('d m Y H:i'),
            Tables\Columns\TextColumn::make('created_at')
                ->label('Registered At')
                ->dateTime('d m Y H:i'),
        ]);
}

Enter fullscreen mode Exit fullscreen mode

Step 3: Add filters to retrieve verified or unverified accounts

Use filters to help admins find users faster. For example, filter by email verification status:

public static function table(Table $table): Table
{
    return $table
        ...
        ->filters([
            Tables\Filters\Filter::make('verified')
                ->label('Email Verified')
                ->query(fn (Builder $query) => $query->whereNotNull('email_verified_at')),
            Tables\Filters\Filter::make('unverified')
                ->label('Email Not Verified')
                ->query(fn (Builder $query) => $query->whereNull('email_verified_at')),
        ]);
}

Enter fullscreen mode Exit fullscreen mode
  • Filter::make('verified'): Retrieves accounts where the email_verified_at column is not null, indicating the email has been verified.
  • Filter::make('unverified'): Retrieves accounts where the email_verified_at column is null, indicating the email is unverified.

Also, you can use a ternary filter, which simplifies the process of filtering between null and not null values:

public static function table(Table $table): Table
{
    return $table
        ...
        ->filters([
            Tables\Filters\TernaryFilter::make('verified')
                ->label('Verified email')
                ->attribute('email_verified_at')
                ->nullable(),
        ]);
}

Enter fullscreen mode Exit fullscreen mode

Step 3: Add a table action to resend verification email

Add a table action to resend the verification email for unverified user account:

use Filament\Notifications\Auth\VerifyEmail;
use Filament\Notifications\Notification;

public static function table(Table $table): Table
{
    return $table
        ...
        ->actions([
            Tables\Actions\EditAction::make(),
            Tables\Actions\Action::make('resend_verification_email')
                ->label('Resend Verification Email')
                ->icon('heroicon-o-envelope')
                ->authorize(fn(User $record) => !$record->hasVerifiedEmail())
                ->action(function (User $record) {
                    $notification = new VerifyEmail();
                    $notification->url = filament()->getVerifyEmailUrl($record);
                    $record->notify($notification);

                    Notification::make()
                        ->title("Verification email has been resent.")
                        ->send();
                })
                ->requiresConfirmation(),
        ]);
}

Enter fullscreen mode Exit fullscreen mode
  • ->authorize(fn(User $record) => !$record->hasVerifiedEmail()): The action is only authorized if the user's email is not verified

This implementation is for the current panel. If the user is verified on another panel, you need to retrieve the correct URL like this: filament()->getPanel('id_of_panel')->getVerifyEmailUrl($record);

📬 Join the community on filamentmastery.com — it's free!

Top comments (0)