koel/resources/assets/js/components/user/UserCard.vue

92 lines
3.1 KiB
Vue
Raw Normal View History

2022-04-15 14:24:30 +00:00
<template>
2024-04-04 22:20:42 +00:00
<article
:class="{ me: isCurrentUser }"
class="apply p-4 flex items-center rounded-md bg-k-bg-secondary border border-k-border
gap-3 transition-[border-color] duration-200 ease-in-out hover:border-white/15"
>
<UserAvatar :user="user" width="48" />
2024-04-04 22:20:42 +00:00
<main class="flex flex-col justify-between relative flex-1 gap-1">
<h3 class="font-medium flex gap-2 items-center">
2023-08-20 22:35:58 +00:00
<span v-if="user.name" class="name">{{ user.name }}</span>
2024-04-04 22:20:42 +00:00
<span v-else class="name font-light text-k-text-secondary">Anonymous</span>
<Icon v-if="isCurrentUser" :icon="faCircleCheck" class="you text-k-highlight" title="This is you!" />
2024-03-30 16:49:25 +00:00
<Icon
2022-07-15 07:23:55 +00:00
v-if="user.is_admin"
:icon="faShield"
2024-04-04 22:20:42 +00:00
class="is-admin text-k-primary"
2022-07-15 07:23:55 +00:00
title="User has admin privileges"
/>
2024-03-30 16:49:25 +00:00
<img
v-if="user.sso_provider === 'Google'"
title="Google SSO"
:src="googleLogo"
alt="Google"
width="14"
height="14"
>
2024-04-04 22:20:42 +00:00
</h3>
2024-04-04 22:20:42 +00:00
<p class="text-k-text-secondary">{{ user.email }}</p>
</main>
2024-04-04 22:20:42 +00:00
<div class="space-x-2">
<template v-if="user.is_prospect">
2024-04-04 22:20:42 +00:00
<Btn class="btn-revoke" danger small @click="revokeInvite">Revoke</Btn>
</template>
<template v-else>
2024-04-04 22:20:42 +00:00
<Btn v-if="!user.is_prospect" highlight small @click="edit">
{{ isCurrentUser ? 'Your Profile' : 'Edit' }}
</Btn>
2024-04-04 22:20:42 +00:00
<Btn v-if="!isCurrentUser" danger small @click="destroy">Delete</Btn>
</template>
</div>
2022-04-15 14:24:30 +00:00
</article>
</template>
2022-04-15 17:00:08 +00:00
<script lang="ts" setup>
2024-03-30 16:49:25 +00:00
import googleLogo from '@/../img/logos/google.svg'
2022-07-15 07:23:55 +00:00
import { faCircleCheck, faShield } from '@fortawesome/free-solid-svg-icons'
import { computed, toRefs } from 'vue'
2022-04-15 14:24:30 +00:00
import { userStore } from '@/stores'
2023-08-20 22:35:58 +00:00
import { invitationService } from '@/services'
import { useAuthorization, useDialogBox, useErrorHandler, useMessageToaster, useRouter } from '@/composables'
import { eventBus } from '@/utils'
2022-04-15 14:24:30 +00:00
2024-04-04 22:20:42 +00:00
import Btn from '@/components/ui/form/Btn.vue'
2024-01-18 11:13:05 +00:00
import UserAvatar from '@/components/user/UserAvatar.vue'
2022-04-15 14:24:30 +00:00
2022-04-15 17:00:08 +00:00
const props = defineProps<{ user: User }>()
const { user } = toRefs(props)
2022-04-15 14:24:30 +00:00
const { toastSuccess } = useMessageToaster()
const { showConfirmDialog } = useDialogBox()
2022-11-18 18:44:20 +00:00
const { go } = useRouter()
const { currentUser } = useAuthorization()
const isCurrentUser = computed(() => user.value.id === currentUser.value.id)
2022-04-15 17:00:08 +00:00
2022-11-18 18:44:20 +00:00
const edit = () => isCurrentUser.value ? go('profile') : eventBus.emit('MODAL_SHOW_EDIT_USER_FORM', user.value)
const destroy = async () => {
2023-08-20 22:35:58 +00:00
if (!await showConfirmDialog(`Unperson ${user.value.name}?`)) return
await userStore.destroy(user.value)
toastSuccess(`User "${user.value.name}" deleted.`)
2022-04-15 17:00:08 +00:00
}
2023-08-20 22:35:58 +00:00
const revokeInvite = async () => {
if (!await showConfirmDialog(`Revoke the invite for ${user.value.email}?`)) return
try {
await invitationService.revoke(user.value)
toastSuccess(`Invitation for ${user.value.email} revoked.`)
} catch (error: unknown) {
useErrorHandler('dialog').handleHttpError(error, {
404: 'Cannot revoke the invite. Maybe it has been accepted?'
})
2023-08-20 22:35:58 +00:00
}
}
2022-04-15 14:24:30 +00:00
</script>