Files
portfolio-generator-app/layouts/default.vue
Valentin Le Moign 59dfbe4155 Générateur de portfolios PDF Figures Libres (app Nuxt autonome)
App Nuxt 3 + Nuxt UI qui lit les projets du CMS Grav et compose des portfolios
A3 paysage exportés en PDF (gabarit book_v3) : composeur WYSIWYG, templates
cover/toc/projet/grille/page libre, pipeline Playwright + Ghostscript, gel du
contenu à la génération, partage public opt-in.

Dépôt autonome : Dockerfile (base Playwright + Ghostscript + ffmpeg + rsync) inclus.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 18:37:09 +02:00

67 lines
2.0 KiB
Vue

<script setup lang="ts">
const route = useRoute()
const toast = useToast()
const syncing = ref(false)
async function refreshContent() {
syncing.value = true
try {
const result = await $fetch<{ ok: boolean, summary: string }>('/api/sync', {
method: 'POST',
timeout: 900_000,
})
toast.add({
title: result.ok ? 'Contenu rafraîchi' : 'Synchronisation en échec',
description: result.summary,
color: result.ok ? 'success' : 'error',
})
if (result.ok) await refreshNuxtData()
} catch {
toast.add({ title: 'Échec de la synchronisation', color: 'error' })
} finally {
syncing.value = false
}
}
async function logout() {
await $fetch('/api/auth/logout', { method: 'POST' })
navigateTo('/login')
}
</script>
<template>
<div class="min-h-screen bg-[var(--fl-base)] dark:bg-neutral-950">
<header
v-if="route.path !== '/login'"
class="sticky top-0 z-40 border-b border-neutral-200 bg-white/90 backdrop-blur dark:border-neutral-800 dark:bg-neutral-900/90"
>
<UContainer class="flex h-14 items-center gap-6">
<NuxtLink to="/" class="flex items-center gap-2 font-bold text-[var(--fl-ink)] dark:text-white">
<span class="flex size-7 items-center justify-center rounded-full bg-[var(--fl-ink)] text-xs text-white">FL</span>
Portfolios
</NuxtLink>
<div class="ml-auto flex items-center gap-1">
<UTooltip text="Actualise les données depuis Grav">
<UButton
icon="i-lucide-refresh-cw"
label="Rafraîchir"
variant="ghost"
color="neutral"
:loading="syncing"
@click="refreshContent"
/>
</UTooltip>
<UButton
icon="i-lucide-log-out"
variant="ghost"
color="neutral"
aria-label="Se déconnecter"
@click="logout"
/>
</div>
</UContainer>
</header>
<slot />
</div>
</template>