diff --git a/components/CritereFilter.vue b/components/CritereFilter.vue new file mode 100644 index 0000000..fb820d7 --- /dev/null +++ b/components/CritereFilter.vue @@ -0,0 +1,41 @@ + + + CRITÈRES RÉGÉ + + + {{ critere.label }} + {{ counts[critere.id] }} + + + + + + diff --git a/components/EuropeMap.vue b/components/EuropeMap.vue new file mode 100644 index 0000000..6a6c157 --- /dev/null +++ b/components/EuropeMap.vue @@ -0,0 +1,224 @@ + + + + + + + diff --git a/components/OutremerMapPratiques.vue b/components/OutremerMapPratiques.vue new file mode 100644 index 0000000..416eb89 --- /dev/null +++ b/components/OutremerMapPratiques.vue @@ -0,0 +1,276 @@ + + + + + {{ dom.label }} + + + {{ orgCounts[dom.code] ?? 0 }} fiche{{ (orgCounts[dom.code] ?? 0) > 1 ? 's' : '' }} + + + + + + + + + + + + + + + + + diff --git a/components/PaysFilter.vue b/components/PaysFilter.vue new file mode 100644 index 0000000..7a50dd3 --- /dev/null +++ b/components/PaysFilter.vue @@ -0,0 +1,60 @@ + + + + PAYS — EUROPE + + + {{ PAYS_LABELS[code] ?? code }} + {{ counts[code] }} + + + + + OUTRE-MER + + + {{ PAYS_LABELS[code] ?? code }} + {{ counts[code] }} + + + + + + diff --git a/components/PratiqueSidebar.vue b/components/PratiqueSidebar.vue new file mode 100644 index 0000000..e591c6f --- /dev/null +++ b/components/PratiqueSidebar.vue @@ -0,0 +1,241 @@ + + + + + + + diff --git a/components/TypeEntiteFilter.vue b/components/TypeEntiteFilter.vue new file mode 100644 index 0000000..ca77067 --- /dev/null +++ b/components/TypeEntiteFilter.vue @@ -0,0 +1,41 @@ + + + TYPE D'ENTITÉ + + + {{ TYPES_ENTITE_LABELS[type] ?? type }} + {{ counts[type] }} + + + + + + diff --git a/pages/pratique/[id].vue b/pages/pratique/[id].vue new file mode 100644 index 0000000..03eda4c --- /dev/null +++ b/pages/pratique/[id].vue @@ -0,0 +1,170 @@ + + + + + + + + + + + Retour aux pratiques régénératives + + + + + Chargement de la fiche… + + + + + Fiche introuvable + La pratique demandée n'existe pas ou a été supprimée. + + + + + + + + + {{ pratique.nom }} + + {{ TYPES_ENTITE_LABELS[pratique.type] ?? pratique.type }} + + + + + + {{ PAYS_LABELS[pratique.pays] ?? pratique.pays }} + · {{ pratique.ville }} + + + Score {{ pratique.score }}/5 + + Site web → + + + + + {{ pratique.description }} + + + + + + + + + Critères régénératifs + + + {{ CRITERES.find(c => c.id === cId)?.label ?? `Critère ${cId}` }} + + + + + + + Tags + + {{ tag }} + + + + + + Informations + + + Passe : + {{ pratique.passe }} + + + Source : + {{ pratique.source }} + + + Coordonnées : + {{ pratique.lat }}, {{ pratique.lng }} + + + + + + + + + + + diff --git a/pages/pratiques-regeneratives.vue b/pages/pratiques-regeneratives.vue new file mode 100644 index 0000000..a5050c9 --- /dev/null +++ b/pages/pratiques-regeneratives.vue @@ -0,0 +1,469 @@ + + + + + + + + + + + + + + + + + + + + + Chargement de la carte… + + + + + + + + + + + + + Chargement… + + + + + + + + + + + Europe + Outre-mer + + + + + + + + + + + Chargement de la carte… + + + + + + + + + + + + Chargement… + + + + + + + + + + + + + + + + + + + + + + + + + + CRITÈRES + + {{ c.label }} + + + + + + TYPE + + {{ TYPES_ENTITE_LABELS[t] ?? t }} + + + + Effacer les filtres + + + + + + {{ filtered.length }} résultat{{ filtered.length > 1 ? 's' : '' }} + + + Chargement des fiches… + + + Aucun résultat pour ces filtres. + + Effacer les filtres + + + + + + {{ pratique.nom }} + {{ pratique.pays }} + + + {{ CRITERES.find(c => c.id === cId)?.label }} + + + {{ pratique.ville }} + + + + + + + + + + + + + + + + Chatbot + + + + + + diff --git a/server/api/pratiques.get.ts b/server/api/pratiques.get.ts new file mode 100644 index 0000000..c1d82e3 --- /dev/null +++ b/server/api/pratiques.get.ts @@ -0,0 +1,20 @@ +import { readFileSync } from 'fs' +import { resolve } from 'path' +import type { Pratique } from '~/types/pratique' + +/** + * GET /api/pratiques + * Lit public/data/pratiques-regeneratives.json + * Retourne { list: Pratique[], source: 'static' } + */ +export default defineEventHandler(async (_event) => { + try { + const jsonPath = resolve(process.cwd(), 'public/data/pratiques-regeneratives.json') + const raw = readFileSync(jsonPath, 'utf-8') + const list: Pratique[] = JSON.parse(raw) + return { list, source: 'static' } + } catch (err) { + console.error('[PRATIQUES API] Erreur lecture JSON:', err) + throw createError({ statusCode: 503, message: 'Données pratiques-regeneratives indisponibles' }) + } +}) diff --git a/types/pratique.ts b/types/pratique.ts new file mode 100644 index 0000000..c4a8429 --- /dev/null +++ b/types/pratique.ts @@ -0,0 +1,69 @@ +/** + * Interface canonique Pratique — AEP Pratiques Régénératives + * Source unique : types/pratique.ts + * Importée dans pages/pratiques-regeneratives.vue, pages/pratique/[id].vue + */ +export interface Pratique { + id: number + nom: string + pays: string // ISO-2 — Europe (FR/BE/...) ou DOM-TOM (GP/MQ/GF/RE/YT/PF/NC/...) + ville: string + type: 'agence' | 'cooperative' | 'collectif' | 'reseau' | 'asso' | 'recherche' | 'mouvement' | 'plateforme' | 'inconnu' + url: string + lat: number | null + lng: number | null + description: string + criteres: number[] // 1-8 + score: number + tags: string[] + source: string + passe: 1 | 2 | 3 +} + +export const CRITERES = [ + { id: 1, label: 'Matériaux' }, + { id: 2, label: 'Filières' }, + { id: 3, label: 'Posture' }, + { id: 4, label: 'Process' }, + { id: 5, label: 'Politique' }, + { id: 6, label: 'Modèle éco' }, + { id: 7, label: 'Vivant' }, + { id: 8, label: 'Transmission' }, +] as const + +export const TYPES_ENTITE = [ + 'agence', + 'cooperative', + 'collectif', + 'reseau', + 'asso', + 'recherche', + 'mouvement', + 'plateforme', + 'inconnu', +] as const + +export const TYPES_ENTITE_LABELS: Record = { + agence: 'Agence', + cooperative: 'Coopérative', + collectif: 'Collectif', + reseau: 'Réseau', + asso: 'Association', + recherche: 'Recherche', + mouvement: 'Mouvement', + plateforme: 'Plateforme', + inconnu: 'Autre', +} + +export const EUROPE_CODES = ['FR', 'BE', 'UK', 'DE', 'ES', 'NL', 'CH', 'IT', 'PT', 'SE', 'DK', 'FI', 'NO', 'PL', 'CZ', 'AT'] as const +export const OUTREMER_CODES = ['GP', 'MQ', 'GF', 'RE', 'YT', 'PF', 'NC', 'BL', 'MF', 'PM', 'WF'] as const + +export const PAYS_LABELS: Record = { + FR: 'France', BE: 'Belgique', UK: 'Royaume-Uni', DE: 'Allemagne', + ES: 'Espagne', NL: 'Pays-Bas', CH: 'Suisse', IT: 'Italie', + PT: 'Portugal', SE: 'Suède', DK: 'Danemark', FI: 'Finlande', + NO: 'Norvège', PL: 'Pologne', CZ: 'Tchéquie', AT: 'Autriche', + GP: 'Guadeloupe', MQ: 'Martinique', GF: 'Guyane', RE: 'La Réunion', + YT: 'Mayotte', PF: 'Polynésie française', NC: 'Nouvelle-Calédonie', + BL: 'Saint-Barthélemy', MF: 'Saint-Martin', PM: 'Saint-Pierre-et-Miquelon', WF: 'Wallis-et-Futuna', +}
Fiche introuvable
La pratique demandée n'existe pas ou a été supprimée.
+ {{ pratique.description }} +
Aucun résultat pour ces filtres.