87 lines
3.8 KiB
JavaScript
87 lines
3.8 KiB
JavaScript
const UserPresence = {
|
|
template: `
|
|
<div class="row items-center gt-sm q-mx-md">
|
|
<div class="row items-center no-wrap">
|
|
<!-- User Avatars -->
|
|
<q-avatar
|
|
v-for="user in visibleUsers"
|
|
:key="user.id"
|
|
size="30px"
|
|
class="avatar-stack-item avatar-stack-img"
|
|
>
|
|
<img :src="user.img">
|
|
<q-tooltip
|
|
anchor="bottom middle"
|
|
self="top middle"
|
|
:offset="[0, 10]"
|
|
class="bg-white text-grey-9 shadow-10 q-pa-none rounded-borders border"
|
|
>
|
|
<div class="profile-card row no-wrap items-start">
|
|
<q-avatar size="48px" class="q-mr-md border">
|
|
<img :src="user.img">
|
|
</q-avatar>
|
|
<div class="column flex-1 min-w-0">
|
|
<div class="text-weight-bold text-subtitle2 flex items-center no-wrap">
|
|
{{ user.name }}
|
|
<q-icon name="verified" color="blue-6" size="14px" class="q-ml-xs"></q-icon>
|
|
</div>
|
|
<div class="text-caption text-grey-7 text-weight-medium">{{ user.role }}</div>
|
|
<div class="row items-center text-grey-5 q-mt-xs" style="font-size: 10px;">
|
|
<q-icon name="mail" size="12px" class="q-mr-xs"></q-icon>
|
|
<span class="truncate">{{ user.email }}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</q-tooltip>
|
|
</q-avatar>
|
|
|
|
<!-- FIXED COUNT CIRCLE -->
|
|
<div
|
|
v-if="remainingCount > 0"
|
|
class="avatar-stack-item avatar-stack-count-circle"
|
|
>
|
|
+{{ remainingCount }}
|
|
|
|
<q-tooltip>Click to see all users online</q-tooltip>
|
|
|
|
<q-menu class="bg-white shadow-15 border" anchor="bottom right" self="top right">
|
|
<q-list dense style="min-width: 220px">
|
|
<q-item-label header class="text-weight-bold text-overline text-indigo-9 bg-grey-1">
|
|
ALL USERS ONLINE ({{ allUsers.length }})
|
|
</q-item-label>
|
|
<q-separator></q-separator>
|
|
<q-scroll-area style="height: 250px;">
|
|
<q-item v-for="user in allUsers" :key="user.id" clickable v-ripple class="q-py-sm">
|
|
<q-item-section avatar>
|
|
<q-avatar size="28px">
|
|
<img :src="user.img">
|
|
</q-avatar>
|
|
</q-item-section>
|
|
<q-item-section>
|
|
<q-item-label class="text-weight-bold text-caption text-grey-8">{{ user.name }}</q-item-label>
|
|
<q-item-label caption lines="1">{{ user.role }}</q-item-label>
|
|
</q-item-section>
|
|
</q-item>
|
|
</q-scroll-area>
|
|
</q-list>
|
|
</q-menu>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`,
|
|
setup() {
|
|
const { computed } = Vue;
|
|
const maxVisibleUsers = 5;
|
|
|
|
const allUsers = computed(() => store.onlineUsers);
|
|
const visibleUsers = computed(() => allUsers.value.slice(0, maxVisibleUsers));
|
|
const remainingCount = computed(() => Math.max(0, allUsers.value.length - maxVisibleUsers));
|
|
|
|
return {
|
|
allUsers,
|
|
visibleUsers,
|
|
remainingCount
|
|
}
|
|
}
|
|
};
|