This commit is contained in:
2026-03-09 18:19:38 +01:00
parent 4c279c387c
commit 2d5e5a05a2
56 changed files with 2970 additions and 41 deletions

View File

@@ -12,6 +12,9 @@ plante :
- [x] plante du potager, fleur, arbre ou arbuste
- [x] liste de plantes courantes seedée : carotte, tomate, ail, oignon, haricot, petits pois, poireaux, pomme de terre, salade, fraise, framboise, persil, échalote, courgette, chou-fleur, chou boule, ...
- [x] association des plantes (favorables / défavorables) : tags noms communs, validation croisée, édition depuis popup plante
- [ ] ajouter un bouton "ajouter varieté" a gauche de modifier ce qui affiche un popup speciifque variété ou je peut saisir les champ specifique a une varieté et/ou modifier le contenu de champs de la plante "nom commun" ne supprime pas les champs et contenu de nom commun, mais se substitue. possibilite d'inserer les capture d'image du sachet de graine ( 2 photo avant et arriere) optimisiation de la taille de l'image
- [ ] analyse le dossier doc/graine et arbustre ( json et image) et ingrer une seule foisdans la bdd les élement, attention il y aura necessité de créer de nouvelle varité en fonction du nom commun. fait une selection intelligente des champ json utile dans ma base de donnée et qui concerne les caracteristiique de la varité . il y aura certainement la nencessité de rajoter des champ. verifie que les champ date de semis, repiquage, resolte soit bien present ( date => mois a cocher), verifie ensoleillement, arrosage, conseils, t° de germination, maladies, distance de semis, temps de levée. ces champs doivent aussi apparaire dans le poptup plante " nom commun" . brainstorming general pour la gestion des plantes pour une structure de donnée coherente, evolutive et efficace
- [ ] dans la base de donnée actuelle des plantes y a t il dans plan qui peuvent etre fusionner en créeant des vatiété ( ex haricot et haricot grimpant ?) analyse et propose une modiifcation de la bdd qui créer ainsi les nouvelles varietés
taches:
- [x] liste des tâches courantes au jardin pré-remplie (seed)
@@ -25,6 +28,7 @@ outils:
planning:
- [x] PlanningView : calendrier 4 semaines, tâches et plantations par jour
- [] une vue calendrier et une vue gantt 2 bouton dans le hedader pour selectionner ou calendrier ou gantt
calendrier:
- [x] renommer le header lunaire en calendrier (Météo + Lunaire + Dictons + navigation)

0
backend/data/jardin.db Normal file
View File

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 MiB

After

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 MiB

After

Width:  |  Height:  |  Size: 3.7 MiB

View File

@@ -130,6 +130,7 @@ const links = [
{ to: '/plantes', label: 'Plantes', icon: '🌱' },
{ to: '/bibliotheque', label: 'Bibliothèque', icon: '📷' },
{ to: '/outils', label: 'Outils', icon: '🔧' },
{ to: '/intrants', label: 'Intrants', icon: '🧪' },
{ to: '/plantations', label: 'Plantations', icon: '🥕' },
{ to: '/taches', label: 'Tâches', icon: '✅' },
{ to: '/planning', label: 'Planning', icon: '📆' },

View File

@@ -0,0 +1,9 @@
// frontend/src/api/achats.ts
import client from './client';
export const achatsApi = {
list: (params) => client.get('/api/achats', { params }).then(r => r.data),
get: (id) => client.get(`/api/achats/${id}`).then(r => r.data),
create: (a) => client.post('/api/achats', a).then(r => r.data),
update: (id, a) => client.put(`/api/achats/${id}`, a).then(r => r.data),
delete: (id) => client.delete(`/api/achats/${id}`),
};

View File

@@ -0,0 +1,10 @@
// frontend/src/api/fabrications.ts
import client from './client';
export const fabricationsApi = {
list: (params) => client.get('/api/fabrications', { params }).then(r => r.data),
get: (id) => client.get(`/api/fabrications/${id}`).then(r => r.data),
create: (f) => client.post('/api/fabrications', f).then(r => r.data),
update: (id, f) => client.put(`/api/fabrications/${id}`, f).then(r => r.data),
updateStatut: (id, statut) => client.patch(`/api/fabrications/${id}/statut`, { statut }).then(r => r.data),
delete: (id) => client.delete(`/api/fabrications/${id}`),
};

View File

@@ -1,3 +1,4 @@
// frontend/src/api/plants.ts
import client from './client';
export const plantsApi = {
list: (categorie) => client.get('/api/plants', { params: categorie ? { categorie } : {} }).then(r => r.data),
@@ -5,4 +6,8 @@ export const plantsApi = {
create: (p) => client.post('/api/plants', p).then(r => r.data),
update: (id, p) => client.put(`/api/plants/${id}`, p).then(r => r.data),
delete: (id) => client.delete(`/api/plants/${id}`),
// Variétés
createVariety: (plantId, v) => client.post(`/api/plants/${plantId}/varieties`, v).then(r => r.data),
updateVariety: (plantId, vid, v) => client.put(`/api/plants/${plantId}/varieties/${vid}`, v).then(r => r.data),
deleteVariety: (plantId, vid) => client.delete(`/api/plants/${plantId}/varieties/${vid}`),
};

View File

@@ -7,6 +7,7 @@ const links = [
{ to: '/plantes', label: 'Plantes' },
{ to: '/bibliotheque', label: '📷 Bibliothèque' },
{ to: '/outils', label: 'Outils' },
{ to: '/intrants', label: '🧪 Intrants' },
{ to: '/plantations', label: 'Plantations' },
{ to: '/taches', label: 'Tâches' },
{ to: '/planning', label: 'Planning' },

View File

@@ -8,6 +8,7 @@ export default createRouter({
{ path: '/plantes', component: () => import('@/views/PlantesView.vue') },
{ path: '/bibliotheque', component: () => import('@/views/BibliothequeView.vue') },
{ path: '/outils', component: () => import('@/views/OutilsView.vue') },
{ path: '/intrants', component: () => import('@/views/IntratsView.vue') },
{ path: '/plantations', component: () => import('@/views/PlantationsView.vue') },
{ path: '/planning', component: () => import('@/views/PlanningView.vue') },
{ path: '/taches', component: () => import('@/views/TachesView.vue') },

View File

@@ -0,0 +1,27 @@
// frontend/src/stores/achats.ts
import { defineStore } from 'pinia';
import { ref } from 'vue';
import { achatsApi } from '@/api/achats';
export const useAchatsStore = defineStore('achats', () => {
const achats = ref([]);
const loading = ref(false);
async function fetchAll(params) {
loading.value = true;
try {
achats.value = await achatsApi.list(params);
}
finally {
loading.value = false;
}
}
async function create(a) {
const created = await achatsApi.create(a);
achats.value.unshift(created);
return created;
}
async function remove(id) {
await achatsApi.delete(id);
achats.value = achats.value.filter(a => a.id !== id);
}
return { achats, loading, fetchAll, create, remove };
});

View File

@@ -0,0 +1,34 @@
// frontend/src/stores/fabrications.ts
import { defineStore } from 'pinia';
import { ref } from 'vue';
import { fabricationsApi } from '@/api/fabrications';
export const useFabricationsStore = defineStore('fabrications', () => {
const fabrications = ref([]);
const loading = ref(false);
async function fetchAll(params) {
loading.value = true;
try {
fabrications.value = await fabricationsApi.list(params);
}
finally {
loading.value = false;
}
}
async function create(f) {
const created = await fabricationsApi.create(f);
fabrications.value.unshift(created);
return created;
}
async function updateStatut(id, statut) {
const updated = await fabricationsApi.updateStatut(id, statut);
const idx = fabrications.value.findIndex(f => f.id === id);
if (idx !== -1)
fabrications.value[idx] = updated;
return updated;
}
async function remove(id) {
await fabricationsApi.delete(id);
fabrications.value = fabrications.value.filter(f => f.id !== id);
}
return { fabrications, loading, fetchAll, create, updateStatut, remove };
});

View File

@@ -1,3 +1,4 @@
// frontend/src/stores/plants.ts
import { defineStore } from 'pinia';
import { ref } from 'vue';
import { plantsApi } from '@/api/plants';
@@ -18,9 +19,43 @@ export const usePlantsStore = defineStore('plants', () => {
plants.value.push(created);
return created;
}
async function update(id, p) {
const updated = await plantsApi.update(id, p);
const idx = plants.value.findIndex(x => x.id === id);
if (idx !== -1)
plants.value[idx] = updated;
return updated;
}
async function remove(id) {
await plantsApi.delete(id);
plants.value = plants.value.filter(p => p.id !== id);
}
return { plants, loading, fetchAll, create, remove };
async function createVariety(plantId, v) {
const created = await plantsApi.createVariety(plantId, v);
const plant = plants.value.find(p => p.id === plantId);
if (plant) {
if (!plant.varieties)
plant.varieties = [];
plant.varieties.push(created);
}
return created;
}
async function updateVariety(plantId, vid, v) {
const updated = await plantsApi.updateVariety(plantId, vid, v);
const plant = plants.value.find(p => p.id === plantId);
if (plant?.varieties) {
const idx = plant.varieties.findIndex(x => x.id === vid);
if (idx !== -1)
plant.varieties[idx] = updated;
}
return updated;
}
async function removeVariety(plantId, vid) {
await plantsApi.deleteVariety(plantId, vid);
const plant = plants.value.find(p => p.id === plantId);
if (plant?.varieties) {
plant.varieties = plant.varieties.filter(v => v.id !== vid);
}
}
return { plants, loading, fetchAll, create, update, remove, createVariety, updateVariety, removeVariety };
});

File diff suppressed because it is too large Load Diff

View File

@@ -15,13 +15,29 @@ const loadingPhotos = ref(false);
const lightbox = ref(null);
const fileInput = ref(null);
const uploadTarget = ref(null);
// Navigation variétés
const detailVarieties = ref([]);
// Navigation variétés (groupe de Plant par nom_commun)
const detailPlantGroup = ref([]);
const detailVarietyIdx = ref(0);
const detailPlant = computed(() => detailVarieties.value[detailVarietyIdx.value] ?? null);
const detailPlant = computed(() => detailPlantGroup.value[detailVarietyIdx.value] ?? null);
// detailPlantObj : ref sur la plante ouverte en détail (Plant complet)
const detailPlantObj = ref(null);
// detailVarieties : variétés (PlantVariety) de la plante affichée
const detailVarieties = computed(() => {
if (!detailPlantObj.value)
return [];
return detailPlantObj.value.varieties ?? [];
});
// Associations au niveau nom_commun (première variété ayant des données)
const detailAssociations = computed(() => detailVarieties.value.find(v => v.associations_favorables?.length || v.associations_defavorables?.length)
const detailAssociations = computed(() => detailPlantGroup.value.find(v => v.associations_favorables?.length || v.associations_defavorables?.length)
?? detailPlant.value);
// Refs pour le formulaire variété
const showFormVariety = ref(false);
const editVariety = ref(null);
const formVariety = reactive({
variete: '', tags: '', notes_variete: '',
boutique_nom: '', boutique_url: '', prix_achat: undefined,
date_achat: '', poids: '', dluo: '',
});
const categories = [
{ val: '', label: 'TOUTES' },
{ val: 'potager', label: '🥕 POTAGER' },
@@ -84,7 +100,7 @@ const filteredPlants = computed(() => {
const q = searchQuery.value.toLowerCase();
result = result.filter(p => {
const group = plantGroups.value.get((p.nom_commun || '').toLowerCase()) || [];
return group.some(v => v.nom_commun?.toLowerCase().includes(q) || v.variete?.toLowerCase().includes(q));
return group.some(v => v.nom_commun?.toLowerCase().includes(q) || v.varieties?.[0]?.variete?.toLowerCase().includes(q));
});
}
return result.sort((a, b) => (a.nom_commun || '').localeCompare(b.nom_commun || '', 'fr'));
@@ -144,26 +160,30 @@ function catTextClass(cat) {
}[cat] || 'text-text-muted';
}
function closeDetail() {
detailVarieties.value = [];
detailPlantGroup.value = [];
detailPlantObj.value = null;
detailVarietyIdx.value = 0;
plantPhotos.value = [];
}
async function openDetails(p) {
const key = (p.nom_commun || '').toLowerCase();
const group = plantGroups.value.get(key) || [p];
detailVarieties.value = [...group].sort((a, b) => (a.id || 0) - (b.id || 0));
detailPlantGroup.value = [...group].sort((a, b) => (a.id || 0) - (b.id || 0));
detailVarietyIdx.value = 0;
await fetchPhotos(detailVarieties.value[0].id);
detailPlantObj.value = detailPlantGroup.value[0];
await fetchPhotos(detailPlantGroup.value[0].id);
}
async function prevVariety() {
if (detailVarietyIdx.value > 0) {
detailVarietyIdx.value--;
detailPlantObj.value = detailPlant.value;
await fetchPhotos(detailPlant.value.id);
}
}
async function nextVariety() {
if (detailVarietyIdx.value < detailVarieties.value.length - 1) {
if (detailVarietyIdx.value < detailPlantGroup.value.length - 1) {
detailVarietyIdx.value++;
detailPlantObj.value = detailPlant.value;
await fetchPhotos(detailPlant.value.id);
}
}
@@ -186,15 +206,16 @@ function startEdit(p) {
const withAssoc = group.find(v => v.associations_favorables?.length || v.associations_defavorables?.length) ?? p;
closeDetail();
editPlant.value = p;
const v0 = p.varieties?.[0];
Object.assign(form, {
nom_commun: p.nom_commun || '', variete: p.variete || '', famille: p.famille || '',
nom_commun: p.nom_commun || '', variete: v0?.variete || '', famille: p.famille || '',
categorie: p.categorie || 'potager', besoin_eau: p.besoin_eau || 'moyen', besoin_soleil: p.besoin_soleil || 'plein soleil',
plantation_mois: p.plantation_mois || '', notes: p.notes || '',
associations_favorables: [...(withAssoc.associations_favorables ?? [])],
associations_defavorables: [...(withAssoc.associations_defavorables ?? [])],
boutique_nom: p.boutique_nom || '', boutique_url: p.boutique_url || '',
prix_achat: p.prix_achat ?? null, date_achat: p.date_achat || '',
poids: p.poids || '', dluo: p.dluo || '',
boutique_nom: v0?.boutique_nom || '', boutique_url: v0?.boutique_url || '',
prix_achat: v0?.prix_achat ?? null, date_achat: v0?.date_achat || '',
poids: v0?.poids || '', dluo: v0?.dluo || '',
});
assocFilter.value = '';
showAssocModal.value = false;
@@ -211,15 +232,87 @@ function closeForm() {
date_achat: '', poids: '', dluo: '',
});
}
function openAddVariety() {
if (!detailPlantObj.value)
return;
editVariety.value = null;
Object.assign(formVariety, {
variete: '', tags: '', notes_variete: '',
boutique_nom: '', boutique_url: '', prix_achat: undefined,
date_achat: '', poids: '', dluo: '',
});
showFormVariety.value = true;
}
function openEditVariety(v) {
editVariety.value = v;
Object.assign(formVariety, { ...v });
showFormVariety.value = true;
}
function closeFormVariety() {
showFormVariety.value = false;
editVariety.value = null;
}
async function submitVariety() {
if (!detailPlantObj.value?.id)
return;
const payload = { ...formVariety, prix_achat: formVariety.prix_achat ?? undefined };
try {
if (editVariety.value?.id) {
await plantsStore.updateVariety(detailPlantObj.value.id, editVariety.value.id, payload);
toast.success('Variété modifiée');
}
else {
await plantsStore.createVariety(detailPlantObj.value.id, payload);
toast.success('Variété ajoutée');
}
// Refresh plant data so detailPlantObj reflects updated varieties
await plantsStore.fetchAll();
const updatedPlant = plantsStore.plants.find(p => p.id === detailPlantObj.value?.id);
if (updatedPlant)
detailPlantObj.value = updatedPlant;
closeFormVariety();
}
catch {
// L'intercepteur Axios affiche le message d'erreur
}
}
async function deleteVariety(vid) {
if (!detailPlantObj.value?.id)
return;
if (!confirm('Supprimer cette variété ?'))
return;
try {
await plantsStore.removeVariety(detailPlantObj.value.id, vid);
await plantsStore.fetchAll();
const updatedPlant = plantsStore.plants.find(p => p.id === detailPlantObj.value?.id);
if (updatedPlant)
detailPlantObj.value = updatedPlant;
toast.success('Variété supprimée');
}
catch {
// L'intercepteur Axios affiche le message d'erreur
}
}
async function submitPlant() {
if (submitting.value)
return;
submitting.value = true;
try {
const payload = { ...form, prix_achat: form.prix_achat ?? undefined };
// Extraire les champs variété du form (non envoyés dans Plant)
const varietyPayload = {
variete: form.variete || undefined,
boutique_nom: form.boutique_nom || undefined,
boutique_url: form.boutique_url || undefined,
prix_achat: form.prix_achat ?? undefined,
date_achat: form.date_achat || undefined,
poids: form.poids || undefined,
dluo: form.dluo || undefined,
};
// Payload Plant pur (sans champs variété)
const { variete: _v, boutique_nom: _bn, boutique_url: _bu, prix_achat: _pa, date_achat: _da, poids: _po, dluo: _d, ...plantPayload } = { ...form };
if (editPlant.value) {
await axios.put(`/api/plants/${editPlant.value.id}`, payload);
// Synchroniser les associations à toutes les variétés du même nom commun
await axios.put(`/api/plants/${editPlant.value.id}`, plantPayload);
// Synchroniser associations aux plantes du même nom commun
const nomKey = form.nom_commun.toLowerCase();
const siblings = plantsStore.plants.filter(p => p.id !== editPlant.value.id && (p.nom_commun || '').toLowerCase() === nomKey);
for (const sibling of siblings) {
@@ -228,11 +321,27 @@ async function submitPlant() {
associations_defavorables: form.associations_defavorables,
});
}
// Mettre à jour ou créer la variété
const existingVariety = editPlant.value.varieties?.[0];
const hasVarietyData = Object.values(varietyPayload).some(v => v !== undefined);
const plantId = editPlant.value.id;
if (existingVariety?.id) {
await plantsStore.updateVariety(plantId, existingVariety.id, varietyPayload);
}
else if (hasVarietyData) {
await plantsStore.createVariety(plantId, varietyPayload);
}
await plantsStore.fetchAll();
toast.success('Plante modifiée');
}
else {
await plantsStore.create(payload);
const created = await plantsStore.create(plantPayload);
// Créer la variété si des données variété sont présentes
const hasVarietyData = Object.values(varietyPayload).some(v => v !== undefined);
if (created.id && hasVarietyData) {
await plantsStore.createVariety(created.id, varietyPayload);
}
await plantsStore.fetchAll();
toast.success('Plante créée');
}
closeForm();
@@ -470,7 +579,7 @@ if (__VLS_ctx.detailPlant) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "flex items-center gap-3 mt-3" },
});
if (__VLS_ctx.detailVarieties.length > 1) {
if (__VLS_ctx.detailPlantGroup.length > 1) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "flex items-center gap-2" },
});
@@ -484,19 +593,19 @@ if (__VLS_ctx.detailPlant) {
...{ class: "text-text-muted text-xs font-bold" },
});
(__VLS_ctx.detailVarietyIdx + 1);
(__VLS_ctx.detailVarieties.length);
(__VLS_ctx.detailPlantGroup.length);
__VLS_asFunctionalElement(__VLS_intrinsicElements.button, __VLS_intrinsicElements.button)({
...{ onClick: (__VLS_ctx.nextVariety) },
disabled: (__VLS_ctx.detailVarietyIdx === __VLS_ctx.detailVarieties.length - 1),
disabled: (__VLS_ctx.detailVarietyIdx === __VLS_ctx.detailPlantGroup.length - 1),
...{ class: (['w-7 h-7 rounded-full border flex items-center justify-center text-sm font-bold transition-all',
__VLS_ctx.detailVarietyIdx === __VLS_ctx.detailVarieties.length - 1 ? 'border-bg-soft text-text-muted/30 cursor-not-allowed' : 'border-yellow/50 text-yellow hover:bg-yellow/10']) },
__VLS_ctx.detailVarietyIdx === __VLS_ctx.detailPlantGroup.length - 1 ? 'border-bg-soft text-text-muted/30 cursor-not-allowed' : 'border-yellow/50 text-yellow hover:bg-yellow/10']) },
});
}
if (__VLS_ctx.detailPlant.variete) {
if (__VLS_ctx.detailPlant.varieties?.[0]?.variete) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.p, __VLS_intrinsicElements.p)({
...{ class: "text-yellow font-bold uppercase tracking-widest text-sm" },
});
(__VLS_ctx.detailPlant.variete);
(__VLS_ctx.detailPlant.varieties?.[0]?.variete);
}
__VLS_asFunctionalElement(__VLS_intrinsicElements.button, __VLS_intrinsicElements.button)({
...{ onClick: (__VLS_ctx.closeDetail) },
@@ -550,41 +659,7 @@ if (__VLS_ctx.detailPlant) {
...{ class: "font-bold" },
});
(__VLS_ctx.detailPlant.plantation_mois);
if (__VLS_ctx.detailPlant.boutique_nom || __VLS_ctx.detailPlant.prix_achat || __VLS_ctx.detailPlant.poids || __VLS_ctx.detailPlant.dluo) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "space-y-2" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.h3, __VLS_intrinsicElements.h3)({
...{ class: "text-[10px] font-black text-text-muted uppercase tracking-widest" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "grid grid-cols-2 sm:grid-cols-3 gap-3" },
});
if (__VLS_ctx.detailPlant.boutique_nom) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "bg-bg/30 p-3 rounded-xl border border-bg-soft" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
...{ class: "text-[9px] font-black text-text-muted uppercase block mb-0.5" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
...{ class: "text-text text-sm font-bold" },
});
(__VLS_ctx.detailPlant.boutique_nom);
}
if (__VLS_ctx.detailPlant.prix_achat) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "bg-bg/30 p-3 rounded-xl border border-bg-soft" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
...{ class: "text-[9px] font-black text-text-muted uppercase block mb-0.5" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
...{ class: "text-yellow font-bold" },
});
(__VLS_ctx.detailPlant.prix_achat.toFixed(2));
}
if (__VLS_ctx.detailPlant.date_achat) {
if (__VLS_ctx.detailPlantObj?.temp_germination) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "bg-bg/30 p-3 rounded-xl border border-bg-soft" },
});
@@ -594,9 +669,31 @@ if (__VLS_ctx.detailPlant) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
...{ class: "text-text text-sm" },
});
(__VLS_ctx.detailPlant.date_achat);
(__VLS_ctx.detailPlantObj.temp_germination);
}
if (__VLS_ctx.detailPlant.poids) {
if (__VLS_ctx.detailPlantObj?.temps_levee_j) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "bg-bg/30 p-3 rounded-xl border border-bg-soft" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
...{ class: "text-[9px] font-black text-text-muted uppercase block mb-0.5" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
...{ class: "text-text text-sm" },
});
(__VLS_ctx.detailPlantObj.temps_levee_j);
}
if (__VLS_ctx.detailPlant.varieties?.[0]?.boutique_nom || __VLS_ctx.detailPlant.varieties?.[0]?.prix_achat || __VLS_ctx.detailPlant.varieties?.[0]?.poids || __VLS_ctx.detailPlant.varieties?.[0]?.dluo) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "space-y-2" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.h3, __VLS_intrinsicElements.h3)({
...{ class: "text-[10px] font-black text-text-muted uppercase tracking-widest" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "grid grid-cols-2 sm:grid-cols-3 gap-3" },
});
if (__VLS_ctx.detailPlant.varieties?.[0]?.boutique_nom) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "bg-bg/30 p-3 rounded-xl border border-bg-soft" },
});
@@ -606,9 +703,9 @@ if (__VLS_ctx.detailPlant) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
...{ class: "text-text text-sm font-bold" },
});
(__VLS_ctx.detailPlant.poids);
(__VLS_ctx.detailPlant.varieties?.[0]?.boutique_nom);
}
if (__VLS_ctx.detailPlant.dluo) {
if (__VLS_ctx.detailPlant.varieties?.[0]?.prix_achat) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "bg-bg/30 p-3 rounded-xl border border-bg-soft" },
});
@@ -616,12 +713,48 @@ if (__VLS_ctx.detailPlant) {
...{ class: "text-[9px] font-black text-text-muted uppercase block mb-0.5" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
...{ class: (['text-sm font-bold', __VLS_ctx.isDluoExpired(__VLS_ctx.detailPlant.dluo) ? 'text-red' : 'text-green']) },
...{ class: "text-yellow font-bold" },
});
(__VLS_ctx.detailPlant.dluo);
(__VLS_ctx.isDluoExpired(__VLS_ctx.detailPlant.dluo) ? ' ⚠️' : '');
(__VLS_ctx.detailPlant.varieties?.[0]?.prix_achat?.toFixed(2));
}
if (__VLS_ctx.detailPlant.boutique_url) {
if (__VLS_ctx.detailPlant.varieties?.[0]?.date_achat) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "bg-bg/30 p-3 rounded-xl border border-bg-soft" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
...{ class: "text-[9px] font-black text-text-muted uppercase block mb-0.5" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
...{ class: "text-text text-sm" },
});
(__VLS_ctx.detailPlant.varieties?.[0]?.date_achat);
}
if (__VLS_ctx.detailPlant.varieties?.[0]?.poids) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "bg-bg/30 p-3 rounded-xl border border-bg-soft" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
...{ class: "text-[9px] font-black text-text-muted uppercase block mb-0.5" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
...{ class: "text-text text-sm font-bold" },
});
(__VLS_ctx.detailPlant.varieties?.[0]?.poids);
}
if (__VLS_ctx.detailPlant.varieties?.[0]?.dluo) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "bg-bg/30 p-3 rounded-xl border border-bg-soft" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
...{ class: "text-[9px] font-black text-text-muted uppercase block mb-0.5" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
...{ class: (['text-sm font-bold', __VLS_ctx.isDluoExpired(__VLS_ctx.detailPlant.varieties?.[0]?.dluo ?? '') ? 'text-red' : 'text-green']) },
});
(__VLS_ctx.detailPlant.varieties?.[0]?.dluo);
(__VLS_ctx.isDluoExpired(__VLS_ctx.detailPlant.varieties?.[0]?.dluo ?? '') ? ' ⚠️' : '');
}
if (__VLS_ctx.detailPlant.varieties?.[0]?.boutique_url) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "bg-bg/30 p-3 rounded-xl border border-bg-soft" },
});
@@ -629,7 +762,7 @@ if (__VLS_ctx.detailPlant) {
...{ class: "text-[9px] font-black text-text-muted uppercase block mb-0.5" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.a, __VLS_intrinsicElements.a)({
href: (__VLS_ctx.detailPlant.boutique_url),
href: (__VLS_ctx.detailPlant.varieties?.[0]?.boutique_url),
target: "_blank",
rel: "noopener",
...{ class: "text-blue text-xs hover:underline truncate block" },
@@ -691,6 +824,69 @@ if (__VLS_ctx.detailPlant) {
}
}
}
if (__VLS_ctx.detailVarieties.length) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "space-y-2 mt-4" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.h3, __VLS_intrinsicElements.h3)({
...{ class: "text-[9px] font-black text-text-muted uppercase tracking-widest" },
});
(__VLS_ctx.detailVarieties.length);
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "space-y-1" },
});
for (const [v] of __VLS_getVForSourceType((__VLS_ctx.detailVarieties))) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
key: (v.id),
...{ class: "flex items-center justify-between bg-bg/30 px-3 py-2 rounded-lg border border-bg-soft" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({});
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
...{ class: "text-text text-sm font-bold" },
});
(v.variete || '(sans nom)');
if (v.boutique_nom) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
...{ class: "text-text-muted text-xs ml-2" },
});
(v.boutique_nom);
}
if (v.prix_achat) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
...{ class: "text-yellow text-xs ml-2" },
});
(v.prix_achat.toFixed(2));
}
if (v.dluo && __VLS_ctx.isDluoExpired(v.dluo)) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
...{ class: "text-red text-xs ml-1" },
});
}
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "flex gap-1" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.button, __VLS_intrinsicElements.button)({
...{ onClick: (...[$event]) => {
if (!(__VLS_ctx.detailPlant))
return;
if (!(__VLS_ctx.detailVarieties.length))
return;
__VLS_ctx.openEditVariety(v);
} },
...{ class: "text-text-muted hover:text-yellow text-xs px-2" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.button, __VLS_intrinsicElements.button)({
...{ onClick: (...[$event]) => {
if (!(__VLS_ctx.detailPlant))
return;
if (!(__VLS_ctx.detailVarieties.length))
return;
__VLS_ctx.deleteVariety(v.id);
} },
...{ class: "text-text-muted hover:text-red text-xs px-2" },
});
}
}
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "space-y-3" },
});
@@ -766,6 +962,10 @@ if (__VLS_ctx.detailPlant) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "p-4 bg-bg-hard border-t border-bg-soft flex gap-3" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.button, __VLS_intrinsicElements.button)({
...{ onClick: (__VLS_ctx.openAddVariety) },
...{ class: "btn-primary !bg-green !text-bg py-2 px-4 font-black uppercase text-xs flex items-center gap-1" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.button, __VLS_intrinsicElements.button)({
...{ onClick: (...[$event]) => {
if (!(__VLS_ctx.detailPlant))
@@ -1249,6 +1449,152 @@ __VLS_asFunctionalElement(__VLS_intrinsicElements.input)({
...{ class: "hidden" },
});
/** @type {typeof __VLS_ctx.fileInput} */ ;
if (__VLS_ctx.showFormVariety) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ onClick: (__VLS_ctx.closeFormVariety) },
...{ class: "fixed inset-0 bg-black/80 backdrop-blur-sm z-[70] flex items-center justify-center p-4" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "bg-bg-hard rounded-3xl p-6 w-full max-w-xl border border-bg-soft shadow-2xl max-h-[90vh] overflow-y-auto" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "flex items-center justify-between mb-5 border-b border-bg-soft pb-4" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.h2, __VLS_intrinsicElements.h2)({
...{ class: "text-text font-black text-xl uppercase" },
});
(__VLS_ctx.editVariety ? 'Modifier la variété' : ' Nouvelle variété');
__VLS_asFunctionalElement(__VLS_intrinsicElements.button, __VLS_intrinsicElements.button)({
...{ onClick: (__VLS_ctx.closeFormVariety) },
...{ class: "text-text-muted hover:text-red text-2xl" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.p, __VLS_intrinsicElements.p)({
...{ class: "text-text-muted text-xs mb-4 italic" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.span, __VLS_intrinsicElements.span)({
...{ class: "text-yellow font-bold" },
});
(__VLS_ctx.detailPlantObj?.nom_commun);
__VLS_asFunctionalElement(__VLS_intrinsicElements.form, __VLS_intrinsicElements.form)({
...{ onSubmit: (__VLS_ctx.submitVariety) },
...{ class: "grid grid-cols-1 md:grid-cols-2 gap-4" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "md:col-span-2" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.label, __VLS_intrinsicElements.label)({
...{ class: "text-text-muted text-[10px] font-black uppercase tracking-widest block mb-1" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.input)({
required: true,
...{ class: "w-full bg-bg border border-bg-soft rounded-xl px-4 py-3 text-text text-sm focus:border-yellow outline-none" },
placeholder: "Ex: Nantaise, Cornue des Andes, Moneymaker…",
});
(__VLS_ctx.formVariety.variete);
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "md:col-span-2" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.label, __VLS_intrinsicElements.label)({
...{ class: "text-text-muted text-[10px] font-black uppercase tracking-widest block mb-1" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.input)({
...{ class: "w-full bg-bg border border-bg-soft rounded-xl px-4 py-3 text-text text-sm focus:border-yellow outline-none" },
placeholder: "bio, f1, ancien, résistant…",
});
(__VLS_ctx.formVariety.tags);
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({});
__VLS_asFunctionalElement(__VLS_intrinsicElements.label, __VLS_intrinsicElements.label)({
...{ class: "text-text-muted text-[10px] font-black uppercase tracking-widest block mb-1" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.select, __VLS_intrinsicElements.select)({
value: (__VLS_ctx.formVariety.boutique_nom),
...{ class: "w-full bg-bg border border-bg-soft rounded-xl px-4 py-3 text-text text-sm outline-none focus:border-yellow appearance-none" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.option, __VLS_intrinsicElements.option)({
value: "",
});
for (const [b] of __VLS_getVForSourceType((__VLS_ctx.BOUTIQUES))) {
__VLS_asFunctionalElement(__VLS_intrinsicElements.option, __VLS_intrinsicElements.option)({
key: (b),
value: (b),
});
(b);
}
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({});
__VLS_asFunctionalElement(__VLS_intrinsicElements.label, __VLS_intrinsicElements.label)({
...{ class: "text-text-muted text-[10px] font-black uppercase tracking-widest block mb-1" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.input)({
type: "number",
step: "0.01",
min: "0",
...{ class: "w-full bg-bg border border-bg-soft rounded-xl px-4 py-3 text-text text-sm focus:border-yellow outline-none" },
});
(__VLS_ctx.formVariety.prix_achat);
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({});
__VLS_asFunctionalElement(__VLS_intrinsicElements.label, __VLS_intrinsicElements.label)({
...{ class: "text-text-muted text-[10px] font-black uppercase tracking-widest block mb-1" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.input)({
placeholder: "ex: 5g, 100 graines",
...{ class: "w-full bg-bg border border-bg-soft rounded-xl px-4 py-3 text-text text-sm focus:border-yellow outline-none" },
});
(__VLS_ctx.formVariety.poids);
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({});
__VLS_asFunctionalElement(__VLS_intrinsicElements.label, __VLS_intrinsicElements.label)({
...{ class: "text-text-muted text-[10px] font-black uppercase tracking-widest block mb-1" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.input)({
type: "date",
...{ class: "w-full bg-bg border border-bg-soft rounded-xl px-4 py-3 text-text text-sm focus:border-yellow outline-none" },
});
(__VLS_ctx.formVariety.date_achat);
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({});
__VLS_asFunctionalElement(__VLS_intrinsicElements.label, __VLS_intrinsicElements.label)({
...{ class: "text-text-muted text-[10px] font-black uppercase tracking-widest block mb-1" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.input)({
type: "date",
...{ class: "w-full bg-bg border border-bg-soft rounded-xl px-4 py-3 text-text text-sm focus:border-yellow outline-none" },
});
(__VLS_ctx.formVariety.dluo);
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "md:col-span-2" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.label, __VLS_intrinsicElements.label)({
...{ class: "text-text-muted text-[10px] font-black uppercase tracking-widest block mb-1" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.input)({
type: "url",
placeholder: "https://…",
...{ class: "w-full bg-bg border border-bg-soft rounded-xl px-4 py-3 text-text text-sm focus:border-yellow outline-none" },
});
(__VLS_ctx.formVariety.boutique_url);
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "md:col-span-2" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.label, __VLS_intrinsicElements.label)({
...{ class: "text-text-muted text-[10px] font-black uppercase tracking-widest block mb-1" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.textarea)({
value: (__VLS_ctx.formVariety.notes_variete),
rows: "3",
...{ class: "w-full bg-bg border border-bg-soft rounded-xl px-4 py-3 text-text text-sm focus:border-yellow outline-none resize-none" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.div, __VLS_intrinsicElements.div)({
...{ class: "md:col-span-2 flex justify-between pt-4 border-t border-bg-soft" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.button, __VLS_intrinsicElements.button)({
...{ onClick: (__VLS_ctx.closeFormVariety) },
type: "button",
...{ class: "text-text-muted hover:text-red uppercase text-xs font-bold px-6" },
});
__VLS_asFunctionalElement(__VLS_intrinsicElements.button, __VLS_intrinsicElements.button)({
type: "submit",
...{ class: "btn-primary px-8 py-3 !bg-green !text-bg font-black" },
});
(__VLS_ctx.editVariety ? 'Sauvegarder' : 'Ajouter');
}
/** @type {__VLS_StyleScopedClasses['p-4']} */ ;
/** @type {__VLS_StyleScopedClasses['max-w-[1800px]']} */ ;
/** @type {__VLS_StyleScopedClasses['mx-auto']} */ ;
@@ -1503,6 +1849,32 @@ __VLS_asFunctionalElement(__VLS_intrinsicElements.input)({
/** @type {__VLS_StyleScopedClasses['gap-2']} */ ;
/** @type {__VLS_StyleScopedClasses['text-green']} */ ;
/** @type {__VLS_StyleScopedClasses['font-bold']} */ ;
/** @type {__VLS_StyleScopedClasses['bg-bg/30']} */ ;
/** @type {__VLS_StyleScopedClasses['p-3']} */ ;
/** @type {__VLS_StyleScopedClasses['rounded-xl']} */ ;
/** @type {__VLS_StyleScopedClasses['border']} */ ;
/** @type {__VLS_StyleScopedClasses['border-bg-soft']} */ ;
/** @type {__VLS_StyleScopedClasses['text-[9px]']} */ ;
/** @type {__VLS_StyleScopedClasses['font-black']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text-muted']} */ ;
/** @type {__VLS_StyleScopedClasses['uppercase']} */ ;
/** @type {__VLS_StyleScopedClasses['block']} */ ;
/** @type {__VLS_StyleScopedClasses['mb-0.5']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text']} */ ;
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
/** @type {__VLS_StyleScopedClasses['bg-bg/30']} */ ;
/** @type {__VLS_StyleScopedClasses['p-3']} */ ;
/** @type {__VLS_StyleScopedClasses['rounded-xl']} */ ;
/** @type {__VLS_StyleScopedClasses['border']} */ ;
/** @type {__VLS_StyleScopedClasses['border-bg-soft']} */ ;
/** @type {__VLS_StyleScopedClasses['text-[9px]']} */ ;
/** @type {__VLS_StyleScopedClasses['font-black']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text-muted']} */ ;
/** @type {__VLS_StyleScopedClasses['uppercase']} */ ;
/** @type {__VLS_StyleScopedClasses['block']} */ ;
/** @type {__VLS_StyleScopedClasses['mb-0.5']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text']} */ ;
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
/** @type {__VLS_StyleScopedClasses['space-y-2']} */ ;
/** @type {__VLS_StyleScopedClasses['text-[10px]']} */ ;
/** @type {__VLS_StyleScopedClasses['font-black']} */ ;
@@ -1653,6 +2025,45 @@ __VLS_asFunctionalElement(__VLS_intrinsicElements.input)({
/** @type {__VLS_StyleScopedClasses['py-0.5']} */ ;
/** @type {__VLS_StyleScopedClasses['rounded-full']} */ ;
/** @type {__VLS_StyleScopedClasses['capitalize']} */ ;
/** @type {__VLS_StyleScopedClasses['space-y-2']} */ ;
/** @type {__VLS_StyleScopedClasses['mt-4']} */ ;
/** @type {__VLS_StyleScopedClasses['text-[9px]']} */ ;
/** @type {__VLS_StyleScopedClasses['font-black']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text-muted']} */ ;
/** @type {__VLS_StyleScopedClasses['uppercase']} */ ;
/** @type {__VLS_StyleScopedClasses['tracking-widest']} */ ;
/** @type {__VLS_StyleScopedClasses['space-y-1']} */ ;
/** @type {__VLS_StyleScopedClasses['flex']} */ ;
/** @type {__VLS_StyleScopedClasses['items-center']} */ ;
/** @type {__VLS_StyleScopedClasses['justify-between']} */ ;
/** @type {__VLS_StyleScopedClasses['bg-bg/30']} */ ;
/** @type {__VLS_StyleScopedClasses['px-3']} */ ;
/** @type {__VLS_StyleScopedClasses['py-2']} */ ;
/** @type {__VLS_StyleScopedClasses['rounded-lg']} */ ;
/** @type {__VLS_StyleScopedClasses['border']} */ ;
/** @type {__VLS_StyleScopedClasses['border-bg-soft']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text']} */ ;
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
/** @type {__VLS_StyleScopedClasses['font-bold']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text-muted']} */ ;
/** @type {__VLS_StyleScopedClasses['text-xs']} */ ;
/** @type {__VLS_StyleScopedClasses['ml-2']} */ ;
/** @type {__VLS_StyleScopedClasses['text-yellow']} */ ;
/** @type {__VLS_StyleScopedClasses['text-xs']} */ ;
/** @type {__VLS_StyleScopedClasses['ml-2']} */ ;
/** @type {__VLS_StyleScopedClasses['text-red']} */ ;
/** @type {__VLS_StyleScopedClasses['text-xs']} */ ;
/** @type {__VLS_StyleScopedClasses['ml-1']} */ ;
/** @type {__VLS_StyleScopedClasses['flex']} */ ;
/** @type {__VLS_StyleScopedClasses['gap-1']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text-muted']} */ ;
/** @type {__VLS_StyleScopedClasses['hover:text-yellow']} */ ;
/** @type {__VLS_StyleScopedClasses['text-xs']} */ ;
/** @type {__VLS_StyleScopedClasses['px-2']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text-muted']} */ ;
/** @type {__VLS_StyleScopedClasses['hover:text-red']} */ ;
/** @type {__VLS_StyleScopedClasses['text-xs']} */ ;
/** @type {__VLS_StyleScopedClasses['px-2']} */ ;
/** @type {__VLS_StyleScopedClasses['space-y-3']} */ ;
/** @type {__VLS_StyleScopedClasses['flex']} */ ;
/** @type {__VLS_StyleScopedClasses['justify-between']} */ ;
@@ -1722,6 +2133,17 @@ __VLS_asFunctionalElement(__VLS_intrinsicElements.input)({
/** @type {__VLS_StyleScopedClasses['flex']} */ ;
/** @type {__VLS_StyleScopedClasses['gap-3']} */ ;
/** @type {__VLS_StyleScopedClasses['btn-primary']} */ ;
/** @type {__VLS_StyleScopedClasses['!bg-green']} */ ;
/** @type {__VLS_StyleScopedClasses['!text-bg']} */ ;
/** @type {__VLS_StyleScopedClasses['py-2']} */ ;
/** @type {__VLS_StyleScopedClasses['px-4']} */ ;
/** @type {__VLS_StyleScopedClasses['font-black']} */ ;
/** @type {__VLS_StyleScopedClasses['uppercase']} */ ;
/** @type {__VLS_StyleScopedClasses['text-xs']} */ ;
/** @type {__VLS_StyleScopedClasses['flex']} */ ;
/** @type {__VLS_StyleScopedClasses['items-center']} */ ;
/** @type {__VLS_StyleScopedClasses['gap-1']} */ ;
/** @type {__VLS_StyleScopedClasses['btn-primary']} */ ;
/** @type {__VLS_StyleScopedClasses['!bg-yellow']} */ ;
/** @type {__VLS_StyleScopedClasses['!text-bg']} */ ;
/** @type {__VLS_StyleScopedClasses['flex-1']} */ ;
@@ -2333,6 +2755,235 @@ __VLS_asFunctionalElement(__VLS_intrinsicElements.input)({
/** @type {__VLS_StyleScopedClasses['hover:opacity-90']} */ ;
/** @type {__VLS_StyleScopedClasses['transition-opacity']} */ ;
/** @type {__VLS_StyleScopedClasses['hidden']} */ ;
/** @type {__VLS_StyleScopedClasses['fixed']} */ ;
/** @type {__VLS_StyleScopedClasses['inset-0']} */ ;
/** @type {__VLS_StyleScopedClasses['bg-black/80']} */ ;
/** @type {__VLS_StyleScopedClasses['backdrop-blur-sm']} */ ;
/** @type {__VLS_StyleScopedClasses['z-[70]']} */ ;
/** @type {__VLS_StyleScopedClasses['flex']} */ ;
/** @type {__VLS_StyleScopedClasses['items-center']} */ ;
/** @type {__VLS_StyleScopedClasses['justify-center']} */ ;
/** @type {__VLS_StyleScopedClasses['p-4']} */ ;
/** @type {__VLS_StyleScopedClasses['bg-bg-hard']} */ ;
/** @type {__VLS_StyleScopedClasses['rounded-3xl']} */ ;
/** @type {__VLS_StyleScopedClasses['p-6']} */ ;
/** @type {__VLS_StyleScopedClasses['w-full']} */ ;
/** @type {__VLS_StyleScopedClasses['max-w-xl']} */ ;
/** @type {__VLS_StyleScopedClasses['border']} */ ;
/** @type {__VLS_StyleScopedClasses['border-bg-soft']} */ ;
/** @type {__VLS_StyleScopedClasses['shadow-2xl']} */ ;
/** @type {__VLS_StyleScopedClasses['max-h-[90vh]']} */ ;
/** @type {__VLS_StyleScopedClasses['overflow-y-auto']} */ ;
/** @type {__VLS_StyleScopedClasses['flex']} */ ;
/** @type {__VLS_StyleScopedClasses['items-center']} */ ;
/** @type {__VLS_StyleScopedClasses['justify-between']} */ ;
/** @type {__VLS_StyleScopedClasses['mb-5']} */ ;
/** @type {__VLS_StyleScopedClasses['border-b']} */ ;
/** @type {__VLS_StyleScopedClasses['border-bg-soft']} */ ;
/** @type {__VLS_StyleScopedClasses['pb-4']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text']} */ ;
/** @type {__VLS_StyleScopedClasses['font-black']} */ ;
/** @type {__VLS_StyleScopedClasses['text-xl']} */ ;
/** @type {__VLS_StyleScopedClasses['uppercase']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text-muted']} */ ;
/** @type {__VLS_StyleScopedClasses['hover:text-red']} */ ;
/** @type {__VLS_StyleScopedClasses['text-2xl']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text-muted']} */ ;
/** @type {__VLS_StyleScopedClasses['text-xs']} */ ;
/** @type {__VLS_StyleScopedClasses['mb-4']} */ ;
/** @type {__VLS_StyleScopedClasses['italic']} */ ;
/** @type {__VLS_StyleScopedClasses['text-yellow']} */ ;
/** @type {__VLS_StyleScopedClasses['font-bold']} */ ;
/** @type {__VLS_StyleScopedClasses['grid']} */ ;
/** @type {__VLS_StyleScopedClasses['grid-cols-1']} */ ;
/** @type {__VLS_StyleScopedClasses['md:grid-cols-2']} */ ;
/** @type {__VLS_StyleScopedClasses['gap-4']} */ ;
/** @type {__VLS_StyleScopedClasses['md:col-span-2']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text-muted']} */ ;
/** @type {__VLS_StyleScopedClasses['text-[10px]']} */ ;
/** @type {__VLS_StyleScopedClasses['font-black']} */ ;
/** @type {__VLS_StyleScopedClasses['uppercase']} */ ;
/** @type {__VLS_StyleScopedClasses['tracking-widest']} */ ;
/** @type {__VLS_StyleScopedClasses['block']} */ ;
/** @type {__VLS_StyleScopedClasses['mb-1']} */ ;
/** @type {__VLS_StyleScopedClasses['w-full']} */ ;
/** @type {__VLS_StyleScopedClasses['bg-bg']} */ ;
/** @type {__VLS_StyleScopedClasses['border']} */ ;
/** @type {__VLS_StyleScopedClasses['border-bg-soft']} */ ;
/** @type {__VLS_StyleScopedClasses['rounded-xl']} */ ;
/** @type {__VLS_StyleScopedClasses['px-4']} */ ;
/** @type {__VLS_StyleScopedClasses['py-3']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text']} */ ;
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
/** @type {__VLS_StyleScopedClasses['focus:border-yellow']} */ ;
/** @type {__VLS_StyleScopedClasses['outline-none']} */ ;
/** @type {__VLS_StyleScopedClasses['md:col-span-2']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text-muted']} */ ;
/** @type {__VLS_StyleScopedClasses['text-[10px]']} */ ;
/** @type {__VLS_StyleScopedClasses['font-black']} */ ;
/** @type {__VLS_StyleScopedClasses['uppercase']} */ ;
/** @type {__VLS_StyleScopedClasses['tracking-widest']} */ ;
/** @type {__VLS_StyleScopedClasses['block']} */ ;
/** @type {__VLS_StyleScopedClasses['mb-1']} */ ;
/** @type {__VLS_StyleScopedClasses['w-full']} */ ;
/** @type {__VLS_StyleScopedClasses['bg-bg']} */ ;
/** @type {__VLS_StyleScopedClasses['border']} */ ;
/** @type {__VLS_StyleScopedClasses['border-bg-soft']} */ ;
/** @type {__VLS_StyleScopedClasses['rounded-xl']} */ ;
/** @type {__VLS_StyleScopedClasses['px-4']} */ ;
/** @type {__VLS_StyleScopedClasses['py-3']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text']} */ ;
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
/** @type {__VLS_StyleScopedClasses['focus:border-yellow']} */ ;
/** @type {__VLS_StyleScopedClasses['outline-none']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text-muted']} */ ;
/** @type {__VLS_StyleScopedClasses['text-[10px]']} */ ;
/** @type {__VLS_StyleScopedClasses['font-black']} */ ;
/** @type {__VLS_StyleScopedClasses['uppercase']} */ ;
/** @type {__VLS_StyleScopedClasses['tracking-widest']} */ ;
/** @type {__VLS_StyleScopedClasses['block']} */ ;
/** @type {__VLS_StyleScopedClasses['mb-1']} */ ;
/** @type {__VLS_StyleScopedClasses['w-full']} */ ;
/** @type {__VLS_StyleScopedClasses['bg-bg']} */ ;
/** @type {__VLS_StyleScopedClasses['border']} */ ;
/** @type {__VLS_StyleScopedClasses['border-bg-soft']} */ ;
/** @type {__VLS_StyleScopedClasses['rounded-xl']} */ ;
/** @type {__VLS_StyleScopedClasses['px-4']} */ ;
/** @type {__VLS_StyleScopedClasses['py-3']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text']} */ ;
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
/** @type {__VLS_StyleScopedClasses['outline-none']} */ ;
/** @type {__VLS_StyleScopedClasses['focus:border-yellow']} */ ;
/** @type {__VLS_StyleScopedClasses['appearance-none']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text-muted']} */ ;
/** @type {__VLS_StyleScopedClasses['text-[10px]']} */ ;
/** @type {__VLS_StyleScopedClasses['font-black']} */ ;
/** @type {__VLS_StyleScopedClasses['uppercase']} */ ;
/** @type {__VLS_StyleScopedClasses['tracking-widest']} */ ;
/** @type {__VLS_StyleScopedClasses['block']} */ ;
/** @type {__VLS_StyleScopedClasses['mb-1']} */ ;
/** @type {__VLS_StyleScopedClasses['w-full']} */ ;
/** @type {__VLS_StyleScopedClasses['bg-bg']} */ ;
/** @type {__VLS_StyleScopedClasses['border']} */ ;
/** @type {__VLS_StyleScopedClasses['border-bg-soft']} */ ;
/** @type {__VLS_StyleScopedClasses['rounded-xl']} */ ;
/** @type {__VLS_StyleScopedClasses['px-4']} */ ;
/** @type {__VLS_StyleScopedClasses['py-3']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text']} */ ;
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
/** @type {__VLS_StyleScopedClasses['focus:border-yellow']} */ ;
/** @type {__VLS_StyleScopedClasses['outline-none']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text-muted']} */ ;
/** @type {__VLS_StyleScopedClasses['text-[10px]']} */ ;
/** @type {__VLS_StyleScopedClasses['font-black']} */ ;
/** @type {__VLS_StyleScopedClasses['uppercase']} */ ;
/** @type {__VLS_StyleScopedClasses['tracking-widest']} */ ;
/** @type {__VLS_StyleScopedClasses['block']} */ ;
/** @type {__VLS_StyleScopedClasses['mb-1']} */ ;
/** @type {__VLS_StyleScopedClasses['w-full']} */ ;
/** @type {__VLS_StyleScopedClasses['bg-bg']} */ ;
/** @type {__VLS_StyleScopedClasses['border']} */ ;
/** @type {__VLS_StyleScopedClasses['border-bg-soft']} */ ;
/** @type {__VLS_StyleScopedClasses['rounded-xl']} */ ;
/** @type {__VLS_StyleScopedClasses['px-4']} */ ;
/** @type {__VLS_StyleScopedClasses['py-3']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text']} */ ;
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
/** @type {__VLS_StyleScopedClasses['focus:border-yellow']} */ ;
/** @type {__VLS_StyleScopedClasses['outline-none']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text-muted']} */ ;
/** @type {__VLS_StyleScopedClasses['text-[10px]']} */ ;
/** @type {__VLS_StyleScopedClasses['font-black']} */ ;
/** @type {__VLS_StyleScopedClasses['uppercase']} */ ;
/** @type {__VLS_StyleScopedClasses['tracking-widest']} */ ;
/** @type {__VLS_StyleScopedClasses['block']} */ ;
/** @type {__VLS_StyleScopedClasses['mb-1']} */ ;
/** @type {__VLS_StyleScopedClasses['w-full']} */ ;
/** @type {__VLS_StyleScopedClasses['bg-bg']} */ ;
/** @type {__VLS_StyleScopedClasses['border']} */ ;
/** @type {__VLS_StyleScopedClasses['border-bg-soft']} */ ;
/** @type {__VLS_StyleScopedClasses['rounded-xl']} */ ;
/** @type {__VLS_StyleScopedClasses['px-4']} */ ;
/** @type {__VLS_StyleScopedClasses['py-3']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text']} */ ;
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
/** @type {__VLS_StyleScopedClasses['focus:border-yellow']} */ ;
/** @type {__VLS_StyleScopedClasses['outline-none']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text-muted']} */ ;
/** @type {__VLS_StyleScopedClasses['text-[10px]']} */ ;
/** @type {__VLS_StyleScopedClasses['font-black']} */ ;
/** @type {__VLS_StyleScopedClasses['uppercase']} */ ;
/** @type {__VLS_StyleScopedClasses['tracking-widest']} */ ;
/** @type {__VLS_StyleScopedClasses['block']} */ ;
/** @type {__VLS_StyleScopedClasses['mb-1']} */ ;
/** @type {__VLS_StyleScopedClasses['w-full']} */ ;
/** @type {__VLS_StyleScopedClasses['bg-bg']} */ ;
/** @type {__VLS_StyleScopedClasses['border']} */ ;
/** @type {__VLS_StyleScopedClasses['border-bg-soft']} */ ;
/** @type {__VLS_StyleScopedClasses['rounded-xl']} */ ;
/** @type {__VLS_StyleScopedClasses['px-4']} */ ;
/** @type {__VLS_StyleScopedClasses['py-3']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text']} */ ;
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
/** @type {__VLS_StyleScopedClasses['focus:border-yellow']} */ ;
/** @type {__VLS_StyleScopedClasses['outline-none']} */ ;
/** @type {__VLS_StyleScopedClasses['md:col-span-2']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text-muted']} */ ;
/** @type {__VLS_StyleScopedClasses['text-[10px]']} */ ;
/** @type {__VLS_StyleScopedClasses['font-black']} */ ;
/** @type {__VLS_StyleScopedClasses['uppercase']} */ ;
/** @type {__VLS_StyleScopedClasses['tracking-widest']} */ ;
/** @type {__VLS_StyleScopedClasses['block']} */ ;
/** @type {__VLS_StyleScopedClasses['mb-1']} */ ;
/** @type {__VLS_StyleScopedClasses['w-full']} */ ;
/** @type {__VLS_StyleScopedClasses['bg-bg']} */ ;
/** @type {__VLS_StyleScopedClasses['border']} */ ;
/** @type {__VLS_StyleScopedClasses['border-bg-soft']} */ ;
/** @type {__VLS_StyleScopedClasses['rounded-xl']} */ ;
/** @type {__VLS_StyleScopedClasses['px-4']} */ ;
/** @type {__VLS_StyleScopedClasses['py-3']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text']} */ ;
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
/** @type {__VLS_StyleScopedClasses['focus:border-yellow']} */ ;
/** @type {__VLS_StyleScopedClasses['outline-none']} */ ;
/** @type {__VLS_StyleScopedClasses['md:col-span-2']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text-muted']} */ ;
/** @type {__VLS_StyleScopedClasses['text-[10px]']} */ ;
/** @type {__VLS_StyleScopedClasses['font-black']} */ ;
/** @type {__VLS_StyleScopedClasses['uppercase']} */ ;
/** @type {__VLS_StyleScopedClasses['tracking-widest']} */ ;
/** @type {__VLS_StyleScopedClasses['block']} */ ;
/** @type {__VLS_StyleScopedClasses['mb-1']} */ ;
/** @type {__VLS_StyleScopedClasses['w-full']} */ ;
/** @type {__VLS_StyleScopedClasses['bg-bg']} */ ;
/** @type {__VLS_StyleScopedClasses['border']} */ ;
/** @type {__VLS_StyleScopedClasses['border-bg-soft']} */ ;
/** @type {__VLS_StyleScopedClasses['rounded-xl']} */ ;
/** @type {__VLS_StyleScopedClasses['px-4']} */ ;
/** @type {__VLS_StyleScopedClasses['py-3']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text']} */ ;
/** @type {__VLS_StyleScopedClasses['text-sm']} */ ;
/** @type {__VLS_StyleScopedClasses['focus:border-yellow']} */ ;
/** @type {__VLS_StyleScopedClasses['outline-none']} */ ;
/** @type {__VLS_StyleScopedClasses['resize-none']} */ ;
/** @type {__VLS_StyleScopedClasses['md:col-span-2']} */ ;
/** @type {__VLS_StyleScopedClasses['flex']} */ ;
/** @type {__VLS_StyleScopedClasses['justify-between']} */ ;
/** @type {__VLS_StyleScopedClasses['pt-4']} */ ;
/** @type {__VLS_StyleScopedClasses['border-t']} */ ;
/** @type {__VLS_StyleScopedClasses['border-bg-soft']} */ ;
/** @type {__VLS_StyleScopedClasses['text-text-muted']} */ ;
/** @type {__VLS_StyleScopedClasses['hover:text-red']} */ ;
/** @type {__VLS_StyleScopedClasses['uppercase']} */ ;
/** @type {__VLS_StyleScopedClasses['text-xs']} */ ;
/** @type {__VLS_StyleScopedClasses['font-bold']} */ ;
/** @type {__VLS_StyleScopedClasses['px-6']} */ ;
/** @type {__VLS_StyleScopedClasses['btn-primary']} */ ;
/** @type {__VLS_StyleScopedClasses['px-8']} */ ;
/** @type {__VLS_StyleScopedClasses['py-3']} */ ;
/** @type {__VLS_StyleScopedClasses['!bg-green']} */ ;
/** @type {__VLS_StyleScopedClasses['!text-bg']} */ ;
/** @type {__VLS_StyleScopedClasses['font-black']} */ ;
var __VLS_dollars;
const __VLS_self = (await import('vue')).defineComponent({
setup() {
@@ -2346,10 +2997,15 @@ const __VLS_self = (await import('vue')).defineComponent({
loadingPhotos: loadingPhotos,
lightbox: lightbox,
fileInput: fileInput,
detailVarieties: detailVarieties,
detailPlantGroup: detailPlantGroup,
detailVarietyIdx: detailVarietyIdx,
detailPlant: detailPlant,
detailPlantObj: detailPlantObj,
detailVarieties: detailVarieties,
detailAssociations: detailAssociations,
showFormVariety: showFormVariety,
editVariety: editVariety,
formVariety: formVariety,
categories: categories,
BOUTIQUES: BOUTIQUES,
form: form,
@@ -2373,6 +3029,11 @@ const __VLS_self = (await import('vue')).defineComponent({
nextVariety: nextVariety,
startEdit: startEdit,
closeForm: closeForm,
openAddVariety: openAddVariety,
openEditVariety: openEditVariety,
closeFormVariety: closeFormVariety,
submitVariety: submitVariety,
deleteVariety: deleteVariety,
submitPlant: submitPlant,
removePlant: removePlant,
openUpload: openUpload,

View File

@@ -99,7 +99,7 @@ const plantingsByGarden = computed(() => {
function plantingLabel(p) {
const plant = plantsStore.plants.find(pl => pl.id === p.variety_id);
const nom = plant
? [plant.nom_commun, plant.variete].filter(Boolean).join(' — ')
? [plant.nom_commun, plant.varieties?.[0]?.variete].filter(Boolean).join(' — ')
: `Variété #${p.variety_id}`;
const date = p.date_plantation ? ` (${fmtDate(p.date_plantation)})` : '';
return `${nom}${date}`;