my-favs/frontend/src/App.vue
RamonCalvo 8caa836102
All checks were successful
Deploy / deploy (push) Successful in 9s
feat: add version footer with VITE_DEPLOYED_VERSION
Shows v:dev locally and v:<commit-hash> in deployed builds.
Variable passed as build arg through Docker Compose.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 20:47:23 -06:00

118 lines
3.3 KiB
Vue

<script setup>
import { ref, computed, watch } from 'vue'
import { useAuth } from './composables/useAuth.js'
import { getBookmarks, triggerCategorize } from './api.js'
import { sections } from './sections.js'
import BookmarkForm from './components/BookmarkForm.vue'
import BookmarkList from './components/BookmarkList.vue'
const { user, loading, loginWithGoogle, logout } = useAuth()
const bookmarks = ref([])
const activeIndex = ref(4) // N = default (primer plano)
const categorizing = ref(false)
const status = ref('')
const currentSection = computed(() => sections[activeIndex.value])
const filtered = computed(() => {
const letter = currentSection.value.letter.toLowerCase()
return bookmarks.value.filter(b => {
if (!b.category) return letter === 'n'
return b.category.charAt(0).toLowerCase() === letter
})
})
const year = new Date().getFullYear()
const version = import.meta.env.VITE_DEPLOYED_VERSION || 'dev'
async function load() {
if (!user.value) return
bookmarks.value = await getBookmarks()
}
function onCreated(bookmark) {
bookmarks.value.unshift(bookmark)
}
function onDeleted(id) {
bookmarks.value = bookmarks.value.filter(b => b.id !== id)
}
async function categorize() {
categorizing.value = true
status.value = ''
try {
const res = await triggerCategorize()
status.value = `${res.categorized} categorized`
await load()
} catch (e) {
status.value = `Error: ${e.message}`
} finally {
categorizing.value = false
}
}
watch(user, (u) => { if (u) load() })
</script>
<template>
<!-- Loading -->
<div v-if="loading" class="loading-screen">loading...</div>
<!-- Login -->
<div v-else-if="!user" class="login-screen">
<div class="login-title">ramon</div>
<div class="login-subtitle">personal bookmarks</div>
<button class="btn-google" @click="loginWithGoogle">Sign in with Google</button>
</div>
<!-- App -->
<div v-else class="layout">
<div class="panel-left">
<div class="header-bar">
<span class="user-email">{{ user.email }}</span>
<button class="btn-logout" @click="logout">logout</button>
</div>
<div class="section-subtitle">{{ currentSection.subtitle }}</div>
<div class="section-title">{{ currentSection.title }}</div>
<div class="section-divider"></div>
<div class="section-meta">
<span class="section-year">{{ year }}</span>
<span class="section-count">{{ filtered.length }} links</span>
</div>
<div class="section-description">{{ currentSection.description }}</div>
<BookmarkForm @created="onCreated" />
<div class="actions-bar">
<button class="btn-action" @click="categorize" :disabled="categorizing">
{{ categorizing ? 'categorizing...' : 'categorize' }}
</button>
<span v-if="status" class="status">{{ status }}</span>
</div>
<div class="content-area">
<BookmarkList :bookmarks="filtered" @deleted="onDeleted" />
</div>
</div>
<nav class="panel-right">
<button
v-for="(section, i) in sections"
:key="section.letter"
class="nav-tab"
:class="{ active: activeIndex === i }"
@click="activeIndex = i"
>{{ section.letter }}</button>
</nav>
<footer class="footer">
<span class="footer-version">v:{{ version }}</span>
</footer>
</div>
</template>