Claude m'a aidé tout au long du projet, mais la ca atteint des sommets. En meme temps, je suis en retard de fou !! Heuresuement quil explique mega bien sinon je ne comprendrais rien... et encore, je comprends deja assez peu les lignes que je rentre moi meme. trop de balises tuent les balises......

This commit is contained in:
camille
2026-03-29 12:54:47 +02:00
parent b26f3080f9
commit 7aa8912276
6 changed files with 516 additions and 13 deletions
@@ -0,0 +1,106 @@
<comparateur>
<h2>Comparateur de formations</h2>
<a href="#">← Retour à la recherche</a>
<a href="#/estimation">🎯 Estimer mes chances</a>
<div if={ state.formations.length === 0 }>
Aucune formation sélectionnée.
</div>
<div class="comparateur-grille">
<div each={ formation in state.formations } class="comparateur-colonne">
<h3>{ formation.fil_lib_voe_acc }</h3>
<h4>{ formation.g_ea_lib_vx }</h4>
<p>{ formation.ville_etab } ({ formation.dep_lib })</p>
<p>Taux d'accès : { formation.taux_acces_ens }%</p>
<p>Places : { formation.capa_fin }</p>
<p>Candidatures : { formation.voe_tot }</p>
<p>Admis : { formation.acc_tot }</p>
<p>Bac Général : { formation.pct_bg }%</p>
<p>Bac Techno : { formation.pct_bt }%</p>
<p>Bac Pro : { formation.pct_bp }%</p>
<p>Mention AB : { formation.pct_ab }%</p>
<p>Mention B : { formation.pct_b }%</p>
<p>Mention TB : { formation.pct_tb }%</p>
<button onclick={ () => retirerFormation(formation) }>
Retirer
</button>
</div>
</div>
<style>
.comparateur-grille
{
display: flex;
flex-direction: row;
gap: 20px;
}
.comparateur-colonne
{
border: 1px solid #ccc;
padding: 15px;
min-width: 200px;
}
</style>
<script>
export default
{
state:
{
formations: []
},
onMounted()
{
const saved = localStorage.getItem('comparateur')
if (saved)
{
this.update({ formations: JSON.parse(saved) })
}
},
retirerFormation(formation)
{
const formations = this.state.formations.filter(f => f.cod_aff_form !== formation.cod_aff_form)
localStorage.setItem('comparateur', JSON.stringify(formations))
this.update({ formations })
}
}
</script>
</comparateur>
File diff suppressed because one or more lines are too long
@@ -1,17 +1,13 @@
<ligne-resultat> <ligne-resultat>
<div class="ligne-resultat"> <div class="ligne-resultat">
<h3>{ props.formation.fil_lib_voe_acc } — { props.formation.g_ea_lib_vx }</h3> <h3>{ props.formation.fil_lib_voe_acc } — { props.formation.g_ea_lib_vx }</h3>
<p>{ props.formation.ville_etab } ({ props.formation.dep_lib })</p> <p>{ props.formation.ville_etab } ({ props.formation.dep_lib })</p>
<p>Taux d'accès : { props.formation.taux_acces_ens }%</p> <p>Taux d'accès : { props.formation.taux_acces_ens }%</p>
<a href={ '#/formation/' + props.formation.cod_aff_form }>Voir le détail</a> <a href={ '#/formation/' + props.formation.cod_aff_form }>Voir le détail</a>
<button onclick={ ajouterComparateur }>+ Comparer</button>
</div> </div>
<style> <style>
.ligne-resultat .ligne-resultat
@@ -23,4 +19,27 @@
</style> </style>
<script>
export default
{
ajouterComparateur()
{
const saved = localStorage.getItem('comparateur')
const formations = saved ? JSON.parse(saved) : []
const dejaDedans = formations.some(f => f.cod_aff_form === this.props.formation.cod_aff_form)
if (!dejaDedans)
{
formations.push(this.props.formation)
localStorage.setItem('comparateur', JSON.stringify(formations))
}
window.location.hash = '#/comparateur'
}
}
</script>
</ligne-resultat> </ligne-resultat>
@@ -4,12 +4,34 @@
Chargement... Chargement...
</div> </div>
<div if={ state.formation }> <div if={ state.formation }>
<h2>{ state.formation.fil_lib_voe_acc }</h2> <h2>{ state.formation.fil_lib_voe_acc }</h2>
<h3>{ state.formation.g_ea_lib_vx }</h3> <h3>{ state.formation.g_ea_lib_vx }</h3>
<p>{ state.formation.ville_etab } ({ state.formation.dep_lib })</p> <p>{ state.formation.ville_etab } ({ state.formation.dep_lib })</p>
<a href="#">← Retour à la recherche</a> <a href="#">← Retour à la recherche</a>
<button onclick={ ajouterComparateur }>+ Ajouter au comparateur</button>
<a href="#/comparateur">Voir le comparateur</a>
<h4>Phase d'admission</h4> <h4>Phase d'admission</h4>
@@ -42,6 +64,15 @@
</table> </table>
<h4>Profil des admis — Type de bac</h4> <h4>Profil des admis — Type de bac</h4>
<table class="charts-css bar show-labels" style="height: 150px; width: 600px;"> <table class="charts-css bar show-labels" style="height: 150px; width: 600px;">
@@ -72,8 +103,20 @@
</table> </table>
<h4>Profil des admis — Mentions</h4> <h4>Profil des admis — Mentions</h4>
<table class="charts-css bar show-labels" style="height: 200px; width: 600px;"> <table class="charts-css bar show-labels" style="height: 200px; width: 600px;">
<tbody> <tbody>
@@ -116,6 +159,12 @@
</table> </table>
<h4>Évolution du taux d'accès depuis 2020</h4> <h4>Évolution du taux d'accès depuis 2020</h4>
<div if={ !state.evolution }> <div if={ !state.evolution }>
@@ -135,12 +184,43 @@
</tbody> </tbody>
</table> </table>
<h4>Phase complémentaire</h4>
<div if={ state.formation.nb_voe_pc }>
<p>Candidatures en phase complémentaire : <b>{ state.formation.nb_voe_pc }</b></p>
<p>Admis en phase complémentaire : <b>{ state.formation.acc_pc }</b></p>
<p>Dont bac général : <b>{ state.formation.nb_voe_pc_bg }</b></p>
<p>Dont bac techno : <b>{ state.formation.nb_voe_pc_bt }</b></p>
<p>Dont bac pro : <b>{ state.formation.nb_voe_pc_bp }</b></p>
</div>
<div if={ !state.formation.nb_voe_pc }>
Pas de phase complémentaire pour cette formation.
</div>
</div> </div>
<style> <style>
th th
@@ -185,12 +265,14 @@
export default export default
{ {
state: state:
{ {
formation: null, formation: null,
evolution: null evolution: null
}, },
async onMounted() async onMounted()
{ {
const id = this.props.id const id = this.props.id
@@ -199,9 +281,30 @@
const evolution = await recupereEvolutionFormation(id) const evolution = await recupereEvolutionFormation(id)
this.update({ evolution }) this.update({ evolution })
},
ajouterComparateur()
{
const saved = localStorage.getItem('comparateur')
const formations = saved ? JSON.parse(saved) : []
const dejaDedans = formations.some(f => f.cod_aff_form === this.state.formation.cod_aff_form)
if (!dejaDedans)
{
formations.push(this.state.formation)
localStorage.setItem('comparateur', JSON.stringify(formations))
}
window.location.hash = '#/comparateur'
} }
} }
</script> </script>
</page-detail> </page-detail>
+15
View File
@@ -1,7 +1,10 @@
import { component, unmount } from 'riot' import { component, unmount } from 'riot'
import App from './components/app.riot' import App from './components/app.riot'
import PageDetail from './components/page-detail.riot' import PageDetail from './components/page-detail.riot'
import Comparateur from './components/comparateur.riot'
import 'chart.css' import 'chart.css'
import './style.css'
import EstimationChances from './components/estimation-chances.riot'
const app = document.getElementById('app') const app = document.getElementById('app')
let currentComponent = null let currentComponent = null
@@ -20,10 +23,22 @@ function navigate()
const id = hash.replace('#/formation/', '') const id = hash.replace('#/formation/', '')
currentComponent = component(PageDetail)(app, { id }) currentComponent = component(PageDetail)(app, { id })
} }
else if (hash === '#/comparateur')
{
currentComponent = component(Comparateur)(app)
}
else if (hash === '#/estimation')
{
currentComponent = component(EstimationChances)(app)
}
else else
{ {
currentComponent = component(App)(app) currentComponent = component(App)(app)
} }
} }
window.addEventListener('hashchange', navigate) window.addEventListener('hashchange', navigate)
+128
View File
@@ -0,0 +1,128 @@
*
{
box-sizing: border-box;
margin: 0;
padding: 0;
}
body
{
background-color: #1a1a2e;
color: #e0e0e0;
font-family: 'Segoe UI', sans-serif;
padding: 20px;
}
h1, h2, h3, h4
{
color: #e94560;
margin-bottom: 10px;
}
a
{
color: #0f3460;
background-color: #e94560;
padding: 5px 10px;
border-radius: 5px;
text-decoration: none;
display: inline-block;
margin: 5px 0;
}
a:hover
{
background-color: #c73652;
}
button
{
background-color: #0f3460;
color: #e0e0e0;
border: none;
padding: 8px 15px;
border-radius: 5px;
cursor: pointer;
margin: 5px 0;
}
button:hover
{
background-color: #16213e;
}
input, select
{
background-color: #16213e;
color: #e0e0e0;
border: 1px solid #e94560;
padding: 8px;
border-radius: 5px;
width: 100%;
}
.ligne-resultat
{
background-color: #16213e;
border: 1px solid #0f3460;
padding: 15px;
margin: 8px 0;
border-radius: 8px;
}
.ligne-resultat:hover
{
border-color: #e94560;
}
.comparateur-grille
{
display: flex;
flex-direction: row;
gap: 20px;
overflow-x: auto;
}
.comparateur-colonne
{
background-color: #16213e;
border: 1px solid #0f3460;
padding: 15px;
min-width: 250px;
border-radius: 8px;
}
.formulaire
{
background-color: #16213e;
padding: 20px;
border-radius: 8px;
max-width: 400px;
margin: 20px 0;
}
.estimation-ligne
{
background-color: #16213e;
border: 1px solid #0f3460;
padding: 15px;
margin: 10px 0;
border-radius: 8px;
}
table
{
margin: 15px 0;
}
#carte
{
border-radius: 8px;
border: 2px solid #e94560;
}
p
{
margin: 5px 0;
line-height: 1.5;
}