maj
This commit is contained in:
+20
-11
@@ -1,3 +1,8 @@
|
|||||||
|
// Échapper les apostrophes dans les valeurs injectées dans la clause where
|
||||||
|
function echapperValeur(valeur) {
|
||||||
|
return String(valeur).replace(/'/g, "\\'")
|
||||||
|
}
|
||||||
|
|
||||||
// Construire l'URL de requête vers l'API Parcoursup
|
// Construire l'URL de requête vers l'API Parcoursup
|
||||||
export function construireURL(requete, limite = 20, decalage = 0, filtres = {}) {
|
export function construireURL(requete, limite = 20, decalage = 0, filtres = {}) {
|
||||||
|
|
||||||
@@ -9,19 +14,19 @@ export function construireURL(requete, limite = 20, decalage = 0, filtres = {})
|
|||||||
var conditions = []
|
var conditions = []
|
||||||
|
|
||||||
if (requete && requete.trim() !== "") {
|
if (requete && requete.trim() !== "") {
|
||||||
conditions.push("search(lib_for_voe_ins, '" + requete + "')")
|
conditions.push("search(lib_for_voe_ins, '" + echapperValeur(requete.trim()) + "')")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filtres.filiere && filtres.filiere !== "") {
|
if (filtres.filiere && filtres.filiere !== "") {
|
||||||
conditions.push("fili='" + filtres.filiere + "'")
|
conditions.push("fili='" + echapperValeur(filtres.filiere) + "'")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filtres.selectivite && filtres.selectivite !== "") {
|
if (filtres.selectivite && filtres.selectivite !== "") {
|
||||||
conditions.push("select_form='" + filtres.selectivite + "'")
|
conditions.push("select_form='" + echapperValeur(filtres.selectivite) + "'")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filtres.region && filtres.region !== "") {
|
if (filtres.region && filtres.region !== "") {
|
||||||
conditions.push("region_etab_aff='" + filtres.region + "'")
|
conditions.push("region_etab_aff='" + echapperValeur(filtres.region) + "'")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filtres.tauxMin && filtres.tauxMin > 0) {
|
if (filtres.tauxMin && filtres.tauxMin > 0) {
|
||||||
@@ -33,7 +38,7 @@ export function construireURL(requete, limite = 20, decalage = 0, filtres = {})
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (conditions.length > 0) {
|
if (conditions.length > 0) {
|
||||||
url += "&where=" + conditions.join(" AND ")
|
url += "&where=" + encodeURIComponent(conditions.join(" AND "))
|
||||||
}
|
}
|
||||||
|
|
||||||
return url
|
return url
|
||||||
@@ -46,7 +51,7 @@ export async function chargerFormations(requete, limite = 20, decalage = 0, filt
|
|||||||
var reponse = await fetch(url)
|
var reponse = await fetch(url)
|
||||||
|
|
||||||
if (!reponse.ok) {
|
if (!reponse.ok) {
|
||||||
throw new Error("Erreur HTTP")
|
throw new Error("Erreur HTTP " + reponse.status)
|
||||||
}
|
}
|
||||||
|
|
||||||
return await reponse.json()
|
return await reponse.json()
|
||||||
@@ -64,9 +69,10 @@ export async function chargerHistoriqueFormation(codUai, nomFormation) {
|
|||||||
2025: "fr-esr-parcoursup"
|
2025: "fr-esr-parcoursup"
|
||||||
}
|
}
|
||||||
|
|
||||||
var historique = []
|
var historique = []
|
||||||
var nomCourt = nomFormation.substring(0, 40).replace(/'/g, "\\'")
|
var nomCourt = echapperValeur((nomFormation || "").substring(0, 40))
|
||||||
var annees = [2020, 2021, 2022, 2023, 2024, 2025]
|
var codeUai = echapperValeur(codUai)
|
||||||
|
var annees = [2020, 2021, 2022, 2023, 2024, 2025]
|
||||||
|
|
||||||
for (var i = 0; i < annees.length; i++) {
|
for (var i = 0; i < annees.length; i++) {
|
||||||
|
|
||||||
@@ -75,11 +81,14 @@ export async function chargerHistoriqueFormation(codUai, nomFormation) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
var where =
|
||||||
|
"cod_uai='" + codeUai + "' AND search(lib_for_voe_ins, '" + nomCourt + "')"
|
||||||
|
|
||||||
var url = "https://data.enseignementsup-recherche.gouv.fr/api/explore/v2.1/catalog/datasets/"
|
var url = "https://data.enseignementsup-recherche.gouv.fr/api/explore/v2.1/catalog/datasets/"
|
||||||
+ dataset + "/records?"
|
+ dataset + "/records?"
|
||||||
+ "limit=5"
|
+ "limit=5"
|
||||||
+ "&where=cod_uai%3D'" + codUai + "' AND search(lib_for_voe_ins, '" + nomCourt + "')"
|
+ "&where=" + encodeURIComponent(where)
|
||||||
+ "&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"
|
+ "&select=" + encodeURIComponent("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 reponse = await fetch(url)
|
var reponse = await fetch(url)
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>Parcoursup - test API</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Mini projet Parcoursup</h1>
|
|
||||||
<p>Recherche de formations Parcoursup</p>
|
|
||||||
|
|
||||||
<input id="search" type="text" placeholder="Ex : BUT informatique" />
|
|
||||||
<button id="btn-test">Rechercher</button>
|
|
||||||
|
|
||||||
<div id="output">En attente...</div>
|
|
||||||
|
|
||||||
|
|
||||||
<script type="module" src="./main.js"></script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -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