Filament - How to add Terms and Conditions checkbox on Filament registration page

Julien BOYER
Julien BOYER (aka. yebor974) Buy Me A Coffee
Published at 09 Jul 2024
This article describes how we can add and enforce terms and conditions consent on a filament registration page.

This article uses the Filament Terms Guard Plugin.

  1. Start by installing and registering the plugin on panel following the official documentation.

For this article, we use a default panel identified by id admin and we add in .env file the following key :

TERMS_GUARD_PANELS=admin
  1. Create custom registration page on your panel

We create a new register page extending the default Filament registration page

php artisan make:filament-page Register
namespace App\Filament\Admin\Pages;

class Register extends \Filament\Pages\Auth\Register
{
    //protected static string $view = 'filament.admin.pages.register';
}

Don't forget to remove or comment the view attribute to use the Filament registration one.

Now we override the getForms function and declare a getTermsFormComponent function to add our terms checkbox. We manage handleRegistration function to attach our accepted terms to the created user too:

namespace App\Filament\Admin\Pages;

use App\Models\User;
use Filament\Forms\Components\Actions\Action;
use Filament\Forms\Components\Checkbox;
use Filament\Forms\Components\Component;
use Filament\Support\Enums\IconSize;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\HtmlString;
use Yebor974\FilamentTermsGuard\Models\Term;

class Register extends \Filament\Pages\Auth\Register
{

    public Term $terms;

    protected function beforeFill(): void
    {
        $this->terms = Term::getCurrentTerm(filament()->getCurrentPanel()->getId()); // we retrieve the current published terms
    }

    protected function getForms(): array
    {
        return [
            'form' => $this->form(
                $this->makeForm()
                    ->schema([
                        $this->getNameFormComponent(),
                        $this->getEmailFormComponent(),
                        $this->getPasswordFormComponent(),
                        $this->getPasswordConfirmationFormComponent(),
                        $this->getTermsFormComponent(), // call our getTermsFormComponent function to get a checkbox component
                    ])
                    ->statePath('data'),
            ),
        ];
    }

    protected function getTermsFormComponent(): Component
    {
        return Checkbox::make('terms')
            ->label(fn() => __('filament-terms-guard::terms-guard.actions.accept.submit'))
            ->hintAction(
                Action::make('show-terms')
                    ->hiddenLabel()
                    ->icon('heroicon-o-information-circle')
                    ->iconSize(IconSize::Large)
                    ->tooltip('Show terms')
                    ->modalHeading(__('filament-terms-guard::terms-guard.actions.accept.title', [
                        'date' => $this->terms->published_at->translatedFormat('d F Y')
                    ]))
                    ->modalContent(new HtmlString("<div class='prose max-w-full text-justify'>" . $this->terms->content . "</div>"))
                    ->modalCancelActionLabel(__('back'))
                    ->modalSubmitAction(false)
            )
            ->required();
    }

    protected function handleRegistration(array $data): Model
    {
        /** @var User $model */
        $model = parent::handleRegistration($data);
        $model->terms()->attach($this->terms);
        return $model;
    }

}

Then we replace the default Filament registration page with this one on the Panel Provider:

namespace App\Providers\Filament;

use App\Filament\Admin\Pages\Register;
use Filament\Panel;
use Filament\PanelProvider;

class AdminPanelProvider extends PanelProvider
{
    /**
     * @throws \Exception
     */
    public function panel(Panel $panel): Panel
    {
        return $panel
            ->id('admin'),
            ->login()
            ->registration(Register::class)
            //...
    }
}

That's all, we can test our implementation.

Before test, you have to create and publish new terms for this panel, following the official documentation.

  1. Examples

On the panel registration page we can see the new terms checkbox:

We can show the current terms and conditions with the tooltip information icon:

Fill the forms and submit it. The user is created and attached to the current published terms and conditions.

On the Terms resource, we can see our user and his consent for this one:

Of course, if you create and publish new terms, the user will be asked to consent to these new terms upon their next use/login.

Other posts

Plugins

To contact me

If you have an idea to bring to life, a problem to solve, or a significant technical challenge to tackle, don't waste any more time. Contact me now and let me help you turn your ambitions into reality. My expertise is at your disposal to successfully materialize your projects.

Geographic location

Paris & Reunion Island (France - UTC+4)