feat(frontend): vues MVP — dashboard, jardins, grille, variétés, tâches, plantations

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-22 04:18:11 +01:00
parent 3c5f0d571f
commit 911395accc
9 changed files with 398 additions and 18 deletions

View File

@@ -1,5 +1,66 @@
<template>
<div class="p-4">
<h1 class="text-2xl font-bold text-green">Détail jardin</h1>
<div class="p-4 max-w-3xl mx-auto">
<button class="text-text-muted text-sm mb-4 hover:text-text" @click="router.back()"> Retour</button>
<div v-if="garden">
<h1 class="text-2xl font-bold text-green mb-1">{{ garden.nom }}</h1>
<p class="text-text-muted text-sm mb-6">
{{ garden.type }} · {{ garden.exposition ?? 'exposition non définie' }}
<span v-if="garden.sol_type"> · Sol : {{ garden.sol_type }}</span>
</p>
<h2 class="text-text-muted text-xs uppercase tracking-widest mb-3">
Grille {{ garden.grille_largeur }}×{{ garden.grille_hauteur }}
</h2>
<div class="overflow-x-auto pb-2">
<div
class="grid gap-1 w-max"
:style="`grid-template-columns: repeat(${garden.grille_largeur}, 52px)`"
>
<div
v-for="cell in displayCells" :key="`${cell.row}-${cell.col}`"
class="w-[52px] h-[52px] bg-bg-soft border border-bg-hard rounded-md flex items-center justify-center text-xs text-text-muted cursor-pointer hover:border-green transition-colors select-none"
:class="{ 'border-orange/60 bg-orange/10 text-orange': cell.etat === 'occupe' }"
:title="cell.libelle"
>
{{ cell.libelle }}
</div>
</div>
</div>
</div>
<div v-else class="text-text-muted text-sm">Chargement...</div>
</div>
</template>
<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { gardensApi, type Garden, type GardenCell } from '@/api/gardens'
const route = useRoute()
const router = useRouter()
const garden = ref<Garden | null>(null)
const cells = ref<GardenCell[]>([])
const displayCells = computed(() => {
if (!garden.value) return []
const map = new Map(cells.value.map(c => [`${c.row}-${c.col}`, c]))
const result: GardenCell[] = []
for (let row = 0; row < garden.value.grille_hauteur; row++) {
for (let col = 0; col < garden.value.grille_largeur; col++) {
result.push(map.get(`${row}-${col}`) ?? {
col, row,
libelle: `${String.fromCharCode(65 + row)}${col + 1}`,
etat: 'libre',
})
}
}
return result
})
onMounted(async () => {
const id = Number(route.params.id)
garden.value = await gardensApi.get(id)
cells.value = await gardensApi.cells(id)
})
</script>