feat(aep): carte AEP — push Gitea 2026-04-28
This commit is contained in:
123
pages/fiche/[id].vue
Normal file
123
pages/fiche/[id].vue
Normal file
@@ -0,0 +1,123 @@
|
||||
<template>
|
||||
<div class="min-h-screen" style="background: var(--nav-bg);">
|
||||
<div class="max-w-4xl mx-auto px-4 py-6">
|
||||
|
||||
<!-- ── Bouton retour carte (préserve filtres URL) ─── -->
|
||||
<NuxtLink
|
||||
:to="retourUrl"
|
||||
class="inline-flex items-center gap-1.5 text-sm mb-6 rounded-lg px-3 py-1.5 transition-colors"
|
||||
style="color: var(--nav-text); background: var(--nav-bg-alt);"
|
||||
aria-label="Retour à la carte"
|
||||
>
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
||||
<line x1="19" y1="12" x2="5" y2="12"/>
|
||||
<polyline points="12 19 5 12 12 5"/>
|
||||
</svg>
|
||||
Retour à la carte
|
||||
</NuxtLink>
|
||||
|
||||
<!-- ── Chargement ──────────────────────────────────── -->
|
||||
<div v-if="pending" class="py-16 text-center text-sm" style="color: var(--nav-text-muted);">
|
||||
Chargement de la fiche…
|
||||
</div>
|
||||
|
||||
<!-- ── Erreur ──────────────────────────────────────── -->
|
||||
<div v-else-if="error" class="py-16 text-center">
|
||||
<p class="text-lg font-semibold mb-2" style="color: var(--nav-text);">Fiche introuvable</p>
|
||||
<p class="text-sm" style="color: var(--nav-text-muted);">L'organisation demandée n'existe pas ou a été supprimée.</p>
|
||||
</div>
|
||||
|
||||
<!-- ── Contenu ─────────────────────────────────────── -->
|
||||
<template v-else-if="org">
|
||||
|
||||
<!-- FicheDetail -->
|
||||
<FicheDetail :org="org" />
|
||||
|
||||
<!-- Séparateur -->
|
||||
<div class="mb-6" style="height: 1px; background: var(--nav-bg-alt);"></div>
|
||||
|
||||
<!-- CommentSection -->
|
||||
<CommentSection :org-id="org.Id" :refresh="commentRefreshTick" />
|
||||
|
||||
<!-- CommentForm -->
|
||||
<CommentForm :org-id="org.Id" @submitted="onCommentSubmitted" />
|
||||
|
||||
</template>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Org } from '~/types/org'
|
||||
|
||||
// ── Params & route ────────────────────────────────────────────────────
|
||||
const route = useRoute()
|
||||
const orgId = route.params.id as string
|
||||
|
||||
// ── Retour carte — préserve les filtres via sessionStorage ────────────
|
||||
const retourUrl = ref('/')
|
||||
|
||||
onMounted(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
const stored = sessionStorage.getItem('nav_back_filters')
|
||||
if (stored) {
|
||||
retourUrl.value = `/?${stored}`
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// ── Fetch fiche SSR ───────────────────────────────────────────────────
|
||||
const { data: org, pending, error } = await useFetch<Org>(`/api/fiche/${orgId}`, {
|
||||
key: `fiche-${orgId}`,
|
||||
})
|
||||
|
||||
// ── Commentaires — tick de rafraîchissement ───────────────────────────
|
||||
const commentRefreshTick = ref(0)
|
||||
|
||||
function onCommentSubmitted() {
|
||||
// Incrémenter pour que CommentSection se recharge
|
||||
commentRefreshTick.value++
|
||||
}
|
||||
|
||||
// ── SEO dynamiques ────────────────────────────────────────────────────
|
||||
const description = computed(() => {
|
||||
if (!org.value) return 'Fiche organisation — AEP'
|
||||
const desc =
|
||||
org.value.description_enrichie ||
|
||||
org.value.description_user ||
|
||||
org.value.description ||
|
||||
''
|
||||
return desc.substring(0, 160).trim()
|
||||
})
|
||||
|
||||
useHead({
|
||||
title: computed(() =>
|
||||
org.value ? `${org.value.nom} — AEP` : 'Fiche organisation — AEP'
|
||||
),
|
||||
meta: [
|
||||
{
|
||||
name: 'description',
|
||||
content: description,
|
||||
},
|
||||
{
|
||||
property: 'og:title',
|
||||
content: computed(() =>
|
||||
org.value ? `${org.value.nom} — AEP` : 'AEP'
|
||||
),
|
||||
},
|
||||
{
|
||||
property: 'og:description',
|
||||
content: description,
|
||||
},
|
||||
{
|
||||
property: 'og:image',
|
||||
content: '/og-default.png', // logo par défaut dans public/
|
||||
},
|
||||
{
|
||||
property: 'og:type',
|
||||
content: 'article',
|
||||
},
|
||||
],
|
||||
})
|
||||
</script>
|
||||
Reference in New Issue
Block a user