mirror of
https://github.com/HangarMC/Hangar.git
synced 2024-12-21 06:51:19 +08:00
allow locking users
This commit is contained in:
parent
80d0fde4cb
commit
0f8aa2be1b
@ -32,7 +32,7 @@ const canEditCurrentUser = computed<boolean>(() => {
|
||||
|
||||
<template>
|
||||
<Card accent>
|
||||
<div class="flex mb-4">
|
||||
<div class="flex mb-4 md:mb-0">
|
||||
<div class="relative">
|
||||
<UserAvatar :username="user.name" :avatar-url="avatarUrl(user.name)" />
|
||||
<AvatarChangeModal v-if="user.isOrganization && hasPerms(NamedPermission.EDIT_SUBJECT_SETTINGS)" :user="user" />
|
||||
@ -41,9 +41,12 @@ const canEditCurrentUser = computed<boolean>(() => {
|
||||
<div class="ml-2 overflow-clip">
|
||||
<h1 class="text-2xl text-strong inline-flex items-center">
|
||||
{{ user.name }}
|
||||
<a v-if="!user.isOrganization" class="inline-flex mx-1" :href="forumUserUrl(user.name)" :title="i18n.t('author.viewOnForums')"
|
||||
><IconMdiOpenInNew
|
||||
/></a>
|
||||
<a v-if="!user.isOrganization" class="inline-flex mx-1" :href="forumUserUrl(user.name)" :title="i18n.t('author.viewOnForums')">
|
||||
<IconMdiOpenInNew />
|
||||
</a>
|
||||
<span v-if="user.locked">
|
||||
<IconMdiLockOutline />
|
||||
</span>
|
||||
</h1>
|
||||
|
||||
<div>
|
||||
@ -55,8 +58,6 @@ const canEditCurrentUser = computed<boolean>(() => {
|
||||
:action="`${user.isOrganization ? 'organizations/org' : 'users'}/${user.name}/settings/tagline`"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- todo lock user modal -->
|
||||
</div>
|
||||
<div class="flex-grow" />
|
||||
<div class="<md:hidden flex flex-col space-y-1 items-end flex-shrink-0">
|
||||
|
61
frontend-new/src/components/modals/LockUserModal.vue
Normal file
61
frontend-new/src/components/modals/LockUserModal.vue
Normal file
@ -0,0 +1,61 @@
|
||||
<script lang="ts" setup>
|
||||
import { useI18n } from "vue-i18n";
|
||||
import Button from "~/components/design/Button.vue";
|
||||
import Modal from "~/components/modals/Modal.vue";
|
||||
import { useInternalApi } from "~/composables/useApi";
|
||||
import { handleRequestError } from "~/composables/useErrorHandling";
|
||||
import { AxiosError } from "axios";
|
||||
import Tooltip from "~/components/design/Tooltip.vue";
|
||||
import { useContext } from "vite-ssr/vue";
|
||||
import InputFile from "~/components/ui/InputFile.vue";
|
||||
import { User } from "hangar-api";
|
||||
import { ref } from "vue";
|
||||
import { useRouter } from "vue-router";
|
||||
import InputTextarea from "~/components/ui/InputTextarea.vue";
|
||||
import { useNotificationStore } from "~/store/notification";
|
||||
|
||||
const props = defineProps<{
|
||||
user: User;
|
||||
}>();
|
||||
|
||||
const i18n = useI18n();
|
||||
const ctx = useContext();
|
||||
const router = useRouter();
|
||||
|
||||
const comment = ref<string>("");
|
||||
|
||||
async function confirm(close: () => void) {
|
||||
try {
|
||||
await useInternalApi(`admin/lock-user/${props.user.name}/${!props.user.locked}`, true, "post", {
|
||||
content: comment.value,
|
||||
});
|
||||
close();
|
||||
router.go(0);
|
||||
useNotificationStore().success(i18n.t(`author.lock.success${props.user.locked ? "Unlock" : "Lock"}`, [props.user.name]));
|
||||
} catch (e) {
|
||||
handleRequestError(e as AxiosError, ctx, i18n);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal :title="i18n.t(`author.lock.confirm${user.locked ? 'Unlock' : 'Lock'}`, [user.name])">
|
||||
<template #default="{ on }">
|
||||
<InputTextarea v-model="comment" />
|
||||
|
||||
<Button button-type="secondary" class="mt-2" @click="on.click">{{ i18n.t("general.close") }}</Button>
|
||||
<Button button-type="primary" class="mt-2 ml-2" @click="confirm(on.click)">{{ i18n.t("general.confirm") }}</Button>
|
||||
</template>
|
||||
<template #activator="{ on }">
|
||||
<Tooltip>
|
||||
<template #content>
|
||||
{{ i18n.t(`author.tooltips.${user.locked ? "unlock" : "lock"}`) }}
|
||||
</template>
|
||||
<Button size="small" class="mr-1 inline-flex" v-on="on">
|
||||
<IconMdiLockOpenOutline v-if="user.locked" />
|
||||
<IconMdiLockOutline v-else />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</template>
|
||||
</Modal>
|
||||
</template>
|
@ -25,6 +25,7 @@ import IconMdiWrench from "~icons/mdi/wrench";
|
||||
import IconMdiKey from "~icons/mdi/key";
|
||||
import IconMdiCalendar from "~icons/mdi/calendar";
|
||||
import OrgVisibilityModal from "~/components/modals/OrgVisibilityModal.vue";
|
||||
import LockUserModal from "~/components/modals/LockUserModal.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
user: User;
|
||||
@ -40,6 +41,7 @@ if (props.user.name === useAuthStore().user?.name) {
|
||||
organizationVisibility = await useOrgVisibility(props.user.name);
|
||||
}
|
||||
const orgRoles = useBackendDataStore().orgRoles;
|
||||
const authStore = useAuthStore();
|
||||
|
||||
interface UserButton {
|
||||
icon: FunctionalComponent;
|
||||
@ -68,6 +70,8 @@ const buttons = computed<UserButton[]>(() => {
|
||||
return list;
|
||||
});
|
||||
|
||||
const isCurrentUser = computed<boolean>(() => authStore.user != null && authStore.user.name === props.user.name);
|
||||
|
||||
useHead(useSeo(props.user.name, props.user.tagline, route, avatarUrl(props.user.name)));
|
||||
</script>
|
||||
|
||||
@ -89,6 +93,8 @@ useHead(useSeo(props.user.name, props.user.tagline, route, avatarUrl(props.user.
|
||||
<Button size="small" class="mr-1 inline-flex"><component :is="btn.icon" /></Button>
|
||||
</Link>
|
||||
</Tooltip>
|
||||
|
||||
<LockUserModal v-if="!isCurrentUser && !user.isOrganization && hasPerms(NamedPermission.IS_STAFF)" :user="user" />
|
||||
</Card>
|
||||
|
||||
<template v-if="!user.isOrganization">
|
||||
|
Loading…
Reference in New Issue
Block a user