feat: new person card
This commit is contained in:
parent
0f44f0f2cb
commit
152ea4d2df
1 changed files with 264 additions and 0 deletions
264
src/components/shared/NewPersonCard.vue
Normal file
264
src/components/shared/NewPersonCard.vue
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
<script lang="ts" setup>
|
||||
import { Icon } from '@iconify/vue';
|
||||
|
||||
import AppBox from 'components/app/AppBox.vue';
|
||||
import AppCircle from 'components/app/AppCircle.vue';
|
||||
import KebabAction from './KebabAction.vue';
|
||||
|
||||
defineProps<{
|
||||
data: {
|
||||
name: string;
|
||||
male?: boolean;
|
||||
female?: boolean;
|
||||
img?: string;
|
||||
fallbackImg?: string;
|
||||
detail?: { icon: string; value: string }[];
|
||||
index: number;
|
||||
};
|
||||
tag?: [{ color: string; value: string }];
|
||||
disabled?: boolean;
|
||||
noHover?: boolean;
|
||||
noBg?: boolean;
|
||||
history?: boolean;
|
||||
prefixId?: string;
|
||||
separateEnter?: boolean;
|
||||
}>();
|
||||
|
||||
defineEmits<{
|
||||
(e: 'cancel', index: number): void;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<AppBox
|
||||
bordered
|
||||
no-padding
|
||||
class="column person-box"
|
||||
:class="{
|
||||
'person-box__disabled': disabled,
|
||||
'person-box__no-hover': noHover,
|
||||
'person-box__no-detail': !data.detail,
|
||||
'person-box__no-bg': noBg,
|
||||
}"
|
||||
>
|
||||
<div class="column">
|
||||
<!-- kebab menu -->
|
||||
<div class="flex">
|
||||
<div class="col-2 flax">
|
||||
<AppCircle
|
||||
bordered
|
||||
class="avatar relative-position"
|
||||
style="border: 2px solid var(--border-color); overflow: visible"
|
||||
>
|
||||
<q-img
|
||||
v-if="!$slots.img"
|
||||
:src="data.img ?? '/no-profile.png'"
|
||||
loading="lazy"
|
||||
fit="cover"
|
||||
style="width: 100%; height: 100%; border-radius: 50%"
|
||||
>
|
||||
<template #error>
|
||||
<div
|
||||
style="background: none"
|
||||
class="no-padding full-width full-height flex items-center justify-center"
|
||||
>
|
||||
<q-img
|
||||
:src="data.fallbackImg || '/no-profile.png'"
|
||||
fit="cover"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</q-img>
|
||||
<slot name="img"></slot>
|
||||
<q-badge
|
||||
class="absolute-bottom-right"
|
||||
style="
|
||||
border-radius: 50%;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
z-index: 2;
|
||||
background: var(--border-color);
|
||||
"
|
||||
>
|
||||
<q-badge
|
||||
class="absolute-center"
|
||||
style="
|
||||
border-radius: 7px;
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
background: hsl(var(--positive-bg));
|
||||
"
|
||||
></q-badge>
|
||||
<!-- :style="`background: hsl(var(${active ? '--positive-bg' : '--text-mute'}))`" -->
|
||||
</q-badge>
|
||||
</AppCircle>
|
||||
</div>
|
||||
<div class="col column q-pl-xs">
|
||||
<div class="col row">
|
||||
<span style="max-width: calc(100% - 35%)">
|
||||
<span class="row items-center ellipsis">
|
||||
<div class="ellipsis" style="max-width: calc(100% - 30%)">
|
||||
{{ data.name }}
|
||||
<q-tooltip>
|
||||
{{ data.name }}
|
||||
</q-tooltip>
|
||||
</div>
|
||||
<Icon
|
||||
v-if="data.male || data.female"
|
||||
class="q-pl-xs"
|
||||
:class="{
|
||||
'symbol-gender': data.male || data.female,
|
||||
'symbol-gender__male': !disabled && data.male,
|
||||
'symbol-gender__female': !disabled && data.female,
|
||||
'symbol-gender__disable': disabled,
|
||||
}"
|
||||
:icon="`material-symbols:${data.male ? 'male' : 'female'}`"
|
||||
width="24px"
|
||||
/>
|
||||
</span>
|
||||
</span>
|
||||
|
||||
<div class="row items-center q-gutter-x-xs q-ml-auto">
|
||||
<q-btn
|
||||
:id="`btn-history-${prefixId}`"
|
||||
flat
|
||||
round
|
||||
class="app-text-muted-2"
|
||||
padding="xs"
|
||||
icon="mdi-close-circle"
|
||||
size="sm"
|
||||
@click.stop="$emit('cancel', data.index)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- profile -->
|
||||
|
||||
<!-- name symbol -->
|
||||
</div>
|
||||
|
||||
<!-- detail -->
|
||||
</AppBox>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.person-box {
|
||||
background-color: var(--surface-1);
|
||||
transition: 100ms ease-in-out;
|
||||
padding: var(--size-2);
|
||||
|
||||
&.person-box__disabled {
|
||||
opacity: 0.5;
|
||||
filter: grayscale(0.9);
|
||||
|
||||
.status-circle {
|
||||
background-color: var(--surface-1);
|
||||
}
|
||||
}
|
||||
|
||||
&.person-box__no-detail {
|
||||
padding-block: 2rem;
|
||||
}
|
||||
|
||||
&.person-box__no-bg {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
& .detail-icon {
|
||||
color: hsl(var(--text-mute-2));
|
||||
background-color: hsla(var(--stone-6-hsl) / 0.15);
|
||||
border-radius: 50%;
|
||||
scale: 0.8;
|
||||
}
|
||||
|
||||
& .bg-gender {
|
||||
color: hsla(var(--_fg));
|
||||
background-color: hsl(var(--_bg));
|
||||
|
||||
&.bg-gender__disable {
|
||||
--_bg: var(--stone-6-hsl);
|
||||
background-color: hsla(var(--_bg) / 0.3);
|
||||
}
|
||||
|
||||
&.bg-gender__light {
|
||||
color: unset;
|
||||
background-color: hsla(var(--_bg) / 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
& .symbol-gender {
|
||||
color: hsla(var(--_fg));
|
||||
|
||||
&.symbol-gender__disable {
|
||||
--_fg: var(--stone-6-hsl);
|
||||
}
|
||||
|
||||
&.symbol-gender__male {
|
||||
--_fg: var(--gender-male);
|
||||
}
|
||||
|
||||
&.symbol-gender__female {
|
||||
--_fg: var(--gender-female);
|
||||
}
|
||||
}
|
||||
|
||||
& .status-circle {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
border-radius: 50%;
|
||||
background-color: var(--teal-6);
|
||||
border: 2px solid var(--border-color);
|
||||
bottom: 0.6rem;
|
||||
right: 0.6rem;
|
||||
position: absolute;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
&:not(.person-box__disabled):not(.person-box__no-hover):hover {
|
||||
--_hover: hsl(var(--gender-male));
|
||||
cursor: pointer;
|
||||
box-shadow: var(--shadow-2);
|
||||
}
|
||||
}
|
||||
|
||||
.person-container {
|
||||
display: grid;
|
||||
gap: var(--size-6);
|
||||
}
|
||||
|
||||
.avatar {
|
||||
block-size: 2.5rem;
|
||||
/* transform: rotate(45deg); */
|
||||
|
||||
& .avatar__status {
|
||||
content: ' ';
|
||||
display: block;
|
||||
block-size: 1rem;
|
||||
aspect-ratio: 1;
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
right: -0.5rem;
|
||||
border: 1px solid var(--border-color);
|
||||
top: calc(50% - 0.5rem);
|
||||
bottom: calc(50% - 0.5rem);
|
||||
background-color: hsla(var(--positive-bg) / 1);
|
||||
}
|
||||
|
||||
/* & :deep(.q-img) {
|
||||
transform: rotate(-45deg);
|
||||
} */
|
||||
}
|
||||
|
||||
.edit-profile {
|
||||
cursor: pointer;
|
||||
transition: opacity 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
opacity: 80%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Loading…
Add table
Add a link
Reference in a new issue