App: Added a sidebar store with BannerAction to adjust the z-depth. CreatorLayout: Resized the content with the sidebar and added the option for a closed or open menu. Also added a value in SidebarStore to track the menu state for correct positioning.
This commit is contained in:
18
src/App.vue
18
src/App.vue
@@ -1,35 +1,33 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-app>
|
<v-app>
|
||||||
<div class="flex flex-row">
|
<div class="flex flex-row">
|
||||||
|
<div class="border-r-2 z-30">
|
||||||
<div class="fixed h-full w-60 border-r-2 z-30 ">
|
|
||||||
<side-bar></side-bar>
|
<side-bar></side-bar>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pl-60 w-full">
|
<div :class="['w-full', sideBarStore.sidebarWidth]">
|
||||||
|
|
||||||
<div v-if="!brandingStore.loading"
|
<div v-if="!brandingStore.loading"
|
||||||
class="min-h-screen justify-center items-center py-10"
|
class="min-h-screen justify-center items-center py-10"
|
||||||
:style="{backgroundColor: brandingStore.colors.background}">
|
:style="{ backgroundColor: brandingStore.colors.background }">
|
||||||
<router-view></router-view>
|
<router-view></router-view>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</v-app>
|
</v-app>
|
||||||
|
|
||||||
<size-indicator></size-indicator>
|
<size-indicator></size-indicator>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script async setup>
|
<script async setup>
|
||||||
import SideBar from "@/views/main/SideBar.vue";
|
import SideBar from "@/views/main/SideBar.vue";
|
||||||
import SizeIndicator from "@/views/tools/SizeIndicator.vue";
|
import SizeIndicator from "@/views/tools/SizeIndicator.vue";
|
||||||
import {useBrandingStore} from "@/stores/brandingStore.js";
|
import { useBrandingStore } from "@/stores/brandingStore.js";
|
||||||
|
import { useSideBarStore } from "@/stores/sideBarStore.js";
|
||||||
|
|
||||||
const brandingStore = useBrandingStore()
|
const brandingStore = useBrandingStore();
|
||||||
|
const sideBarStore = useSideBarStore();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
</style>
|
</style>
|
||||||
|
s
|
||||||
@@ -1,23 +1,16 @@
|
|||||||
import {computed, ref} from 'vue';
|
// src/stores/sideBarStore.js
|
||||||
import {defineStore} from "pinia";
|
import { computed, ref } from 'vue';
|
||||||
|
import { defineStore } from 'pinia';
|
||||||
|
|
||||||
export const useSideBarStore = defineStore(
|
export const useSideBarStore = defineStore('sideBar', () => {
|
||||||
'sideBar',
|
const isOpen = ref(true); // par défaut, le menu est ouvert
|
||||||
() => {
|
|
||||||
const state = ref(false)
|
|
||||||
const visible = computed(() => state.value)
|
|
||||||
|
|
||||||
function toggle() {
|
const toggle = () => {
|
||||||
state.value = !state.value
|
isOpen.value = !isOpen.value;
|
||||||
}
|
};
|
||||||
|
|
||||||
function show() {
|
// Classe de largeur dynamique pour le contenu principal
|
||||||
state.value = true
|
const sidebarWidth = computed(() => (isOpen.value ? 'ml-64' : 'ml-16'));
|
||||||
}
|
|
||||||
|
|
||||||
function hide() {
|
return { isOpen, toggle, sidebarWidth };
|
||||||
state.value = false
|
});
|
||||||
}
|
|
||||||
|
|
||||||
return {visible, toggle, show, hide}
|
|
||||||
})
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="absolute bottom-6 right-8 z-30 shadow-2xl rounded-md text-white w-64 h-28 flex justify-center align-center"
|
<div class="absolute bottom-6 right-8 z-20 shadow-2xl rounded-md text-white w-64 h-28 flex justify-center align-center"
|
||||||
:style="{ backgroundColor: brandingStore.colors.secondary}">
|
:style="{ backgroundColor: brandingStore.colors.secondary}">
|
||||||
|
|
||||||
<donation-button-banner
|
<donation-button-banner
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
|
|
||||||
<div class="flex flex-col min-h-screen max-w-[1200px] mx-auto">
|
<div class="flex flex-col min-h-screen max-w-[1100px] mx-auto">
|
||||||
<div v-if="brandingStore.loading">
|
<div v-if="brandingStore.loading">
|
||||||
<v-progress-linear indeterminate></v-progress-linear>
|
<v-progress-linear indeterminate></v-progress-linear>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import SubscriptionList from "@/views/creators/SubscriptionList.vue";
|
import SubscriptionList from "@/views/creators/SubscriptionList.vue";
|
||||||
import {useAuthStore} from "@/stores/authStore.js";
|
import { useAuthStore } from "@/stores/authStore.js";
|
||||||
import {useRouter} from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import {computed, ref} from "vue";
|
import { computed, ref } from "vue";
|
||||||
import {useI18n} from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import {useCreatorProfileStore} from "@/stores/creatorProfileStore.js";
|
import { useCreatorProfileStore } from "@/stores/creatorProfileStore.js";
|
||||||
import {useUserProfileStore} from "@/stores/userProfileStore.js";
|
import {useUserProfileStore} from "@/stores/userProfileStore.js";
|
||||||
|
import {useSideBarStore} from "@/stores/sideBarStore.js";
|
||||||
|
|
||||||
const {locale} = useI18n();
|
const {locale} = useI18n();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -14,6 +15,7 @@ const selectedLanguage = ref(locale.value);
|
|||||||
const userProfileStore = useUserProfileStore();
|
const userProfileStore = useUserProfileStore();
|
||||||
const creatorProfileStore = useCreatorProfileStore();
|
const creatorProfileStore = useCreatorProfileStore();
|
||||||
const authStore = useAuthStore();
|
const authStore = useAuthStore();
|
||||||
|
const sideBarStore = useSideBarStore();
|
||||||
|
|
||||||
const creatorIsCurrentUser = computed(() => authStore.isAuthenticated && authStore.userId);
|
const creatorIsCurrentUser = computed(() => authStore.isAuthenticated && authStore.userId);
|
||||||
|
|
||||||
@@ -34,46 +36,56 @@ function toggleLanguage() {
|
|||||||
localStorage.setItem('preferredLocale', lang);
|
localStorage.setItem('preferredLocale', lang);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleMenu() {
|
||||||
|
sideBarStore.toggle();
|
||||||
|
}
|
||||||
|
|
||||||
initializeLocale();
|
initializeLocale();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<nav class="flex flex-col h-full bg-white">
|
<nav :class="['fixed flex flex-col h-full bg-white border-r border-gray-300', sideBarStore.isOpen ? 'max-w-64 px-4' : 'max-w-[82px] px-2']">
|
||||||
|
<!-- LOGO HUTOPY -->
|
||||||
<!-- APP SECTION -->
|
<div class="mt-4" :class="sideBarStore.isOpen ? 'px-4' : 'px-2'">
|
||||||
<div class="px-4 mt-4">
|
|
||||||
|
|
||||||
<!-- LOGO HUTOPY -->
|
|
||||||
<router-link to="/">
|
<router-link to="/">
|
||||||
<img src="/images/hutopymedia/banners/hutopy.png"
|
<img v-if="sideBarStore.isOpen"
|
||||||
|
src="/images/hutopymedia/banners/hutopy.png"
|
||||||
alt="hutopy"
|
alt="hutopy"
|
||||||
width="300px"
|
width="300px"
|
||||||
height="64px">
|
height="64px">
|
||||||
|
<img v-else
|
||||||
|
src="/images/usersmedia/HutopyProfile/profilepictures/profileHutopyProfile01.png"
|
||||||
|
alt="hutopy"
|
||||||
|
width="42px"
|
||||||
|
height="42px">
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div v-if="creatorIsCurrentUser" class="justify-center text-center">
|
<div class="flex-grow mt-4" :class="sideBarStore.isOpen ? 'px-4' : 'px-2'">
|
||||||
<v-btn variant="flat" icon="" @click="createHtmlContent">
|
|
||||||
<v-icon>mdi-pencil</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<!-- SUBSCRIPTION SECTION -->
|
|
||||||
<div class="flex-grow px-4 mt-4">
|
|
||||||
<template v-if="authStore.isAuthenticated">
|
<template v-if="authStore.isAuthenticated">
|
||||||
<div class="font-bold"> {{ $t('sidebar.subscriptionTitle') }}</div>
|
<div class="font-bold" :class="{ 'text-center': !sideBarStore.isOpen }">
|
||||||
<!-- SUBSCRIPTION LIST -->
|
<span v-if="sideBarStore.isOpen">{{ $t('sidebar.subscriptionTitle') }}</span>
|
||||||
<subscription-list>
|
<span v-else>A</span>
|
||||||
</subscription-list>
|
</div>
|
||||||
|
<div
|
||||||
|
class="border-b border-gray-300 my-4 mx-auto"
|
||||||
|
:class="sideBarStore.isOpen ? 'w-48' : 'w-16'"
|
||||||
|
></div>
|
||||||
|
<subscription-list v-if="sideBarStore.isOpen"></subscription-list>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<v-divider class="my-4" style="border-width: 1px; border-color: black;"></v-divider>
|
<div
|
||||||
<!-- USER SECTION -->
|
class="border-b border-gray-300 my-4 mx-auto"
|
||||||
<div class="px-4 mb-4">
|
:class="sideBarStore.isOpen ? 'w-48' : 'w-16'"
|
||||||
<div class="flex items-center justify-start p-2 mb-4">
|
></div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- SECTION UTILISATEUR -->
|
||||||
|
<div :class="sideBarStore.isOpen ? 'px-4' : 'px-2'">
|
||||||
|
<div class="flex items-center justify-start p-2 mb-4" :class="!sideBarStore.isOpen ? 'my-2' : ''">
|
||||||
<img
|
<img
|
||||||
:src="userProfileStore.portraitUrl"
|
:src="userProfileStore.portraitUrl"
|
||||||
alt="Profile Image"
|
alt="Profile Image"
|
||||||
@@ -81,73 +93,52 @@ initializeLocale();
|
|||||||
class="rounded-full"
|
class="rounded-full"
|
||||||
width="42"
|
width="42"
|
||||||
height="42"
|
height="42"
|
||||||
style="max-height: 42px;"
|
style="max-height: 42px;">
|
||||||
>
|
<span v-if="sideBarStore.isOpen" class="ml-2 text-sm font-sans capitalize">
|
||||||
<span class="ml-2 text-sm font-sans capitalize">
|
|
||||||
{{ userProfileStore.alias }}
|
{{ userProfileStore.alias }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-4 mb-4">
|
||||||
<div class="flex flex-column gap-4">
|
<router-link v-if="creatorProfileStore.hasCreator" :to="`/@${creatorProfileStore.creator.name}`">
|
||||||
<!-- YOUR PAGE -->
|
<v-btn class="w-full justify-start" prepend-icon="mdi-home-account" variant="flat" :class="!sideBarStore.isOpen ? 'my-2' : ''">
|
||||||
<router-link v-if="creatorProfileStore.hasCreator"
|
<span v-if="sideBarStore.isOpen">{{ creatorProfileStore.creator.name }}</span>
|
||||||
:to="`/@${creatorProfileStore.creator.name}`">
|
|
||||||
<v-btn class="w-full justify-start"
|
|
||||||
prepend-icon="mdi-home-account"
|
|
||||||
variant="flat">
|
|
||||||
{{ creatorProfileStore.creator.name }}
|
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
||||||
<router-link v-else-if="authStore.isAuthenticated"
|
<router-link v-else-if="authStore.isAuthenticated" class="w-full justify-start"
|
||||||
class="w-full justify-start"
|
|
||||||
to="/profile?target=CreatorPage">
|
to="/profile?target=CreatorPage">
|
||||||
<v-btn class="w-100" variant="plain">Activer votre page</v-btn>
|
<v-btn class="w-full" variant="plain" :class="!sideBarStore.isOpen ? 'my-2' : ''"><span v-if="sideBarStore.isOpen">Activer votre page</span></v-btn>
|
||||||
</router-link>
|
</router-link>
|
||||||
<!-- CREATE CONTENT -->
|
|
||||||
|
|
||||||
<!-- PROFILE -->
|
<div v-if="authStore.isAuthenticated">
|
||||||
<template v-if="authStore.isAuthenticated">
|
<v-btn to="/profile" class="w-full justify-start" prepend-icon="mdi-account" variant="flat" :class="!sideBarStore.isOpen ? 'my-2' : ''">
|
||||||
<v-btn to="/profile"
|
<span v-if="sideBarStore.isOpen">{{ $t('header.myprofile') }}</span>
|
||||||
class="w-full justify-start"
|
|
||||||
prepend-icon="mdi-account"
|
|
||||||
variant="flat">
|
|
||||||
{{ $t('header.myprofile') }}
|
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</template>
|
</div>
|
||||||
|
|
||||||
<!-- LANGUAGE -->
|
<v-btn variant="flat" class="w-full justify-start" prepend-icon="mdi-translate-variant" @click="toggleLanguage" :class="!sideBarStore.isOpen ? 'my-2' : ''">
|
||||||
<v-btn
|
<span v-if="sideBarStore.isOpen">{{ selectedLanguage.value === 'fr' ? 'Fr' : 'En' }}</span>
|
||||||
variant="flat"
|
|
||||||
class="w-full justify-start"
|
|
||||||
prepend-icon="mdi-translate-variant"
|
|
||||||
@click="toggleLanguage"
|
|
||||||
>
|
|
||||||
{{ selectedLanguage === 'fr' ? 'Fr' : 'En' }}
|
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
||||||
<!-- LOGIN / LOGOUT -->
|
<div>
|
||||||
<template v-if="!authStore.isAuthenticated">
|
<v-btn @click="toggleMenu" variant="flat" class="w-full justify-start" :prepend-icon="sideBarStore.isOpen ? 'mdi-arrow-collapse-left' : 'mdi-arrow-collapse-right'" :class="!sideBarStore.isOpen ? 'my-2' : ''">
|
||||||
<v-btn to="/login"
|
<span v-if="sideBarStore.isOpen">{{ sideBarStore.isOpen ? 'Réduire' : '' }}</span>
|
||||||
variant="flat"
|
|
||||||
class="w-full justify-start"
|
|
||||||
prepend-icon="mdi-login">
|
|
||||||
Connexion
|
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</template>
|
</div>
|
||||||
<template v-else>
|
|
||||||
<v-btn @click="authStore.logout"
|
<div v-if="!authStore.isAuthenticated">
|
||||||
variant="flat"
|
<v-btn to="/login" variant="flat" class="justify-start" prepend-icon="mdi-login" :class="!sideBarStore.isOpen ? 'my-2' : ''">
|
||||||
class="w-full justify-start"
|
<span v-if="sideBarStore.isOpen">Connexion</span>
|
||||||
prepend-icon="mdi-logout">
|
|
||||||
{{ $t('header.Signout') }}
|
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</template>
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<v-btn @click="authStore.logout" variant="flat" class="justify-start" prepend-icon="mdi-logout" :class="!sideBarStore.isOpen ? 'my-2' : ''">
|
||||||
|
<span v-if="sideBarStore.isOpen">{{ $t('header.Signout') }}</span>
|
||||||
|
</v-btn>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</nav>
|
</nav>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user