I have multiple dashboards in one of my apps and I took a similar approach as you. Here is the quick and dirty of what I did:
Controllers: Separate directories for each (Admin, User, etc.)
- Admin/DashboardController.php (should return only views from views/admin)
- User/DashboardController.php (should return only views from views/user)
- AuthController.php (should only return views from views/auth)
Views: Separate directories for each (Admin, User, etc.)
- views/admin/dashboard (only admin dashboard views in this directory)
- views/user/dashboard (only user dashboard views in this directory)
- views/auth (this will hold auth views for the whole application)
We can use middleware and routing to ensure that Admins are directed to the admin dashboard and normal users are directed to the user dashboard.
Use php artisan make:middleware IsAdminMiddleware to create a middleware file titled 'IsAdminMiddleware'. Once created, you can find this file at app/Http/Middleware/IsAdminMiddleware.php. This is what my IsAdminMiddleware looks like. I've added a few comments for clarity's sake.
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class IsAdminMiddleware
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle(Request $request, Closure $next): mixed
{
// auth()->user() will return the currently authenticated user. We can use that to check the isAdmin flag you have on your User model
if (!auth()->user()) return redirect()->to("/"); // no auth'd user
if (!auth()->user()->isAdmin) return redirect()->to("/"); // user is not admin, redirect to user dashboard
return $next($request); // user is admin as they do not meet the above conditions
}
}
Now that we have middleware created, we need to register is with our app so that it runs during every HTTP request.
In app/Http/Kernel.php, you will find an array called middlewareAliases. We can register our new middleware by adding an entry to this array.
protected $middlewareAliases = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \App\Http\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'admin'=> \App\Http\Middleware\IsAdminMiddleware::class, // OUR NEW ADMIN MIDDLEWARE *******
];
Now we can create a Route::group for our admin routes with the auth and admin middleware. If someone who's is not an admin tries to reach any of these routes, the server will return 401: Not Authorized.
Routing: My web.php is laid out as follows. Comments added for clarity.
// global routes (mostly just authentication routes)
Route::get('login', [AuthController::class, 'login'])->name('login');
Route::get('logout', [AuthController::class, 'logout']);
Route::post('login', [AuthController::class, 'attempt']);
// Administrative Only Routes
Route::group(['prefix' => 'admin', 'middleware' => ['auth', 'admin']], function () {
//Admin Dashboard
Route::controller(AdminDashboardController::class)->group(function () {
Route::get("/dashboard", 'index');
});
});
// Non-Administrative (Normal User) Only Routes
Route::group(['prefix' => 'home', 'middleware' => ['auth']], function () {
//Admin Dashboard
Route::controller(UserDashboardController::class)->group(function () {
Route::get("/dashboard", 'index');
});
});
NOTE: My routes have prefixes attached to each group. This means that any routes to admin resources will need to include the admin prefix like so admin/dashboard Non-admin users have the prefix of home so any routes to non-admin resources will need to include the home prefix like so home/dashboard. Non-admin users will not be able to click links like admin/dashboard and vice versa.