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

141 lines
3.7 KiB
Vue
Raw Normal View History

2022-04-15 14:24:30 +00:00
<template>
<article :class="{ me: isCurrentUser }" class="user-card">
2024-01-18 11:13:05 +00:00
<UserAvatar :user="user" width="80" />
<main>
<h1>
2023-08-20 22:35:58 +00:00
<span v-if="user.name" class="name">{{ user.name }}</span>
<span v-else class="name anonymous">Anonymous</span>
2023-11-10 13:16:06 +00:00
<Icon v-if="isCurrentUser" :icon="faCircleCheck" class="you text-highlight" title="This is you!" />
2022-07-15 07:23:55 +00:00
<icon
v-if="user.is_admin"
:icon="faShield"
class="is-admin text-blue"
title="User has admin privileges"
/>
</h1>
<p class="email text-secondary">{{ user.email }}</p>
<footer>
2023-08-20 22:35:58 +00:00
<template v-if="user.is_prospect">
<Btn class="btn-revoke" red small @click="revokeInvite">Revoke</Btn>
</template>
<template v-else>
<Btn v-if="!isCurrentUser" class="btn-delete" red small @click="destroy">Delete</Btn>
<Btn v-if="!user.is_prospect" class="btn-edit" orange small @click="edit">
{{ isCurrentUser ? 'Your Profile' : 'Edit' }}
</Btn>
</template>
</footer>
</main>
2022-04-15 14:24:30 +00:00
</article>
</template>
2022-04-15 17:00:08 +00:00
<script lang="ts" setup>
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'
2022-11-18 18:44:20 +00:00
import { useAuthorization, useDialogBox, useMessageToaster, useRouter } from '@/composables'
2023-08-20 22:35:58 +00:00
import { eventBus, parseValidationError } from '@/utils'
2022-04-15 14:24:30 +00:00
import Btn from '@/components/ui/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()
2023-08-20 22:35:58 +00:00
const { showConfirmDialog, showErrorDialog } = 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 (err: any) {
if (err.response.status === 404) {
showErrorDialog('Cannot revoke the invite. Maybe it has been accepted?', 'Revocation Failed')
return
}
const msg = err.response.status === 422 ? parseValidationError(err.response.data)[0] : 'Unknown error.'
showErrorDialog(msg, 'Error')
}
}
2022-04-15 14:24:30 +00:00
</script>
<style lang="scss" scoped>
.user-card {
padding: 10px;
display: flex;
flex-direction: row;
align-items: center;
border-radius: 5px;
background: var(--color-bg-secondary);
border: 1px solid var(--color-bg-secondary);
gap: 1rem;
2023-08-20 22:35:58 +00:00
.anonymous {
font-weight: var(--font-weight-light);
color: var(--color-text-secondary);
}
img {
2022-07-18 17:01:30 +00:00
border-radius: 50%;
flex: 0 0 80px;
background: rgba(0, 0, 0, .2)
}
2022-04-15 14:24:30 +00:00
main {
flex: 1;
2022-04-15 14:24:30 +00:00
display: flex;
flex-direction: column;
justify-content: space-between;
position: relative;
gap: .5rem;
}
2022-04-15 14:24:30 +00:00
h1 {
font-size: 1rem;
font-weight: var(--font-weight-normal);
2022-04-15 14:24:30 +00:00
> * + * {
margin-left: .5rem
2022-04-15 14:24:30 +00:00
}
}
2022-04-15 14:24:30 +00:00
footer {
visibility: hidden;
2022-04-23 21:46:25 +00:00
> * + * {
margin-left: .3rem;
2022-04-15 14:24:30 +00:00
}
@media (hover: none) {
visibility: visible;
2022-04-15 14:24:30 +00:00
}
}
&:hover footer {
visibility: visible;
2022-04-15 14:24:30 +00:00
}
}
</style>