Admin navigation permissions
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import pool from '../db';
|
||||
import { Role } from '@app/shared/types/roles'
|
||||
|
||||
export async function assignUserGroup(userID: number, roleID: number) {
|
||||
|
||||
@@ -16,7 +17,7 @@ export async function createGroup(name: string, color: string, description: stri
|
||||
return { id: result.insertId, name, color, description };
|
||||
}
|
||||
|
||||
export async function getUserRoles(userID: number) {
|
||||
export async function getUserRoles(userID: number): Promise<Role[]> {
|
||||
const sql = `SELECT r.id, r.name
|
||||
FROM members_roles mr
|
||||
INNER JOIN roles r ON mr.role_id = r.id
|
||||
|
||||
6
shared/types/roles.ts
Normal file
6
shared/types/roles.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
export interface Role {
|
||||
id: number;
|
||||
name: string;
|
||||
color?: string;
|
||||
description?: string;
|
||||
}
|
||||
@@ -17,8 +17,11 @@ import NavigationMenuLink from '../ui/navigation-menu/NavigationMenuLink.vue';
|
||||
import NavigationMenuTrigger from '../ui/navigation-menu/NavigationMenuTrigger.vue';
|
||||
import NavigationMenuContent from '../ui/navigation-menu/NavigationMenuContent.vue';
|
||||
import { navigationMenuTriggerStyle } from '../ui/navigation-menu/'
|
||||
import { useAuth } from '@/composables/useAuth';
|
||||
import { CircleArrowOutUpRight } from 'lucide-vue-next';
|
||||
|
||||
const userStore = useUserStore();
|
||||
const auth = useAuth();
|
||||
|
||||
//@ts-ignore
|
||||
const APIHOST = import.meta.env.VITE_APIHOST;
|
||||
@@ -88,50 +91,57 @@ function blurAfter() {
|
||||
</NavigationMenuItem>
|
||||
|
||||
<!-- Administration (Dropdown) -->
|
||||
<NavigationMenuItem>
|
||||
<NavigationMenuItem v-if="auth.hasAnyRole(['17th Administrator', '17th HQ', '17th Command', 'Recruiter'])">
|
||||
<NavigationMenuTrigger>Administration</NavigationMenuTrigger>
|
||||
<NavigationMenuContent
|
||||
class="grid gap-1 p-2 text-left [&_a]:w-full [&_a]:block [&_a]:whitespace-nowrap *:bg-transparent">
|
||||
|
||||
<NavigationMenuLink as-child :class="navigationMenuTriggerStyle()">
|
||||
<NavigationMenuLink
|
||||
v-if="auth.hasAnyRole(['17th Administrator', '17th HQ', '17th Command'])"
|
||||
as-child :class="navigationMenuTriggerStyle()">
|
||||
<RouterLink to="/administration/rankChange" @click="blurAfter">
|
||||
Promotions
|
||||
</RouterLink>
|
||||
</NavigationMenuLink>
|
||||
|
||||
<NavigationMenuLink as-child :class="navigationMenuTriggerStyle()">
|
||||
<NavigationMenuLink
|
||||
v-if="auth.hasAnyRole(['17th Administrator', '17th HQ', '17th Command'])"
|
||||
as-child :class="navigationMenuTriggerStyle()">
|
||||
<RouterLink to="/administration/loa" @click="blurAfter">
|
||||
Leave of Absence
|
||||
</RouterLink>
|
||||
</NavigationMenuLink>
|
||||
|
||||
<NavigationMenuLink as-child :class="navigationMenuTriggerStyle()">
|
||||
<NavigationMenuLink
|
||||
v-if="auth.hasAnyRole(['17th Administrator', '17th HQ', '17th Command'])"
|
||||
as-child :class="navigationMenuTriggerStyle()">
|
||||
<RouterLink to="/administration/transfer" @click="blurAfter">
|
||||
Transfer Requests
|
||||
</RouterLink>
|
||||
</NavigationMenuLink>
|
||||
|
||||
<NavigationMenuLink as-child :class="navigationMenuTriggerStyle()">
|
||||
<NavigationMenuLink v-if="auth.hasRole('Recruiter')" as-child
|
||||
:class="navigationMenuTriggerStyle()">
|
||||
<RouterLink to="/administration/applications" @click="blurAfter">
|
||||
Recruitment
|
||||
</RouterLink>
|
||||
</NavigationMenuLink>
|
||||
|
||||
<NavigationMenuLink as-child :class="navigationMenuTriggerStyle()">
|
||||
<NavigationMenuLink v-if="auth.hasRole('17th Administrator')" as-child
|
||||
:class="navigationMenuTriggerStyle()">
|
||||
<RouterLink to="/administration/roles" @click="blurAfter">
|
||||
Role Management
|
||||
</RouterLink>
|
||||
</NavigationMenuLink>
|
||||
|
||||
<NavigationMenuLink as-child :class="navigationMenuTriggerStyle()">
|
||||
<RouterLink to="/members" @click="blurAfter">
|
||||
Members (debug)
|
||||
</RouterLink>
|
||||
</NavigationMenuLink>
|
||||
|
||||
</NavigationMenuContent>
|
||||
</NavigationMenuItem>
|
||||
|
||||
<NavigationMenuItem as-child :class="navigationMenuTriggerStyle()">
|
||||
<RouterLink to="/members" @click="blurAfter">
|
||||
Members (debug)
|
||||
</RouterLink>
|
||||
</NavigationMenuItem>
|
||||
|
||||
</NavigationMenuList>
|
||||
</NavigationMenu>
|
||||
</div>
|
||||
|
||||
32
ui/src/composables/useAuth.ts
Normal file
32
ui/src/composables/useAuth.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { useUserStore } from "@/stores/user"
|
||||
import { computed } from "vue";
|
||||
import { Role } from "@shared/types/roles"
|
||||
|
||||
export function useAuth() {
|
||||
const userStore = useUserStore();
|
||||
|
||||
const roles = computed<string[]>(() => {
|
||||
return userStore.user?.roleData?.map((r: Role) => r.name) ?? [];
|
||||
});
|
||||
|
||||
function isDev() {
|
||||
return roles.value.includes('Dev');
|
||||
}
|
||||
|
||||
function hasRole(roleName: string): boolean {
|
||||
if (isDev()) return true;
|
||||
return roles.value.includes(roleName);
|
||||
}
|
||||
|
||||
function hasAnyRole(roleNames: string[]): boolean {
|
||||
if (isDev()) return true;
|
||||
return roles.value.some(name => roleNames.includes(name))
|
||||
}
|
||||
|
||||
function hasAllRoles(roleNames: string[]): boolean {
|
||||
if (isDev()) return true;
|
||||
return roles.value.every(name => roleNames.includes(name))
|
||||
}
|
||||
|
||||
return { hasRole, hasAnyRole, hasAllRoles }
|
||||
}
|
||||
@@ -16,6 +16,7 @@ export const useUserStore = defineStore('user', () => {
|
||||
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
console.log(data);
|
||||
user.value = data;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user