fix: profile banner fallback

This commit is contained in:
puriphatt 2024-08-02 07:29:41 +00:00
parent 4cbcaeb3f2
commit 664284ce95

View file

@ -3,12 +3,12 @@ import { ref } from 'vue';
defineProps<{ defineProps<{
icon?: string; icon?: string;
fallbackCover?: string;
color?: string; color?: string;
img?: string | null; img?: string | null;
bgColor?: string; bgColor?: string;
title?: string; title?: string;
caption?: string; caption?: string;
cover?: string | null;
hideFade?: boolean; hideFade?: boolean;
active?: boolean; active?: boolean;
@ -22,49 +22,75 @@ defineEmits<{
(e: 'edit'): void; (e: 'edit'): void;
}>(); }>();
const coverUrl = defineModel<string>('coverUrl', {
required: false,
default: '',
});
const showOverlay = ref(false); const showOverlay = ref(false);
</script> </script>
<template> <template>
<div <q-img
fit="cover"
class="cover rounded bordered relative-position" class="cover rounded bordered relative-position"
:style="`background-image: linear-gradient( position="0 0"
:src="coverUrl || fallbackCover || 'blank-cover.png'"
@error="coverUrl = ''"
>
<nav
class="full-width full-height"
:style="`background-image: linear-gradient(
90deg, ${ 90deg, ${
$q.dark.isActive $q.dark.isActive
? `hsla(var(--gray-10-hsl) / ${hideFade ? '0' : '1'}) 10%,hsla(var(--gray-10-hsl) / 0) 100%` ? `hsla(var(--gray-10-hsl) / ${hideFade ? '0' : '1'}) 10%,hsla(var(--gray-10-hsl) / 0) 100%`
: `rgba(255, 255, 255, ${hideFade ? '0' : '1'}) 10%,rgba(255, 255, 255, 0) 100%` : `rgba(255, 255, 255, ${hideFade ? '0' : '1'}) 10%,rgba(255, 255, 255, 0) 100%`
} }
), )`"
url(${cover || 'blank-cover.png'});`" >
> <!-- profile -->
<!-- profile --> <div class="flex items-center full-height q-pl-lg" style="z-index: 999">
<div class="absolute-top flex items-center full-height q-pl-lg">
<div
class="surface-1"
style="
border-radius: 50%;
border: 4px solid var(--surface-1);
overflow: hidden;
"
>
<div <div
class="avatar__status" class="surface-1"
style="z-index: 2" style="
:style="`${active ? 'background-color: hsla(var(--positive-bg) / 1)' : 'background-color: hsla(var(--text-mute) / 1)'}`" border-radius: 50%;
></div> border: 4px solid var(--surface-1);
<q-avatar overflow: hidden;
size="6rem" "
font-size="3rem"
class="cursor-pointer"
style="z-index: 1"
:style="`background-color: ${img ? 'white' : bgColor || 'var(--brand-1)'}; color: ${color || 'white'}`"
@mouseover="showOverlay = true"
@mouseleave="showOverlay = false"
@click.stop="$emit('view')"
> >
<q-img v-if="img" :src="img" :ratio="1" /> <div
<q-icon v-if="!img" :name="icon || 'mdi-account'" /> class="avatar__status"
style="z-index: 2"
:style="`${active ? 'background-color: hsla(var(--positive-bg) / 1)' : 'background-color: hsla(var(--text-mute) / 1)'}`"
></div>
<q-avatar
size="6rem"
font-size="3rem"
class="cursor-pointer relative-position"
style="z-index: 1"
:style="{
'background-color': `${bgColor || 'var(--brand-1)'}`,
color: `${color || 'white'}`,
}"
@mouseover="showOverlay = true"
@mouseleave="showOverlay = false"
@click.stop="$emit('view')"
>
<q-img v-if="img" :src="img" :ratio="1">
<template #error>
<div
class="full-width full-height flex items-center justify-center"
style="background-color: transparent"
:style="{
color: `${color || 'white'}`,
}"
>
<q-icon :name="icon || 'mdi-account'" />
</div>
</template>
</q-img>
<q-icon v-else :name="icon || 'mdi-account'" />
<Transition name="slide-fade"> <!-- <Transition name="slide-fade"> -->
<div <div
v-if="showOverlay && !readonly" v-if="showOverlay && !readonly"
class="absolute-bottom text-caption flex items-center justify-center upload-overlay" class="absolute-bottom text-caption flex items-center justify-center upload-overlay"
@ -73,37 +99,38 @@ const showOverlay = ref(false);
> >
{{ $t('editImage') }} {{ $t('editImage') }}
</div> </div>
</Transition> <!-- </Transition> -->
</q-avatar> </q-avatar>
</div>
</div>
<!-- text -->
<div
class="absolute-bottom relative-position justify-between row text-cover"
:class="{ dark: $q.dark.isActive }"
>
<div class="column">
<span class="text-bold q-pt-xs text-body1">{{ title }}</span>
<span class="app-text-muted">{{ caption }}</span>
</div>
<!-- icon -->
<div class="row items-center q-pr-lg">
<div class="q-gutter-x-sm">
<q-btn
v-for="(item, n) in menu"
:key="n"
flat
size="sm"
class="q-pa-xs rounded"
:icon="item.icon"
:style="`background-color: ${item.bgColor}; color: ${item.color}`"
/>
</div> </div>
</div> </div>
</div>
</div> <!-- text -->
<div
class="absolute-bottom relative-position justify-between row text-cover"
:class="{ dark: $q.dark.isActive }"
>
<div class="column">
<span class="text-bold q-pt-xs text-body1">{{ title }}</span>
<span class="app-text-muted">{{ caption }}</span>
</div>
<!-- icon -->
<div class="row items-center q-pr-lg" style="z-index: 999">
<div class="q-gutter-x-sm">
<q-btn
v-for="(item, n) in menu"
:key="n"
flat
size="sm"
class="q-pa-xs rounded"
:icon="item.icon"
:style="`background-color: ${item.bgColor}; color: ${item.color}`"
/>
</div>
</div>
</div>
</nav>
</q-img>
</template> </template>
<style lang="scss"> <style lang="scss">
@ -149,8 +176,7 @@ const showOverlay = ref(false);
.upload-overlay { .upload-overlay {
top: 3.5rem; top: 3.5rem;
background-color: hsla(var(--gray-10-hsl) / 0.2); background-color: hsla(var(--gray-10-hsl) / 0.5);
backdrop-filter: blur(8px);
color: white; color: white;
&.dark { &.dark {
@ -170,4 +196,8 @@ const showOverlay = ref(false);
.slide-fade-leave-to { .slide-fade-leave-to {
opacity: 0; opacity: 0;
} }
.q-img__content > nav {
pointer-events: all;
}
</style> </style>