23-01-2026
This commit is contained in:
parent
07959c0ba2
commit
854ce02bf6
166 changed files with 32909 additions and 1262 deletions
|
|
@ -8,15 +8,13 @@ use Livewire\Volt\Volt;
|
|||
// Admin-Dashboard
|
||||
Route::get('/', function () {
|
||||
return redirect()->route('dashboard');
|
||||
})->name('home');
|
||||
})->name('admin.home');
|
||||
|
||||
// Partner Setup Wizard (muss vor anderen auth-Routes sein, um keine Middleware zu bekommen)
|
||||
Route::middleware(['auth'])->group(function () {
|
||||
Volt::route('partner/setup', 'partner.setup-wizard')
|
||||
->name('partner.setup.wizard');
|
||||
});
|
||||
// Partner Setup Wizard wird in routes/web.php definiert
|
||||
|
||||
Route::view('dashboard', 'admin.dashboard')->middleware(['auth', 'verified', 'partner.setup'])->name('dashboard');
|
||||
Volt::route('/partner/my-data', 'partner.my-data')
|
||||
->name('partner.my-data');
|
||||
|
||||
// Admin-Einstellungen
|
||||
Route::middleware(['auth', 'partner.setup'])->group(function () {
|
||||
|
|
@ -26,6 +24,24 @@ Route::middleware(['auth', 'partner.setup'])->group(function () {
|
|||
Volt::route('settings/password', 'settings.password')->name('settings.password');
|
||||
Volt::route('settings/appearance', 'settings.appearance')->name('settings.appearance');
|
||||
|
||||
// Impersonation
|
||||
Route::post('admin/impersonate/leave', function () {
|
||||
$adminUserId = session('impersonate_from');
|
||||
|
||||
if ($adminUserId) {
|
||||
$adminUser = \App\Models\User::find($adminUserId);
|
||||
|
||||
if ($adminUser) {
|
||||
session()->forget('impersonate_from');
|
||||
\Illuminate\Support\Facades\Auth::login($adminUser);
|
||||
|
||||
return redirect()->route('admin.users')->with('message', __('Erfolgreich zurück zum Admin-Account.'));
|
||||
}
|
||||
}
|
||||
|
||||
return redirect()->route('dashboard');
|
||||
})->name('admin.impersonate.leave');
|
||||
|
||||
// Weitere Admin-Routen hier...
|
||||
|
||||
// User Management
|
||||
|
|
@ -35,6 +51,32 @@ Route::middleware(['auth', 'partner.setup'])->group(function () {
|
|||
|
||||
// Partner Management
|
||||
Volt::route('admin/partners/invite', 'admin.partners.invite')->name('admin.partners.invite');
|
||||
Volt::route('admin/partners/registration-codes', 'admin.partners.registration-codes')->name('admin.partners.registration-codes');
|
||||
|
||||
// Testing
|
||||
Volt::route('testing/registration', 'admin.testing.registration-tester')->name('testing.landing');
|
||||
|
||||
// CMS Routes
|
||||
Route::get('admin/cms/cabinet', \App\Livewire\Admin\CMS\CabinetDisplay::class)->name('admin.cms.cabinet');
|
||||
|
||||
// Product Routes
|
||||
Volt::route('products', 'products.index')->name('products.index');
|
||||
Volt::route('products/create', 'products.create')->name('products.create');
|
||||
|
||||
// Hub Management
|
||||
Volt::route('admin/hubs', 'admin.hubs.index')->name('admin.hubs.index');
|
||||
Volt::route('admin/hubs/create', 'admin.hubs.manage')->name('admin.hubs.create');
|
||||
Volt::route('admin/hubs/{hubId}/edit', 'admin.hubs.manage')->name('admin.hubs.edit');
|
||||
|
||||
// Documentation
|
||||
Volt::route('admin/documentation', 'admin.documentation')->name('admin.documentation');
|
||||
Route::get('admin/documentation/download', function () {
|
||||
$mdPath = base_path('dev/entwicklung.md');
|
||||
if (!file_exists($mdPath)) {
|
||||
abort(404);
|
||||
}
|
||||
return response()->download($mdPath, 'b2in-entwicklung.md');
|
||||
})->name('admin.documentation.download');
|
||||
});
|
||||
|
||||
// Admin-Authentication wird bereits in domains.php geladen
|
||||
|
|
|
|||
|
|
@ -56,3 +56,6 @@ Route::post('/login', function (Request $request) {
|
|||
'message' => 'Ungültige Anmeldedaten',
|
||||
], 401);
|
||||
});
|
||||
|
||||
// Display-Konfiguration für Cabinet Display
|
||||
Route::get('/display/config', [\App\Http\Controllers\Api\DisplayConfigController::class, 'index']);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,45 @@ Route::group(['middleware' => config('fortify.middleware', ['web'])], function (
|
|||
->middleware(['auth:' . config('fortify.guard')])
|
||||
->name('verification.notice');
|
||||
|
||||
// E-Mail-Verifizierung durchführen (ohne Login - verifiziert und loggt User ein)
|
||||
Route::get('/email/verify/{id}/{hash}', function (Illuminate\Http\Request $request, $id, $hash) {
|
||||
// Ablaufzeit prüfen
|
||||
$expires = $request->query('expires');
|
||||
if ($expires && time() > $expires) {
|
||||
return redirect()->route('login')
|
||||
->withErrors(['email' => __('Der Verifizierungslink ist abgelaufen. Bitte fordern Sie einen neuen an.')]);
|
||||
}
|
||||
|
||||
// User finden
|
||||
$user = \App\Models\User::findOrFail($id);
|
||||
|
||||
// Hash überprüfen (E-Mail-Hash)
|
||||
if (!hash_equals($hash, sha1($user->getEmailForVerification()))) {
|
||||
abort(403, __('Ungültiger Verifizierungslink.'));
|
||||
}
|
||||
|
||||
// E-Mail verifizieren (falls noch nicht verifiziert)
|
||||
if (!$user->hasVerifiedEmail()) {
|
||||
$user->markEmailAsVerified();
|
||||
|
||||
// Event auslösen (für Listeners)
|
||||
event(new \Illuminate\Auth\Events\Verified($user));
|
||||
}
|
||||
|
||||
// User einloggen
|
||||
\Illuminate\Support\Facades\Auth::login($user);
|
||||
|
||||
return redirect()->route('partner.setup.wizard')
|
||||
->with('message', __('E-Mail erfolgreich verifiziert! Willkommen! Bitte schließen Sie Ihr Setup ab.'));
|
||||
})->name('verification.verify');
|
||||
|
||||
// E-Mail-Verifizierung erneut senden
|
||||
Route::post('/email/verification-notification', function (Illuminate\Http\Request $request) {
|
||||
$request->user()->sendEmailVerificationNotification();
|
||||
|
||||
return back()->with('message', __('Verifizierungslink wurde erneut gesendet!'));
|
||||
})->middleware(['auth:' . config('fortify.guard'), 'throttle:6,1'])->name('verification.send');
|
||||
|
||||
// Passwort bestätigen mit Livewire
|
||||
Volt::route('/confirm-password', 'auth.confirm-password')
|
||||
->middleware(['auth:' . config('fortify.guard')])
|
||||
|
|
@ -37,5 +76,5 @@ Route::group(['middleware' => config('fortify.middleware', ['web'])], function (
|
|||
|
||||
// Logout-Route
|
||||
Route::post('/logout', [Laravel\Fortify\Http\Controllers\AuthenticatedSessionController::class, 'destroy'])
|
||||
->name('logout');
|
||||
->name('auth.logout');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -3,8 +3,30 @@
|
|||
use Illuminate\Support\Facades\Route;
|
||||
use Illuminate\Support\Facades\Vite;
|
||||
|
||||
// Admin-Bereich auf portal.b2in.local
|
||||
Route::domain('portal.b2in.test')->group(function () {
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Domain-Konfiguration aus config/domains.php laden
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Die Domains werden dynamisch aus der Konfiguration geladen.
|
||||
| In .env können die Live-Domains definiert werden:
|
||||
|
|
||||
| DOMAIN_PORTAL=portal.beispiel.de
|
||||
| DOMAIN_B2IN=b2in.de
|
||||
| DOMAIN_B2A=b2a.de
|
||||
| DOMAIN_STILEIGENTUM=stileigentum.de
|
||||
| DOMAIN_STYLE2OWN=style2own.de
|
||||
|
|
||||
*/
|
||||
|
||||
$domainPortal = config('domains.domain_portal', 'portal.b2in.test');
|
||||
$domainB2in = config('domains.domain_b2in', 'b2in.test');
|
||||
$domainB2a = config('domains.domain_b2a', 'b2a.test');
|
||||
$domainStileigentum = config('domains.domain_stileigentum', 'stileigentum.test');
|
||||
$domainStyle2own = config('domains.domain_style2own', 'style2own.test');
|
||||
|
||||
// Admin-Bereich (Portal)
|
||||
Route::domain($domainPortal)->group(function () {
|
||||
// Auth-Routen laden
|
||||
require __DIR__ . '/auth.php';
|
||||
|
||||
|
|
@ -14,48 +36,44 @@ Route::domain('portal.b2in.test')->group(function () {
|
|||
// Test-Route laden
|
||||
require __DIR__ . '/test.php';
|
||||
|
||||
// Display-API-Route (öffentlich zugänglich)
|
||||
Route::get('/api/display/config', [\App\Http\Controllers\Api\DisplayConfigController::class, 'index']);
|
||||
|
||||
// FluxUI Asset-Routen explizit für Portal-Domain registrieren
|
||||
// (Notwendig weil Route-Cache die globalen Flux-Routen nicht für alle Domains enthält)
|
||||
Route::get('/flux/flux.js', [\Flux\AssetManager::class, 'fluxJs']);
|
||||
Route::get('/flux/flux.min.js', [\Flux\AssetManager::class, 'fluxMinJs']);
|
||||
Route::get('/flux/editor.css', [\Flux\AssetManager::class, 'editorCss']);
|
||||
Route::get('/flux/editor.js', [\Flux\AssetManager::class, 'editorJs']);
|
||||
Route::get('/flux/editor.min.js', [\Flux\AssetManager::class, 'editorMinJs']);
|
||||
|
||||
// Admin-Assets (Vite)
|
||||
Vite::useBuildDirectory('build/admin');
|
||||
Vite::useBuildDirectory('build/portal');
|
||||
});
|
||||
|
||||
// API-Routen für alle Domains
|
||||
Route::domain('api.b2in.test')->group(function () {
|
||||
// API-Routen für alle Domains (optional: auch dynamisch machen)
|
||||
Route::domain(config('domains.domain_api', 'api.b2in.test'))->group(function () {
|
||||
require __DIR__ . '/api.php';
|
||||
});
|
||||
|
||||
// B2IN Theme für b2in.test (Hauptwebsite)
|
||||
Route::domain('b2in.test')->group(function () {
|
||||
// Web-Routes laden
|
||||
require __DIR__ . '/web.php';
|
||||
// Web-Routes für alle Themes (werden außerhalb der Domain-Gruppen geladen, um Duplikate zu vermeiden)
|
||||
// Das Theme wird automatisch basierend auf der Domain vom ThemeServiceProvider ausgewählt
|
||||
require __DIR__ . '/web.php';
|
||||
|
||||
// B2IN Theme Assets (Vite)
|
||||
// Domain-spezifische Vite Build-Verzeichnisse
|
||||
Route::domain($domainB2in)->group(function () {
|
||||
Vite::useBuildDirectory('build/b2in');
|
||||
});
|
||||
|
||||
// B2A Theme für b2a.test
|
||||
Route::domain('b2a.test')->group(function () {
|
||||
// Web-Routes laden
|
||||
require __DIR__ . '/web.php';
|
||||
|
||||
// B2A Theme Assets (Vite)
|
||||
Route::domain($domainB2a)->group(function () {
|
||||
Vite::useBuildDirectory('build/b2a');
|
||||
});
|
||||
|
||||
// Stileigentum Theme für stileigentum.test
|
||||
Route::domain('stileigentum.test')->group(function () {
|
||||
// Web-Routes laden
|
||||
require __DIR__ . '/web.php';
|
||||
|
||||
// Stileigentum Theme Assets (Vite)
|
||||
Route::domain($domainStileigentum)->group(function () {
|
||||
Vite::useBuildDirectory('build/stileigentum');
|
||||
});
|
||||
|
||||
// Style2own Theme für style2own.test
|
||||
Route::domain('style2own.test')->group(function () {
|
||||
// Web-Routes laden
|
||||
require __DIR__ . '/web.php';
|
||||
|
||||
// Style2own Theme Assets (Vite)
|
||||
Route::domain($domainStyle2own)->group(function () {
|
||||
Vite::useBuildDirectory('build/style2own');
|
||||
});
|
||||
|
||||
|
|
@ -85,3 +103,6 @@ Route::domain('landing2.test')->group(function () {
|
|||
|
||||
Vite::useBuildDirectory('build/web');
|
||||
});*/
|
||||
|
||||
// Fallback: Display-API für alle anderen Domains (z.B. localhost)
|
||||
Route::get('/api/display/config', [\App\Http\Controllers\Api\DisplayConfigController::class, 'index']);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,10 @@
|
|||
<?php
|
||||
|
||||
use App\Mail\PartnerInvitationMail;
|
||||
use App\Models\PartnerInvitation;
|
||||
use App\Models\User;
|
||||
use App\Notifications\CustomResetPasswordNotification;
|
||||
use App\Notifications\CustomVerifyEmailNotification;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Livewire\Volt\Volt;
|
||||
|
||||
|
|
@ -22,3 +27,60 @@ Route::get('/debug-login', function () {
|
|||
Route::get('/simple-test', function () {
|
||||
return view('test-simple');
|
||||
})->name('simple.test');
|
||||
|
||||
// E-Mail-Vorschau-Routen (nur für Entwicklung)
|
||||
Route::prefix('test/emails')->group(function () {
|
||||
// Partner-Einladung Vorschau
|
||||
Route::get('/partner-invitation', function () {
|
||||
$invitation = PartnerInvitation::first() ?? new PartnerInvitation([
|
||||
'company_name' => 'Musterfirma GmbH',
|
||||
'contact_first_name' => 'Max',
|
||||
'contact_last_name' => 'Mustermann',
|
||||
'email' => 'max@musterfirma.de',
|
||||
'expires_at' => now()->addWeeks(2),
|
||||
]);
|
||||
|
||||
// Mock role if not exists
|
||||
if (!$invitation->role) {
|
||||
$invitation->setRelation('role', (object)[
|
||||
'display_name' => 'Premium Partner',
|
||||
'name' => 'partner'
|
||||
]);
|
||||
}
|
||||
|
||||
$invitationUrl = 'https://portal.b2in.test/partner/invitation/accept/ABC123';
|
||||
|
||||
return new PartnerInvitationMail($invitation, $invitationUrl);
|
||||
})->name('test.email.partner-invitation');
|
||||
|
||||
// Passwort-Reset Vorschau
|
||||
Route::get('/password-reset', function () {
|
||||
$user = User::first() ?? new User([
|
||||
'name' => 'Max Mustermann',
|
||||
'email' => 'max@example.com'
|
||||
]);
|
||||
|
||||
$notification = new CustomResetPasswordNotification('test-token-123');
|
||||
$mailMessage = $notification->toMail($user);
|
||||
|
||||
return $mailMessage->render();
|
||||
})->name('test.email.password-reset');
|
||||
|
||||
// E-Mail-Verifizierung Vorschau
|
||||
Route::get('/email-verification', function () {
|
||||
$user = User::first() ?? new User([
|
||||
'name' => 'Max Mustermann',
|
||||
'email' => 'max@example.com'
|
||||
]);
|
||||
|
||||
$notification = new CustomVerifyEmailNotification();
|
||||
$mailMessage = $notification->toMail($user);
|
||||
|
||||
return $mailMessage->render();
|
||||
})->name('test.email.verification');
|
||||
|
||||
// Übersicht aller E-Mail-Vorlagen
|
||||
Route::get('/', function () {
|
||||
return view('emails.test-overview');
|
||||
})->name('test.emails');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -64,12 +64,12 @@ Route::get('/theme-demo', function () {
|
|||
return view('web.theme-demo');
|
||||
})->name('theme-demo');
|
||||
|
||||
|
||||
// Pfad-basierte Theme-Routen für lokale Entwicklung wurden entfernt
|
||||
// Die Themensauswahl wird nun über den ThemeServiceProvider gesteuert (Domain oder ?theme=... GET-Parameter)
|
||||
|
||||
|
||||
Volt::route('/partner/invitation/{token}', 'partner.invitation-accept')
|
||||
->name('partner.invitation.accept');
|
||||
|
||||
|
||||
Route::get('/partner/invitation/expired/{token}', function (string $token) {
|
||||
$invitation = \App\Models\PartnerInvitation::with('role')->where('token', $token)->firstOrFail();
|
||||
|
|
@ -81,8 +81,27 @@ Route::get('/partner/invitation/used/{token}', function (string $token) {
|
|||
return view('partner.invitation-used', compact('invitation'));
|
||||
})->name('partner.invitation.used');
|
||||
|
||||
// Partner Setup Wizard
|
||||
Volt::route('/partner/invitation/{token}', 'partner.invitation-accept')
|
||||
->name('partner.invitation.accept');
|
||||
|
||||
|
||||
Volt::route('/partner/create-account', 'partner.create-account')
|
||||
->name('partner.create.account');
|
||||
|
||||
|
||||
// Öffentliche Registrierung per QR-/Code (Landing, code-check)
|
||||
Volt::route('/reg/{role}', 'reg.landing')
|
||||
->name('registration.landing');
|
||||
|
||||
Volt::route('/registration/thank-you', 'reg.thank-you')
|
||||
->name('registration.thank-you');
|
||||
|
||||
|
||||
// Partner Setup Wizard & Daten
|
||||
Route::middleware('auth')->group(function () {
|
||||
Volt::route('/partner/setup', 'partner.setup-wizard')
|
||||
->name('partner.setup.wizard');
|
||||
});
|
||||
|
||||
// Authentifizierungs-Routen werden in domains.php eingebunden
|
||||
//require __DIR__ . '/auth.php';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue