- Reworked the tenant admin login page

- Updated the User model to implement Filament’s tenancy contracts
- Seeded a ready-to-use demo tenant (user, tenant, active package, purchase)
- Introduced a branded, translated 403 error page to replace the generic forbidden message for unauthorised admin hits
- Removed the public “Register” links from the marketing header
- hardened join event logic and improved error handling in the guest pwa.
This commit is contained in:
Codex Agent
2025-10-13 12:50:46 +02:00
parent 9394c3171e
commit 64a5411fb9
69 changed files with 5447 additions and 588 deletions

View File

@@ -8,10 +8,16 @@ use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Laravel\Sanctum\HasApiTokens;
use Filament\Models\Contracts\FilamentUser;
use Filament\Models\Contracts\HasTenants as FilamentHasTenants;
use Filament\Panel;
use Illuminate\Support\Collection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Filament\Models\Contracts\HasName;
class User extends Authenticatable implements MustVerifyEmail, HasName
class User extends Authenticatable implements MustVerifyEmail, HasName, FilamentUser, FilamentHasTenants
{
/** @use HasFactory<\Database\Factories\UserFactory> */
use HasApiTokens, HasFactory, Notifiable;
@@ -99,8 +105,43 @@ class User extends Authenticatable implements MustVerifyEmail, HasName
return $this->username ?? $this->email ?? 'Unnamed User';
}
public function tenant(): HasOne
public function tenant(): BelongsTo
{
return $this->hasOne(Tenant::class);
return $this->belongsTo(Tenant::class);
}
public function canAccessPanel(Panel $panel): bool
{
if (! $this->email_verified_at && $this->role !== 'super_admin') {
return false;
}
return in_array($this->role, ['tenant_admin', 'super_admin'], true);
}
public function canAccessTenant(Model $tenant): bool
{
if ($this->role === 'super_admin') {
return true;
}
$ownedTenant = $this->tenant;
if (! $ownedTenant) {
return false;
}
return (int) $tenant->getKey() === (int) $ownedTenant->getKey();
}
public function getTenants(Panel $panel): array | Collection
{
if ($this->role === 'super_admin') {
return Tenant::query()->orderBy('name')->get();
}
$tenant = $this->tenant;
return $tenant ? collect([$tenant]) : collect();
}
}