Textes projet éditables suivant Grav + écriture atomique du store

- Champ Présentation prérempli avec le texte Grav, suivi modifié/synchro
  (textOverride undefined = suit Grav, sinon figé ; bouton Réinitialiser)
- Fix génération PDF : savePortfolio écrit en atomique (temp+rename) pour
  éviter la corruption de lecture par l'autosave concurrent du rendu print
- Toast d'échec de génération explicite (message serveur)
- Refonte architecture visuelle, fond unifié white/tint/full, dispositions
  couverture bandeau/colonne, instantané public complet, index 3 lignes
This commit is contained in:
2026-07-06 13:26:06 +02:00
parent 59dfbe4155
commit ef1f14335d
22 changed files with 750 additions and 334 deletions

View File

@@ -0,0 +1,42 @@
<script setup lang="ts">
// Bouton « Rafraîchir » : resynchronise le contenu depuis Grav. Placé à côté de
// « Générer le PDF » (éditeur) et « Nouveau portfolio » (index).
withDefaults(defineProps<{ size?: 'xs' | 'sm' | 'md' }>(), { size: 'sm' })
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
}
}
</script>
<template>
<UTooltip text="Actualise les données depuis Grav">
<UButton
icon="i-lucide-refresh-cw"
label="Rafraîchir"
:size="size"
variant="ghost"
color="neutral"
:loading="syncing"
@click="refreshContent"
/>
</UTooltip>
</template>