idavoll/dashboard-module
A Laravel/PHP dashboard module for adding structured dashboard pages and widgets to your application. It aims to fit common Laravel conventions, offering a foundation for admin, reporting, or project dashboards without heavy setup.
This is not a standalone package. idavoll/dashboard-module is the admin dashboard module for AsgardCMS — a modular Laravel CMS. Pulling it into a clean Laravel app will do nothing useful; you need the AsgardCMS platform scaffolded first (composer create-project asgardcms/platform my-site), which then pulls the Dashboard module (and sibling modules like Menu, Page, Media) through the Platform metapackage.
Where to look first
Modules/Dashboard/ (or vendor/idavoll/dashboard-module/ if not published). Start at Providers/DashboardServiceProvider.php — that's where the dashboard manager binding, widget registration hooks, and view/route loading happen.Http/Controllers/DashboardController.php and its view (Resources/views/dashboard/index.blade.php) to see what renders on /backend.First use case
Log in to /backend on a fresh AsgardCMS install. The dashboard page you land on is this module. Your first useful task is almost always "add one custom widget tile" — either by registering into the dashboard manager from your own module's service provider, or by shadowing the module's Blade view (see patterns below). Adding a widget, not editing core, is the right entry point.
If the module isn't showing up at all: confirm AsgardCMS is installed, run php artisan module:list, verify the Dashboard module is enabled, and check that config/app.php / bootstrap/providers.php includes the platform's module service registration. Nine times out of ten "the dashboard is blank" is actually "AsgardCMS isn't installed" or "module disabled," not a bug in this package.
Register widgets from your own module. The idiomatic AsgardCMS way to reach the dashboard is from another module's service provider or boot method — you push a named widget with a closure/view. Do this in your module's boot() rather than editing Modules/Dashboard/ so the change survives composer update. A typical shape:
// In your module's ServiceProvider::boot()
if (app()->bound('dashboard')) {
app('dashboard')->push('my-module.stats', function () {
return view('my-module::widgets.stats', [
'count' => Post::published()->count(),
]);
});
}
The if (app()->bound(...)) guard matters: this provider may load in console/queue contexts where the dashboard isn't wired up, and you don't want a hard crash on artisan migrate.
Shadow views instead of forking. Laravel's conventional override path works — copy dashboard/index.blade.php (and any widget partials) into resources/views/vendor/dashboard/ in your app, or publish with php artisan vendor:publish. This is the lowest-risk customization surface: layout tweaks, adding a welcome banner, reordering tiles in template only. You keep the composer dependency intact.
Compose, don't stuff. Don't put query logic directly in a widget closure. Put it behind a small service or repository call, and let the closure just pass the result to the view. Widgets render on every dashboard load; N+1 queries in a dashboard tile is a classic way to make /backend crawl. If a widget is expensive, wrap the count in Cache::remember(..., 60, ...).
Use permissions, not controller edits. AsgardCMS exposes a permissions config per module (Config/permissions.php style). If you're adding a widget that only admins should see, gate visibility in the widget registration or template with @can/Auth::user()->hasRole(...) rather than editing the Dashboard controller. That keeps the module upgradeable.
Integrate with events/view composers. If you need pre/post hooks around dashboard rendering rather than replacing it, register a view composer on the dashboard views from your own provider. It's less invasive than touching DashboardController and composes cleanly across modules.
Treat it as a platform piece. The day-to-day mental model: Dashboard module = "host"; your modules = "plugin." Anything you write that plugs into the dashboard should be in your module, registered through the host's contract, so composer update idavoll/dashboard-module is never a merge conflict.
NOASSERTION. That's GitHub/composer failing to detect a declared license, not necessarily "no license." Check the actual LICENSE file in the repo before shipping it in something commercial; treat it as "unknown until verified" rather than "MIT-safe."BindingResolutionException only for dashboard widgets, you're registering too early — defer the widget push to boot() and wrap dependencies in closures, or use app(SomeService::class) lazily inside the widget callback rather than capturing a resolved instance.app()->bound('dashboard') guard, or any artisan command that boots your provider will throw.php artisan cache:clear and view:clear before debugging the code.dashboard::...), or your override silently doesn't apply — Laravel falls back to the package view without an error. If your override isn't taking effect, php artisan view:clear then re-check the path spelling.Modules/Dashboard/ in place on a platform install if you plan to composer update. Platform modules are often symlinked from vendor; in-place edits get wiped. Publish/override or register from your own module.return response('ok');. If the tile now renders "ok," the registration pipeline is fine and the problem is the view or a query inside it. If the tile is still empty, the closure never ran — check registration timing and app()->bound('dashboard').How can I help you explore Laravel packages today?