jws-frontend/src/components/ImageHover.vue
2024-12-06 15:32:47 +07:00

144 lines
3.7 KiB
Vue

<script setup lang="ts">
import { ref } from 'vue';
withDefaults(
defineProps<{
img?: string | null;
icon?: string;
title?: string;
caption?: string;
color?: string;
bgColor?: string;
toggleTitle?: string;
fallbackImg?: string;
fallbackCover?: string;
hideFade?: boolean;
hideActive?: boolean;
active?: boolean;
readonly?: boolean;
useToggle?: boolean;
labelAction?: string;
menu?: { icon: string; color: string; bgColor: string }[];
tabsList?: { name: string | number; label: string }[];
}>(),
{},
);
const showOverlay = ref(false);
defineEmits<{
(e: 'view'): void;
(e: 'edit'): void;
}>();
</script>
<template>
<div>
<div class="surface-1" style="border: 4px solid var(--surface-1)">
<q-avatar
square
size="10rem"
font-size="8rem"
class="relative-position"
style="z-index: 1; cursor: pointer"
@mouseover="showOverlay = true"
@mouseleave="showOverlay = false"
@click.stop="
() => {
if (readonly === false) $emit('view');
}
"
>
<div
v-if="img"
class="full-width full-height"
:style="{
background: `${bgColor || 'var(--brand-1)'}`,
color: `${color || 'white'}`,
}"
>
<q-img id="profile-view" :src="img" :ratio="1">
<template #error>
<q-img
v-if="fallbackImg"
:src="fallbackImg"
:ratio="1"
style="background-color: transparent"
>
<template #error>
<div
class="full-width full-height flex items-center justify-center"
:style="{
background: `${bgColor || 'var(--brand-1)'}`,
color: `${color || 'white'}`,
}"
>
<q-icon :name="icon || 'mdi-account'" />
</div>
</template>
</q-img>
<div
v-else
class="full-width full-height flex items-center justify-center"
:style="{
background: `${bgColor || 'var(--brand-1)'}`,
color: `${color || 'white'}`,
}"
>
<q-icon :name="icon || 'mdi-account'" />
</div>
</template>
</q-img>
</div>
<div
v-else
class="full-width full-height flex items-center justify-center"
:style="{
background: `${bgColor || 'var(--brand-1)'}`,
color: `${color || 'white'}`,
}"
>
<q-icon :name="icon || 'mdi-account'" />
</div>
<Transition name="slide-fade">
<div
v-if="showOverlay && !readonly"
class="absolute text-caption full-width full-height"
style="overflow: hidden"
:class="{ dark: $q.dark.isActive }"
>
<div
class="upload-overlay absolute-bottom flex items-center justify-center"
@click.stop="
() => {
if (readonly === false) $emit('edit');
}
"
>
{{
labelAction === undefined
? $t('general.editImage')
: labelAction
}}
</div>
</div>
</Transition>
</q-avatar>
</div>
</div>
</template>
<style scoped>
.upload-overlay {
top: 60%;
background-color: hsla(var(--gray-10-hsl) / 0.5);
color: white;
&.dark {
background-color: rgba(255, 255, 255, 0.2);
}
}
</style>