This commit is contained in:
pro.boooooo 2023-03-12 18:58:41 +01:00
parent 5f18a9fcbd
commit da5ea3a932
7 changed files with 318 additions and 50 deletions

View File

@ -3,8 +3,6 @@
### A faire
```text
1. Ajouter "Moyenne des admis" dans la section centrale de gauche
2. Affiner les calculs pour "Selectivite" section centrale de gauche
3. Ajouter "Moyenne" et "Selectivite" dans la liste des etablissements
4. Faire la modal avec + d'info
5. Map en haut de la liste d'etablissement
```
@ -15,12 +13,8 @@ Probleme 1 : Ingenieur, Ecole de commerce, Tout ce qui commence par "Formation"
Raison : Le model d'envoie de donnees ne prends pas en charge le cas ou une formation = 2 sous sections
(Faire des tests: donneesProchaineSection == null)
Probleme 2 : Spammer peut faire bugger l'affichage du chemin
Probleme 2 : Spammer peut faire bugger l'affichage du chemin (et aussi les autres spe)
Raison : Pas de timer ni de bloqueur (En rajouter ducoup lol)
Probleme 3 : Si il y a eu un bug (cote utilisateur) et que le localstorage enregistre [], a moins de supprimer le localstorage
depuis l'inspecteur, ca ne chargera plus jamais les categories
Raison : Ajouter une condition dans les getModelDataN() pour refaire des calls api si le localstoage = []
```
### IMPORTANT
@ -28,6 +22,8 @@ depuis l'inspecteur, ca ne chargera plus jamais les categories
Si ca ne s'affiche pas dans la milli seconde, pas besoin de forcer le boutton,
faut juste attendre que le MVC receptionne les donnees. Si ca persiste, supprimer le local storage
inspecter l'element -> Application (ou stockage) -> Local Storage
SPAMMER PAS LES CAT TANT QUE #Probleme 2 N'EST PAS REGLE !
```
### Documentation de riot :

View File

@ -8,6 +8,12 @@ export default class Controller {
constructor(model, view) {
this.model = model
this.view = view
/**
* TODO: Tej ca avant de rendre le projet
* */
localStorage.clear()
this.getData(0).then()
/**
@ -45,7 +51,7 @@ export default class Controller {
}
}
this.model.setSCat(null)
this.model.setTCat(null)
log("Selector", "Controller 3/3")
}
@ -73,11 +79,15 @@ export default class Controller {
})
} else if(n === 3) {
log("Selector->Controller", "Requete de la liste des etablissements")
this.model.getModelData3().then((res) => {
this.view.renderStat(res)
this.view.renderEtab(res)
this.view.renderPath(this.model.getPath())
})
let data = null
while(!data) {
data = await this.model.getModelData3()
}
this.view.renderStat(await data)
this.view.renderEtab(await data, `${ this.model.getPath()[1] } - ${ this.model.getPath()[2] }`)
this.view.renderPath(this.model.getPath())
} else {
log("Selector->Controller", "Numero de page inconnue")
}

View File

@ -178,8 +178,6 @@ export default class Model {
`&refine.${encodeURIComponent(this.state.api.facet.filiaire)}=${encodeURIComponent(this.state.page.cat)}` +
`&refine.${encodeURIComponent(this.state.api.facet.formation)}=${encodeURIComponent(this.state.page.scat)}`
console.log(link)
return fetch(link)
.then((res) => res.json())
.then((data) => {
@ -202,36 +200,41 @@ export default class Model {
* @return { array[json] | Promise } les donnees demandees en JSON
* */
getModelData3() {
if(!localStorage.getItem(`sec-etab-${this.state.page.cat}-${this.state.page.scat}-${this.state.page.tcat}`)) {
const link = `${this.state.api.link}&rows=10000` +
`&facet=${encodeURIComponent(this.state.api.facet.filiaire)}` +
`&facet=${encodeURIComponent(this.state.api.facet.formation)}` +
`&facet=${encodeURIComponent(this.state.api.facet.spec)}` +
`&refine.${encodeURIComponent(this.state.api.facet.filiaire)}=${encodeURIComponent(this.state.page.cat)}` +
`&refine.${encodeURIComponent(this.state.api.facet.formation)}=${encodeURIComponent(this.state.page.scat)}` +
`&refine.${encodeURIComponent(this.state.api.facet.spec)}=${encodeURIComponent(this.state.page.tcat)}`
try {
if(!localStorage.getItem(`sec-etab-${this.state.page.cat}-${this.state.page.scat}-${this.state.page.tcat}`) ||
localStorage.getItem(`sec-etab-${this.state.page.cat}-${this.state.page.scat}-${this.state.page.tcat}`) === "[]"
) {
const link = `${this.state.api.link}&rows=10000` +
`&facet=${encodeURIComponent(this.state.api.facet.filiaire)}` +
`&facet=${encodeURIComponent(this.state.api.facet.formation)}` +
`&facet=${encodeURIComponent(this.state.api.facet.spec)}` +
`&refine.${encodeURIComponent(this.state.api.facet.filiaire)}=${encodeURIComponent(this.state.page.cat)}` +
`&refine.${encodeURIComponent(this.state.api.facet.formation)}=${encodeURIComponent(this.state.page.scat)}` +
`&refine.${encodeURIComponent(this.state.api.facet.spec)}=${encodeURIComponent(this.state.page.tcat)}`
return fetch(link)
.then((res) => {
return res.json()
})
.then((data) => {
try {
if(data) {
if(this.state.page.tcat) {
localStorage.setItem(`sec-etab-${this.state.page.cat}-${this.state.page.scat}-${this.state.page.tcat}`, JSON.stringify(data.records))
return fetch(link)
.then((res) => {
return res.json()
})
.then((data) => {
try {
if(data) {
if(this.state.page.tcat) {
localStorage.setItem(`sec-etab-${this.state.page.cat}-${this.state.page.scat}-${this.state.page.tcat}`, JSON.stringify(data.records))
}
this.state.page.tcat = null
return data.records
}
this.state.page.tcat = null
return data.records
}
} catch(donothing) {}
} catch(donothing) {}
})
} else {
return new Promise((resolve, reject) => {
resolve(JSON.parse(localStorage.getItem(`sec-etab-${this.state.page.cat}-${this.state.page.scat}-${this.state.page.tcat}`)))
})
} else {
return new Promise((resolve, reject) => {
resolve(JSON.parse(localStorage.getItem(`sec-etab-${this.state.page.cat}-${this.state.page.scat}-${this.state.page.tcat}`)))
this.state.page.tcat = null
})
}
} catch(e) {
console.error(e)
}
}
}

View File

@ -9,6 +9,12 @@ export default class View {
this.stat = document.getElementById("generalytics")
this.etab = document.getElementById("etablanalytics-list")
this.btn = document.getElementById("selector-top-btn")
this.home = document.getElementById("home")
this.left = document.getElementById("left")
this.right = document.getElementById("right")
this.antispam = null
this.inAction = false
this.btn.onclick = () => {
this.updateMenu(" ", "previous")
@ -19,18 +25,28 @@ export default class View {
/**
* Contruction de la balise <li> qui vas se loger dans le menu.
* Si l'utilisateur spam clique, ca annule l'action (ce qui peut empecher les crashs)
* @param { array[json] } data Donnees a afficher.
* @param { string } title Titre de la section d'un menu.
* */
renderMenu(title, data) {
renderMenu(title, data) {
this.title.innerText = title
this.zone.innerHTML = ""
if(title || data) {
data.forEach((e) => {
let elem = document.createElement("selectorfragment")
elem.onclick = async () => {
await this.updateMenu(document.getElementById(`menu0-${e.name}`).innerText, "next")
elem.onclick = () => {
if(this.antispam === null) {
this.antispam = setTimeout(() => {
this.updateMenu(document.getElementById(`menu0-${e.name}`).innerText, "next")
this.antispam = null
}, 400)
} else {
clearTimeout(this.antispam)
this.antispam = null
log("View->Anti-spam", "Spam detecte")
}
}
riot.mount(elem, {
@ -68,8 +84,9 @@ export default class View {
/**
* Pour afficher en bas a gauche la liste.
* @param { array[json] } data La liste des etablissements.
* @param { string } form
* */
renderEtab(data) {
renderEtab(data, form) {
this.etab.innerHTML =
"<tbody>" +
" <th>Nom</th>" +
@ -85,9 +102,30 @@ export default class View {
let city = e.fields.ville_etab
let moy = "?"
let selection = e.fields.taux_acces_ens
let acad = e.fields.acad_mies
let type = e.fields.contrat_etab
let capacity = e.fields.capa_fin
let admishorsacad = e.fields.pct_aca_orig
let voeuxtotal = e.fields.voe_tot
let woman = `${ Math.round(100 * e.fields.acc_tot_f / e.fields.acc_tot) }%`
let man = `${ Math.round(100 * (e.fields.acc_tot - e.fields.acc_tot_f) / e.fields.acc_tot) }%`
let totbac = Math.round(e.fields.acc_bg + e.fields.acc_bp + e.fields.acc_bt + e.fields.acc_at)
let gen = `${ Math.round(100 * e.fields.acc_bg / totbac) }%`
let pro = `${ Math.round(100 * e.fields.acc_bp / totbac) }%`
let tech = `${ Math.round(100 * e.fields.acc_bt / totbac) }%`
let autre = `${ Math.round(100 * e.fields.acc_at / totbac) }%`
let tot = e.fields.acc_sansmention + e.fields.acc_ab + e.fields.acc_b + e.fields.acc_tb + e.fields.acc_tbf
let p = `${ Math.round(100 * e.fields.acc_sansmention / tot) }%`
let ab = `${ Math.round(100 * e.fields.acc_ab / tot) }%`
let b = `${ Math.round(100 * e.fields.acc_b / tot) }%`
let tb = `${ Math.round(100 * e.fields.acc_tb / tot) }%`
let tbf = `${ Math.round(100 * e.fields.acc_tbf / tot) }%`
/**
* TODO: Transformer ca en composant riot (GALERE MAX)
* TODO: Transformer ca en composant riot (GALERE MAX pour faire des <tr><etablanalyticsfragment/></tr>)
* */
let tr = document.createElement("tr")
@ -119,6 +157,59 @@ export default class View {
tr.appendChild(td4)
tr.appendChild(td5)
tr.onclick = () => {
this.left.style.filter = "blur(15px)"
this.right.style.filter = "blur(15px)"
let modal = document.createElement("modal")
const close = () => {
riot.unmount(modal, false)
this.left.style.filter = "none"
this.right.style.filter = "none"
}
riot.mount(modal, {
close : close,
etabname: etab,
formation: form,
city: city,
acad: acad,
type: type,
capacity: capacity,
wish: voeuxtotal,
nhacad: Math.round(100 - admishorsacad),
manPercent: man,
womanPercent: woman,
hstyle: `width: ${parseInt(man.split("%")[0]) > 10 ? man : `23%`};`,
fstyle: `width: ${parseInt(woman.split("%")[0]) > 10 ? woman : `23%`};`,
nbacgen: gen,
genstyle: `width: ${parseInt(gen.split("%")[0]) > 10 ? gen : `23%`};`,
nbacpro: pro,
prostyle: `width: ${parseInt(pro.split("%")[0]) > 10 ? pro : `23%`};`,
nbactech: tech,
techstyle: `width: ${parseInt(tech.split("%")[0]) > 10 ? tech : `23%`};`,
nbacautre: autre,
autrestyle: `width: ${parseInt(autre.split("%")[0]) > 10 ? autre : `23%`};`,
nmentionp: p,
pstyle: `width: ${parseInt(p.split("%")[0]) > 10 ? autre : `23%`};`,
nmentionab: ab,
abstyle: `width: ${parseInt(ab.split("%")[0]) > 10 ? autre : `23%`};`,
nmentionb: b,
bstyle: `width: ${parseInt(b.split("%")[0]) > 10 ? autre : `23%`};`,
nmentiontb: tb,
tbstyle: `width: ${parseInt(tb.split("%")[0]) > 10 ? autre : `23%`};`,
nmentiontbf: tbf,
tbfstyle: `width: ${parseInt(tbf.split("%")[0]) > 10 ? autre : `23%`};`
}, "modal")
this.home.appendChild(modal)
}
this.etab.appendChild(tr)
})
}
@ -273,7 +364,7 @@ export default class View {
selectivitycount: gen.selectivitycount,
manPercent: gender.man,
hstyle: `width: ${parseInt(gender.man.split("%")[0]) > 10 ? gender.man : `23%`};`,
womenPercent: gender.woman,
womanPercent: gender.woman,
fstyle: `width: ${parseInt(gender.woman.split("%")[0]) > 10 ? gender.woman : `23%`};`,
nbacgen: bac.gen,
genstyle: `width: ${parseInt(bac.gen.split("%")[0]) > 10 ? bac.gen : `23%` };`,
@ -301,6 +392,7 @@ export default class View {
}
/**
* Envoyer dans le controlleur tous les events fait.
* @param { string } selection Ce qu'on va utiliser pour le &refine.

View File

@ -304,7 +304,7 @@
</span>
<span class="generalysticsfragment-percent" style={ this.props.fstyle } id="woman">
{ this.props.womenPercent } (F)
{ this.props.womanPercent } (F)
</span>
</div>

View File

@ -0,0 +1,168 @@
<modal>
<style>
#modal {
position: absolute;
margin: auto;
top: 0;
bottom: 0;
right: 0;
left: 0;
background: #7A90A4;
box-shadow: 0px 0px 9px 1px black;
width: 85%;
height: 85%;
border-radius: 14px;
display: flex;
flex-direction: column;
color: white;
font-weight: bold;
overflow: auto;
}
#modal
#modal-title {
width: auto;
height: auto;
padding: 1.5vw;
background: #344D59;
overflow-wrap: break-word;
text-align: center;
color: white;
font-weight: bold;
position: relative;
border-top-right-radius: 14px;
}
#modal
#modal-title
#modal-close-menu {
border-top-right-radius: 14px;
position: absolute;
top: 0;
right: 0;
font-weight: bold;
color: white;
background: red;
width: 50px;
height: 50px;
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 1.5vw;
cursor: pointer;
}
#modal
#modal-info {
display: flex;
flex-direction: column;
padding: 1vw;
width: 100%;
}
#modal
#modal-info
.modal-info-text {
color: white;
font-weight: bold;
}
#modal
#modal-info
generalysticsfragment
#generalysticsfragment-gen {
display: none;
}
#modal
#modal-info
generalysticsfragment {
width: 100%;
}
</style>
<div id="modal">
<div id="modal-title">
<span id="modal-close-menu" onclick={ this.props.close }>X</span>
<span class="modal-info-text">{ this.props.etabname }</span> <br/>
<span class="modal-info-text">{ this.props.formation}</span>
</div>
<div id="modal-info">
<span class="modal-info-text">Ville : { this.props.city }</span>
<span class="modal-info-text">Academie : { this.props.acad }</span>
<span class="modal-info-text">{ this.props.type }</span>
<span class="modal-info-text">Capacite : { this.props.capacity }</span>
<span class="modal-info-text">Nombre de voeux : { this.props.wish }</span>
<span class="modal-info-text">Admis hors academie : { this.props.nhacad }%</span>
<generalysticsfragment
manPercent = { this.props.manPercent }
womanPercent = { this.props.womanPercent }
hstyle = { this.props.hstyle }
fstyle = { this.props.fstyle }
nbacgen = { this.props.nbacgen }
genstyle = { this.props.genstyle }
nbacpro = { this.props.nbacpro }
prostyle = { this.props.prostyle }
nbactech = { this.props.nbactech }
techstyle = { this.props.techstyle }
nbacautre = { this.props.nbacautre }
autrestyle = { this.props.autrestyle }
nmentionp = { this.props.nmentionp }
pstyle = { this.props.pstyle }
nmentionab = { this.props.nmentionab }
abstyle = { this.props.abstyle }
nmentionb = { this.props.nmentionb }
bstyle = { this.props.bstyle }
nmentiontb = { this.props.nmentiontb }
tbstyle = { this.props.tbstyle }
nmentiontbf = { this.props.nmentiontbf }
tbfstyle = { this.props.tbfstyle }
/>
</div>
</div>
<script>
export default {
props: [
"close",
"etabname",
"formation",
"city",
"acad",
"type",
"capacity",
"wish",
"nhacad",
"manPercent",
"womanPercent",
"hstyle",
"fstyle",
"nbacgen",
"genstyle",
"nbacpro",
"prostyle",
"nbactech",
"techstyle",
"nbacautre",
"autrestyle",
"nmentionp",
"pstyle",
"nmentionab",
"abstyle",
"nmentionb",
"bstyle",
"nmentiontb",
"tbstyle",
"nmentiontbf",
"tbfstyle"
]
}
</script>
</modal>

View File

@ -17,7 +17,6 @@
align-items: center;
}
</style>
<div id="root"></div>
</body>
</html>