feat(codev): skip fiche + annuaire table sticky + page QR code

This commit is contained in:
Jules Neny
2026-05-07 00:04:42 +02:00
parent 606b9f0a47
commit 142e5cf787
3 changed files with 226 additions and 17 deletions

View File

@@ -9,12 +9,12 @@
{{ fiches.length }} fiche{{ fiches.length !== 1 ? 's' : '' }} - clique sur un nom pour voir le detail
</template>
</p>
<NuxtLink to="/codev/qr" class="qr-link" title="QR Code">[ QR ]</NuxtLink>
</header>
<div class="codev-tabs">
<button :class="{ active: tab === 'carto' }" @click="tab = 'carto'" type="button">Carto</button>
<button :class="{ active: tab === 'besoins' }" @click="tab = 'besoins'" type="button">Besoins</button>
<button :class="{ active: tab === 'competences' }" @click="tab = 'competences'" type="button">Compétences</button>
<button :class="{ active: tab === 'annuaire' }" @click="tab = 'annuaire'" type="button">Annuaire</button>
</div>
<div v-if="tab === 'carto'">
@@ -81,22 +81,32 @@
</div>
</div>
<div v-else-if="tab === 'besoins'" class="list-view">
<div v-for="f in fiches" :key="f.id" class="list-card">
<div class="list-card-name">{{ f.nom }}</div>
<p class="list-card-text">{{ f.besoin }}</p>
<NuxtLink :to="`/codev/fiche?id=${f.id}`" class="list-card-link">Modifier</NuxtLink>
</div>
<div v-if="fiches.length === 0" class="list-empty">Aucune fiche. <NuxtLink to="/codev/fiche">Ajouter la mienne</NuxtLink></div>
</div>
<div v-else-if="tab === 'annuaire'" class="annuaire-wrap">
<div v-else-if="tab === 'competences'" class="list-view">
<div v-for="f in fiches" :key="f.id" class="list-card">
<div class="list-card-name">{{ f.nom }}</div>
<p class="list-card-text">{{ f.offre }}</p>
<NuxtLink :to="`/codev/fiche?id=${f.id}`" class="list-card-link">Modifier</NuxtLink>
<div v-if="fiches.length === 0" class="list-empty">
Aucune fiche. <NuxtLink to="/codev/fiche">Ajouter la mienne</NuxtLink>
</div>
<div v-if="fiches.length === 0" class="list-empty">Aucune fiche. <NuxtLink to="/codev/fiche">Ajouter la mienne</NuxtLink></div>
<div v-else class="annuaire-scroll">
<table class="annuaire-table">
<thead>
<tr>
<th class="col-nom">Prénom</th>
<th class="col-besoin">Besoin</th>
<th class="col-offre">Ce que j'offre</th>
</tr>
</thead>
<tbody>
<tr v-for="f in fiches" :key="f.id" @click="navigateTo(`/codev/fiche?id=${f.id}`)" class="annuaire-row">
<td class="col-nom">{{ f.nom }}</td>
<td class="col-besoin">{{ f.besoin }}</td>
<td class="col-offre">{{ f.offre }}</td>
</tr>
</tbody>
</table>
</div>
<p class="annuaire-hint">Clique sur une ligne pour modifier la fiche</p>
</div>
<!-- FAB ajouter une fiche -->
@@ -141,7 +151,7 @@ const fiches = computed(() => data.value?.list ?? [])
const matches = ref<CodevMatch[]>([])
const mode = ref<'none' | 'solution' | 'alliance' | 'surprise'>('none')
const showLabels = ref(false)
const tab = ref<'carto' | 'besoins' | 'competences'>('carto')
const tab = ref<'carto' | 'annuaire'>('carto')
const selectedFiche = ref<CodevFiche | null>(null)
const isMobileView = typeof window !== 'undefined' ? window.innerWidth < 600 : false
@@ -403,6 +413,96 @@ function onSelectFiche(id: number) {
.sheet-enter-active, .sheet-leave-active { transition: opacity 0.2s; }
.sheet-enter-from, .sheet-leave-to { opacity: 0; }
/* ── QR link ── */
.qr-link {
font-size: 0.75rem;
color: #9ca3af;
text-decoration: none;
align-self: flex-end;
}
.qr-link:hover { color: #6b7280; }
/* ── Annuaire ── */
.annuaire-wrap {
display: flex;
flex-direction: column;
gap: 8px;
flex: 1;
}
.annuaire-scroll {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
border: 1px solid #e5e7eb;
border-radius: 10px;
}
.annuaire-table {
width: 100%;
border-collapse: collapse;
min-width: 480px;
}
.annuaire-table thead tr {
background: #f9fafb;
border-bottom: 2px solid #e5e7eb;
}
.annuaire-table th {
padding: 10px 14px;
text-align: left;
font-size: 0.75rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.05em;
color: #6b7280;
white-space: nowrap;
}
.annuaire-table td {
padding: 12px 14px;
font-size: 0.875rem;
color: #374151;
vertical-align: top;
border-bottom: 1px solid #f3f4f6;
line-height: 1.5;
}
.annuaire-row {
cursor: pointer;
transition: background 0.12s;
}
.annuaire-row:hover { background: #f9fafb; }
.annuaire-row:last-child td { border-bottom: none; }
.col-nom {
position: sticky;
left: 0;
background: inherit;
z-index: 1;
font-weight: 600;
color: #1a1a2e !important;
white-space: nowrap;
min-width: 80px;
border-right: 1px solid #e5e7eb;
}
.annuaire-row:hover .col-nom { background: #f9fafb; }
thead tr .col-nom { background: #f9fafb; }
.col-besoin { min-width: 200px; max-width: 260px; }
.col-offre { min-width: 200px; max-width: 260px; }
.annuaire-hint {
font-size: 0.75rem;
color: #9ca3af;
text-align: center;
margin: 0;
}
/* ── Mobile ── */
@media (max-width: 600px) {