ajout du comparateur avec tri retrait et persistance locale

This commit is contained in:
2026-03-18 14:17:03 +01:00
parent 77b9435613
commit 666048cc0e
2 changed files with 122 additions and 50 deletions
+93 -49
View File
@@ -27,9 +27,8 @@
<div class="compare-controls"> <div class="compare-controls">
<div> <div>
<label for="note"><b>Note moyenne :</b></label><br /> <label><b>Note moyenne :</b></label><br />
<input <input
id="note"
type="number" type="number"
min="0" min="0"
max="20" max="20"
@@ -40,29 +39,47 @@
</div> </div>
<div> <div>
<label for="serie"><b>Série :</b></label><br /> <label><b>Série :</b></label><br />
<select id="serie" onchange={ updateSerie }> <select onchange={ updateSerie }>
<option value="general" selected={ state.serie === 'general' }>Général</option> <option value="general" selected={ state.serie === 'general' }>Général</option>
<option value="techno" selected={ state.serie === 'techno' }>Technologique</option> <option value="techno" selected={ state.serie === 'techno' }>Technologique</option>
<option value="pro" selected={ state.serie === 'pro' }>Professionnel</option> <option value="pro" selected={ state.serie === 'pro' }>Professionnel</option>
</select> </select>
</div> </div>
<div>
<label><b>Trier par :</b></label><br />
<select onchange={ updateSort }>
<option value="nom" selected={ state.sortBy === 'nom' }>Nom</option>
<option value="ville" selected={ state.sortBy === 'ville' }>Ville</option>
<option value="taux" selected={ state.sortBy === 'taux' }>Taux d'accès</option>
</select>
</div>
</div> </div>
<hr /> <hr />
<h3>Formations sélectionnées</h3> <h3>Formations sélectionnées</h3>
<div each={ f in state.selectedFormations } key={ f.id } class="card"> <div each={ f in getSortedSelection() } key={ f.id } class="card">
<h4>{ f.nom }</h4> <h4>{ f.nom }</h4>
<p><b>Ville :</b> { f.ville }</p> <p><b>Ville :</b> { f.ville }</p>
<p><b>Filière :</b> { f.filiere }</p> <p><b>Filière :</b> { f.filiere }</p>
<p><b>Taux d'accès :</b> { f.tauxAcces }%</p> <p><b>Taux d'accès :</b> { f.tauxAcces }%</p>
<p> <p>
<b>Profil admis :</b> <b>Profil admis :</b>
Général { f.pctGeneral }% / Techno { f.pctTechno }% / Pro { f.pctPro }% Général { f.pctGeneral }% /
Techno { f.pctTechno }% /
Pro { f.pctPro }%
</p> </p>
<p><b>Estimation :</b> { estimateFormation(f) }</p> <p><b>Estimation :</b> { estimateFormation(f) }</p>
<button onclick={ () => removeFromSelection(f.id) }>
Retirer
</button>
</div> </div>
</div> </div>
</div> </div>
@@ -84,7 +101,22 @@
selected: null, selected: null,
selectedFormations: [], selectedFormations: [],
note: 12, note: 12,
serie: 'general' serie: 'general',
sortBy: 'nom'
},
onMounted() {
const saved = localStorage.getItem('selectionFormations')
if (saved) {
try {
this.update({
selectedFormations: JSON.parse(saved)
})
} catch (e) {
console.error(e)
}
}
}, },
async launchSearch(query) { async launchSearch(query) {
@@ -101,8 +133,7 @@
if (data.results) { if (data.results) {
for (let i = 0; i < data.results.length; i++) { for (let i = 0; i < data.results.length; i++) {
const raw = data.results[i] const raw = data.results[i]
const formation = window.createFormation(raw) formations.push(window.createFormation(raw))
formations.push(formation)
} }
} }
@@ -125,6 +156,12 @@
}) })
}, },
backToList() {
this.update({
selected: null
})
},
addToSelection(index) { addToSelection(index) {
const formation = this.state.results[index] const formation = this.state.results[index]
const selection = [...this.state.selectedFormations] const selection = [...this.state.selectedFormations]
@@ -140,62 +177,69 @@
if (!exists) { if (!exists) {
selection.push(formation) selection.push(formation)
this.update({ selectedFormations: selection }) this.update({ selectedFormations: selection })
localStorage.setItem('selectionFormations', JSON.stringify(selection))
} }
}, },
backToList() { removeFromSelection(id) {
const newSelection = []
for (let i = 0; i < this.state.selectedFormations.length; i++) {
const f = this.state.selectedFormations[i]
if (f.id !== id) {
newSelection.push(f)
}
}
this.update({ this.update({
selected: null selectedFormations: newSelection
}) })
localStorage.setItem('selectionFormations', JSON.stringify(newSelection))
}, },
updateNote(event) { updateNote(e) {
this.update({ this.update({ note: Number(e.target.value) })
note: Number(event.target.value)
})
}, },
updateSerie(event) { updateSerie(e) {
this.update({ this.update({ serie: e.target.value })
serie: event.target.value
})
}, },
estimateFormation(formation) { updateSort(e) {
this.update({ sortBy: e.target.value })
},
getSortedSelection() {
const selection = [...this.state.selectedFormations]
if (this.state.sortBy === 'taux') {
selection.sort((a, b) => b.tauxAcces - a.tauxAcces)
} else if (this.state.sortBy === 'ville') {
selection.sort((a, b) => a.ville.localeCompare(b.ville))
} else {
selection.sort((a, b) => a.nom.localeCompare(b.nom))
}
return selection
},
estimateFormation(f) {
let score = 0 let score = 0
if (formation.tauxAcces >= 50) { if (f.tauxAcces >= 50) score += 2
score += 2 else if (f.tauxAcces >= 20) score += 1
} else if (formation.tauxAcces >= 20) {
score += 1
}
if (this.state.note >= 15) { if (this.state.note >= 15) score += 2
score += 2 else if (this.state.note >= 12) score += 1
} else if (this.state.note >= 12) {
score += 1
}
if (this.state.serie === 'general' && formation.pctGeneral >= 50) { if (this.state.serie === 'general' && f.pctGeneral >= 50) score += 2
score += 2 if (this.state.serie === 'techno' && f.pctTechno >= 20) score += 2
} if (this.state.serie === 'pro' && f.pctPro >= 15) score += 2
if (this.state.serie === 'techno' && formation.pctTechno >= 20) {
score += 2
}
if (this.state.serie === 'pro' && formation.pctPro >= 15) {
score += 2
}
if (score >= 5) {
return 'Favorable'
}
if (score >= 3) {
return 'Possible'
}
if (score >= 5) return 'Favorable'
if (score >= 3) return 'Possible'
return 'Difficile' return 'Difficile'
} }
} }
+29 -1
View File
@@ -74,6 +74,20 @@ body {
border: none; border: none;
border-top: 1px solid #ddd; border-top: 1px solid #ddd;
} }
.compare-controls {
display: flex;
gap: 20px;
flex-wrap: wrap;
margin-bottom: 15px;
}
.compare-controls input,
.compare-controls select {
padding: 8px;
font-size: 14px;
min-width: 140px;
}
.detail-card h2, .detail-card h2,
.detail-card h3 { .detail-card h3 {
@@ -83,7 +97,7 @@ body {
.detail-card p { .detail-card p {
margin: 8px 0; margin: 8px 0;
} }
.map-box { .map-box {
overflow: hidden; overflow: hidden;
} }
@@ -94,6 +108,20 @@ body {
border-radius: 6px; border-radius: 6px;
} }
.compare-controls {
display: flex;
gap: 20px;
flex-wrap: wrap;
margin-bottom: 15px;
}
.compare-controls input,
.compare-controls select {
padding: 8px;
font-size: 14px;
min-width: 140px;
}
.message { .message {
padding: 12px; padding: 12px;
background: white; background: white;