mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-12 23:35:58 +00:00
- if there is no user.avatar, we show a user's initials - up to 3
characters unless there is no name or the name is 'Anonymous'. This is
to support users who on the old alpha were allowed to be anonymous (do
we still want to support this?)
- Add test cases for ☝️
- Refactor to not use any styleguide components and move UserAvatar to
generic directory
147 lines
3.6 KiB
Vue
147 lines
3.6 KiB
Vue
<template>
|
|
<dropdown class="avatar-menu" offset="8" :placement="placement">
|
|
<template #default="{ toggleMenu }">
|
|
<a
|
|
class="avatar-menu-trigger"
|
|
:href="
|
|
$router.resolve({
|
|
name: 'profile-id-slug',
|
|
params: { id: user.id, slug: user.slug },
|
|
}).href
|
|
"
|
|
@click.prevent="toggleMenu"
|
|
>
|
|
<user-avatar :user="user" />
|
|
<base-icon class="dropdown-arrow" name="angle-down" />
|
|
</a>
|
|
</template>
|
|
<template #popover="{ closeMenu }">
|
|
<div class="avatar-menu-popover">
|
|
{{ $t('login.hello') }}
|
|
<b>{{ userName }}</b>
|
|
<template v-if="user.role !== 'user'">
|
|
<ds-text color="softer" size="small" style="margin-bottom: 0">
|
|
{{ user.role | camelCase }}
|
|
</ds-text>
|
|
</template>
|
|
<hr />
|
|
<ds-menu :routes="routes" :matcher="matcher">
|
|
<ds-menu-item
|
|
slot="menuitem"
|
|
slot-scope="item"
|
|
:route="item.route"
|
|
:parents="item.parents"
|
|
@click.native="closeMenu(false)"
|
|
>
|
|
<base-icon :name="item.route.icon" />
|
|
{{ item.route.name }}
|
|
</ds-menu-item>
|
|
</ds-menu>
|
|
<hr />
|
|
<nuxt-link class="logout-link" :to="{ name: 'logout' }">
|
|
<base-icon name="sign-out" />
|
|
{{ $t('login.logout') }}
|
|
</nuxt-link>
|
|
</div>
|
|
</template>
|
|
</dropdown>
|
|
</template>
|
|
<script>
|
|
import { mapGetters } from 'vuex'
|
|
import Dropdown from '~/components/Dropdown'
|
|
import UserAvatar from '~/components/_new/generic/UserAvatar/UserAvatar'
|
|
|
|
export default {
|
|
components: {
|
|
Dropdown,
|
|
UserAvatar,
|
|
},
|
|
props: {
|
|
placement: { type: String, default: 'top-end' },
|
|
},
|
|
computed: {
|
|
...mapGetters({
|
|
user: 'auth/user',
|
|
isModerator: 'auth/isModerator',
|
|
isAdmin: 'auth/isAdmin',
|
|
}),
|
|
routes() {
|
|
if (!this.user.slug) {
|
|
return []
|
|
}
|
|
const routes = [
|
|
{
|
|
name: this.$t('profile.name'),
|
|
path: `/profile/${this.user.id}/${this.user.slug}`,
|
|
icon: 'user',
|
|
},
|
|
{
|
|
name: this.$t('notifications.pageLink'),
|
|
path: '/notifications',
|
|
icon: 'bell',
|
|
},
|
|
{
|
|
name: this.$t('settings.name'),
|
|
path: `/settings`,
|
|
icon: 'cogs',
|
|
},
|
|
]
|
|
if (this.isModerator) {
|
|
routes.push({
|
|
name: this.$t('moderation.name'),
|
|
path: `/moderation`,
|
|
icon: 'balance-scale',
|
|
})
|
|
}
|
|
if (this.isAdmin) {
|
|
routes.push({
|
|
name: this.$t('admin.name'),
|
|
path: `/admin`,
|
|
icon: 'shield',
|
|
})
|
|
}
|
|
return routes
|
|
},
|
|
userName() {
|
|
const { name } = this.user || {}
|
|
return name || this.$t('profile.userAnonym')
|
|
},
|
|
},
|
|
methods: {
|
|
matcher(url, route) {
|
|
if (url.indexOf('/profile') === 0) {
|
|
// do only match own profile
|
|
return this.$route.path === url
|
|
}
|
|
return this.$route.path.indexOf(url) === 0
|
|
},
|
|
},
|
|
}
|
|
</script>
|
|
<style lang="scss">
|
|
.avatar-menu {
|
|
margin: $space-xxx-small 0px 0px $space-xx-small;
|
|
}
|
|
.avatar-menu-trigger {
|
|
user-select: none;
|
|
display: flex;
|
|
align-items: center;
|
|
padding-left: $space-xx-small;
|
|
}
|
|
.avatar-menu-popover {
|
|
padding-top: $space-x-small;
|
|
padding-bottom: $space-x-small;
|
|
hr {
|
|
color: $color-neutral-90;
|
|
background-color: $color-neutral-90;
|
|
}
|
|
.logout-link {
|
|
color: $text-color-base;
|
|
padding-top: $space-xx-small;
|
|
&:hover {
|
|
color: $text-color-link-active;
|
|
}
|
|
}
|
|
}
|
|
</style>
|