maj
This commit is contained in:
+16
-2
@@ -4,7 +4,12 @@ Application web permettant de consulter les données ouvertes de Parcoursup pour
|
|||||||
|
|
||||||
Ce projet a été réalisé dans le cadre des modules R4.01 et R4.A.10.
|
Ce projet a été réalisé dans le cadre des modules R4.01 et R4.A.10.
|
||||||
|
|
||||||
|
## 🌐 Démo en ligne
|
||||||
|
|
||||||
|
👉 **[https://dwarves.iut-fbleau.fr/~yolou/parcoursup2/public-html2/parcoursup/#/](https://dwarves.iut-fbleau.fr/~yolou/parcoursup2/public-html2/parcoursup/#/)**
|
||||||
|
|
||||||
## Fonctionnalités principales
|
## Fonctionnalités principales
|
||||||
|
|
||||||
* **Recherche** de formations par mots-clés (via l'API OpenData)
|
* **Recherche** de formations par mots-clés (via l'API OpenData)
|
||||||
* **Visualisation cartographique** des établissements avec Leaflet
|
* **Visualisation cartographique** des établissements avec Leaflet
|
||||||
* **Consultation détaillée** d'une formation (taux d'accès, profil des admis, évolution multi-années)
|
* **Consultation détaillée** d'une formation (taux d'accès, profil des admis, évolution multi-années)
|
||||||
@@ -20,12 +25,12 @@ L'application est construite de façon déclarative et modulaire avec le framewo
|
|||||||
|
|
||||||
### 1. `app.riot` (Composant Racine)
|
### 1. `app.riot` (Composant Racine)
|
||||||
C'est le chef d'orchestre de l'application.
|
C'est le chef d'orchestre de l'application.
|
||||||
* **Fonction :** Gère le routage principal (`<router>`, `<route>`), l'état global (données de recherche, sélection) et coordonne les autres composants.
|
* **Fonction :** Gère le routage principal, l'état global (données de recherche, sélection) et coordonne les autres composants.
|
||||||
* **État (State) :** Stocke les résultats de recherche (`state.results`), la formation active (`state.selected`), la sélection pour comparaison (`state.selectedFormations`), et l'utilisateur connecté (`state.user`).
|
* **État (State) :** Stocke les résultats de recherche (`state.results`), la formation active (`state.selected`), la sélection pour comparaison (`state.selectedFormations`), et l'utilisateur connecté (`state.user`).
|
||||||
* **Enfants :**
|
* **Enfants :**
|
||||||
* Charge `<search-bar>`, `<map-view>`, `<result-list>` sur la route `/`
|
* Charge `<search-bar>`, `<map-view>`, `<result-list>` sur la route `/`
|
||||||
* Charge `<detail-view>` sur la route `/formation/:id`
|
* Charge `<detail-view>` sur la route `/formation/:id`
|
||||||
* Gère seule la route `/comparateur`
|
* Charge `<comparateur-view>` sur la route `/comparateur`
|
||||||
|
|
||||||
### 2. `components/search-bar.riot`
|
### 2. `components/search-bar.riot`
|
||||||
* **Fonction :** Moteur de recherche et filtres.
|
* **Fonction :** Moteur de recherche et filtres.
|
||||||
@@ -63,6 +68,15 @@ C'est le chef d'orchestre de l'application.
|
|||||||
* **Sorties (Events) :**
|
* **Sorties (Events) :**
|
||||||
* `onauth()` et `onlogout()` pour notifier `<app>` des changements de session, ce qui déclenche la synchronisation de la sélection `localStorage` <-> `Firestore`.
|
* `onauth()` et `onlogout()` pour notifier `<app>` des changements de session, ce qui déclenche la synchronisation de la sélection `localStorage` <-> `Firestore`.
|
||||||
|
|
||||||
|
### 7. `components/comparateur.riot`
|
||||||
|
* **Fonction :** Comparateur de formations permettant à l'utilisateur d'estimer ses chances d'admission selon son profil (note, série de bac).
|
||||||
|
* **Props :**
|
||||||
|
* `formations` : le tableau des formations sélectionnées (passé par `<app>`).
|
||||||
|
* `onretirer(id)` : callback pour retirer une formation de la sélection.
|
||||||
|
* `onvider()` : callback pour vider toute la sélection.
|
||||||
|
* **État interne (State) :** Gère `note`, `serie` et `sortBy` — paramètres propres à l'affichage du comparateur, sans impacter le reste de l'app.
|
||||||
|
* **Logique :** Calcule un score sur 100 pour chaque formation (taux d'accès + note + proportion de la série) via `calculerScore()`, puis retourne une estimation textuelle (`"Favorable"`, `"Possible"`, etc.).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Modèle de Données et API
|
## Modèle de Données et API
|
||||||
|
|||||||
@@ -1,81 +0,0 @@
|
|||||||
import { fetchFormations } from "./api.js"
|
|
||||||
import { createFormation } from "./formation.js"
|
|
||||||
|
|
||||||
let lastFormations = []
|
|
||||||
|
|
||||||
const button = document.getElementById("btn-test")
|
|
||||||
const output = document.getElementById("output")
|
|
||||||
const searchInput = document.getElementById("search")
|
|
||||||
|
|
||||||
function showDetail(index) {
|
|
||||||
const f = lastFormations[index]
|
|
||||||
|
|
||||||
output.innerHTML = `
|
|
||||||
<div style="border:1px solid #ccc; padding:10px; margin:10px;">
|
|
||||||
<h2>${f.nom}</h2>
|
|
||||||
<p><b>Établissement :</b> ${f.etablissement}</p>
|
|
||||||
<p><b>Ville :</b> ${f.ville}</p>
|
|
||||||
<p><b>Département :</b> ${f.departement}</p>
|
|
||||||
<p><b>Filière :</b> ${f.filiere}</p>
|
|
||||||
<p><b>Sélectivité :</b> ${f.selectivite}</p>
|
|
||||||
<p><b>Capacité :</b> ${f.capacite}</p>
|
|
||||||
<p><b>Candidats :</b> ${f.candidats}</p>
|
|
||||||
<p><b>Admis :</b> ${f.admis}</p>
|
|
||||||
<p><b>Taux d'accès :</b> ${f.tauxAcces}%</p>
|
|
||||||
<button id="back-btn">Retour</button>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
|
|
||||||
const backBtn = document.getElementById("back-btn")
|
|
||||||
backBtn.addEventListener("click", testAPI)
|
|
||||||
}
|
|
||||||
|
|
||||||
window.showDetail = showDetail
|
|
||||||
|
|
||||||
async function testAPI() {
|
|
||||||
output.textContent = "Chargement..."
|
|
||||||
|
|
||||||
try {
|
|
||||||
const query = searchInput.value
|
|
||||||
|
|
||||||
const data = await fetchFormations(query)
|
|
||||||
|
|
||||||
if (data.results && data.results.length > 0) {
|
|
||||||
const formations = []
|
|
||||||
|
|
||||||
for (let i = 0; i < data.results.length; i++) {
|
|
||||||
const raw = data.results[i]
|
|
||||||
const formation = createFormation(raw)
|
|
||||||
formations.push(formation)
|
|
||||||
}
|
|
||||||
|
|
||||||
lastFormations = formations
|
|
||||||
|
|
||||||
let html = ""
|
|
||||||
|
|
||||||
for (let i = 0; i < formations.length; i++) {
|
|
||||||
const f = formations[i]
|
|
||||||
|
|
||||||
html += `
|
|
||||||
<div style="border:1px solid #ccc; padding:10px; margin:10px;">
|
|
||||||
<h3>${f.nom}</h3>
|
|
||||||
<p><b>Établissement :</b> ${f.etablissement}</p>
|
|
||||||
<p><b>Ville :</b> ${f.ville} (${f.departement})</p>
|
|
||||||
<p><b>Filière :</b> ${f.filiere}</p>
|
|
||||||
<p><b>Taux d'accès :</b> ${f.tauxAcces}%</p>
|
|
||||||
<button onclick="showDetail(${i})">Voir détail</button>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
output.innerHTML = html
|
|
||||||
} else {
|
|
||||||
output.textContent = "Aucun résultat trouvé"
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Erreur :", error)
|
|
||||||
output.textContent = "Erreur lors de la requête"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
button.addEventListener("click", testAPI)
|
|
||||||
Reference in New Issue
Block a user