refactor(ui): simplify layout by introducing an unified site-bar

This commit is contained in:
2025-08-26 16:35:48 -04:00
parent 262f21d157
commit 9da862b629
2 changed files with 46 additions and 56 deletions

View 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>