# Registrierungs-Fixes: Redirect, Error-Clearing und Role-Handling (2025-10-02) ## Problem-Beschreibung - **Redirect-Fehler**: Bei erfolgreicher Registrierung (free oder paid Package) wurde onSuccess in Register.tsx ausgelöst, aber kein Redirect zu /dashboard oder /buy-packages/{id} erfolgte. Ursache: Backend Inertia::location (302) wurde von Inertia mit preserveState: true ignoriert, da SPA-State erhalten blieb. - **Persistente Errors**: Server-Errors (z.B. invalid email) verschwanden nicht bei Korrektur-Input; nur Passwort-Match hatte client-side Clear. - **Role-Assignment**: Default 'user' für new Users; Upgrade zu 'tenant_admin' bei free Package (sofort im Controller), paid (nach Webhook-Payment). - **Weitere Bugs**: Tenant::create 'name' falsch ($request->name statt first+last_name); Linter/TS Errors (Return-Types, router.visit unknown). ## Fixes ### Backend (MarketingRegisterController.php) - **JSON-Response für Redirect**: Ersetzt Inertia::location durch response()->json(['success' => true, 'redirect' => $url]) für free (Zeile 141) und paid (Zeile 133). Kompatibel mit Inertia onSuccess (page.props.success/redirect prüfen). - **Tenant Name Fix**: 'name' => $request->first_name . ' ' . $request->last_name (Zeile 71); slug entsprechend angepasst. - **Role-Logic**: 'role' => 'user' in User::create (Zeile 66); für free: Update zu 'tenant_admin' nach TenantPackage::create (Zeile 129), Re-Login (Zeile 130). Für paid: Kein Upgrade bis Webhook (Paddle). - **Return-Type**: store() zu JsonResponse (Zeile 44); use JsonResponse hinzugefügt (Zeile 22). ### Frontend (Register.tsx) - **onSuccess-Handling**: Prüfe page.props.success && router.visit(page.props.redirect as string) (Zeile 66-68); Fallback zu data.package_id ? `/buy-packages/${data.package_id}` : '/dashboard' (Zeile 71-75); console.log für Debug (Zeile 67, 74). - **Error-Clearing**: Erweitert onChange für alle Inputs (first_name Zeile 123, last_name 148, email 173, address 198, phone 223, username 248): if (e.target.value.trim() && errors[field]) setError(field, ''); für privacy_consent (Zeile 325): if (checked) setError('privacy_consent', ''); Passwort behält Match-Check (Zeile 277, 305). - **General Errors Key**: