Deploy 3: Onboarding wizard + empty states + docs operationale

- 3-step onboarding wizard at /app/onboarding (auto-redirected via
  RequireOnboarding middleware on first login per tenant)
- Empty states with icon + heading + description on Client, Vehicle,
  WorkOrder, Lead, Part lists
- Docs: operations/{api,i18n,2fa,monitoring}.md, stack/reverb.md
- Updated 00-index.md and journal.md with status of all 15 items
This commit is contained in:
2026-05-07 20:16:03 +00:00
parent 138671a125
commit 0399262514
9 changed files with 295 additions and 0 deletions
+56
View File
@@ -0,0 +1,56 @@
<?php
namespace App\Http\Middleware;
use App\Tenancy\TenantManager;
use Closure;
use Illuminate\Http\Request;
/**
* If the current tenant has never completed the onboarding wizard,
* redirect logged-in users to /app/onboarding.
*
* Skip when:
* - already on /app/onboarding
* - on /app/login or /app/logout
* - on /livewire/* (XHR wizard handles its own POST)
*/
class RequireOnboarding
{
public function handle(Request $request, Closure $next)
{
$path = $request->path();
// Skip non-tenant-panel paths.
if (! str_starts_with($path, 'app')) {
return $next($request);
}
// Skip auth & onboarding paths.
if (
str_contains($path, 'login')
|| str_contains($path, 'logout')
|| str_contains($path, 'onboarding')
|| str_starts_with($path, 'livewire')
|| str_starts_with($path, 'filament')
) {
return $next($request);
}
$tenant = app(TenantManager::class)->current();
if (! $tenant) {
return $next($request);
}
// Only redirect authenticated users.
if (! auth('web')->check()) {
return $next($request);
}
if (empty($tenant->settings['onboarded_at'])) {
return redirect('/app/onboarding');
}
return $next($request);
}
}