11<template >
2- <div class =" h-screen flex flex-column" >
3- <TopNavbar @open-search =" isSearchVisible = true" />
4- <Splitter style =" height : calc (100vh - 4rem )" class =" mb-5" >
5- <SplitterPanel :size =" 20" :minSize =" 10" class =" flex align-items-center justify-content-center" >
6- <SidebarMenu class =" w-full h-full" />
7- </SplitterPanel >
8- <SplitterPanel :size =" 80" :minSize =" 30" >
9- <Splitter layout =" vertical" >
10- <SplitterPanel :size =" 50" :minSize =" 20" class =" flex align-items-center justify-content-center" >
11- <RequestPanel class =" w-full h-full" />
12- </SplitterPanel >
13- <SplitterPanel :size =" 50" :minSize =" 20" class =" flex align-items-center justify-content-center" >
14- <ResponsePanel class =" w-full h-full" />
15- </SplitterPanel >
16- </Splitter >
17- </SplitterPanel >
18- </Splitter >
19- <SearchPalette v-model:visible =" isSearchVisible" />
20- </div >
2+ <n-config-provider :theme =" currentTheme" :theme-overrides =" currentThemeOverrides" >
3+ <n-message-provider >
4+ <n-notification-provider >
5+ <n-global-style />
6+ <div class =" h-screen flex flex-column" >
7+ <TopNavbar @open-search =" isSearchVisible = true" @toggle-theme =" toggleTheme" :is-dark =" isDark" />
8+ <n-split
9+ direction =" horizontal"
10+ :default-size =" 0.2"
11+ :min =" 0.1"
12+ :max =" 0.4"
13+ style =" height : calc (100vh - 4rem )"
14+ >
15+ <template #1 >
16+ <SidebarMenu ref =" sidebarRef" class =" w-full h-full" />
17+ </template >
18+ <template #2 >
19+ <n-split
20+ direction =" vertical"
21+ :default-size =" 0.5"
22+ :min =" 0.2"
23+ :max =" 0.8"
24+ >
25+ <template #1 >
26+ <RequestPanel class =" w-full h-full" />
27+ </template >
28+ <template #2 >
29+ <ResponsePanel class =" w-full h-full" />
30+ </template >
31+ </n-split >
32+ </template >
33+ </n-split >
34+ <SearchPalette v-model:visible =" isSearchVisible" />
35+ </div >
36+ </n-notification-provider >
37+ </n-message-provider >
38+ </n-config-provider >
2139</template >
2240
2341<script setup lang="ts">
24- import { ref , onMounted } from ' vue' ;
42+ import { ref , onMounted , provide , computed } from ' vue' ;
43+ import { NConfigProvider , NMessageProvider , NNotificationProvider , NGlobalStyle , NSplit } from ' naive-ui' ;
44+ import { darkTheme , customDarkTheme , customLightTheme } from ' ./theme' ;
2545import TopNavbar from ' ./components/TopNavbar.vue' ;
2646import SidebarMenu from ' ./components/SidebarMenu.vue' ;
2747import RequestPanel from ' ./components/RequestPanel.vue' ;
2848import ResponsePanel from ' ./components/ResponsePanel.vue' ;
2949import SearchPalette from ' ./components/SearchPalette.vue' ;
30- import Splitter from ' primevue/splitter' ;
31- import SplitterPanel from ' primevue/splitterpanel' ;
3250import { useApiStore } from ' ./stores/api' ;
51+ import { useLocalStorage } from ' @vueuse/core' ;
3352
3453const apiStore = useApiStore ();
3554
3655const isSearchVisible = ref (false );
56+ const sidebarRef = ref ();
57+
58+ // Theme management
59+ const isDark = useLocalStorage (' theme-dark' , true );
60+
61+ const currentTheme = computed (() => isDark .value ? darkTheme : null );
62+ const currentThemeOverrides = computed (() => isDark .value ? customDarkTheme : customLightTheme );
63+
64+ const toggleTheme = () => {
65+ isDark .value = ! isDark .value ;
66+ };
67+
68+ // Provide sidebar ref and theme to children
69+ provide (' sidebarRef' , sidebarRef );
70+ provide (' isDark' , isDark );
3771
3872onMounted (async () => {
3973 await apiStore .fetchRoutes ();
@@ -50,4 +84,10 @@ onMounted(async () => {
5084.flex-column {
5185 flex-direction : column ;
5286}
87+ .w-full {
88+ width : 100% ;
89+ }
90+ .h-full {
91+ height : 100% ;
92+ }
5393 </style >
0 commit comments