From f00e6ecf642fd9baa852e441374236093bc21917 Mon Sep 17 00:00:00 2001 From: Nicolas Brohee Date: Mon, 27 Feb 2017 16:50:58 +0100 Subject: [PATCH] Refactor PEPITE selection components to query API instead of static file --- client/src/actions/pepiteActions.js | 22 ++ client/src/api/pepiteApi.js | 33 +++ .../application/Pepite/EstablishmentSelect.js | 63 ++++++ .../application/Pepite/PepiteForm.js | 95 +++------ .../application/Pepite/PepitePage.js | 33 ++- .../application/Pepite/PepiteSelect.js | 65 ++++++ .../application/Pepite/RegionSelect.js | 40 ++++ .../Pepite/pepiteEstablishmentMap.js | 189 ------------------ 8 files changed, 277 insertions(+), 263 deletions(-) create mode 100644 client/src/api/pepiteApi.js create mode 100644 client/src/components/application/Pepite/EstablishmentSelect.js create mode 100644 client/src/components/application/Pepite/PepiteSelect.js create mode 100644 client/src/components/application/Pepite/RegionSelect.js delete mode 100644 client/src/components/application/Pepite/pepiteEstablishmentMap.js diff --git a/client/src/actions/pepiteActions.js b/client/src/actions/pepiteActions.js index bafc725..b46aefa 100644 --- a/client/src/actions/pepiteActions.js +++ b/client/src/actions/pepiteActions.js @@ -1,4 +1,5 @@ import * as types from './actionTypes' +import pepiteApi from '../api/pepiteApi' export function loadPepiteSuccess(pepite) { return { type: types.LOAD_PEPITE_SUCCESS, pepite } @@ -8,3 +9,24 @@ export function updatePepite(pepite) { return { type: types.UPDATE_PEPITE, pepite } } +export function getRegions() { + return (dispatch, getState) => { + return pepiteApi.getRegions() + } +} + +export function getEstablishments(regionId) { + return (dispatch, getState) => { + return pepiteApi.getEstablishments(regionId) + } +} + +export function getPepites(regionId, pepiteId) { + return (dispatch, getState) => { + if (pepiteId) { + return [pepiteApi.getPepite(pepiteId)] + } else { + return pepiteApi.getPepites(regionId) + } + } +} diff --git a/client/src/api/pepiteApi.js b/client/src/api/pepiteApi.js new file mode 100644 index 0000000..a082324 --- /dev/null +++ b/client/src/api/pepiteApi.js @@ -0,0 +1,33 @@ +import axios from 'axios' + +class pepiteApi { + static getRegions() { + return axios.get('/region/') + .then((res) => { + return res.data + }) + } + + static getEstablishments(regionId) { + return axios.get(`/region/${regionId}/establishment`) + .then((res) => { + return res.data + }) + } + + static getPepites(regionId) { + return axios.get(`/region/${regionId}/pepite`) + .then((res) => { + return res.data + }) + } + + static getPepite(pepiteId) { + return axios.get(`/pepite/${pepiteId}`) + .then((res) => { + return res.data + }) + } +} + +export default pepiteApi diff --git a/client/src/components/application/Pepite/EstablishmentSelect.js b/client/src/components/application/Pepite/EstablishmentSelect.js new file mode 100644 index 0000000..2f1ce4b --- /dev/null +++ b/client/src/components/application/Pepite/EstablishmentSelect.js @@ -0,0 +1,63 @@ +import React, { PropTypes } from 'react' +import { FormGroup, ControlLabel } from 'react-bootstrap' +import ValidatedFormControl from '../../common/ValidatedFormControl' +import { getCurrentYear } from '../../common/yearHelper' +import pepiteApi from '../../../api/pepiteApi' + +class EstablishmentSelect extends React.Component { + constructor(props, context) { + super(props, context) + this.state = { + establishments: [] + } + this.onEstablishementSelect = this.onEstablishementSelect.bind(this) + if (this.props.selectedRegion) { + this.loadEstablishements(this.props.selectedRegion) + } + } + + componentWillReceiveProps(nextProps) { + if (this.props.selectedRegion != nextProps.selectedRegion) { + this.loadEstablishements(nextProps.selectedRegion) + } + } + + loadEstablishements(regionId) { + pepiteApi.getEstablishments(regionId).then(establishments => { + this.setState({ establishments }) + }) + } + + onEstablishementSelect(event) { + const establishment = this.state.establishments.find((e) => (e._id == event.target.value)) + this.props.onEstablishementChange(establishment) + } + + render() { + if (this.props.isStudent && this.props.selectedRegion) { + return ( + + Mon établissement pour l'année {getCurrentYear()} + + + {this.state.establishments.map((establishment) => { + return () + })} + + + ) + } else { + return null + } + } +} + +EstablishmentSelect.propTypes = { + selectedRegion: PropTypes.string.isRequired, + selectedEstablishment: PropTypes.string.isRequired, + isStudent: PropTypes.bool.isRequired, + onEstablishementChange: PropTypes.func.isRequired, + errors: PropTypes.object, +} + +export default EstablishmentSelect diff --git a/client/src/components/application/Pepite/PepiteForm.js b/client/src/components/application/Pepite/PepiteForm.js index 7e7ef9a..7f13dae 100644 --- a/client/src/components/application/Pepite/PepiteForm.js +++ b/client/src/components/application/Pepite/PepiteForm.js @@ -1,77 +1,36 @@ -import React, {PropTypes} from 'react' +import React, { PropTypes } from 'react' import { FormGroup, ControlLabel, FormControl, Radio, HelpBlock, Panel } from 'react-bootstrap' import RadioGroup from '../../common/RadioGroup' import ValidatedFormControl from '../../common/ValidatedFormControl' -import {regions, pepites, establishments} from './pepiteEstablishmentMap' +import RegionSelect from './RegionSelect' +import EstablishmentSelect from './EstablishmentSelect' +import PepiteSelect from './PepiteSelect' -function getPepiteFromEstablishment(establishmentId) { - return ({ - 'id': establishments[establishmentId].pepite , - 'name': pepites[establishments[establishmentId].pepite] - }) -} - -function getAllValidPepites(regionId, establishmentId) { - if (establishmentId >= 0) { - return ([getPepiteFromEstablishment(establishmentId)]) - } - if (regionId >= 0) { - return deleteDuplicate((regions[regionId].establishments.map(getPepiteFromEstablishment))) - } - return [] -} - -function deleteDuplicate(array) { - return array.filter(function(item, pos) { - return array.findIndex(i => i.id == item.id) == pos - }) -} - -function isOverduePepite(idPepite) { - return (false) -} - -const PepiteForm = ({pepite, contact, errors, onChange}) => { +const PepiteForm = ({pepite, contact, errors, onChange, onEstablishmentChange, regions}) => { return (
+ + + - Ma région - - - {regions.map((region, index) => { return () }) } - + Je demande un accès à l'espace de coworking PEPITE (selon disponibilité) + + oui + non + - {(() => { - if (pepite.region != 0) { - return( - - Mon établissement pour l'année 2016 - - - {regions[pepite.region - 1].establishments.map((eid) => { return () }) } - - - ) - }})()} - {(() => { - if (pepite.region != 0) { - return( - - Mon PEPITE - - - {getAllValidPepites(pepite.region - 1, pepite.establishment - 1).map((pepite, index) => { return () }) } - - - ) - }})()} - - Je demande un accès à l'espace de coworking PEPITE (selon disponibilité) - - oui - non - - ) } @@ -80,7 +39,9 @@ PepiteForm.propTypes = { pepite: PropTypes.object.isRequired, contact: PropTypes.object.isRequired, onChange: PropTypes.func.isRequired, - errors: PropTypes.object + onEstablishmentChange: PropTypes.func.isRequired, + errors: PropTypes.object, + regions: PropTypes.array.isRequired } export default PepiteForm diff --git a/client/src/components/application/Pepite/PepitePage.js b/client/src/components/application/Pepite/PepitePage.js index 5d0fd01..ec22fae 100644 --- a/client/src/components/application/Pepite/PepitePage.js +++ b/client/src/components/application/Pepite/PepitePage.js @@ -1,11 +1,11 @@ -import React, {PropTypes} from 'react' +import React, { PropTypes } from 'react' import PepiteForm from './PepiteForm' -import {connect} from 'react-redux' -import {bindActionCreators} from 'redux' +import { connect } from 'react-redux' +import { bindActionCreators } from 'redux' import * as pepiteActions from '../../../actions/pepiteActions' import * as errorsActions from '../../../actions/errorsActions' import Validation from '../../common/Validation' -import {pepiteValidationConstraints} from './PepiteValidationConstraints' +import { pepiteValidationConstraints } from './PepiteValidationConstraints' class PepitePage extends React.Component { constructor(props, context) { @@ -14,8 +14,12 @@ class PepitePage extends React.Component { pepite: Object.assign({}, props.pepite), contact: Object.assign({}, props.contact), errors: Object.assign({}, props.errors), + regions: [], + establishments: [], + pepites: [] } this.updatePepiteState = this.updatePepiteState.bind(this) + this.updateEstablishment = this.updateEstablishment.bind(this) this.pepiteValidation = new Validation(pepiteValidationConstraints) } @@ -27,16 +31,26 @@ class PepitePage extends React.Component { updatePepiteState(event) { const field = event.target.name - let pepite = this.state.pepite + const pepite = this.state.pepite pepite[field] = event.target.value if (field == 'region') { - pepite.establishment = 0 + pepite.establishment = '0' + pepite.pepite = '0' } this.validatePepiteField(field, event.target.value) this.props.actions.updatePepite(pepite) return this.setState({ pepite }) } + updateEstablishment(establishment) { + const pepite = this.state.pepite + pepite.establishment = establishment._id.toString() + pepite.pepite = establishment.pepite.toString() + this.validatePepiteField('pepite', pepite.pepite) + this.props.actions.updatePepite(pepite) + return this.setState({ pepite }) + } + validatePepiteField(field, value) { const errors = Object.assign({}, this.state.errors) errors[field] = this.pepiteValidation.validateField(field, value) @@ -53,7 +67,12 @@ class PepitePage extends React.Component { pepite={this.state.pepite} contact={this.state.contact} onChange={this.updatePepiteState} - errors={this.state.errors}/> + onEstablishmentChange={this.updateEstablishment} + errors={this.state.errors} + regions={this.state.regions} + establishments={this.state.establishments} + pepites={this.state.pepites} + /> ) } } diff --git a/client/src/components/application/Pepite/PepiteSelect.js b/client/src/components/application/Pepite/PepiteSelect.js new file mode 100644 index 0000000..feef80d --- /dev/null +++ b/client/src/components/application/Pepite/PepiteSelect.js @@ -0,0 +1,65 @@ +import React, { PropTypes } from 'react' +import { FormGroup, ControlLabel } from 'react-bootstrap' +import ValidatedFormControl from '../../common/ValidatedFormControl' +import { getCurrentYear } from '../../common/yearHelper' +import pepiteApi from '../../../api/pepiteApi' + +class PepiteSelect extends React.Component { + constructor(props, context) { + super(props, context) + this.state = { + pepites: [] + } + if (this.props.selectedRegion) { + this.loadPepites(this.props.selectedRegion, this.props.selectedPepite) + } + } + + componentWillReceiveProps(nextProps) { + if ((this.props.selectedRegion != nextProps.selectedRegion) || + (this.props.selectedPepite != nextProps.selectedPepite)) { + this.loadPepites(nextProps.selectedRegion, nextProps.selectedPepite) + } + } + + loadPepites(regionId, pepiteId) { + if (pepiteId && pepiteId != '0') { + pepiteApi.getPepite(pepiteId).then(pepite => { + this.setState({ pepites: [pepite] }) + }) + } else { + pepiteApi.getPepites(regionId).then(pepites => { + this.setState({ pepites }) + }) + } + } + + isComponentVisible() { + return (this.props.selectedRegion) + } + + render() { + if (this.isComponentVisible()) { + return ( + + Mon PEPITE + + + {this.state.pepites.map((pepite) => { return () })} + + + ) + } else { + return null + } + } +} + +PepiteSelect.propTypes = { + selectedRegion: PropTypes.string.isRequired, + selectedPepite: PropTypes.string.isRequired, + onChange: PropTypes.func.isRequired, + errors: PropTypes.object, +} + +export default PepiteSelect diff --git a/client/src/components/application/Pepite/RegionSelect.js b/client/src/components/application/Pepite/RegionSelect.js new file mode 100644 index 0000000..b3ab8a1 --- /dev/null +++ b/client/src/components/application/Pepite/RegionSelect.js @@ -0,0 +1,40 @@ +import React, { PropTypes } from 'react' +import { FormGroup, ControlLabel } from 'react-bootstrap' +import ValidatedFormControl from '../../common/ValidatedFormControl' +import pepiteApi from '../../../api/pepiteApi' + +class RegionSelect extends React.Component { + constructor(props, context) { + super(props, context) + this.state = { + regions: [] + } + this.loadRegions() + } + + loadRegions() { + pepiteApi.getRegions().then(regions => { + this.setState({ regions }) + }) + } + + render() { + return ( + + Ma région + + + {this.state.regions.map((region, index) => { return () })} + + + ) + } +} + +RegionSelect.propTypes = { + selectedRegion: PropTypes.string.isRequired, + onChange: PropTypes.func.isRequired, + errors: PropTypes.object, +} + +export default RegionSelect diff --git a/client/src/components/application/Pepite/pepiteEstablishmentMap.js b/client/src/components/application/Pepite/pepiteEstablishmentMap.js deleted file mode 100644 index 461ea04..0000000 --- a/client/src/components/application/Pepite/pepiteEstablishmentMap.js +++ /dev/null @@ -1,189 +0,0 @@ -export const regions = [ - { name: 'Alsace - Champagne-Ardenne - Lorraine', establishments: [0, 86, 87] }, - { name: 'Auvergne - Rhône-Alpes', establishments: [85, 89, 90] }, - { name: 'Bretagne', establishments: [1] }, - { name: 'Île de France', establishments: [2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138] }, - { name: 'Nord-Pas-de-Calais - Picardie', establishments: [34, 84] }, - { name: 'Aquitaine - Limousin - Poitou-Charentes', establishments: [11, 88] }, - { name: 'Bourgogne - Franche-Comté', establishments: [91] }, - { name: 'Centre-Val de Loire', establishments: [92] }, - { name: 'Corse', establishments: [93] }, - { name: 'Languedoc-Roussillon - Midi-Pyrénées', establishments: [94, 95] }, - { name: 'Normandie', establishments: [52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 61,] }, - { name: 'Pays de Loire', establishments: [83] }, - { name: 'Provence-Alpes-Côte d’Azur', establishments: [96, 97] }, - { name: 'Départements et régions d’outre-mer', establishments: [98, 99] }, -] - -export const pepites = [ - 'ETENA', - 'Champagne-Ardenne', - 'by PEEL', - 'ECA', - 'LPC', - 'PEEA', - 'BeeLYS', - 'oZer', - 'Bretagne', - 'Centre-Val de Loire', - 'Corse', - 'CréaJ IDF', - '3EF', - 'heSam Entreprendre', - 'Paris Ouest Nord', - 'Paris Centre', - 'PEIPS', - 'PSL', - 'Languedoc-Roussillon', - 'ECRIN', - 'Lille Nord de France', - 'Picardie', - 'Vallée de Seine', - 'CRÉER', - 'Aix-Marseille PACA-OUEST', - 'Cré@tude PACA-EST', - 'Antilles-Guyane', - 'P2ER', - 'Bourgone Franche-Comté' -] -export const establishments = [ - { name: 'établissements de l\'académie de Strasgbourg', pepite: 0 }, - { name: 'établissements de l\'académie de Rennes', pepite: 8 }, - { name: 'Arts et Métiers ParisTech', pepite: 13 }, - { name: 'ESCP Europe', pepite: 13 }, - { name: 'Centre de Formation des Journalistes', pepite: 13 }, - { name: 'Centre Michel Serres', pepite: 13 }, - { name: 'CNAM', pepite: 13 }, - { name: 'école du Louvre', pepite: 13 }, - { name: 'ENA', pepite: 13 }, - { name: 'ENSAPLV', pepite: 13 }, - { name: 'ENSCI', pepite: 13 }, - { name: 'établissements de l\'académie de Bordeaux', pepite: 3 }, - { name: 'IFM', pepite: 13 }, - { name: 'INHA', pepite: 13 }, - { name: 'Institut national du patrimoine', pepite: 13 }, - { name: 'Université Paris 1', pepite: 13 }, - { name: 'INED', pepite: 13 }, - { name: 'Université Paris 8', pepite: 14 }, - { name: 'Université Paris Nanterre', pepite: 14 }, - { name: 'IIM', pepite: 14 }, - { name: 'EMLV', pepite: 14 }, - { name: 'EDC Paris Business School', pepite: 14 }, - { name: 'ESILV', pepite: 14 }, - { name: 'Institut Catholique de Paris', pepite: 14 }, - { name: 'EPF École d\'ingenieur·e·s', pepite: 14 }, - { name: 'ISG International Business School', pepite: 14 }, - { name: 'IÉSEG School of Management', pepite: 14 }, - { name: 'Comue Université Paris-Est', pepite: 12 }, - { name: 'UPEC', pepite: 12 }, - { name: 'UPEM', pepite: 12 }, - { name: 'École des Ponts ParisTech', pepite: 12 }, - { name: 'ESIEE Paris', pepite: 12 }, - { name: 'École de l\'architecture de la ville et des territoires à Marne-la-Vallée', pepite: 12 }, - { name: 'École spéciale des travaux publics, du bâtiment et de l\'industrie', pepite: 12 }, - { name: 'établissements de l\'académie d\'Amiens', pepite: 21 }, - { name: 'École nationale vétérinaire d\'Alfort', pepite: 12 }, - { name: 'École nationale supérieure d\'architecture de Paris-Belleville', pepite: 12 }, - { name: 'École des Ingénieurs de la Ville de Paris', pepite: 12 }, - { name: 'École nationale des sciences géographiques', pepite: 12 }, - { name: 'École nationale supérieure d\'architecture de Paris-Malaquais', pepite: 12 }, - { name: 'Cesi', pepite: 22 }, - { name: 'CNAM', pepite: 22 }, - { name: 'EBI - École de Biologie', pepite: 22 }, - { name: 'ENSP - École Supérieure de Paysage de Versailles', pepite: 22 }, - { name: 'EISTI - Traitement de l\'information', pepite: 22 }, - { name: 'ENSEA', pepite: 22 }, - { name: 'EPMI', pepite: 22 }, - { name: 'ESSEC', pepite: 22 }, - { name: 'ILEPS - Métiers du sport', pepite: 22 }, - { name: 'ISTOM', pepite: 22 }, - { name: 'ITESCIA', pepite: 22 }, - { name: 'Université Cergy Pontoise', pepite: 22 }, - { name: 'École de Management de Normandie', pepite: 22 }, - { name: 'ENSA Normanide - Ecole d\'architecture', pepite: 22 }, - { name: 'ENSI Caen', pepite: 22 }, - { name: 'Esadhar', pepite: 22 }, - { name: 'Esigelec', pepite: 22 }, - { name: 'INSA Rouen Normandie', pepite: 22 }, - { name: 'Neoma', pepite: 22 }, - { name: 'Université Caen Normandie', pepite: 22 }, - { name: 'Université Le Havre Normandie', pepite: 22 }, - { name: 'Université Rouen Normandie', pepite: 22 }, - { name: 'Chimie ParisTech', pepite: 17 }, - { name: 'Collège de France', pepite: 17 }, - { name: 'Conservatoire national supérieur de musique et de danse de Paris', pepite: 17 }, - { name: 'École des hautes études en sciences sociales', pepite: 17 }, - { name: 'École française d\'Extrême-Orient', pepite: 17 }, - { name: 'École nationale des chartes', pepite: 17 }, - { name: 'École nationale supérieure des Arts Décoratifs', pepite: 17 }, - { name: 'École nationale supérieure des beaux-arts', pepite: 17 }, - { name: 'École normale supérieure', pepite: 17 }, - { name: 'École Pratique des Hautes Études', pepite: 17 }, - { name: 'ESPCI', pepite: 17 }, - { name: 'Institut Curie', pepite: 17 }, - { name: 'La Fémis', pepite: 17 }, - { name: 'Lycée Henri-IV', pepite: 17 }, - { name: 'MINES ParisTech', pepite: 17 }, - { name: 'Observatoire de Paris', pepite: 17 }, - { name: 'Université Paris-Dauphine', pepite: 17 }, - { name: 'Institut Pasteur', pepite: 17 }, - { name: 'Epita', pepite: 17 }, - { name: 'Epitech', pepite: 17 }, - { name: 'ETNA', pepite: 17 }, - { name: 'établissements de l\'académie de Nantes', pepite: 23 }, - { name: 'établissements de l\'académie de Lille', pepite: 20 }, - { name: 'établissements de l\'académie de Lyon', pepite: 6 }, - { name: 'établissements de l’académie de Nancy-Metz', pepite: 2 }, - { name: 'établissements de l’académie de Reims', pepite: 1 }, //87 - { name: 'établissements des académies de Limoges et Poitiers', pepite: 4 }, - { name: 'établissements de l\'académie de Clermont-Ferrand', pepite: 5 }, - { name: 'établissements de l\'académie de Grenoble', pepite: 7 }, //90 - { name: 'établissements des académies de Besançon et de Dijon', pepite: 28 }, - { name: 'établissements de l’académie d’Orléans-Tours', pepite: 9 }, - { name: 'établissements de l’académie de Corse', pepite: 10 }, - { name: 'établissements de l’académie de Montpellier', pepite: 18 }, - { name: 'établissements de l’académie de Toulouse', pepite: 19 }, - { name: 'établissements de l’académie d’Aix-Marseille', pepite: 24 }, - { name: 'établissements de l’académie de Nice', pepite: 25 }, - { name: 'établissements des académies des Antilles et de Guyane', pepite: 26 }, - { name: 'établissements des académies de la Réunion et de Mayote', pepite: 27 }, - { name: 'Université Paris 13', pepite: 11 },//100 - { name: 'Université Paris 3', pepite: 11 }, - { name: 'Université Paris 5', pepite: 11 }, - { name: 'Université Paris 7', pepite: 11 }, - { name: 'IEP de Paris', pepite: 11 }, - { name: 'IPG', pepite: 11 }, - { name: 'INALCO', pepite: 11 }, - { name: 'EHESP', pepite: 11 }, - { name: 'ISC Paris', pepite: 11 }, - { name: 'Novancia', pepite: 11 }, - { name: 'PSB', pepite: 11 }, - { name: 'Ecole de Commerce du Sport Business', pepite: 11 }, - { name: 'EFREI', pepite: 11 }, //112 - { name: 'Sorbonne Universités', pepite: 15 }, - { name: 'Université Paris 4', pepite: 15 }, - { name: 'Université Paris 6', pepite: 15 }, - { name: 'MNHN', pepite: 15 }, - { name: 'UTC', pepite: 15 }, - { name: 'INSEAD', pepite: 15 }, - { name: 'PSPBB', pepite: 15 }, - { name: 'Université Paris 2', pepite: 15 }, - { name: 'ENM', pepite: 15 }, - { name: 'INHA', pepite: 15 }, - { name: 'Université Paris-Saclay', pepite: 16 }, - { name: 'Université Paris 11', pepite: 16 }, - { name: 'Université Versailles-Saint-Quentin-en-Yvelines', pepite: 16 }, - { name: 'AgroParisTech', pepite: 16 }, - { name: 'CentraleSupélec', pepite: 16 }, - { name: 'HEC Paris', pepite: 16 }, - { name: 'École polytechnique', pepite: 16 }, - { name: 'ENS de Cachan', pepite: 16 }, - { name: 'ENSTA ParisTech', pepite: 16 }, - { name: 'ENSAE', pepite: 16 }, - { name: 'Institut Mines-Télécom', pepite: 16 }, - { name: 'Institut d’Optique Graduate School (IOGS)', pepite: 16 }, - { name: 'Université d’Evry Val d’Essonne (UEVE)', pepite: 16 }, - { name: 'Télécom Sud-Paris', pepite: 16 }, - { name: 'Télécom Ecole de Mangement', pepite: 16 }, - { name: 'ESTACA', pepite: 16 }, -]