Skip to content

Commit 7735003

Browse files
committed
Create AppLayout for authorized users
1 parent a69cc13 commit 7735003

File tree

4 files changed

+150
-10
lines changed

4 files changed

+150
-10
lines changed

Diff for: backend/index.html

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<title>Vite App</title>
88
</head>
99
<body class="h-full">
10-
<div id="app"></div>
10+
<div id="app" class="h-full"></div>
1111
<script type="module" src="/src/main.js"></script>
1212
</body>
1313
</html>

Diff for: backend/src/components/AppLayout.vue

+25-9
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,34 @@
11
<template>
2-
<div class="min-h-full flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
3-
<div class="max-w-md w-full space-y-8">
4-
<div>
5-
Part of the layout
6-
</div>
7-
<router-view></router-view>
2+
<div class="min-h-full bg-gray-200 flex">
3+
<!-- Sidebar-->
4+
<Sidebar :class="{'-ml-[200px]': !sidebarOpened}"/>
5+
<!--/ Sidebar-->
6+
7+
<div class="flex-1">
8+
<TopHeader @toggle-sidebar="toggleSidebar"></TopHeader>
9+
<!-- Content-->
10+
<main class="p-6">
11+
<router-view></router-view>
12+
</main>
13+
<!-- Content-->
814
</div>
915
</div>
1016
</template>
1117

1218
<script setup>
13-
const {title} = defineProps({
14-
title: String
15-
})
19+
import {ref} from 'vue'
20+
import Sidebar from "./Sidebar.vue";
21+
import TopHeader from "./TopHeader.vue";
22+
23+
const {title} = defineProps({
24+
title: String
25+
})
26+
27+
const sidebarOpened = ref(true);
28+
29+
function toggleSidebar() {
30+
sidebarOpened.value = !sidebarOpened.value
31+
}
1632
</script>
1733

1834
<style scoped>

Diff for: backend/src/components/Sidebar.vue

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<template>
2+
<div class="w-[200px] transition-all bg-indigo-700 text-white py-4 px-2">
3+
<router-link :to="{name: 'app.dashboard'}"
4+
class="flex items-center p-2 rounded transition-colors hover:bg-black/30">
5+
<span class="mr-2 text-gray-300">
6+
<HomeIcon class="w-5"/>
7+
</span>
8+
<span class="text-xs">
9+
Dashboard
10+
</span>
11+
</router-link>
12+
<router-link :to="{name: 'app.products'}"
13+
class="flex items-center p-2 rounded transition-colors hover:bg-black/30">
14+
<span class="mr-2 text-gray-300">
15+
<ViewListIcon class="w-5"/>
16+
</span>
17+
<span class="text-xs">
18+
Products
19+
</span>
20+
</router-link>
21+
<router-link :to="{name: 'app.dashboard'}"
22+
class="flex items-center p-2 rounded transition-colors hover:bg-black/30">
23+
<span class="mr-2 text-gray-300">
24+
<UsersIcon class="w-5"/>
25+
</span>
26+
<span class="text-xs">
27+
Users
28+
</span>
29+
</router-link>
30+
<router-link :to="{name: 'app.dashboard'}"
31+
class="flex items-center p-2 rounded transition-colors hover:bg-black/30">
32+
<span class="mr-2 text-gray-300">
33+
<ChartBarIcon class="w-5"/>
34+
</span>
35+
<span class="text-xs">
36+
Reports
37+
</span>
38+
</router-link>
39+
</div>
40+
</template>
41+
42+
<script setup>
43+
import {HomeIcon, UsersIcon, ViewListIcon, ChartBarIcon} from '@heroicons/vue/outline'
44+
</script>
45+
46+
<style scoped>
47+
48+
</style>

Diff for: backend/src/components/TopHeader.vue

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<template>
2+
<header class="flex justify-between items-center p-3 h-14 shadow bg-white">
3+
<button @click="emit('toggle-sidebar')" class="flex items-center justify-center rounded transition-colors w-8 h-8 text-gray-700 hover:bg-black/10">
4+
<MenuIcon class="w-6"/>
5+
</button>
6+
<Menu as="div" class="relative inline-block text-left">
7+
<MenuButton class="flex items-center">
8+
<img src="https://randomuser.me/api/portraits/men/1.jpg" class="rounded-full w-8 mr-2">
9+
<small>John Smith</small>
10+
<ChevronDownIcon
11+
class="h-5 w-5 text-violet-200 hover:text-violet-100"
12+
aria-hidden="true"
13+
/>
14+
</MenuButton>
15+
16+
<transition
17+
enter-active-class="transition duration-100 ease-out"
18+
enter-from-class="transform scale-95 opacity-0"
19+
enter-to-class="transform scale-100 opacity-100"
20+
leave-active-class="transition duration-75 ease-in"
21+
leave-from-class="transform scale-100 opacity-100"
22+
leave-to-class="transform scale-95 opacity-0"
23+
>
24+
<MenuItems
25+
class="absolute right-0 mt-2 w-36 origin-top-right divide-y divide-gray-100 rounded-md bg-white shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none"
26+
>
27+
<div class="px-1 py-1">
28+
<MenuItem v-slot="{ active }">
29+
<button
30+
:class="[
31+
active ? 'bg-violet-500 text-white' : 'text-gray-900',
32+
'group flex w-full items-center rounded-md px-2 py-2 text-sm',
33+
]"
34+
>
35+
<UserIcon
36+
:active="active"
37+
class="mr-2 h-5 w-5 text-violet-400"
38+
aria-hidden="true"
39+
/>
40+
Profile
41+
</button>
42+
</MenuItem>
43+
<MenuItem v-slot="{ active }">
44+
<button
45+
:class="[
46+
active ? 'bg-violet-500 text-white' : 'text-gray-900',
47+
'group flex w-full items-center rounded-md px-2 py-2 text-sm',
48+
]"
49+
>
50+
<LogoutIcon
51+
:active="active"
52+
class="mr-2 h-5 w-5 text-violet-400"
53+
aria-hidden="true"
54+
/>
55+
Logout
56+
</button>
57+
</MenuItem>
58+
</div>
59+
</MenuItems>
60+
</transition>
61+
</Menu>
62+
</header>
63+
</template>
64+
65+
<script setup>
66+
import {MenuIcon, LogoutIcon, UserIcon} from '@heroicons/vue/outline'
67+
import {Menu, MenuButton, MenuItems, MenuItem} from '@headlessui/vue'
68+
import {ChevronDownIcon} from '@heroicons/vue/solid'
69+
70+
const emit = defineEmits(['toggle-sidebar'])
71+
72+
</script>
73+
74+
<style scoped>
75+
76+
</style>

0 commit comments

Comments
 (0)