feat: introducing shared requests to admin dashboard (#3537)
Co-authored-by: jamesgeorge007 <jamesgeorge998001@gmail.com>
This commit is contained in:
committed by
GitHub
parent
6fa722df7b
commit
d9c75ed79e
@@ -24,7 +24,7 @@
|
||||
class="text-secondary border-b border-dividerDark text-sm text-left bg-primaryLight"
|
||||
>
|
||||
<th class="px-6 py-2">{{ t('teams.id') }}</th>
|
||||
<th class="px-6 py-3">{{ t('teams.name') }}</th>
|
||||
<th class="px-6 py-2">{{ t('teams.name') }}</th>
|
||||
<th class="px-6 py-2">{{ t('teams.members') }}</th>
|
||||
<!-- Empty Heading for the Action Button -->
|
||||
<th class="px-6 py-2"></th>
|
||||
|
||||
@@ -1,123 +1,42 @@
|
||||
<template>
|
||||
<div v-if="fetching" class="flex justify-center"><HoppSmartSpinner /></div>
|
||||
<div v-else class="flex flex-col space-y-4">
|
||||
<div>
|
||||
<div class="flex gap-x-3">
|
||||
<button
|
||||
class="p-2 mb-2 rounded-3xl bg-divider"
|
||||
@click="router.push('/users')"
|
||||
>
|
||||
<icon-lucide-arrow-left class="text-xl" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="rounded-md">
|
||||
<div class="grid gap-6 mt-4">
|
||||
<div v-if="user.photoURL" class="relative h-20 w-20">
|
||||
<img class="object-cover rounded-3xl mb-3" :src="user.photoURL" />
|
||||
<span
|
||||
v-if="user.isAdmin"
|
||||
class="absolute left-16 bottom-0 text-xs font-medium px-3 py-0.5 rounded-full bg-green-900 text-green-300"
|
||||
>
|
||||
{{ t('users.admin') }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div v-else class="bg-primaryDark w-16 p-3 rounded-2xl mb-3 relative">
|
||||
<icon-lucide-user class="text-4xl" />
|
||||
<span
|
||||
v-if="user.isAdmin"
|
||||
class="absolute left-16 bottom-0 text-xs font-medium px-3 py-0.5 rounded-full bg-green-900 text-green-300"
|
||||
>
|
||||
{{ t('users.admin') }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div v-if="user.uid">
|
||||
<label class="text-secondaryDark" for="username">{{
|
||||
t('users.uid')
|
||||
}}</label>
|
||||
<div
|
||||
class="w-full p-3 mt-2 bg-divider border-gray-600 rounded-md focus:border-emerald-600 focus:ring focus:ring-opacity-40 focus:ring-emerald-500"
|
||||
>
|
||||
{{ user.uid }}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<label class="text-secondaryDark" for="username">{{
|
||||
t('users.name')
|
||||
}}</label>
|
||||
<div
|
||||
class="w-full p-3 mt-2 bg-divider border-gray-600 rounded-md focus:border-emerald-600 focus:ring focus:ring-opacity-40 focus:ring-emerald-500"
|
||||
>
|
||||
<span v-if="user.displayName">
|
||||
{{ user.displayName }}
|
||||
</span>
|
||||
<span v-else> {{ t('users.unnamed') }} </span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="user.email">
|
||||
<label class="text-secondaryDark" for="username">{{
|
||||
t('users.email')
|
||||
}}</label>
|
||||
<div
|
||||
class="w-full p-3 mt-2 bg-divider border-gray-600 rounded-md focus:border-emerald-600 focus:ring focus:ring-opacity-40 focus:ring-emerald-500"
|
||||
>
|
||||
{{ user.email }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="user.createdOn">
|
||||
<label class="text-secondaryDark" for="username">{{
|
||||
t('users.created_on')
|
||||
}}</label>
|
||||
<div
|
||||
class="w-full p-3 mt-2 bg-divider border-gray-600 rounded-md focus:border-emerald-600 focus:ring focus:ring-opacity-40 focus:ring-emerald-500"
|
||||
>
|
||||
{{ getCreatedDateAndTime(user.createdOn) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-start mt-8">
|
||||
<span v-if="!user.isAdmin">
|
||||
<HoppButtonPrimary
|
||||
class="mr-4"
|
||||
filled
|
||||
outline
|
||||
:label="t('users.make_admin')"
|
||||
@click="makeUserAdmin(user.uid)"
|
||||
/>
|
||||
</span>
|
||||
<span v-else>
|
||||
<HoppButtonPrimary
|
||||
class="mr-4"
|
||||
filled
|
||||
outline
|
||||
:icon="IconUserMinus"
|
||||
:label="t('users.remove_admin_privilege')"
|
||||
@click="makeAdminToUser(user.uid)"
|
||||
/>
|
||||
</span>
|
||||
<HoppButtonSecondary
|
||||
v-if="!user.isAdmin"
|
||||
class="mr-4 bg-red-600 text-white hover:text-gray-100"
|
||||
filled
|
||||
outline
|
||||
:label="t('users.delete')"
|
||||
:icon="IconTrash"
|
||||
@click="deleteUser(user.uid)"
|
||||
/>
|
||||
|
||||
<HoppButtonSecondary
|
||||
v-if="user.isAdmin"
|
||||
class="mr-4 bg-red-600 text-white hover:text-gray-100"
|
||||
filled
|
||||
outline
|
||||
:icon="IconTrash"
|
||||
:label="t('users.delete')"
|
||||
@click="toast.error(t('state.remove_admin_to_delete_user'))"
|
||||
/>
|
||||
<div class="flex items-center space-x-3">
|
||||
<h1 class="text-lg text-accentContrast">
|
||||
{{ user.displayName }}
|
||||
</h1>
|
||||
<span>/</span>
|
||||
<h2 class="text-lg text-accentContrast">
|
||||
{{ currentTabName }}
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="pb-8">
|
||||
<HoppSmartTabs v-model="selectedOptionTab" render-inactive-tabs>
|
||||
<HoppSmartTab :id="'details'" :label="t('users.details')">
|
||||
<UsersDetails
|
||||
:user="user"
|
||||
@delete-user="deleteUser"
|
||||
@make-admin="makeUserAdmin"
|
||||
@remove-admin="makeAdminToUser"
|
||||
class="py-8 px-4"
|
||||
/>
|
||||
</HoppSmartTab>
|
||||
<HoppSmartTab :id="'requests'" :label="t('shared_requests.title')">
|
||||
<UsersSharedRequests :email="user.email" class="py-8 px-4 mt-10" />
|
||||
</HoppSmartTab>
|
||||
</HoppSmartTabs>
|
||||
</div>
|
||||
|
||||
<HoppSmartConfirmModal
|
||||
:show="confirmDeletion"
|
||||
:title="t('users.confirm_user_deletion')"
|
||||
@@ -140,29 +59,37 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { onMounted, ref, computed } from 'vue';
|
||||
import { useMutation } from '@urql/vue';
|
||||
import {
|
||||
MakeUserAdminDocument,
|
||||
UserInfoDocument,
|
||||
RemoveUserByAdminDocument,
|
||||
RemoveUserAsAdminDocument,
|
||||
} from '../../helpers/backend/graphql';
|
||||
} from '~/helpers/backend/graphql';
|
||||
import { useClientHandle } from '@urql/vue';
|
||||
import { format } from 'date-fns';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { useToast } from '~/composables/toast';
|
||||
import IconTrash from '~icons/lucide/trash';
|
||||
import IconUserMinus from '~icons/lucide/user-minus';
|
||||
import { useI18n } from '~/composables/i18n';
|
||||
|
||||
const t = useI18n();
|
||||
|
||||
const toast = useToast();
|
||||
|
||||
// Get Proper Date Formats
|
||||
const getCreatedDateAndTime = (date: string) =>
|
||||
format(new Date(date), 'd-MM-yyyy hh:mm a');
|
||||
// Tabs
|
||||
type OptionTabs = 'details' | 'requests';
|
||||
const selectedOptionTab = ref<OptionTabs>('details');
|
||||
|
||||
const currentTabName = computed(() => {
|
||||
switch (selectedOptionTab.value) {
|
||||
case 'details':
|
||||
return t('users.details');
|
||||
case 'requests':
|
||||
return t('shared_requests.title');
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
});
|
||||
|
||||
// Get User Info
|
||||
const user = ref();
|
||||
|
||||
Reference in New Issue
Block a user