Filament Tenant Room Booking: Public Page, Three Panels and Stripe

Example application of property management and booking with Stripe payments. Inside the example, you will find three different panels: One for Tenants to manage their bookings, one for Owners to manage their properties and overview bookings and one for Super Admins to overview everything in the system.

FilamentExamples ThumbBase (4)-min

Get the Source Code:

How it works

On the frontend, we have a simple template made with Tailwind CSS. In the navigation bar, there's an option User area. When a user isn't logged in, it shows as a dropdown with three filament panels that link to their login pages.

*resources/views/components/nav-dropdown.blade.php:

// ...
<div class="absolute right-0 z-10 mt-2 w-48 rounded-lg bg-white py-2 shadow-lg">
<a href="{{ filament()->getPanel('tenant')->getLoginUrl() }}" class="block px-4 py-2 text-gray-700 hover:bg-gray-100">Tenant</a>
<a href="{{ filament()->getPanel('owner')->getLoginUrl() }}" class="block px-4 py-2 text-gray-700 hover:bg-gray-100">Property Owner</a>
<a href="{{ filament()->getPanel('admin')->getLoginUrl() }}" class="block px-4 py-2 text-gray-700 hover:bg-gray-100">Admin</a>
</div>
// ...

When a user is logged in, instead of a dropdown, a direct link to the panel is shown based on the user's role. There's a method on the User Model that returns a link to the panel.

app/Models/User.php:

use Illuminate\Support\Uri;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
 
class User extends Authenticatable implements FilamentUser, MustVerifyEmail
{
// ...
 
public function role(): BelongsTo
{
return $this->belongsTo(Role::class);
}
 
public function getUserPanelLink(): string
{
$panelPath = match ($this->role->name) {
'tenant' => filament()->getPanel('tenant')->getPath(),
'owner' => filament()->getPanel('owner')->getPath(),
'admin' => filament()->getPanel('admin')->getPath(),
};
 
return Uri::to($panelPath);
}
 
// ...
}

resources/views/components/header.blade.php:

// ...
<nav class="hidden md:block">
<ul class="flex space-x-8 items-center">
<x-nav-link href="{{ route('home') }}">Home</x-nav-link>
<x-nav-link href="#">Listings</x-nav-link>
<x-nav-link href="#">About</x-nav-link>
<x-nav-link href="#">Contact</x-nav-link>
@guest {{-- [tl! highlight:4 --}}
<x-nav-dropdown />
@else
<x-nav-link href="{{ auth()->user()->getUserPanelLink() }}">User area</x-nav-link>
@endguest
</ul>
</nav>
// ...

Users cannot register for the admin panel, but they can register for the owner and tenant panels. After registration, users must verify their email, and an admin must also verify owners. The profile page is enabled, and custom registration pages are used for both panels.

app/Providers/Filament/OwnerPanelProvider.php:

use App\Filament\Owner\Pages\Register;
 
class OwnerPanelProvider extends PanelProvider
{
public function panel(Panel $panel): Panel
{
return $panel
// ...
->login()
->registration(Register::class)
->emailVerification()
->profile(isSimple: false)
// ...
}
}

The tenant panel also has a custom profile class.


Next, we will implement:

  • Payments
  • Registration
  • Tenant panel
  • Map inputs
  • Custom Property creation form
The FULL tutorial is available after the purchase: in the Readme file of the official repository you would get invited to.
Get the Source Code: All 75 Premium Examples for $99