Sidebar that overlapping with my page content
Hi everyone, i need help with some issue with my frontend code that my sidebar overlapping the content page (look at the image).on that sidebar i have few functionality like : toggle-sidebar for open sidebar when it on mobile mode , sidebar menu with accordion with presist the sidebar menu with accordionn that when navigation to another page is unchanged. when i don't presist sidebar menu accordion it's not overlapping, but after i add presist menu accordion my sidebar start overlapping. it's my first project using tailwind and vue so i don't know how to fix it, i'm already use gpt and it doesn't work.

Here my code file :
Dashboard.vue as layout
<template>
<div class="min-h-screen bg-gray-50 dark:bg-gray-900">
<!-- Header -->
<Header @toggle-sidebar="toggleSidebar" />
<!-- Sidebar -->
<Sidebar :isSidebarOpen="isSidebarOpen" @close-sidebar="closeSidebar" />
<!-- Content Container (Fix Overlapping Issue) -->
<div v-if="isSidebarOpen == true" id="main-content"
class="relative overflow-y-auto bg-gray-50 dark:bg-gray-900 transition-all duration-300 lg:ml-64"
style="margin-top: 4rem; height: calc(100vh - 4rem);"
>
<main class="p-6">
<Breadcrumb />
<slot></slot>
</main>
</div>
<div v-else id="main-content"
class="relative overflow-y-auto bg-gray-50 dark:bg-gray-900 transition-all duration-300 ml-0"
style="margin-top: 4rem; height: calc(100vh - 4rem);"
>
<main class="p-6">
<Breadcrumb />
<slot></slot>
</main>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import Header from '../partials/navbar.vue';
import Sidebar from '../partials/sidebar.vue';
import Breadcrumb from '../partials/Breadcrumb.vue';
// Sidebar state
const isSidebarOpen = ref(true);
// Load sidebar state from localStorage on page load
onMounted(() => {
const storedSidebarState = localStorage.getItem('isSidebarOpen');
if (storedSidebarState) {
isSidebarOpen.value = JSON.parse(storedSidebarState);
}
});
// Function to toggle sidebar and store the state
const toggleSidebar = () => {
isSidebarOpen.value = !isSidebarOpen.value;
localStorage.setItem('isSidebarOpen', JSON.stringify(isSidebarOpen.value));
};
// Function to close sidebar and store the state
const closeSidebar = () => {
isSidebarOpen.value = false;
localStorage.setItem('isSidebarOpen', JSON.stringify(isSidebarOpen.value));
};
</script>
Sidebar.vue
<template>
<aside
:class="{
'-translate-x-full': !isSidebarOpen,
'translate-x-0': isSidebarOpen
}"
class="fixed top-0 left-0 z-20 flex flex-col
h-screen pt-16 bg-white border-r
border-gray-200 shadow-md dark:bg-gray-800
dark:border-gray-700 transition-transform duration-300
lg:translate-x-0 w-64 !important"
>
<div class="flex flex-col flex-1 overflow-y-auto">
<nav class="px-4 py-2 space-y-2">
<!-- Loop Through Sidebar Items -->
<template v-for="(item, index) in sidebarItems" :key="index">
<!-- Simple Link -->
<Link v-if="item.type === 'link'" :href="item.route" class="block px-4 py-2 text-gray-700 rounded-md hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700">
{{ item.title }}
</Link>
<!-- Accordion -->
<div v-else-if="item.type === 'accordion'">
<button
@click="toggleDropdown(index)"
class="flex items-center justify-between w-full px-4 py-2 text-gray-700 rounded-md hover:bg-gray-100 dark:text-gray-300 dark:hover:bg-gray-700"
>
<span>{{ item.title }}</span>
<span :class="dropdownOpen[index] ? 'rotate-180' : ''" class="transition-transform">
▼
</span>
</button>
<!-- Dropdown Links -->
<div v-show="dropdownOpen[index]" class="ml-4 space-y-1">
<Link v-for="(link, i) in item.links" :key="i" :href="link.route" class="block px-4 py-2 text-gray-600 rounded-md hover:bg-gray-200 dark:text-gray-400 dark:hover:bg-gray-700">
{{ link.name }}
</Link>
</div>
</div>
</template>
</nav>
</div>
</aside>
<!-- Sidebar Backdrop (Mobile) -->
<div
@click="$emit('close-sidebar')"
:class="{ 'hidden': !isSidebarOpen, 'block': isSidebarOpen }"
class="fixed inset-0 z-10 bg-black bg-opacity-50 lg:hidden"
></div>
</template>
<script setup>
import { ref, defineProps, defineEmits, onMounted } from 'vue';
import { Link } from '@inertiajs/vue3';
import sidebarItems from '../../config/sidebarItems.ts';
// Sidebar State
defineProps({ isSidebarOpen: Boolean });
defineEmits(['close-sidebar']);
// Dropdown States
const dropdownOpen = ref({});
// Load saved state on component mount
onMounted(() => {
const savedState = localStorage.getItem('sidebarAccordionState');
if (savedState) {
dropdownOpen.value = JSON.parse(savedState);
}
});
const toggleDropdown = (index) => {
// Toggle the state
dropdownOpen.value = {
...dropdownOpen.value,
[index]: !dropdownOpen.value[index]
};
// Persist the entire state to localStorage
localStorage.setItem('sidebarAccordionState', JSON.stringify(dropdownOpen.value));
};
</script>
Navbar.vue
<template>
<nav class="fixed top-0 left-0 z-30 w-full bg-white border-b
border-gray-200 dark:bg-gray-800 dark:border-gray-700 h-16">
<div class="flex items-center justify-between px-4 py-3 lg:px-6">
<!-- Left Section: Custom Sidebar Toggle -->
<button
@click="$emit('toggle-sidebar')"
class="lg:hidden p-2 text-gray-700 rounded-md dark:text-gray-200 hover:bg-gray-200 dark:hover:bg-gray-700"
>
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16m-7 6h7"></path>
</svg>
</button>
<!-- Center Section: Logo -->
<div class="flex items-center space-x-3">
<img src="#" alt="YTMP Logo" class="h-8 w-auto" />
<span class="text-lg font-semibold text-gray-900 dark:text-white">ADMIN YTMP</span>
</div>
<!-- Right Section (Optional) -->
<div>
<!-- Add any extra items like user profile or settings here -->
</div>
</div>
</nav>
</template>
<script setup>
defineEmits(['toggle-sidebar']);
</script>
Page.vue
<template>
<Dashboard>
<!-- Page Content -->
<div>
<h2 class="text-xl font-bold">Welcome to the Page</h2>
<p class="mt-2 text-gray-700">This is your main content area.</p>
<div class="mt-4 p-6 bg-white rounded-lg shadow dark:bg-gray-700 dark:shadow-gray-500">Example Card</div>
</div>
</Dashboard>
</template>
<script setup>
import Dashboard from '../../Layouts/_default/Dashboard.vue';
</script>
Please or to participate in this conversation.