ci/woodpecker/push/woodpecker Pipeline was successful
- BookPlayer : toutes les couleurs HSL en dur remplacées par variables CSS palette - Admin (sidebar, formulaires, pages, book, songs, messages, media, login) : idem - L'ambiance graphique suit maintenant la palette active partout Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
98 lines
2.7 KiB
Vue
98 lines
2.7 KiB
Vue
<template>
|
|
<div>
|
|
<div class="flex items-center justify-between mb-6">
|
|
<div>
|
|
<NuxtLink to="/admin" class="text-sm text-white/40 hover:text-white/60 transition-colors">
|
|
← Dashboard
|
|
</NuxtLink>
|
|
<h1 class="font-display text-2xl font-bold text-white mt-1">Pages</h1>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-if="pages" class="flex flex-col gap-6">
|
|
<!-- Root pages -->
|
|
<div v-if="rootPages.length">
|
|
<h2 class="font-display text-lg font-semibold text-white/80 mb-3">Pages principales</h2>
|
|
<div class="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
|
|
<NuxtLink
|
|
v-for="page in rootPages"
|
|
:key="page.path"
|
|
:to="`/admin/pages/${page.path}`"
|
|
class="page-card"
|
|
>
|
|
<div class="i-lucide-file-text h-5 w-5 text-primary mb-1" />
|
|
<span class="font-mono text-sm text-white">{{ page.label }}</span>
|
|
</NuxtLink>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Section pages -->
|
|
<div v-for="[section, sectionPages] in sections" :key="section">
|
|
<h2 class="font-display text-lg font-semibold text-white/80 mb-3">
|
|
<span class="i-lucide-folder h-4 w-4 inline-block mr-1 text-accent" />
|
|
{{ section }}
|
|
</h2>
|
|
<div class="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
|
|
<NuxtLink
|
|
v-for="page in sectionPages"
|
|
:key="page.path"
|
|
:to="`/admin/pages/${page.path}`"
|
|
class="page-card"
|
|
>
|
|
<div class="i-lucide-file-text h-5 w-5 text-primary/60 mb-1" />
|
|
<span class="font-mono text-sm text-white">{{ page.label }}</span>
|
|
</NuxtLink>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
definePageMeta({
|
|
layout: 'admin',
|
|
middleware: 'admin',
|
|
})
|
|
|
|
interface PageEntry {
|
|
path: string
|
|
label: string
|
|
section?: string
|
|
}
|
|
|
|
const { data: pages } = await useFetch<PageEntry[]>('/api/admin/content/pages')
|
|
|
|
const rootPages = computed(() =>
|
|
(pages.value ?? []).filter(p => !p.section),
|
|
)
|
|
|
|
const sections = computed(() => {
|
|
const map = new Map<string, PageEntry[]>()
|
|
for (const p of pages.value ?? []) {
|
|
if (p.section) {
|
|
if (!map.has(p.section)) map.set(p.section, [])
|
|
map.get(p.section)!.push(p)
|
|
}
|
|
}
|
|
return Array.from(map.entries())
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.page-card {
|
|
display: flex;
|
|
flex-direction: column;
|
|
padding: 1rem;
|
|
border-radius: 0.5rem;
|
|
border: 1px solid hsl(var(--color-surface-light));
|
|
background: hsl(var(--color-bg));
|
|
text-decoration: none;
|
|
transition: all 0.2s;
|
|
}
|
|
|
|
.page-card:hover {
|
|
border-color: hsl(var(--color-primary) / 0.3);
|
|
background: hsl(var(--color-surface));
|
|
}
|
|
</style>
|