refactor: consolidated admin dashboard improvements (#3790)
Co-authored-by: jamesgeorge007 <jamesgeorge998001@gmail.com>
This commit is contained in:
committed by
GitHub
parent
aab76f1358
commit
3d6adcc39d
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="rounded-md">
|
||||
<div class="grid gap-6 mt-4">
|
||||
<div class="grid gap-6">
|
||||
<div
|
||||
class="relative"
|
||||
:class="
|
||||
@@ -71,18 +71,14 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { format } from 'date-fns';
|
||||
|
||||
import { useI18n } from '~/composables/i18n';
|
||||
import { useToast } from '~/composables/toast';
|
||||
|
||||
import { UserInfoQuery } from '~/helpers/backend/graphql';
|
||||
import IconTrash from '~icons/lucide/trash';
|
||||
import IconUserCheck from '~icons/lucide/user-check';
|
||||
import IconUserMinus from '~icons/lucide/user-minus';
|
||||
|
||||
import { UserInfoQuery } from '~/helpers/backend/graphql';
|
||||
|
||||
const t = useI18n();
|
||||
|
||||
const toast = useToast();
|
||||
|
||||
const props = defineProps<{
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
v-if="show"
|
||||
dialog
|
||||
:title="t('users.invite_user')"
|
||||
@close="$emit('hide-modal')"
|
||||
@close="emit('hide-modal')"
|
||||
>
|
||||
<template #body>
|
||||
<HoppSmartInput
|
||||
@@ -16,7 +16,6 @@
|
||||
<span class="flex space-x-2">
|
||||
<HoppButtonPrimary
|
||||
:label="t('users.send_invite')"
|
||||
:loading="loadingState"
|
||||
@click="sendInvite"
|
||||
/>
|
||||
<HoppButtonSecondary label="Cancel" outline filled @click="hideModal" />
|
||||
@@ -27,21 +26,18 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { useToast } from '~/composables/toast';
|
||||
import { useI18n } from '~/composables/i18n';
|
||||
import { useToast } from '~/composables/toast';
|
||||
|
||||
const t = useI18n();
|
||||
|
||||
const toast = useToast();
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
show: boolean;
|
||||
loadingState: boolean;
|
||||
}>(),
|
||||
{
|
||||
show: false,
|
||||
loadingState: false,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -54,7 +50,7 @@ const email = ref('');
|
||||
|
||||
const sendInvite = () => {
|
||||
if (email.value.trim() === '') {
|
||||
toast.error(`${t('users.valid_email')}`);
|
||||
toast.error(t('users.valid_email'));
|
||||
return;
|
||||
}
|
||||
emit('send-invite', email.value);
|
||||
|
||||
@@ -1,116 +1,116 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="px-4">
|
||||
<div v-if="fetching" class="flex justify-center">
|
||||
<HoppSmartSpinner />
|
||||
</div>
|
||||
|
||||
<div v-else-if="error">{{ t('shared_requests.load_list_error') }}</div>
|
||||
|
||||
<div v-else-if="sharedRequests.length === 0" class="ml-3 mt-5 text-lg">
|
||||
<div v-else-if="sharedRequests.length === 0" class="mt-5">
|
||||
{{ t('users.no_shared_requests') }}
|
||||
</div>
|
||||
|
||||
<div v-else class="mt-10">
|
||||
<HoppSmartTable :list="sharedRequests">
|
||||
<template #head>
|
||||
<tr
|
||||
class="text-secondary border-b border-dividerDark text-sm text-left bg-primaryLight"
|
||||
>
|
||||
<th class="px-6 py-2">{{ t('shared_requests.id') }}</th>
|
||||
<th class="px-6 py-2 w-30">{{ t('shared_requests.url') }}</th>
|
||||
<th class="px-6 py-2">{{ t('shared_requests.created_on') }}</th>
|
||||
<!-- Empty Heading for the Action Button -->
|
||||
<th class="px-6 py-2 text-center">Actions</th>
|
||||
</tr>
|
||||
</template>
|
||||
<template #body="{ list: sharedRequests }">
|
||||
<tr
|
||||
v-for="request in sharedRequests"
|
||||
:key="request.id"
|
||||
class="text-secondaryDark hover:bg-divider hover:cursor-pointer rounded-xl"
|
||||
>
|
||||
<td class="flex py-4 px-7 max-w-50">
|
||||
<span class="truncate">
|
||||
{{ request.id }}
|
||||
</span>
|
||||
</td>
|
||||
<HoppSmartTable v-else class="mt-8" :list="sharedRequests">
|
||||
<template #head>
|
||||
<tr
|
||||
class="text-secondary border-b border-dividerDark text-sm text-left bg-primaryLight"
|
||||
>
|
||||
<th class="px-6 py-2">{{ t('shared_requests.id') }}</th>
|
||||
<th class="px-6 py-2 w-30">{{ t('shared_requests.url') }}</th>
|
||||
<th class="px-6 py-2">{{ t('shared_requests.created_on') }}</th>
|
||||
<!-- Empty Heading for the Action Button -->
|
||||
<th class="px-6 py-2 text-center">
|
||||
{{ t('shared_requests.action') }}
|
||||
</th>
|
||||
</tr>
|
||||
</template>
|
||||
<template #body="{ list: sharedRequests }">
|
||||
<tr
|
||||
v-for="request in sharedRequests"
|
||||
:key="request.id"
|
||||
class="text-secondaryDark hover:bg-divider hover:cursor-pointer rounded-xl"
|
||||
>
|
||||
<td class="flex py-4 px-7 max-w-50">
|
||||
<span class="truncate">
|
||||
{{ request.id }}
|
||||
</span>
|
||||
</td>
|
||||
|
||||
<td class="py-4 px-7 w-96">
|
||||
{{ sharedRequestURL(request.request) }}
|
||||
</td>
|
||||
<td class="py-4 px-7 w-96">
|
||||
{{ sharedRequestURL(request.request) }}
|
||||
</td>
|
||||
|
||||
<td class="py-2 px-7">
|
||||
{{ getCreatedDate(request.createdOn) }}
|
||||
<div class="text-gray-400 text-tiny">
|
||||
{{ getCreatedTime(request.createdOn) }}
|
||||
</div>
|
||||
</td>
|
||||
<td class="py-2 px-7">
|
||||
{{ getCreatedDate(request.createdOn) }}
|
||||
<div class="text-gray-400 text-tiny">
|
||||
{{ getCreatedTime(request.createdOn) }}
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td class="flex justify-center">
|
||||
<HoppButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('shared_requests.open_request')"
|
||||
:to="`${shortcodeBaseURL}/r/${request.id}`"
|
||||
:blank="true"
|
||||
:icon="IconExternalLink"
|
||||
class="px-3 text-emerald-500 hover:text-accent"
|
||||
/>
|
||||
<td class="flex justify-center">
|
||||
<HoppButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('shared_requests.open_request')"
|
||||
:to="`${shortcodeBaseURL}/r/${request.id}`"
|
||||
:blank="true"
|
||||
:icon="IconExternalLink"
|
||||
class="px-3 text-emerald-500 hover:text-accent"
|
||||
/>
|
||||
|
||||
<UiAutoResetIcon
|
||||
:title="t('shared_requests.copy')"
|
||||
:icon="{ default: IconCopy, temporary: IconCheck }"
|
||||
@click="copySharedRequest(request.id)"
|
||||
/>
|
||||
<UiAutoResetIcon
|
||||
:title="t('shared_requests.copy')"
|
||||
:icon="{ default: IconCopy, temporary: IconCheck }"
|
||||
@click="copySharedRequest(request.id)"
|
||||
/>
|
||||
|
||||
<HoppButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('shared_requests.delete')"
|
||||
:icon="IconTrash"
|
||||
color="red"
|
||||
class="px-3"
|
||||
@click="deleteSharedRequest(request.id)"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</HoppSmartTable>
|
||||
<HoppButtonSecondary
|
||||
v-tippy="{ theme: 'tooltip' }"
|
||||
:title="t('shared_requests.delete')"
|
||||
:icon="IconTrash"
|
||||
color="red"
|
||||
class="px-3"
|
||||
@click="deleteSharedRequest(request.id)"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
</HoppSmartTable>
|
||||
|
||||
<!-- Pagination -->
|
||||
<div
|
||||
v-if="hasNextPage && sharedRequests.length >= sharedRequestsPerPage"
|
||||
class="flex items-center w-28 px-3 py-2 mt-5 mx-auto font-semibold text-secondaryDark bg-divider hover:bg-dividerDark rounded-3xl cursor-pointer"
|
||||
@click="fetchNextSharedRequests"
|
||||
>
|
||||
<span class="mr-2">{{ t('shared_requests.show_more') }}</span>
|
||||
<icon-lucide-chevron-down />
|
||||
</div>
|
||||
<!-- Pagination -->
|
||||
<div
|
||||
v-if="hasNextPage && sharedRequests.length >= sharedRequestsPerPage"
|
||||
class="flex items-center w-28 px-3 py-2 mt-5 mx-auto font-semibold text-secondaryDark bg-divider hover:bg-dividerDark rounded-3xl cursor-pointer"
|
||||
@click="fetchNextSharedRequests"
|
||||
>
|
||||
<span class="mr-2">{{ t('shared_requests.show_more') }}</span>
|
||||
<icon-lucide-chevron-down />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<HoppSmartConfirmModal
|
||||
:show="confirmDeletion"
|
||||
:title="t('shared_requests.confirm_request_deletion')"
|
||||
@hide-modal="confirmDeletion = false"
|
||||
@resolve="deleteSharedRequestMutation(deleteSharedRequestID)"
|
||||
/>
|
||||
<HoppSmartConfirmModal
|
||||
:show="confirmDeletion"
|
||||
:title="t('shared_requests.confirm_request_deletion')"
|
||||
@hide-modal="confirmDeletion = false"
|
||||
@resolve="deleteSharedRequestMutation(deleteSharedRequestID)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useMutation } from '@urql/vue';
|
||||
import { format } from 'date-fns';
|
||||
import { ref } from 'vue';
|
||||
import { useMutation } from '@urql/vue';
|
||||
import {
|
||||
SharedRequestsDocument,
|
||||
RevokeShortcodeByAdminDocument,
|
||||
} from '../../helpers/backend/graphql';
|
||||
import { usePagedQuery } from '~/composables/usePagedQuery';
|
||||
import { useToast } from '~/composables/toast';
|
||||
import { useI18n } from '~/composables/i18n';
|
||||
import { useToast } from '~/composables/toast';
|
||||
import { usePagedQuery } from '~/composables/usePagedQuery';
|
||||
import { copyToClipboard } from '~/helpers/utils/clipboard';
|
||||
import IconTrash from '~icons/lucide/trash';
|
||||
import IconCopy from '~icons/lucide/copy';
|
||||
import IconCheck from '~icons/lucide/check';
|
||||
import IconCopy from '~icons/lucide/copy';
|
||||
import IconExternalLink from '~icons/lucide/external-link';
|
||||
import IconTrash from '~icons/lucide/trash';
|
||||
import {
|
||||
RevokeShortcodeByAdminDocument,
|
||||
SharedRequestsDocument,
|
||||
} from '~/helpers/backend/graphql';
|
||||
|
||||
const t = useI18n();
|
||||
const toast = useToast();
|
||||
@@ -154,7 +154,7 @@ const shortcodeBaseURL =
|
||||
// Copy Shared Request to Clipboard
|
||||
const copySharedRequest = (requestID: string) => {
|
||||
copyToClipboard(`${shortcodeBaseURL}/r/${requestID}`);
|
||||
toast.success(`${t('state.copied_to_clipboard')}`);
|
||||
toast.success(t('state.copied_to_clipboard'));
|
||||
};
|
||||
|
||||
// Shared Request Deletion
|
||||
@@ -170,19 +170,19 @@ const deleteSharedRequest = (id: string) => {
|
||||
const deleteSharedRequestMutation = async (id: string | null) => {
|
||||
if (!id) {
|
||||
confirmDeletion.value = false;
|
||||
toast.error(`${t('state.delete_request_failure')}`);
|
||||
toast.error(t('state.delete_request_failure'));
|
||||
return;
|
||||
}
|
||||
const variables = { codeID: id };
|
||||
await sharedRequestDeletion.executeMutation(variables).then((result) => {
|
||||
if (result.error) {
|
||||
toast.error(`${t('state.delete_request_failure')}`);
|
||||
toast.error(t('state.delete_request_failure'));
|
||||
} else {
|
||||
sharedRequests.value = sharedRequests.value.filter(
|
||||
(request) => request.id !== id
|
||||
);
|
||||
refetch();
|
||||
toast.success(`${t('state.delete_request_success')}`);
|
||||
toast.success(t('state.delete_request_success'));
|
||||
}
|
||||
});
|
||||
confirmDeletion.value = false;
|
||||
|
||||
Reference in New Issue
Block a user