30 lines
952 B
Vue
30 lines
952 B
Vue
<script setup lang="ts">
|
|
import { avatarColor, avatarInitial } from '~/utils/avatar';
|
|
|
|
const props = defineProps<{
|
|
user: {
|
|
id: string;
|
|
name?: string | null;
|
|
image?: string | null;
|
|
} | null | undefined;
|
|
}>();
|
|
|
|
// fall back to the letter placeholder if the image fails to load
|
|
const imageFailed = ref(false);
|
|
|
|
watch(() => props.user?.image, () => {
|
|
imageFailed.value = false;
|
|
});
|
|
|
|
const showImage = computed(() => !!props.user?.image && !imageFailed.value);
|
|
</script>
|
|
|
|
<template>
|
|
<div class="flex-shrink-0 overflow-hidden flex items-center justify-center font-semibold text-white select-none"
|
|
:style="showImage ? {} : { backgroundColor: avatarColor(user?.id ?? '') }">
|
|
<img v-if="showImage" :src="user!.image!" alt="" class="w-full h-full object-cover"
|
|
@error="imageFailed = true" />
|
|
<span v-else aria-hidden="true">{{ avatarInitial(user?.name) }}</span>
|
|
</div>
|
|
</template>
|