feat: wire QuickCaptureBar/FAB into App.vue, add Settings route

This commit is contained in:
pyr0ball 2026-05-11 09:25:49 -07:00
parent 430343fc43
commit 9fdb1b59e8
2 changed files with 33 additions and 5 deletions

View file

@ -12,11 +12,15 @@
:to="link.to" :to="link.to"
class="px-3 py-1 rounded text-sm text-text-muted hover:text-text-primary hover:bg-surface-raised transition-colors" class="px-3 py-1 rounded text-sm text-text-muted hover:text-text-primary hover:bg-surface-raised transition-colors"
active-class="text-accent bg-accent-muted" active-class="text-accent bg-accent-muted"
> >{{ link.label }}</RouterLink>
{{ link.label }}
</RouterLink>
</div> </div>
<div class="ml-auto flex items-center gap-3"> <div class="ml-auto flex items-center gap-3">
<RouterLink
to="/settings"
class="text-text-dim hover:text-text-primary transition-colors leading-none"
title="Settings"
aria-label="Settings"
></RouterLink>
<button <button
@click="toggleTheme" @click="toggleTheme"
:title="isDark ? 'Switch to light mode' : 'Switch to dark mode'" :title="isDark ? 'Switch to light mode' : 'Switch to dark mode'"
@ -26,14 +30,25 @@
<StatusDot /> <StatusDot />
</div> </div>
</nav> </nav>
<!-- Persistent quick-capture bar (topbar mode) -->
<QuickCaptureBar v-if="entryPointStyle === 'topbar'" />
<RouterView /> <RouterView />
<!-- FAB entry point (fab mode) -->
<QuickCaptureFab v-if="entryPointStyle === 'fab'" />
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue' import { ref, onMounted } from 'vue'
import { RouterLink, RouterView } from 'vue-router' import { RouterLink, RouterView } from 'vue-router'
import StatusDot from '@/components/StatusDot.vue' import StatusDot from '@/components/StatusDot.vue'
import QuickCaptureBar from '@/components/QuickCaptureBar.vue'
import QuickCaptureFab from '@/components/QuickCaptureFab.vue'
const BASE = import.meta.env.BASE_URL.replace(/\/$/, '')
const navLinks = [ const navLinks = [
{ to: '/dashboard', label: 'Dashboard' }, { to: '/dashboard', label: 'Dashboard' },
@ -44,11 +59,22 @@ const navLinks = [
{ to: '/sources', label: 'Sources' }, { to: '/sources', label: 'Sources' },
] ]
const isDark = ref(document.documentElement.classList.contains('dark')) const isDark = ref(document.documentElement.classList.contains('dark'))
const entryPointStyle = ref<'topbar' | 'fab'>('topbar')
function toggleTheme() { function toggleTheme() {
isDark.value = !isDark.value isDark.value = !isDark.value
document.documentElement.classList.toggle('dark', isDark.value) document.documentElement.classList.toggle('dark', isDark.value)
localStorage.setItem('ts-theme', isDark.value ? 'dark' : 'light') localStorage.setItem('ts-theme', isDark.value ? 'dark' : 'light')
} }
onMounted(async () => {
try {
const res = await fetch(`${BASE}/api/settings`)
if (res.ok) {
const data = await res.json()
entryPointStyle.value = data.entry_point_style ?? 'topbar'
}
} catch { /* default to topbar */ }
})
</script> </script>

View file

@ -5,6 +5,7 @@ import DiagnoseView from '@/views/DiagnoseView.vue'
import SourcesView from '@/views/SourcesView.vue' import SourcesView from '@/views/SourcesView.vue'
import IncidentsView from '@/views/IncidentsView.vue' import IncidentsView from '@/views/IncidentsView.vue'
import BundlesView from '@/views/BundlesView.vue' import BundlesView from '@/views/BundlesView.vue'
import SettingsView from '@/views/SettingsView.vue'
export default createRouter({ export default createRouter({
history: createWebHistory(import.meta.env.BASE_URL), history: createWebHistory(import.meta.env.BASE_URL),
@ -16,5 +17,6 @@ export default createRouter({
{ path: '/incidents', component: IncidentsView }, { path: '/incidents', component: IncidentsView },
{ path: '/bundles', component: BundlesView }, { path: '/bundles', component: BundlesView },
{ path: '/sources', component: SourcesView }, { path: '/sources', component: SourcesView },
{ path: '/settings', component: SettingsView },
], ],
}) })