diff --git a/parcoursup/README.md b/parcoursup/README.md new file mode 100644 index 0000000..fd3c584 --- /dev/null +++ b/parcoursup/README.md @@ -0,0 +1,92 @@ +# Parcoursup Explorer + +Application web permettant de consulter les données ouvertes de Parcoursup pour aider à l'orientation des lycéens. + +Ce projet a été réalisé dans le cadre des modules R4.01 et R4.A.10. + +## Fonctionnalités principales +* **Recherche** de formations par mots-clés (via l'API OpenData) +* **Visualisation cartographique** des établissements avec Leaflet +* **Consultation détaillée** d'une formation (taux d'accès, profil des admis, évolution multi-années) +* **Graphiques statistiques** intégrés avec Charts.css +* **Comparateur de sélection** pour estimer ses chances d'admission +* **Espace utilisateur** connecté avec Firebase Auth et Firestore (persistance avancée) + +--- + +## Architecture et Composants (Riot.js) + +L'application est construite de façon déclarative et modulaire avec le framework **Riot.js (v9)** et utilise le routeur officiel **@riotjs/route** pour la navigation SPA (Single Page Application). + +### 1. `app.riot` (Composant Racine) +C'est le chef d'orchestre de l'application. +* **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`). +* **Enfants :** + * Charge ``, ``, `` sur la route `/` + * Charge `` sur la route `/formation/:id` + * Gère seule la route `/comparateur` + +### 2. `components/search-bar.riot` +* **Fonction :** Moteur de recherche et filtres. +* **Entrées :** L'utilisateur tape sa requête (mot clé) et peut appliquer des filtres avancés (filière, sélectivité, région...). +* **Sorties :** Déclenche l'événement `onsearch` qui remonte jusqu'à `` pour lancer la requête API (`lancerRecherche`). + +### 3. `components/result-list.riot` +* **Fonction :** Affiche la liste paginée des formations correspondant à la recherche. +* **Props :** + * `results` : tableau des données renvoyées par l'API + * `loading` : booléen pour l'état d'attente + * `hasSearched` : détermine si la liste doit s'afficher +* **Sorties (Events) :** + * `ondetail(index)` : L'application navigue vers la vue détaillée d'une formation. + * `onselect(index)` : Ajoute la formation au tableau "Comparateur". + +### 4. `components/detail-view.riot` +* **Fonction :** Affiche une fiche complète de la formation sélectionnée avec statistiques approfondies et graphiques via Charts.css. +* **Props :** + * `formation` : l'objet complet de la formation courante. +* **Sorties (Events) :** + * `onback()` : Demande de retour à l'écran de recherche principal. +* **Interactions :** Fait un appel API supplémentaire (via `window.chargerHistoriqueFormation`) pour récupérer l'historique sur 6 ans depuis l'API Parcoursup. + +### 5. `components/map-view.riot` +* **Fonction :** Affiche une carte interactive Leaflet. +* **Props :** + * `results` : La liste courante des formations de la vue recherche. +* **Interactions :** Instancie Leaflet dans `onMounted`, place les marqueurs sur carte selon les coordonnées latitude/longitude récupérées, et se redessine automatiquement avec `onUpdated()`. Fournit également une API window globale (`window.mapFocus`) que `result-list` utilise pour recentrer la carte. + +### 6. `components/auth-panel.riot` +* **Fonction :** Panneau de connexion / inscription de l'utilisateur (Bonus Firebase). +* **Props :** + * `user` (objet utilisateur Firebase passé par ``). +* **Sorties (Events) :** + * `onauth()` et `onlogout()` pour notifier `` des changements de session, ce qui déclenche la synchronisation de la sélection `localStorage` <-> `Firestore`. + +--- + +## Modèle de Données et API + +### `api.js` (Modèle de communication HTTP) +Contient les modules d'appel réseau `fetch`. +* `chargerFormations()` : Requete paginée avec filtres croisés vers l'API Data ESR. +* `chargerHistoriqueFormation()` : Requete intelligente multi-datasets (2020-2025) ciblant le code UAI d'un établissement précis pour en extraire l'historique d'admission. + +### `formation.js` (Modèle Métier) +* **Fonction :** Isoler et abstraire la complexité du schéma JSON renvoyé par l'API Parcoursup. +* Transforme `brut.acc_tot` ou `brut.lib_for_voe_ins` en un objet lisible clair pour les composants (ex: `formation.admis` ou `formation.nom`), et y précalcule certains champs de base (comme le `tauxAcces`). + +### `firebase.js` (Service Backend As a Service) +* Gère l'authentification (Emai/Password) avec `firebase-auth`. +* Gère la persistance cloud de la sélection de vœux dans `users/{uid}` via `firebase-firestore`. + + +## Routing (Hash Router) +L'application utilise un système de routage manuel natif basé sur l'API `window.location.hash` : +* Écoute de l'événement natif `hashchange` dans `app.riot`. +* Routage conditionnel géré par la fonction `gererRoute()` (`#/`, `#/formation/:id`, `#/comparateur`). +* Affichage conditionnel des composants via les directives natives `if={ state.view === ... }`. + +*** + +*Réalisé par Aylane Sehl, Jenson Val et Séri-Khane Yolou à l'IUT Sénart-Fontainebleau (UPEC).* diff --git a/parcoursup/api.js b/parcoursup/api.js index 20b2c65..8766324 100644 --- a/parcoursup/api.js +++ b/parcoursup/api.js @@ -1,34 +1,35 @@ -export function buildURL(query, limit = 20, offset = 0, filters = {}) { - let url = - "https://data.enseignementsup-recherche.gouv.fr/api/explore/v2.1/catalog/datasets/fr-esr-parcoursup/records?" +// Construire l'URL de requête vers l'API Parcoursup +export function construireURL(requete, limite = 20, decalage = 0, filtres = {}) { - url += "limit=" + limit - url += "&offset=" + offset + var url = "https://data.enseignementsup-recherche.gouv.fr/api/explore/v2.1/catalog/datasets/fr-esr-parcoursup/records?" + + url += "limit=" + limite + url += "&offset=" + decalage var conditions = [] - if (query && query.trim() !== "") { - conditions.push("search(lib_for_voe_ins, '" + query + "')") + if (requete && requete.trim() !== "") { + conditions.push("search(lib_for_voe_ins, '" + requete + "')") } - if (filters.filiere && filters.filiere !== "") { - conditions.push("fili='" + filters.filiere + "'") + if (filtres.filiere && filtres.filiere !== "") { + conditions.push("fili='" + filtres.filiere + "'") } - if (filters.selectivite && filters.selectivite !== "") { - conditions.push("select_form='" + filters.selectivite + "'") + if (filtres.selectivite && filtres.selectivite !== "") { + conditions.push("select_form='" + filtres.selectivite + "'") } - if (filters.region && filters.region !== "") { - conditions.push("region_etab_aff='" + filters.region + "'") + if (filtres.region && filtres.region !== "") { + conditions.push("region_etab_aff='" + filtres.region + "'") } - if (filters.tauxMin && filters.tauxMin > 0) { - conditions.push("taux_acces_ens>=" + filters.tauxMin) + if (filtres.tauxMin && filtres.tauxMin > 0) { + conditions.push("taux_acces_ens>=" + filtres.tauxMin) } - if (filters.tauxMax && filters.tauxMax < 100) { - conditions.push("taux_acces_ens<=" + filters.tauxMax) + if (filtres.tauxMax && filtres.tauxMax < 100) { + conditions.push("taux_acces_ens<=" + filtres.tauxMax) } if (conditions.length > 0) { @@ -38,19 +39,23 @@ export function buildURL(query, limit = 20, offset = 0, filters = {}) { return url } -export async function fetchFormations(query, limit = 20, offset = 0, filters = {}) { - const url = buildURL(query, limit, offset, filters) - const response = await fetch(url) +// Charger les formations depuis l'API Parcoursup +export async function chargerFormations(requete, limite = 20, decalage = 0, filtres = {}) { - if (!response.ok) { + var url = construireURL(requete, limite, decalage, filtres) + var reponse = await fetch(url) + + if (!reponse.ok) { throw new Error("Erreur HTTP") } - return await response.json() + return await reponse.json() } -export async function fetchFormationHistory(codUai, nomFormation) { - var datasets = { +// Charger l'historique d'une formation sur plusieurs années +export async function chargerHistoriqueFormation(codUai, nomFormation) { + + var jeuDeDonnees = { 2020: "fr-esr-parcoursup_2020", 2021: "fr-esr-parcoursup_2021", 2022: "fr-esr-parcoursup_2022", @@ -59,54 +64,59 @@ export async function fetchFormationHistory(codUai, nomFormation) { 2025: "fr-esr-parcoursup" } - var history = [] - var searchName = nomFormation.substring(0, 40).replace(/'/g, "\\'") - var years = [2020, 2021, 2022, 2023, 2024, 2025] + var historique = [] + var nomCourt = nomFormation.substring(0, 40).replace(/'/g, "\\'") + var annees = [2020, 2021, 2022, 2023, 2024, 2025] - for (var i = 0; i < years.length; i++) { - var year = years[i] - var dataset = datasets[year] + for (var i = 0; i < annees.length; i++) { + + var annee = annees[i] + var dataset = jeuDeDonnees[annee] try { + var url = "https://data.enseignementsup-recherche.gouv.fr/api/explore/v2.1/catalog/datasets/" + dataset + "/records?" + "limit=5" - + "&where=cod_uai%3D'" + codUai + "' AND search(lib_for_voe_ins, '" + searchName + "')" + + "&where=cod_uai%3D'" + codUai + "' AND search(lib_for_voe_ins, '" + nomCourt + "')" + "&select=cod_uai,lib_for_voe_ins,voe_tot,acc_tot,pct_sansmention,pct_ab,pct_b,pct_tb,pct_tbf,pct_bg,pct_bt,pct_bp" - var response = await fetch(url) + var reponse = await fetch(url) - if (response.ok) { - var data = await response.json() + if (reponse.ok) { - if (data.results && data.results.length > 0) { - var r = data.results[0] - var taux = 0 + var donnees = await reponse.json() - if (r.voe_tot && r.voe_tot > 0) { - taux = Math.round((r.acc_tot / r.voe_tot) * 100) + if (donnees.results && donnees.results.length > 0) { + + var ligne = donnees.results[0] + var taux = 0 + + if (ligne.voe_tot && ligne.voe_tot > 0) { + taux = Math.round((ligne.acc_tot / ligne.voe_tot) * 100) } - history.push({ - annee: year, - tauxAcces: taux, - candidats: r.voe_tot || 0, - admis: r.acc_tot || 0, - pctSansMention: r.pct_sansmention || 0, - pctAB: r.pct_ab || 0, - pctB: r.pct_b || 0, - pctTB: r.pct_tb || 0, - pctTBF: r.pct_tbf || 0, - pctGeneral: r.pct_bg || 0, - pctTechno: r.pct_bt || 0, - pctPro: r.pct_bp || 0 + historique.push({ + annee: annee, + tauxAcces: taux, + candidats: ligne.voe_tot || 0, + admis: ligne.acc_tot || 0, + pctSansMention: ligne.pct_sansmention || 0, + pctAB: ligne.pct_ab || 0, + pctB: ligne.pct_b || 0, + pctTB: ligne.pct_tb || 0, + pctTBF: ligne.pct_tbf || 0, + pctGeneral: ligne.pct_bg || 0, + pctTechno: ligne.pct_bt || 0, + pctPro: ligne.pct_bp || 0 }) } } + } catch (e) { - console.warn("Erreur pour " + year + ":", e) + console.warn("Erreur pour l'année " + annee + " :", e) } } - return history + return historique } diff --git a/parcoursup/api.js~ b/parcoursup/api.js~ deleted file mode 100644 index a6b10da..0000000 --- a/parcoursup/api.js~ +++ /dev/null @@ -1,21 +0,0 @@ -export function buildURL(query) { - let url = - "https://data.enseignementsup-recherche.gouv.fr/api/explore/v2.1/catalog/datasets/fr-esr-parcoursup/records?limit=10" - - if (query && query.trim() !== "") { - url += "&where=search(lib_for_voe_ins, '" + query + "')" - } - - return url - } - - export async function fetchFormations(query) { - const url = buildURL(query) - const response = await fetch(url) - - if (!response.ok) { - throw new Error("Erreur HTTP") - } - - return await response.json() - } \ No newline at end of file diff --git a/parcoursup/app.riot b/parcoursup/app.riot index e597f1b..6072d0b 100644 --- a/parcoursup/app.riot +++ b/parcoursup/app.riot @@ -1,23 +1,73 @@
-
- + +
+ -
0 }> -

Comparateur

+

+ { state.query } — { state.total } résultat(s) +

+ + + +
+
+ + + + +
+
+
+ + +
+ + +
+ +
+ Chargement de la formation... +
+ + +
+ + + +
0 }> +

Comparateur de formations

Choisis ton profil pour estimer tes chances d'intégration.

@@ -30,13 +80,13 @@ max="20" step="0.1" value={ state.note } - oninput={ updateNote } + oninput={ mettreAJourNote } />

- @@ -45,7 +95,7 @@

- @@ -54,13 +104,11 @@
- +
-

Formations sélectionnées

- -
+

{ f.nom }

Établissement : { f.etablissement }

@@ -77,60 +125,30 @@

- - { estimateFormation(f) } + + { estimerFormation(f) } - { getEstimateDetail(f) } + { detailEstimation(f) }

-
-

- { state.query } — { state.total } résultat(s) -

- - - -
-
- - - - -
+
+

Aucune formation sélectionnée

+

Retourne à la recherche et clique sur "Ajouter à la sélection" pour comparer des formations.

-
- - -
diff --git a/parcoursup/components/auth-panel.riot b/parcoursup/components/auth-panel.riot new file mode 100644 index 0000000..4fa0727 --- /dev/null +++ b/parcoursup/components/auth-panel.riot @@ -0,0 +1,174 @@ + + + +
+ +
+ + + + + +
+
+ + + +

{ state.titre }

+ + +
+ + +
+ + +
+ +
+ + +
+ +
+ + +
+ + +
+ { state.erreur } +
+ + + +
+
+
+ + + +
diff --git a/parcoursup/components/detail-view.riot b/parcoursup/components/detail-view.riot index 82258d4..bdaefc6 100644 --- a/parcoursup/components/detail-view.riot +++ b/parcoursup/components/detail-view.riot @@ -1,9 +1,7 @@

Formation

-

{ props.formation.etablissement } - { props.formation.nom }

-

Ville : { props.formation.ville }

Département : { props.formation.departement } { props.formation.departementLib }

@@ -15,7 +13,6 @@

Phase principale d'admission

- @@ -68,7 +65,6 @@

Vitesse de remplissage

-
@@ -77,7 +73,6 @@ { props.formation.pctDebutPhase }%
-
@@ -85,7 +80,6 @@ { props.formation.pctDateBac }%
-
@@ -98,7 +92,6 @@

Phase complémentaire d'admission

-
@@ -148,146 +141,288 @@
- +

Profil des admis

- -

Répartition par type de bac

- -
- - - - - - - - - - - - - - - - - - - - - -
TypePourcentage
Général - { props.formation.pctGeneral || 0 }% -
Techno - { props.formation.pctTechno || 0 }% -
Pro - { props.formation.pctPro || 0 }% -
-
+
-

Mentions au bac des admis

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MentionPourcentage
Sans - { props.formation.pctSansMention || 0 }% -
AB - { props.formation.pctAB || 0 }% -
Bien - { props.formation.pctB || 0 }% -
TB - { props.formation.pctTB || 0 }% -
TB Féli. - { props.formation.pctTBF || 0 }% -
-
+
-

Profil sociologique

- -
- - - - - - - - - - - - - - - - - - - - - -
CatégoriePourcentage
Femmes - { props.formation.pctFemmes || 0 }% -
Boursiers - { props.formation.pctBoursiers || 0 }% -
Néo-bac - { props.formation.pctNeoBac || 0 }% -
-
+
-
- + + +

Évolution depuis 2020

+ +
+ Chargement de l'historique... +
+ +
+ Aucune donnée historique disponible pour cette formation. +
+ +
0 }> +
+

Taux d'accès par année

+
+
+ +
+

Nombre de candidats et admis

+
+
+ +
+

Évolution des mentions au bac

+
+
+
+ +
+ diff --git a/parcoursup/components/map-view.riot b/parcoursup/components/map-view.riot index f8aea27..e3a9805 100644 --- a/parcoursup/components/map-view.riot +++ b/parcoursup/components/map-view.riot @@ -1,100 +1,120 @@

Carte des formations

-
+
+
diff --git a/parcoursup/components/result-list.riot b/parcoursup/components/result-list.riot index e84a631..5fa57f8 100644 --- a/parcoursup/components/result-list.riot +++ b/parcoursup/components/result-list.riot @@ -1,5 +1,6 @@
+
Aucun résultat trouvé
@@ -8,26 +9,41 @@ Chargement...
-
-

{ f.nom }

-

Établissement : { f.etablissement }

-

Ville : { f.ville } ({ f.departement })

-

Filière : { f.filiere }

-

Taux d'accès : { f.tauxAcces }%

+
+

{ formation.nom }

+

Établissement : { formation.etablissement }

+

Ville : { formation.ville } ({ formation.departement })

+

Filière : { formation.filiere }

+

Taux d'accès : { formation.tauxAcces }%

- - - + + +
+
+
diff --git a/parcoursup/components/search-bar.riot b/parcoursup/components/search-bar.riot index 1511402..81c2937 100644 --- a/parcoursup/components/search-bar.riot +++ b/parcoursup/components/search-bar.riot @@ -12,7 +12,7 @@
@@ -91,6 +91,7 @@ state: { query: '', showFilters: false, + labelFiltres: 'Filtres avancés', filiere: '', selectivite: '', region: '', @@ -109,14 +110,30 @@ }, toggleFilters() { - this.update({ showFilters: !this.state.showFilters }) + var visible = !this.state.showFilters + var label = visible ? 'Masquer les filtres' : 'Filtres avancés' + this.update({ showFilters: visible, labelFiltres: label }) }, - updateFiliere(e) { this.update({ filiere: e.target.value }) }, - updateSelectivite(e) { this.update({ selectivite: e.target.value }) }, - updateRegion(e) { this.update({ region: e.target.value }) }, - updateTauxMin(e) { this.update({ tauxMin: Number(e.target.value) }) }, - updateTauxMax(e) { this.update({ tauxMax: Number(e.target.value) }) }, + updateFiliere(e) { + this.update({ filiere: e.target.value }) + }, + + updateSelectivite(e) { + this.update({ selectivite: e.target.value }) + }, + + updateRegion(e) { + this.update({ region: e.target.value }) + }, + + updateTauxMin(e) { + this.update({ tauxMin: Number(e.target.value) }) + }, + + updateTauxMax(e) { + this.update({ tauxMax: Number(e.target.value) }) + }, submitSearch() { var filters = { diff --git a/parcoursup/firebase.js b/parcoursup/firebase.js new file mode 100644 index 0000000..069dab1 --- /dev/null +++ b/parcoursup/firebase.js @@ -0,0 +1,80 @@ +import { initializeApp } from "https://www.gstatic.com/firebasejs/11.6.1/firebase-app.js"; + +import { + getAuth, + createUserWithEmailAndPassword, + signInWithEmailAndPassword, + signOut, + onAuthStateChanged +} from "https://www.gstatic.com/firebasejs/11.6.1/firebase-auth.js"; + +import { + getFirestore, + doc, + setDoc, + getDoc +} from "https://www.gstatic.com/firebasejs/11.6.1/firebase-firestore.js"; + + +const firebaseConfig = { + apiKey: "AIzaSyDr1jMgGm0Oj_bOiWY-8Gy27IlzkmAzlOM", + authDomain: "parcoursupp-expl.firebaseapp.com", + projectId: "parcoursupp-expl", + storageBucket: "parcoursupp-expl.firebasestorage.app", + messagingSenderId: "973054617217", + appId: "1:973054617217:web:4d52af4280396976228f80" +}; + + +const app = initializeApp(firebaseConfig); +const auth = getAuth(app); +const db = getFirestore(app); + + +// Créer un compte avec email et mot de passe +async function createAccount(email, password) { + return createUserWithEmailAndPassword(auth, email, password); +} + +// Se connecter avec email et mot de passe +async function login(email, password) { + return signInWithEmailAndPassword(auth, email, password); +} + +// Se déconnecter +async function logout() { + return signOut(auth); +} + +// Écouter les changements d'état de connexion +function onUserChanged(callback) { + return onAuthStateChanged(auth, callback); +} + +// Sauvegarder les données d'un utilisateur dans Firestore +async function saveUserData(uid, data) { + await setDoc(doc(db, "users", uid), data, { merge: true }); +} + +// Charger les données d'un utilisateur depuis Firestore +async function loadUserData(uid) { + var snap = await getDoc(doc(db, "users", uid)); + + if (snap.exists()) { + return snap.data(); + } else { + return null; + } +} + + +export { + auth, + db, + createAccount, + login, + logout, + onUserChanged, + saveUserData, + loadUserData +}; \ No newline at end of file diff --git a/parcoursup/formation.js b/parcoursup/formation.js index 0bfa12b..eedec42 100644 --- a/parcoursup/formation.js +++ b/parcoursup/formation.js @@ -1,93 +1,97 @@ -export function createFormation(raw) { - let taux = 0 +// Créer un objet formation à partir des données brutes de l'API +export function creerFormation(brut) { - if (raw.voe_tot && raw.voe_tot > 0) { - taux = Math.round((raw.acc_tot / raw.voe_tot) * 100) + var taux = 0 + var latitude = null + var longitude = null + + if (brut.voe_tot && brut.voe_tot > 0) { + taux = Math.round((brut.acc_tot / brut.voe_tot) * 100) + } + + if (brut.g_olocalisation_des_formations) { + latitude = brut.g_olocalisation_des_formations.lat + longitude = brut.g_olocalisation_des_formations.lon } return { - id: raw.cod_uai + "-" + raw.lib_for_voe_ins, + id: brut.cod_uai + "-" + brut.lib_for_voe_ins, - nom: raw.lib_for_voe_ins, - etablissement: raw.g_ea_lib_vx, - ville: raw.ville_etab, - departement: raw.dep, - departementLib: raw.dep_lib, - region: raw.region_etab_aff, - academie: raw.acad_mies, - contrat: raw.contrat_etab, + nom: brut.lib_for_voe_ins, + etablissement: brut.g_ea_lib_vx, + ville: brut.ville_etab, + departement: brut.dep, + departementLib: brut.dep_lib, + region: brut.region_etab_aff, + academie: brut.acad_mies, + contrat: brut.contrat_etab, - filiere: raw.fili, - selectivite: raw.select_form, + filiere: brut.fili, + selectivite: brut.select_form, - capacite: raw.capa_fin, - candidats: raw.voe_tot, - admis: raw.acc_tot, - tauxAcces: taux, + capacite: brut.capa_fin, + candidats: brut.voe_tot, + admis: brut.acc_tot, + tauxAcces: taux, - latitude: raw.g_olocalisation_des_formations - ? raw.g_olocalisation_des_formations.lat - : null, + latitude: latitude, + longitude: longitude, - longitude: raw.g_olocalisation_des_formations - ? raw.g_olocalisation_des_formations.lon - : null, + pctFemmes: brut.pct_f, + pctBoursiers: brut.pct_bours, + pctNeoBac: brut.pct_neobac, - pctFemmes: raw.pct_f, - pctBoursiers: raw.pct_bours, - pctNeoBac: raw.pct_neobac, + pctGeneral: brut.pct_bg, + pctTechno: brut.pct_bt, + pctPro: brut.pct_bp, - pctGeneral: raw.pct_bg, - pctTechno: raw.pct_bt, - pctPro: raw.pct_bp, + pctSansMention: brut.pct_sansmention, + pctAB: brut.pct_ab, + pctB: brut.pct_b, + pctTB: brut.pct_tb, + pctTBF: brut.pct_tbf, - pctSansMention: raw.pct_sansmention, - pctAB: raw.pct_ab, - pctB: raw.pct_b, - pctTB: raw.pct_tb, - pctTBF: raw.pct_tbf, + pctDebutPhase: brut.pct_acc_debutpp, + pctDateBac: brut.pct_acc_datebac, + pctFinPhase: brut.pct_acc_finpp, - pctDebutPhase: raw.pct_acc_debutpp, - pctDateBac: raw.pct_acc_datebac, - pctFinPhase: raw.pct_acc_finpp, + admisDebutPhase: brut.acc_debutpp, + admisDateBac: brut.acc_datebac, + admisFinPhase: brut.acc_finpp, - admisDebutPhase: raw.acc_debutpp, - admisDateBac: raw.acc_datebac, - admisFinPhase: raw.acc_finpp, + // Phase principale + voePPGeneral: brut.nb_voe_pp_bg, + voePPTechno: brut.nb_voe_pp_bt, + voePPPro: brut.nb_voe_pp_bp, + voePPAutres: brut.nb_voe_pp_at, + voePPTotal: brut.nb_voe_pp, - // phase principale - voePPGeneral: raw.nb_voe_pp_bg, - voePPTechno: raw.nb_voe_pp_bt, - voePPPro: raw.nb_voe_pp_bp, - voePPAutres: raw.nb_voe_pp_at, - voePPTotal: raw.nb_voe_pp, + classesPPGeneral: brut.nb_cla_pp_bg, + classesPPTechno: brut.nb_cla_pp_bt, + classesPPPro: brut.nb_cla_pp_bp, + classesPPAutres: brut.nb_cla_pp_at, + classesPPTotal: brut.nb_cla_pp, - classesPPGeneral: raw.nb_cla_pp_bg, - classesPPTechno: raw.nb_cla_pp_bt, - classesPPPro: raw.nb_cla_pp_bp, - classesPPAutres: raw.nb_cla_pp_at, - classesPPTotal: raw.nb_cla_pp, + propositionsPPGeneral: brut.prop_tot_bg, + propositionsPPTechno: brut.prop_tot_bt, + propositionsPPPro: brut.prop_tot_bp, + propositionsPPAutres: brut.prop_tot_at, + propositionsPPTotal: brut.prop_tot, - propositionsPPGeneral: raw.prop_tot_bg, - propositionsPPTechno: raw.prop_tot_bt, - propositionsPPPro: raw.prop_tot_bp, - propositionsPPAutres: raw.prop_tot_at, - propositionsPPTotal: raw.prop_tot, + acceptesPPGeneral: brut.acc_bg, + acceptesPPTechno: brut.acc_bt, + acceptesPPPro: brut.acc_bp, + acceptesPPAutres: brut.acc_at, + acceptesPPTotal: brut.acc_pp, - acceptesPPGeneral: raw.acc_bg, - acceptesPPTechno: raw.acc_bt, - acceptesPPPro: raw.acc_bp, - acceptesPPAutres: raw.acc_at, - acceptesPPTotal: raw.acc_pp, + // Phase complémentaire + voePCGeneral: brut.nb_voe_pc_bg, + voePCTechno: brut.nb_voe_pc_bt, + voePCPro: brut.nb_voe_pc_bp, + voePCAutres: brut.nb_voe_pc_at, + voePCTotal: brut.nb_voe_pc, - // phase complémentaire - voePCGeneral: raw.nb_voe_pc_bg, - voePCTechno: raw.nb_voe_pc_bt, - voePCPro: raw.nb_voe_pc_bp, - voePCAutres: raw.nb_voe_pc_at, - voePCTotal: raw.nb_voe_pc, - - classesPCTotal: raw.nb_cla_pc, - acceptesPCTotal: raw.acc_pc + classesPCTotal: brut.nb_cla_pc, + acceptesPCTotal: brut.acc_pc } } \ No newline at end of file diff --git a/parcoursup/formation.js~ b/parcoursup/formation.js~ deleted file mode 100644 index a7931d1..0000000 --- a/parcoursup/formation.js~ +++ /dev/null @@ -1,23 +0,0 @@ -export function createFormation(raw) { - let taux = 0 - - if (raw.voe_tot && raw.voe_tot > 0) { - taux = Math.round((raw.acc_tot / raw.voe_tot) * 100) - } - - return { - id: raw.cod_uai + "-" + raw.lib_for_voe_ins, - nom: raw.lib_for_voe_ins, - etablissement: raw.g_ea_lib_vx, - ville: raw.ville_etab, - departement: raw.dep, - filiere: raw.fili, - selectivite: raw.select_form, - capacite: raw.capa_fin, - candidats: raw.voe_tot, - admis: raw.acc_tot, - tauxAcces: taux, - latitude: raw.g_olocalisation_des_formations ? raw.g_olocalisation_des_formations.lat : null, - longitude: raw.g_olocalisation_des_formations ? raw.g_olocalisation_des_formations.lon : null - } - } \ No newline at end of file diff --git a/parcoursup/index.html b/parcoursup/index.html index a614ea9..da008b8 100644 --- a/parcoursup/index.html +++ b/parcoursup/index.html @@ -12,27 +12,47 @@ - - + + - - - - - + + + + + + - + window.chargerFormations = chargerFormations + window.creerFormation = creerFormation + window.chargerHistoriqueFormation = chargerHistoriqueFormation - - + + \ No newline at end of file diff --git a/parcoursup/index.html~ b/parcoursup/index.html~ deleted file mode 100644 index 321d43e..0000000 --- a/parcoursup/index.html~ +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - Parcoursup - test API - - -

Mini projet Parcoursup

-

Recherche de formations Parcoursup

- - - - -
En attente...
- - - - - \ No newline at end of file diff --git a/parcoursup/main.js~ b/parcoursup/main.js~ deleted file mode 100644 index a8b42ab..0000000 --- a/parcoursup/main.js~ +++ /dev/null @@ -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 = ` -
-

${f.nom}

-

Établissement : ${f.etablissement}

-

Ville : ${f.ville}

-

Département : ${f.departement}

-

Filière : ${f.filiere}

-

Sélectivité : ${f.selectivite}

-

Capacité : ${f.capacite}

-

Candidats : ${f.candidats}

-

Admis : ${f.admis}

-

Taux d'accès : ${f.tauxAcces}%

- -
- ` - - 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 += ` -
-

${f.nom}

-

Établissement : ${f.etablissement}

-

Ville : ${f.ville} (${f.departement})

-

Filière : ${f.filiere}

-

Taux d'accès : ${f.tauxAcces}%

- -
- ` - } - - 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) \ No newline at end of file diff --git a/parcoursup/package-lock.json b/parcoursup/package-lock.json new file mode 100644 index 0000000..50faf54 --- /dev/null +++ b/parcoursup/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "parcoursup", + "lockfileVersion": 3, + "requires": true, + "packages": {} +}