├── .styleci.yml ├── LICENSE.md ├── README.md ├── composer.json ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── images │ └── avatar.svg ├── laravel-dashboard-template.css └── mix-manifest.json ├── resources ├── sass │ ├── _tailwind.scss │ └── app.scss └── views │ ├── components │ ├── card.blade.php │ ├── dropdown.blade.php │ ├── dropdown_item.blade.php │ └── topbar.blade.php │ ├── page.blade.php │ └── partials │ ├── alert.blade.php │ ├── alert_error.blade.php │ ├── alert_success.blade.php │ ├── dropdown_arrow.blade.php │ ├── menu_toggle.blade.php │ ├── sidebar.blade.php │ ├── sidebar_link.blade.php │ ├── sidebar_logo.blade.php │ └── topbar_profile_dropdown.blade.php ├── src ├── Console │ ├── InstallCommand.php │ └── PublishCommand.php ├── Http │ ├── Controllers │ │ └── LogoutController.php │ └── routes.php ├── LaravelDashboardTemplate.php ├── LaravelDashboardTemplateApplicationServiceProvider.php ├── LaravelDashboardTemplateFacade.php └── LaravelDashboardTemplateServiceProvider.php ├── stubs └── LaravelDashboardTemplateServiceProvider.stub ├── tailwind.config.js └── webpack.mix.js /.styleci.yml: -------------------------------------------------------------------------------- 1 | preset: laravel 2 | 3 | disabled: 4 | - single_class_element_per_statement 5 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Stratulat Alexandru 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
4 | 💫Basic Dashboard Template as a Package.💫 5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | > Note: Not suitable for single page applications as it's built in `Blade`, however you can use Vue/React/etc. components on all pages.
15 |
16 | ## Installation
17 |
18 | ```bash
19 | composer require sandulat/laravel-dashboard-template
20 | php artisan laravel-dashboard-template:install
21 | ```
22 |
23 | > Note: to re-publish the front-end assets when updating the package use: `php artisan laravel-dashboard-template:publish`
24 |
25 | The `install` command will publish the front-end assets and will create a new service provider `App\Providers\DashboardServiceProvider`. This is basically the main config of the template, but first let's see how to display the dashboard in the next section.
26 |
27 | ## Layout
28 |
29 | Create a route and a controller that will return a view. Inside the view place the following code:
30 |
31 | `my_view.blade.php:`
32 | ```blade
33 | @extends('laravel-dashboard-template::page')
34 |
35 | @section('ldt-content')
36 | Some content
37 | @endsection
38 | ```
39 |
40 | > Note: `ldt` stands for `laravel-dashboard-template`.
41 |
42 | As you can see `laravel-dashboard-template::page` is just a layout. Besides `ldt-content` the layout provides more additional slots:
43 | - `ldt-head` - Head section for CSS, meta, etc.
44 | - `ldt-scripts` - Scripts section to include JS files.
45 | - `ldt-topbar-left` - Left section of topbar.
46 | - `ldt-topbar-right` - Right section of topbar, next to profile dropdown.
47 | - `ldt-sidebar-footer` - Footer section of sidebar.
48 |
49 | To avoid duplication of these slots, it would be better to create your own layout that will extend the package's layout.
50 |
51 | `my_layout.blade.php:`
52 | ```blade
53 | @extends('laravel-dashboard-template::page')
54 |
55 | @section('ldt-topbar-right')
56 | Language Select
57 | @endsection
58 | ```
59 |
60 | So now in your views you can do:
61 |
62 | `my_view.blade.php:`
63 | ```blade
64 | @extends('my_layout')
65 |
66 | @section('ldt-content')
67 | Some content
68 | @endsection
69 | ```
70 |
71 | ## Card
72 |
73 | Besides layout, the package provides a card component:
74 |
75 | ```blade
76 | @component('laravel-dashboard-template::components.card')
77 | @slot('title')
78 | Dahboard
79 | @endslot
80 |
81 | Content
82 | @endcomponent
83 | ```
84 |
85 | The result can be seen in the screenshot at the top of the documentation.
86 |
87 | ## Alerts
88 |
89 | Out of the box the package will display 2 types of alerts above the `content` section of the layout. They will be displayed when you redirect with `success` and `error` flash data:
90 |
91 | ```php
92 | return back()->with('success', 'My success message.');
93 | ```
94 |
95 | ```php
96 | return back()->with('error', 'My error message.');
97 | ```
98 |
99 | ## Configuration
100 |
101 | You can configure the dashboard inside the installed provider: `App\Providers\DashboardServiceProvider`. By default it's empty because everything is already configured so you can start building instantly, however you can add the following methods to start customizing the dashboard:
102 |
103 | ```php
104 | /**
105 | * Topbar user name resolver.
106 | *
107 | * @return string
108 | */
109 | public function userName(): string
110 | {
111 | return Auth::check() ? Auth::user()->name : 'Guest';
112 | }
113 | ```
114 | ```php
115 | /**
116 | * Topbar user avatar resolver.
117 | *
118 | * @return string
119 | */
120 | public function userAvatar(): string
121 | {
122 | if (Auth::check() && Auth::user()->avatar) {
123 | return Auth::user()->avatar;
124 | }
125 |
126 | return URL::asset('/vendor/laravel-dashboard-template/images/avatar.svg')
127 | }
128 | ```
129 | ```php
130 | /**
131 | * Sidebar links.
132 | *
133 | * @return array
134 | */
135 | public function sidebarLinks(): array
136 | {
137 | return [
138 | 'Menu' => [
139 | [
140 | 'label' => 'Users',
141 | 'url' => route('users'),
142 | 'children' => [
143 | [
144 | 'label' => 'Active Users',
145 | 'url' => route('users.active'),
146 | ],
147 | ],
148 | ],
149 | ],
150 | ];
151 | }
152 | ```
153 | ```php
154 | /**
155 | * Profile dropdown links.
156 | *
157 | * @return array
158 | */
159 | public function profileDropdownLinks(): array
160 | {
161 | return [
162 | [
163 | 'label' => 'Edit Profile',
164 | 'url' => route('profile'),
165 | ],
166 | ];
167 | }
168 | ```
169 | ```php
170 | /**
171 | * Logout the user.
172 | *
173 | * @param \Illuminate\Http\Request $request
174 | * @return void
175 | */
176 | public function logout(Request $request): void
177 | {
178 | Auth::guard()->logout();
179 |
180 | $request->session()->invalidate();
181 | }
182 | ```
183 | ```php
184 | /**
185 | * Action to be performed after logout.
186 | *
187 | * @return void
188 | */
189 | public function loggedOut(): void
190 | {
191 | //
192 | }
193 | ```
194 | ```php
195 | /**
196 | * Redirect after logout.
197 | *
198 | * @return \Illuminate\Http\RedirectResponse
199 | */
200 | public function logoutRedirect(): RedirectResponse
201 | {
202 | return redirect('/');
203 | }
204 | ```
205 |
206 | > Note: Each method from this service provider has dependency injection available.
207 |
208 | ## Customization
209 |
210 | I've tried to split the template into as many components & partials as possible. Just create inside your project the folder: `resources/views/vendor/laravel-dashboard-template` and now you can copy the files from the package and customize them. Here is the list:
211 | - partials/alert.blade.php
212 | - partials/alert_error.blade.php
213 | - partials/alert_success.blade.php
214 | - partials/sidebar.blade.php
215 | - partials/sidebar_link.blade.php
216 | - partials/sidebar_logo.blade.php
217 | - partials/topbar_profile_dropdown.blade.php
218 |
219 | ---
220 |
221 | - components/card.blade.php
222 | - components/dropdown.blade.php
223 | - components/dropdown_item.blade.php
224 | - components/topbar.blade.php
225 |
226 | ## Using Vue/React/etc. components
227 |
228 | The main div that wraps the dashboard has an `app` id. You can load your front-end framework onto this id and start using your components on all pages.
229 |
230 | ```jsx
231 | // Vue
232 | new Vue({
233 | el: '#app',
234 | });
235 |
236 | //React
237 | ReactDOM.render(
265 |
266 |
267 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "sandulat/laravel-dashboard-template",
3 | "description": "Basic Laravel Dashboard Template",
4 | "keywords": [
5 | "sandulat",
6 | "laravel-dashboard-template"
7 | ],
8 | "homepage": "https://github.com/sandulat/laravel-dashboard-template",
9 | "license": "MIT",
10 | "type": "library",
11 | "authors": [
12 | {
13 | "name": "Stratulat Alexandru",
14 | "email": "alexanderstratulat97@gmail.com",
15 | "role": "Developer"
16 | }
17 | ],
18 | "require": {
19 | "php": "^7.1",
20 | "illuminate/support": "5.8.*",
21 | "laravel/framework": "~5.8.0|~5.9.0"
22 | },
23 | "require-dev": {
24 | "orchestra/testbench": "3.8.*",
25 | "phpunit/phpunit": "^7.0"
26 | },
27 | "autoload": {
28 | "psr-4": {
29 | "Sandulat\\LaravelDashboardTemplate\\": "src"
30 | }
31 | },
32 | "autoload-dev": {
33 | "psr-4": {
34 | "Sandulat\\LaravelDashboardTemplate\\Tests\\": "tests"
35 | }
36 | },
37 | "scripts": {
38 | "test": "vendor/bin/phpunit",
39 | "test-coverage": "vendor/bin/phpunit --coverage-html coverage"
40 | },
41 | "config": {
42 | "sort-packages": true
43 | },
44 | "extra": {
45 | "laravel": {
46 | "providers": [
47 | "Sandulat\\LaravelDashboardTemplate\\LaravelDashboardTemplateServiceProvider"
48 | ],
49 | "aliases": {
50 | "LaravelDashboardTemplate": "Sandulat\\LaravelDashboardTemplate\\LaravelDashboardTemplateFacade"
51 | }
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "scripts": {
4 | "dev": "npm run development",
5 | "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
6 | "watch": "npm run development -- --watch",
7 | "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
8 | "prod": "npm run production",
9 | "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
10 | },
11 | "devDependencies": {
12 | "cross-env": "^5.2.0",
13 | "laravel-mix": "^4.0.15",
14 | "laravel-mix-purgecss": "^4.1.0",
15 | "sass": "^1.20.1",
16 | "sass-loader": "^7.1.0",
17 | "tailwindcss": "^1.0.2"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sandulat/laravel-dashboard-template/d88893211fa928d3d5fe40dcbf1cfc6742e50b40/public/favicon.ico
--------------------------------------------------------------------------------
/public/images/avatar.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/mix-manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "/laravel-dashboard-template.css": "/laravel-dashboard-template.css?id=9d096b9fa18afe0046b9"
3 | }
4 |
--------------------------------------------------------------------------------
/resources/sass/_tailwind.scss:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/resources/sass/app.scss:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css?family=Rubik:300,400,500,700&subset=cyrillic');
2 | @import 'tailwind';
3 |
--------------------------------------------------------------------------------
/resources/views/components/card.blade.php:
--------------------------------------------------------------------------------
1 |
2 | {{ config('app.name', 'Laravel') }} 3 |
-------------------------------------------------------------------------------- /resources/views/partials/topbar_profile_dropdown.blade.php: -------------------------------------------------------------------------------- 1 | @component('laravel-dashboard-template::components.dropdown', ['class' => $class ?? '']) 2 | @slot('activator') 3 | 4 | {{ $template->userName() }} 5 | @endslot 6 | 7 | @foreach($template->profileDropdownLinks() as $link) 8 | @component('laravel-dashboard-template::components.dropdown_item', $link) 9 | {{ $link['label'] }} 10 | @endcomponent 11 | @endforeach 12 | 13 | @if(auth()->check()) 14 | @component('laravel-dashboard-template::components.dropdown_item', ['onClick' => 'event.preventDefault(); document.getElementById("ldt-logout-form").submit();', 'id' => 'ldt-logout-button']) 15 | Logout 16 | @endcomponent 17 | 18 | 21 | @endif 22 | @endcomponent -------------------------------------------------------------------------------- /src/Console/InstallCommand.php: -------------------------------------------------------------------------------- 1 | comment('Publishing Dashboard Service Provider...'); 40 | $this->callSilent('vendor:publish', ['--tag' => 'laravel-dashboard-template-provider']); 41 | 42 | $this->comment('Publishing Dashboard Assets...'); 43 | $this->callSilent('vendor:publish', ['--tag' => 'laravel-dashboard-template-assets']); 44 | $this->registerDashboardServiceProvider(); 45 | 46 | $this->info('Dashboard scaffolding installed successfully.'); 47 | } 48 | 49 | /** 50 | * Register the dashboard service provider in the application configuration file. 51 | * 52 | * @return void 53 | */ 54 | protected function registerDashboardServiceProvider(): void 55 | { 56 | $namespace = str_replace_last('\\', '', $this->getAppNamespace()); 57 | 58 | $appConfig = file_get_contents(config_path('app.php')); 59 | 60 | if (Str::contains($appConfig, $namespace.'\\Providers\\DashboardServiceProvider::class')) { 61 | return; 62 | } 63 | 64 | $lineEndingCount = [ 65 | "\r\n" => substr_count($appConfig, "\r\n"), 66 | "\r" => substr_count($appConfig, "\r"), 67 | "\n" => substr_count($appConfig, "\n"), 68 | ]; 69 | 70 | $eol = array_keys($lineEndingCount, max($lineEndingCount))[0]; 71 | 72 | file_put_contents(config_path('app.php'), str_replace( 73 | "{$namespace}\\Providers\EventServiceProvider::class,".$eol, 74 | "{$namespace}\\Providers\EventServiceProvider::class,".$eol." {$namespace}\Providers\DashboardServiceProvider::class,".$eol, 75 | $appConfig 76 | )); 77 | 78 | file_put_contents(app_path('Providers/DashboardServiceProvider.php'), str_replace( 79 | "namespace App\Providers;", 80 | "namespace {$namespace}\Providers;", 81 | file_get_contents(app_path('Providers/DashboardServiceProvider.php')) 82 | )); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/Console/PublishCommand.php: -------------------------------------------------------------------------------- 1 | call('vendor:publish', [ 36 | '--tag' => 'laravel-dashboard-template-assets', 37 | '--force' => true, 38 | ]); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Http/Controllers/LogoutController.php: -------------------------------------------------------------------------------- 1 | logout(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Http/routes.php: -------------------------------------------------------------------------------- 1 | name('laravel-dashboard-template.logout'); 6 | -------------------------------------------------------------------------------- /src/LaravelDashboardTemplate.php: -------------------------------------------------------------------------------- 1 | name : 'Guest'; 149 | })(); 150 | } 151 | 152 | /** 153 | * Get the user avatar. 154 | * 155 | * @return string 156 | */ 157 | public function userAvatar(): string 158 | { 159 | return (static::$userAvatar ?? function () { 160 | return URL::asset('/vendor/laravel-dashboard-template/images/avatar.svg'); 161 | })(); 162 | } 163 | 164 | /** 165 | * Get the sidebar links. 166 | * 167 | * @return array 168 | */ 169 | public function sidebarLinks(): array 170 | { 171 | return (static::$sidebarLinks ?? function () { 172 | return [ 173 | 'Menu' => [ 174 | [ 175 | 'label' => 'Home', 176 | 'url' => '/', 177 | ], 178 | ], 179 | ]; 180 | })(); 181 | } 182 | 183 | /** 184 | * Get the profile dropdown links. 185 | * 186 | * @return array 187 | */ 188 | public function profileDropdownLinks(): array 189 | { 190 | return (static::$profileDropdownLinks ?? function () { 191 | return []; 192 | })(); 193 | } 194 | 195 | /** 196 | * Logout the user. 197 | * 198 | * @return \Illuminate\Http\RedirectResponse 199 | */ 200 | public function logout(): RedirectResponse 201 | { 202 | (static::$logout ?? function () { 203 | Auth::guard()->logout(); 204 | 205 | request()->session()->invalidate(); 206 | })(); 207 | 208 | $this->loggedOut(); 209 | 210 | return $this->logoutRedirect(); 211 | } 212 | 213 | /** 214 | * The user has logged out of the application. 215 | * 216 | * @return void 217 | */ 218 | public function loggedOut(): void 219 | { 220 | (static::$loggedOut ?? function () { 221 | // 222 | })(); 223 | } 224 | 225 | /** 226 | * Redirect after logout. 227 | * 228 | * @return \Illuminate\Http\RedirectResponse 229 | */ 230 | public function logoutRedirect(): RedirectResponse 231 | { 232 | return (static::$logoutRedirect ?? function () { 233 | return redirect('/'); 234 | })(); 235 | } 236 | } 237 | -------------------------------------------------------------------------------- /src/LaravelDashboardTemplateApplicationServiceProvider.php: -------------------------------------------------------------------------------- 1 | app->call([$this, $method]); 39 | }); 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/LaravelDashboardTemplateFacade.php: -------------------------------------------------------------------------------- 1 | registerRoutes(); 18 | 19 | $this->loadViewsFrom(__DIR__.'/../resources/views', 'laravel-dashboard-template'); 20 | 21 | if ($this->app->runningInConsole()) { 22 | $this->publishes([ 23 | __DIR__.'/../resources/views' => resource_path('views/vendor/laravel-dashboard-template'), 24 | ], 'laravel-dashboard-template-views'); 25 | 26 | $this->publishes([ 27 | __DIR__.'/../public' => public_path('vendor/laravel-dashboard-template'), 28 | ], 'laravel-dashboard-template-assets'); 29 | 30 | $this->publishes([ 31 | __DIR__.'/../stubs/LaravelDashboardTemplateServiceProvider.stub' => app_path('Providers/DashboardServiceProvider.php'), 32 | ], 'laravel-dashboard-template-provider'); 33 | } 34 | } 35 | 36 | /** 37 | * Register the application services. 38 | */ 39 | public function register(): void 40 | { 41 | $this->commands([ 42 | Console\InstallCommand::class, 43 | Console\PublishCommand::class, 44 | ]); 45 | 46 | $this->app->singleton('laravel-dashboard-template', function () { 47 | return new LaravelDashboardTemplate; 48 | }); 49 | } 50 | 51 | /** 52 | * Register the package routes. 53 | * 54 | * @return void 55 | */ 56 | private function registerRoutes(): void 57 | { 58 | Route::group($this->routeConfiguration(), function () { 59 | $this->loadRoutesFrom(__DIR__.'/Http/routes.php'); 60 | }); 61 | } 62 | 63 | /** 64 | * Get the main route group configuration array. 65 | * 66 | * @return array 67 | */ 68 | private function routeConfiguration(): array 69 | { 70 | return [ 71 | 'namespace' => 'Sandulat\LaravelDashboardTemplate\Http\Controllers', 72 | 'prefix' => 'laravel-dashboard-template', 73 | 'middleware' => 'web', 74 | ]; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /stubs/LaravelDashboardTemplateServiceProvider.stub: -------------------------------------------------------------------------------- 1 |