Admin One - Laravel Dashboard Preset (SPA)
vikdiesel/admin-one-laravel-dashboard is a Laravel package for admin one - laravel dashboard preset (spa).
It currently has 141 GitHub stars and 5.522 downloads on Packagist (latest version 1.5.1).
Install it with composer require vikdiesel/admin-one-laravel-dashboard.
Discover more Laravel packages by vikdiesel
or browse all Laravel packages to compare alternatives.
Last updated
This guide will help you integrate your Laravel Jetstream application with vikdiesel/admin-one-vue-bulma-dashboard Vue Bulma Buefy dashboard.
Please note: this document is work in progress, so some things are missing.
Simple, beautiful and free Vue.js 2.x Bulma Buefy admin dashboard for Laravel 9.x Jetstream Inertia + Vue stack
data, computed, methods, etc.cd to project dirresources/js folder to resources-temp/js. These js files will serve as a reference during development process (just in case, you'll ever need to extract some logic, that is missing here)npm remove @inertiajs/inertia-vue3 @vue/compiler-sfc @tailwindcss/forms @tailwindcss/typography postcss postcss-import tailwindcssnpm i vuex@^3 vue@^2 vue-loader@^15 @vue/composition-api @inertiajs/inertia-vue bulma buefy chart.js vue-chartjs numeral sass sass-loader -DReplace postCss() with sass() and app.scss with main.scss in webpack.mix.js:
mix.js('resources/js/app.js', 'public/js').vue()
.sass('resources/scss/main.scss', 'public/css')
.alias({
'@': 'resources/js',
})
Clone either vikdiesel/admin-one-vue-bulma-dashboard or vikdiesel/admin-two-vue-bulma-dashboard project locally into a separate folder
Next, copy these files from cloned dashboard project directory to laravel project directory:
src/components src/store src/menu.js to resources/js/src/App.vue and src/FullPage.vue to resources/Layouts/src/css and src/scss to resources/src/assets/justboil-logo.svg to resources/js/images/resources/css/app.cssresources directory from this repository to to laravel projectReplace app.css with main.css:
<!-- Styles -->
<link rel="stylesheet" href="{{ mix('css/main.css') }}">
Add before </body>:
<link href="https://cdn.materialdesignicons.com/4.9.95/css/materialdesignicons.min.css" rel="stylesheet" type="text/css">
Replace <router-view /> with <slot />
Add this.$store.dispatch('toggleFullPage', false) to created() lifecycle hook
Add this.$store.dispatch('toggleFullPage', true) to created() lifecycle hook
Remove beforeDestroy() lifecycle hook
Add import filter from 'lodash/filter'
Add filter() and replace this.$slots.default with slots in render() method, so you'll get:
render (createElement) {
const renderAncestor = elements => createElement(
// ...
)
const slots = filter(this.$slots.default, slot => !!slot.tag)
if (slots.length <= this.maxPerRow) {
return renderAncestor(slots)
} else {
return createElement(
'div',
{ attrs: { class: 'is-tiles-wrapper' } },
chunk(slots, this.maxPerRow).map(group => {
return renderAncestor(group)
})
)
}
}
Let's just add first page. You can repeat these steps for other pages, if you wish to. If you've followed previous steps, there's already resources/js/Pages/HomeExample.vue for your reference.
First, copy src/views/Home.vue (original dashboard project) to resources/js/Pages/ (your Laravel project).
Add Head. Then, wrap page contents into App Layout component:
<template>
<app>
<Head title="Dashboard" />
<title-bar :title-stack="titleStack" />
<!-- ... -->
</app>
</template>
<script>
import { Head } from '@inertiajs/inertia-vue'
import App from '@/Layouts/App.vue'
// ...
export default defineComponent({
name: 'Home',
components: {
Head,
App,
// ...
}
// ...
})
</script>
Add route in routes/web.php. There's a /dashboard route already defined by default, so just replace Inertia::render('Dashboard') with Inertia::render('Home'):
Route::get('/dashboard', function () {
return Inertia::render('Home');
})->name('dashboard');
Here we replace router-link with Inertia Link.
Optionally, you can pass menu via Inertia shared props, so it's going to be controlled with PHP. Here we'd just use JS.
to should be replaced with route which specifies route name defined in routes/web.php. For external links href should be used instead. Here's an example for menu.js:
export default [
'General',
[
{
route: 'dashboard',
icon: mdiDesktopMac,
label: 'Dashboard'
},
{
href: 'https://example.com/',
icon: mdiDesktopMac,
label: 'Example.com'
}
]
]
Route names reflect ones defined in routes/web.php:
Route::get('/dashboard', function () {
return Inertia::render('Home');
})->name('dashboard');
Now, let's update vue files, to make them work with route names and Inertia links.
Add Link import to <script>:
<script>
import { Link } from '@inertiajs/inertia-vue'
// ...
</script>
Replace componentIs in computed{} with:
<script>
export default defineComponent({
// ...
computed: {
componentIs () {
return this.item.route ? Link : 'a'
}
// ...
}
// ...
})
</script>
Replace <component> attrs with:
<template>
<component
:is="componentIs"
:href="item.route ? $route(item.route) : item.href"
:target="item.target"
:class="{ 'has-icon': !!item.icon, 'has-dropdown-icon': hasDropdown, 'is-active': item.route && $route().current(item.route) }"
@click="menuClick"
>
<!-- ... -->
</component>
</template>
Import and register Link component:
<script>
import { Link } from '@inertiajs/inertia-vue'
// ...
export default defineComponent({
components: {
Link
// ...
}
// ...
})
</script>
Replace <router-link> with <Link>:
<template>
<Link
:href="$route('dashboard')"
class="navbar-item"
:class="{ 'is-active': $route().current('dashboard') }"
>
<!-- ... -->
</Link>
</template>
Replace this.$router with Inertia:
<script>
import { Inertia } from '@inertiajs/inertia'
// ...
export default defineComponent({
// ...
mounted () {
Inertia.on('navigate', (event) => {
this.isMenuActive = false
})
}
// ...
})
</script>
Fix newAvatar computed property, so it fetches profile photo from backend:
<script>
export default defineComponent({
// ...
computed: {
newAvatar () {
return this.avatar ? this.avatar : this.$page.props.user.profile_photo_url
}
}
})
</script>
Update userName and logout:
<script>
export default defineComponent({
// ...
computed: {
// ...
userName () {
return this.$page.props.user.name
},
...mapState([
'isAsideMobileExpanded',
'isNavBarVisible',
// remove 'userName'
])
},
methods: {
// ...
logout () {
Inertia.post(route('logout'))
}
}
// ...
})
</script>
As mentioned, this guide is WIP - work in progress. Contributions open. Here's the list of what's missing right now:
If you're using an older version of Laravel, please follow Laravel 7.x & 8.x guide.