Files
osdb-1-claude-opusplan/frontend/src/views/PublicationList.vue
T
juliaandClaude Sonnet 4.6 1b381d9385 feat: protect write endpoints with JWT auth (story #08)
Add bcrypt user file auth, JWT middleware on all write routes, Pinia
authStore with localStorage persistence, login view with redirect
support, and v-if guards on all CRUD controls and admin nav link.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-19 11:18:42 +02:00

60 lines
1.9 KiB
Vue

<script setup lang="ts">
import { onMounted } from 'vue'
import { usePublicationStore } from '../stores/publicationStore'
import { useAuthStore } from '../stores/authStore'
const store = usePublicationStore()
const auth = useAuthStore()
onMounted(async () => {
try {
await store.fetchPublications()
} catch {
// error already set in store
}
})
</script>
<template>
<div class="mx-auto max-w-4xl p-6">
<div class="mb-4 flex items-center justify-between">
<h1 class="text-2xl font-bold">Publikationen</h1>
<router-link
v-if="auth.isLoggedIn"
to="/publications/new"
class="rounded bg-green-600 px-4 py-2 text-white hover:bg-green-700"
>
Neue Publikation
</router-link>
</div>
<div v-if="store.loading" class="text-gray-500">Lade</div>
<div v-else-if="store.error" class="text-red-600">{{ store.error }}</div>
<div v-else-if="store.publications.length === 0" class="text-gray-500">
Keine Publikationen vorhanden.
</div>
<table v-else class="w-full border-collapse text-sm">
<thead>
<tr class="bg-gray-100 text-left">
<th class="border px-3 py-2">Titel</th>
<th class="border px-3 py-2">Autor</th>
<th class="border px-3 py-2">OSDB Kürzel</th>
<th class="border px-3 py-2"></th>
</tr>
</thead>
<tbody>
<tr v-for="pub in store.publications" :key="pub.id" class="hover:bg-gray-50">
<td class="border px-3 py-2">{{ pub.title }}</td>
<td class="border px-3 py-2">{{ pub.author ?? '—' }}</td>
<td class="border px-3 py-2 font-mono text-xs">{{ pub.osdb_pub_id }}</td>
<td class="border px-3 py-2">
<router-link :to="`/publications/${pub.id}`" class="text-blue-600 hover:underline">
Details
</router-link>
</td>
</tr>
</tbody>
</table>
</div>
</template>