trypost/resources/js/components/ui/avatar/Avatar.vue
vickytechkey 30c6fc5747
All checks were successful
Setup EC2 Tools / setup-server (push) Successful in 1m46s
refactor: improve avatar error handling, storage URL resolution, and upload logging
2026-09-10 23:05:37 +05:30

49 lines
1.4 KiB
Vue

<script setup lang="ts">
import type { HTMLAttributes } from "vue"
import { computed, ref, watch } from "vue"
import { AvatarRoot } from "reka-ui"
import { IconUser } from "@tabler/icons-vue"
import { cn } from "@/lib/utils"
import { getInitials } from "@/composables/useInitials"
const props = defineProps<{
class?: HTMLAttributes["class"]
src?: string | null
name?: string
fallbackClass?: HTMLAttributes["class"]
}>()
const hasError = ref(false)
watch(() => props.src, () => {
hasError.value = false
})
const hasProps = computed(() => props.src !== undefined || props.name !== undefined)
const initials = computed(() => (props.name ? getInitials(props.name) : ''))
</script>
<template>
<AvatarRoot
data-slot="avatar"
:class="cn('relative flex size-8 shrink-0 overflow-hidden rounded-full', props.class)"
>
<template v-if="hasProps">
<img
v-if="src && !hasError"
:src="src"
:alt="name"
class="aspect-square size-full object-cover"
@error="hasError = true"
/>
<div
v-else
:class="cn('flex size-full items-center justify-center bg-muted text-xs font-bold text-foreground select-none', props.fallbackClass)"
>
<span v-if="initials">{{ initials }}</span>
<IconUser v-else class="size-1/2 opacity-70" />
</div>
</template>
<slot v-else />
</AvatarRoot>
</template>