create dashboard layout
This commit is contained in:
30
resources/js/Components/DashboardLayout/Sidebar/Builder.vue
Normal file
30
resources/js/Components/DashboardLayout/Sidebar/Builder.vue
Normal file
@@ -0,0 +1,30 @@
|
||||
<script>
|
||||
import { defineComponent, h } from "vue"
|
||||
import Link from "./Link.vue"
|
||||
import Links from "./Links.vue"
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
menus: Array,
|
||||
},
|
||||
|
||||
setup(props, { attrs }) {
|
||||
return props => {
|
||||
const { menus } = props
|
||||
const generate = (menu, attrs = {}) => {
|
||||
if (menu.childs?.length > 0) {
|
||||
return h(Links, {
|
||||
...attrs,
|
||||
menu,
|
||||
childs: menu.childs,
|
||||
}, menu.childs.map(child => generate(child, { class: 'pl-8' })))
|
||||
}
|
||||
|
||||
return h(Link, { ...attrs, menu })
|
||||
}
|
||||
|
||||
return h('div', { class: 'flex flex-col' }, menus.map(menu => generate(menu)))
|
||||
}
|
||||
},
|
||||
})
|
||||
</script>
|
||||
23
resources/js/Components/DashboardLayout/Sidebar/Link.vue
Normal file
23
resources/js/Components/DashboardLayout/Sidebar/Link.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<script setup>
|
||||
import { getCurrentInstance } from 'vue'
|
||||
import { Link } from '@inertiajs/inertia-vue3'
|
||||
import Icon from '@/Components/Icon.vue'
|
||||
|
||||
const { menu } = defineProps({
|
||||
menu: Object,
|
||||
})
|
||||
|
||||
const active = route().current(menu.route_or_url)
|
||||
|
||||
if (route().has(menu.route_or_url))
|
||||
menu.route_or_url = route(menu.route_or_url)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Link :href="menu.route_or_url" class="w-full px-4 py-3" :class="`${themes().get('sidebar', 'bg-slate-700 text-gray-200')} ${active && 'bg-slate-800'}`">
|
||||
<div class="flex items-center space-x-2">
|
||||
<Icon :name="menu.icon" />
|
||||
<p class="uppercase font-semibold">{{ menu.name }}</p>
|
||||
</div>
|
||||
</Link>
|
||||
</template>
|
||||
41
resources/js/Components/DashboardLayout/Sidebar/Links.vue
Normal file
41
resources/js/Components/DashboardLayout/Sidebar/Links.vue
Normal file
@@ -0,0 +1,41 @@
|
||||
<script setup>
|
||||
import { getCurrentInstance, ref } from 'vue'
|
||||
import Icon from '@/Components/Icon.vue'
|
||||
|
||||
const { menu, childs } = defineProps({
|
||||
menu: Object,
|
||||
childs: Array,
|
||||
})
|
||||
|
||||
const trace = menu => {
|
||||
if (menu.childs?.length) {
|
||||
for (const child of menu.child) {
|
||||
if (trace(child)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return route().current(menu.route_or_url)
|
||||
}
|
||||
|
||||
const active = childs.find(trace)
|
||||
const self = getCurrentInstance()
|
||||
const open = ref(active ? true : false)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full flex flex-col">
|
||||
<button @click.prevent="open = ! open" class="w-full p-4" :class="`${themes().get('sidebar', 'bg-slate-700 text-gray-200')} ${open && 'dark:bg-gray-800'}`">
|
||||
<div class="flex items-center space-x-2">
|
||||
<Icon :name="menu.icon" />
|
||||
<p class="uppercase font-semibold w-full text-left">{{ menu.name }}</p>
|
||||
<Icon name="caret-left" class="transition-all ease-in-out duration-150" :class="open && '-rotate-90'" />
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<div v-if="open" class="flex flex-col">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user