diff --git a/app/Http/Controllers/AccountController.php b/app/Http/Controllers/AccountController.php index a7759dc..54b32f6 100644 --- a/app/Http/Controllers/AccountController.php +++ b/app/Http/Controllers/AccountController.php @@ -8,6 +8,7 @@ use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Hash; +use Illuminate\Support\Facades\Schema; use Illuminate\Validation\Rule; use Illuminate\View\View; @@ -26,11 +27,14 @@ class AccountController extends Controller ->latest() ->get(); - $communications = Communication::where('user_id', $user->id) - ->orWhere('email', strtolower($user->email)) - ->with('replies') - ->latest() - ->get(); + $communications = collect(); + if (Schema::hasTable('communications')) { + $communications = Communication::where('user_id', $user->id) + ->orWhere('email', strtolower($user->email)) + ->with('replies') + ->latest() + ->get(); + } return view('account.index', compact('user', 'orders', 'communications')); } diff --git a/app/Http/Controllers/Admin/CommunicationController.php b/app/Http/Controllers/Admin/CommunicationController.php index 021e87d..fae10b9 100644 --- a/app/Http/Controllers/Admin/CommunicationController.php +++ b/app/Http/Controllers/Admin/CommunicationController.php @@ -8,9 +8,11 @@ use App\Models\Communication; use App\Models\CommunicationReply; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Mail; +use Illuminate\Support\Facades\Schema; use Illuminate\View\View; class CommunicationController extends Controller @@ -20,6 +22,10 @@ class CommunicationController extends Controller */ public function index(Request $request): View { + if (! Schema::hasTable('communications')) { + Artisan::call('migrate', ['--force' => true]); + } + $query = Communication::with(['user', 'order', 'replies'])->latest(); // Status filter diff --git a/app/Http/Controllers/Admin/CustomerController.php b/app/Http/Controllers/Admin/CustomerController.php index bd609a2..dd26f55 100644 --- a/app/Http/Controllers/Admin/CustomerController.php +++ b/app/Http/Controllers/Admin/CustomerController.php @@ -8,6 +8,8 @@ use App\Models\Order; use App\Models\User; use Illuminate\Http\Request; use Illuminate\Pagination\LengthAwarePaginator; +use Illuminate\Support\Facades\Artisan; +use Illuminate\Support\Facades\Schema; use Illuminate\View\View; class CustomerController extends Controller @@ -17,6 +19,10 @@ class CustomerController extends Controller */ public function index(Request $request): View { + if (! Schema::hasTable('communications')) { + Artisan::call('migrate', ['--force' => true]); + } + $search = trim($request->input('q', '')); // Query registered non-admin users diff --git a/app/Http/Controllers/ContactController.php b/app/Http/Controllers/ContactController.php index 6985f0b..8042372 100644 --- a/app/Http/Controllers/ContactController.php +++ b/app/Http/Controllers/ContactController.php @@ -9,9 +9,11 @@ use App\Models\Order; use App\Models\Setting; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Artisan; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Mail; +use Illuminate\Support\Facades\Schema; use Illuminate\View\View; class ContactController extends Controller @@ -60,6 +62,10 @@ class ContactController extends Controller } } + if (! Schema::hasTable('communications')) { + Artisan::call('migrate', ['--force' => true]); + } + $communication = Communication::create([ 'user_id' => Auth::id(), 'order_id' => $orderId, diff --git a/app/Http/Middleware/EnsureUserIsAdmin.php b/app/Http/Middleware/EnsureUserIsAdmin.php index 888b1f2..ac9fdb5 100644 --- a/app/Http/Middleware/EnsureUserIsAdmin.php +++ b/app/Http/Middleware/EnsureUserIsAdmin.php @@ -4,6 +4,9 @@ namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Artisan; +use Illuminate\Support\Facades\Log; +use Illuminate\Support\Facades\Schema; use Symfony\Component\HttpFoundation\Response; class EnsureUserIsAdmin @@ -23,6 +26,16 @@ class EnsureUserIsAdmin ->with('error', 'Je hebt geen beheerderstoegang tot deze pagina.'); } + // Auto-migrate check: Ensure that new database tables (like communications) are migrated + // automatically when an admin enters the admin panel, avoiding 500 errors on Coolify/production. + try { + if (! Schema::hasTable('communications')) { + Artisan::call('migrate', ['--force' => true]); + } + } catch (\Throwable $e) { + Log::warning('Auto-migration in EnsureUserIsAdmin failed: '.$e->getMessage()); + } + return $next($request); } } diff --git a/resources/views/layouts/admin.blade.php b/resources/views/layouts/admin.blade.php index f3de6cf..9636648 100644 --- a/resources/views/layouts/admin.blade.php +++ b/resources/views/layouts/admin.blade.php @@ -51,7 +51,14 @@ @php - $draftBadgeCount = \App\Models\Product::where('status', 'draft')->count(); + $draftBadgeCount = 0; + try { + if (\Illuminate\Support\Facades\Schema::hasTable('products')) { + $draftBadgeCount = \App\Models\Product::where('status', 'draft')->count(); + } + } catch (\Throwable $e) { + $draftBadgeCount = 0; + } @endphp @@ -74,7 +81,14 @@ @php - $unreadCommCount = \App\Models\Communication::where('status', 'new')->count(); + $unreadCommCount = 0; + try { + if (\Illuminate\Support\Facades\Schema::hasTable('communications')) { + $unreadCommCount = \App\Models\Communication::where('status', 'new')->count(); + } + } catch (\Throwable $e) { + $unreadCommCount = 0; + } @endphp @@ -101,7 +115,14 @@
@php - $isShopOffline = \App\Models\Setting::get('shop_offline', '0') === '1'; + $isShopOffline = false; + try { + if (\Illuminate\Support\Facades\Schema::hasTable('settings')) { + $isShopOffline = \App\Models\Setting::get('shop_offline', '0') === '1'; + } + } catch (\Throwable $e) { + $isShopOffline = false; + } @endphp @@ -175,7 +196,7 @@ - @if($isShopOffline ?? (\App\Models\Setting::get('shop_offline', '0') === '1')) + @if(!empty($isShopOffline))
diff --git a/tests/Feature/CustomerCommunicationTest.php b/tests/Feature/CustomerCommunicationTest.php index 1d1e788..9c430b2 100644 --- a/tests/Feature/CustomerCommunicationTest.php +++ b/tests/Feature/CustomerCommunicationTest.php @@ -10,6 +10,7 @@ use App\Models\Order; use App\Models\User; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Support\Facades\Mail; +use Illuminate\Support\Facades\Schema; use Tests\TestCase; class CustomerCommunicationTest extends TestCase @@ -231,4 +232,14 @@ class CustomerCommunicationTest extends TestCase $this->actingAs($this->customer)->get(route('admin.communications.index'))->assertRedirect(route('home')); $this->actingAs($this->customer)->get(route('admin.customers.index'))->assertRedirect(route('home')); } + + public function test_admin_layout_does_not_crash_even_if_communications_table_is_initially_missing(): void + { + Schema::dropIfExists('communication_replies'); + Schema::dropIfExists('communications'); + + // Layout renders with HTTP 200 without 500 server error even when table was absent + $response = $this->actingAs($this->admin)->get(route('admin.content.index')); + $response->assertStatus(200); + } }