refactor(ui): simplify layout by introducing an unified site-bar
This commit is contained in:
192
frontend/src/views/main/SiteBar.vue
Normal file
192
frontend/src/views/main/SiteBar.vue
Normal file
@@ -0,0 +1,192 @@
|
||||
<script setup>
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useAuthStore } from '@/stores/authStore.js';
|
||||
import { useCreatorProfileStore } from '@/stores/creatorProfileStore.js';
|
||||
import { useUserProfileStore } from '@/stores/userProfileStore.js';
|
||||
import { useLanguageStore } from '@/stores/languageStore.js';
|
||||
import { mdiAccount, mdiFileAccountOutline, mdiLogin, mdiLogout, mdiTranslateVariant } from '@mdi/js';
|
||||
|
||||
const { locale, t } = useI18n();
|
||||
const languageStore = useLanguageStore();
|
||||
|
||||
const userProfileStore = useUserProfileStore();
|
||||
const creatorProfileStore = useCreatorProfileStore();
|
||||
const authStore = useAuthStore();
|
||||
|
||||
function toggleLanguage() {
|
||||
const languages = ['fr', 'en'];
|
||||
const currentIndex = languages.indexOf(locale.value);
|
||||
const nextIndex = (currentIndex + 1) % languages.length;
|
||||
languageStore.setLocale(languages[nextIndex]);
|
||||
}
|
||||
|
||||
function handleLogout() {
|
||||
authStore.logout();
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<nav class="side-container">
|
||||
<div class="side-logo">
|
||||
<router-link to="/@hutopy">
|
||||
<img
|
||||
alt="hutopy logo"
|
||||
height="50"
|
||||
src="/images/hutopy-logo.png"
|
||||
/>
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<div class="side-menu">
|
||||
<div
|
||||
v-if="authStore.isAuthenticated"
|
||||
class="side-menu-portrait"
|
||||
>
|
||||
<img
|
||||
:src="userProfileStore.portraitUrl"
|
||||
alt="Profile Image"
|
||||
class="rounded-full"
|
||||
referrerpolicy="no-referrer"
|
||||
/>
|
||||
<span class="profile-label">{{ userProfileStore.alias }}</span>
|
||||
</div>
|
||||
|
||||
<div class="side-menu-items">
|
||||
<template v-if="authStore.isAuthenticated">
|
||||
<router-link
|
||||
v-if="creatorProfileStore.hasCreator"
|
||||
:to="`/@${creatorProfileStore.creator.slug}`"
|
||||
>
|
||||
<button class="menu-item-action">
|
||||
<v-icon :icon="mdiFileAccountOutline" />
|
||||
<span class="label">{{ t('sidebar.myPage') }}</span>
|
||||
</button>
|
||||
</router-link>
|
||||
<router-link
|
||||
v-else
|
||||
to="/create-creator"
|
||||
>
|
||||
<button class="menu-item-action">
|
||||
<v-icon :icon="mdiFileAccountOutline" />
|
||||
<span class="label">{{ t('sidebar.myPage') }}</span>
|
||||
</button>
|
||||
</router-link>
|
||||
</template>
|
||||
|
||||
<template v-if="authStore.isAuthenticated">
|
||||
<router-link to="/profile">
|
||||
<button class="menu-item-action">
|
||||
<v-icon :icon="mdiAccount" />
|
||||
<span class="label">{{ t('sidebar.myProfile') }}</span>
|
||||
</button>
|
||||
</router-link>
|
||||
</template>
|
||||
|
||||
<button
|
||||
class="menu-item-action"
|
||||
@click="toggleLanguage"
|
||||
>
|
||||
<v-icon :icon="mdiTranslateVariant" />
|
||||
<span class="label">{{ locale }}</span>
|
||||
</button>
|
||||
|
||||
<template v-if="!authStore.isAuthenticated">
|
||||
<router-link to="/login">
|
||||
<button class="menu-item-action">
|
||||
<v-icon :icon="mdiLogin" />
|
||||
<span class="label">{{ t('sidebar.signIn') }}</span>
|
||||
</button>
|
||||
</router-link>
|
||||
</template>
|
||||
<div v-else>
|
||||
<button
|
||||
class="menu-item-action"
|
||||
@click="handleLogout"
|
||||
>
|
||||
<v-icon :icon="mdiLogout" />
|
||||
<span class="label">{{ t('sidebar.signOut') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.side-container {
|
||||
@apply bg-hSurface text-hOnSurface;
|
||||
@apply flex;
|
||||
@apply max-h-screen;
|
||||
@apply h-16;
|
||||
}
|
||||
|
||||
.side-logo {
|
||||
@apply flex flex-grow;
|
||||
@apply items-center justify-start p-4;
|
||||
}
|
||||
|
||||
.side-menu {
|
||||
@apply flex gap-4 p-6;
|
||||
@apply items-center;
|
||||
@apply flex-row-reverse;
|
||||
}
|
||||
|
||||
.side-menu-portrait {
|
||||
@apply w-10 h-10;
|
||||
@apply -ml-1;
|
||||
@apply flex items-center justify-start;
|
||||
}
|
||||
|
||||
.side-menu-items {
|
||||
@apply flex gap-2;
|
||||
@apply flex-row;
|
||||
}
|
||||
|
||||
.profile-label {
|
||||
@apply ml-5;
|
||||
@apply text-lg font-sans capitalize;
|
||||
@apply font-semibold;
|
||||
@apply hidden;
|
||||
@apply min-w-40 truncate;
|
||||
}
|
||||
|
||||
.label {
|
||||
@apply text-nowrap;
|
||||
@apply ml-4;
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
.menu-item-action {
|
||||
@apply bg-hSurface text-hOnSurface hover:mix-blend-screen;
|
||||
@apply capitalize;
|
||||
@apply flex items-center gap-3 p-2 rounded-full md:rounded-full;
|
||||
@apply mx-0;
|
||||
@apply lg:pl-2;
|
||||
@apply w-10 h-10 justify-center lg:w-full lg:h-auto lg:justify-normal;
|
||||
|
||||
i {
|
||||
@apply text-xl;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<i18n>
|
||||
{
|
||||
"en": {
|
||||
"sidebar": {
|
||||
"myPage": "My Page",
|
||||
"myProfile": "My Profile",
|
||||
"signIn": "Sign In",
|
||||
"signOut": "Sign Out"
|
||||
}
|
||||
},
|
||||
"fr": {
|
||||
"sidebar": {
|
||||
"myPage": "Ma Page",
|
||||
"myProfile": "Mon Profil",
|
||||
"signIn": "Se Connecter",
|
||||
"signOut": "Se Déconnecter"
|
||||
}
|
||||
}
|
||||
}
|
||||
</i18n>
|
||||
Reference in New Issue
Block a user