default.vue
1 <template> 2 <div class="layout"> 3 <Navbar /> 4 <div class="fade-top"></div> 5 <div class="content"> 6 <slot /> 7 </div> 8 <div 9 class="fade-bottom" 10 :class="{ 'home-page': $route.path === '/' }"></div> 11 <div class="bottombar" v-if="$route.path === '/'"> 12 <p class="coding-time">{{ formattedTime }}</p> 13 <UiSelect v-model="selectedTimeRange" :items="timeRangeOptions" /> 14 </div> 15 </div> 16 </template> 17 18 <script setup lang="ts"> 19 import * as statsLib from "~~/lib/stats"; 20 import { watch } from "vue"; 21 import { useTimeRangeOptions } from "~/composables/useTimeRangeOptions"; 22 23 const stats = ref(statsLib.getStats()); 24 const timeRange = ref(statsLib.getTimeRange()); 25 const { timeRangeOptions } = useTimeRangeOptions(); 26 27 const selectedTimeRange = computed({ 28 get: () => timeRange.value, 29 set: (value: statsLib.TimeRange) => { 30 statsLib.setTimeRange(value); 31 timeRange.value = value; 32 }, 33 }); 34 35 const formattedTime = computed(() => { 36 return statsLib.formatTime(stats.value.totalSeconds || 0); 37 }); 38 39 watch([() => statsLib.getStats(), () => statsLib.getTimeRange()], () => { 40 stats.value = statsLib.getStats(); 41 timeRange.value = statsLib.getTimeRange(); 42 }); 43 </script> 44 45 <style lang="scss"> 46 .layout { 47 width: 100dvw; 48 height: 100dvh; 49 display: flex; 50 flex-direction: column; 51 box-sizing: border-box; 52 padding: 24px; 53 } 54 55 .content { 56 flex: 1; 57 overflow-y: auto; 58 height: 0; 59 margin: 0 -24px; 60 padding: 24px; 61 position: relative; 62 } 63 64 .fade-top { 65 position: absolute; 66 top: 42px; 67 height: 24px; 68 width: calc(100vw - 48px); 69 left: 24px; 70 background: linear-gradient( 71 to bottom, 72 var(--background) 20%, 73 transparent 100% 74 ); 75 z-index: 5; 76 pointer-events: none; 77 } 78 79 .fade-bottom { 80 position: absolute; 81 bottom: 18px; 82 height: 24px; 83 left: 24px; 84 width: calc(100vw - 48px); 85 background: linear-gradient(to top, var(--background) 20%, transparent 100%); 86 z-index: 5; 87 pointer-events: none; 88 89 &.home-page { 90 bottom: 42px; 91 } 92 } 93 94 .bottombar { 95 display: flex; 96 justify-content: space-between; 97 align-items: center; 98 z-index: 10; 99 height: 18px; 100 overflow: visible; 101 color: var(--text-secondary); 102 } 103 </style>