this repo has no descr,ription vt3e.cat

feat: uses page

vt3e.cat fab1c6e8 0229495b

verified
+224 -4
+5 -4
pkgs/web/src/router/index.ts
··· 11 11 12 12 const HomeView = () => import('../views/HomeView.vue') 13 13 const ProjectsView = () => import('../views/ProjectsView.vue') 14 + const UsesView = () => import('../views/UsesView.vue') 14 15 const AboutView = () => import('../views/AboutView.vue') 15 16 16 17 declare module 'vue-router' { ··· 100 101 component: AboutView, 101 102 meta: { 102 103 title: 'about', 103 - bg: AccentColour.Teal 104 + bg: AccentColour.Rosewater 104 105 } 105 106 }, 106 107 { ··· 118 119 { 119 120 path: '/uses', 120 121 name: 'uses', 121 - component: ProjectsView, 122 + component: UsesView, 122 123 meta: { 123 124 isCard: true, 124 125 title: '/uses', 125 126 icon: IconLaptopWindowsOutlineRounded(), 126 127 gridArea: 'area-uses', 127 - bg: AccentColour.Mauve 128 + bg: AccentColour.Sky 128 129 } 129 130 }, 130 131 { ··· 136 137 title: 'gallery', 137 138 icon: IconAutoAwesomeMosaicOutline(), 138 139 gridArea: 'area-gallery', 139 - bg: AccentColour.Sapphire 140 + bg: AccentColour.Lavender 140 141 } 141 142 } 142 143 ],
+219
pkgs/web/src/views/UsesView.vue
··· 1 + <script setup lang="ts"> 2 + import CardLayout from '@/components/Card/CardLayout.vue' 3 + 4 + interface UseItem { 5 + label: string 6 + value: string 7 + subtext?: string 8 + link?: string 9 + } 10 + 11 + interface UseSection { 12 + title: string 13 + purpose?: string 14 + description?: string 15 + category?: 'hardware' | 'software' 16 + items: UseItem[] 17 + } 18 + 19 + const useSections: UseSection[] = [ 20 + { 21 + title: 'dahlia', 22 + description: 'my main daily driver desktop computer', 23 + category: 'hardware', 24 + items: [ 25 + { label: 'purpose', value: 'desktop' }, 26 + { label: 'operating system', value: 'nixos 25.05' }, 27 + { label: 'ram', value: '16gb' }, 28 + { label: 'cpu', value: 'intel core i5-3470' }, 29 + { label: 'gpu', value: 'rx 6400' }, 30 + ], 31 + }, 32 + { 33 + title: 'ivy', 34 + description: 'my home server', 35 + category: 'hardware', 36 + items: [ 37 + { label: 'purpose', value: 'server' }, 38 + { label: 'operating system', value: 'nixos 25.05' }, 39 + { label: 'model', value: 'hp proliant dl360 g9' }, 40 + { label: 'ram', value: '48gb' }, 41 + { label: 'cpu', value: 'intel xeon e5-2620 v4 x2' }, 42 + ], 43 + }, 44 + { 45 + title: 'azalea', 46 + description: 47 + "my [deprecated] home server that used to host my pds and website before ivy took over, it's now used for miscellaneous tasks", 48 + category: 'hardware', 49 + items: [ 50 + { label: 'purpose', value: 'server' }, 51 + { label: 'operating system', value: 'nixos 25.05' }, 52 + { label: 'model', value: 'raspberry pi 4b' }, 53 + { label: 'ram', value: '8gb' }, 54 + { label: 'cpu', value: 'cortex-a72' }, 55 + ], 56 + }, 57 + { 58 + title: 'phone', 59 + description: 'my daily driver phone', 60 + category: 'hardware', 61 + items: [ 62 + { label: 'model', value: 'pixel 9a', subtext: 'google' }, 63 + { label: 'os', value: 'android 16' }, 64 + ], 65 + }, 66 + ] 67 + </script> 68 + 69 + <template> 70 + <CardLayout title="placeholder!"> 71 + <div class="uses-sections"> 72 + <section v-for="section in useSections" :key="section.title" class="uses-section"> 73 + <div class="section-header"> 74 + <div class="title-group"> 75 + <span class="badge">{{ section.category }}</span> 76 + <h2 class="section-title">{{ section.title }}</h2> 77 + </div> 78 + <p class="section-description"> 79 + {{ section.description }} 80 + </p> 81 + </div> 82 + 83 + <table class="uses-table"> 84 + <tbody> 85 + <tr v-for="item in section.items" :key="item.label" class="item-row"> 86 + <td class="item-label">{{ item.label }}</td> 87 + <td class="item-value"> 88 + <span v-if="item.link"> 89 + <a :href="item.link" target="_blank" rel="noopener noreferrer"> 90 + {{ item.value }} 91 + </a> 92 + </span> 93 + <span v-else>{{ item.value }}</span> 94 + <span v-if="item.subtext" class="item-subtext"> 95 + {{ item.subtext }} 96 + </span> 97 + </td> 98 + </tr> 99 + </tbody> 100 + </table> 101 + </section> 102 + </div> 103 + </CardLayout> 104 + </template> 105 + 106 + <style lang="scss" scoped> 107 + .uses-sections { 108 + display: flex; 109 + flex-direction: column; 110 + gap: 0.25rem; 111 + } 112 + 113 + .uses-section { 114 + display: grid; 115 + grid-template-columns: 40% 60%; 116 + overflow: hidden; 117 + background-color: hsla(var(--surface0) / 1); 118 + padding: 0.5rem; 119 + 120 + border-radius: 0.5rem; 121 + &:first-child { 122 + border-radius: 1rem 1rem 0.5rem 0.5rem; 123 + } 124 + &:last-child { 125 + border-radius: 0.5rem 0.5rem 1rem 1rem; 126 + } 127 + 128 + .section-header { 129 + .title-group { 130 + display: flex; 131 + flex-direction: column; 132 + 133 + span.badge { 134 + align-self: flex-start; 135 + background-color: hsla(var(--accent) / 0.1); 136 + color: hsl(var(--accent)); 137 + padding: 0.25rem 0.5rem; 138 + font-size: 0.75rem; 139 + font-weight: 700; 140 + border-radius: 5rem; 141 + user-select: none; 142 + } 143 + 144 + h2.section-title { 145 + font-size: 2rem; 146 + font-weight: 900; 147 + } 148 + } 149 + .section-description { 150 + font-size: 1rem; 151 + color: hsl(var(--subtext1)); 152 + } 153 + } 154 + 155 + @media (max-width: 800px) { 156 + border-radius: 0; 157 + grid-template-columns: 1fr; 158 + gap: 1rem; 159 + } 160 + 161 + .uses-table { 162 + width: 100%; 163 + border-collapse: separate; 164 + border-spacing: 0; 165 + overflow: hidden; 166 + table-layout: fixed; 167 + background-color: hsla(var(--surface0) / 0.1); 168 + border-radius: 0.5rem; 169 + border: 1px solid hsla(var(--overlay1) / 0.25); 170 + 171 + * { 172 + transition: none; 173 + } 174 + 175 + th:first-child, 176 + td:first-child { 177 + width: 40%; 178 + } 179 + 180 + th:last-child, 181 + td:last-child { 182 + width: 60%; 183 + } 184 + 185 + td { 186 + padding: 0.75rem; 187 + color: hsl(var(--text)); 188 + font-size: 1rem; 189 + font-weight: 500; 190 + 191 + .item-subtext { 192 + display: block; 193 + font-size: 0.8rem; 194 + color: hsl(var(--subtext0)); 195 + font-weight: normal; 196 + margin-top: 0.15rem; 197 + } 198 + } 199 + 200 + tbody { 201 + tr { 202 + --opacity: 0.2; 203 + background-color: hsla(var(--overlay0) / 0.15); 204 + &:nth-child(even) { 205 + --opacity: 0.15; 206 + background-color: hsla(var(--overlay0) / 0.05); 207 + } 208 + &:hover { 209 + background-color: hsla(var(--overlay1) / var(--opacity)); 210 + } 211 + } 212 + 213 + tr:last-child td { 214 + border-bottom: none; 215 + } 216 + } 217 + } 218 + } 219 + </style>