From 590bbe5afcc1f3dae5169d819b52c7afafb50ade Mon Sep 17 00:00:00 2001 From: Clement G Date: Sat, 25 Apr 2020 18:13:34 +0200 Subject: [PATCH] feat(restrict-result) : add an restrict result option on create election form --- public/locale/i18n/de/resource.json | 16 +- public/locale/i18n/en/resource.json | 16 +- public/locale/i18n/es/resource.json | 14 +- public/locale/i18n/fr/resource.json | 19 +- public/locale/i18n/ru/resource.json | 14 +- src/components/form/HelpButton.jsx | 2 +- src/components/views/CreateElection.jsx | 911 +++++++++++++----------- src/scss/_app.scss | 8 + 8 files changed, 563 insertions(+), 437 deletions(-) diff --git a/public/locale/i18n/de/resource.json b/public/locale/i18n/de/resource.json index f3fb69e..ec4ad73 100644 --- a/public/locale/i18n/de/resource.json +++ b/public/locale/i18n/de/resource.json @@ -19,12 +19,12 @@ "Candidates/Proposals": "Kandidaten/Abstimmungsvorschlag ", "Add a proposal": "Einen Abstimmungsvorschlag hinzufügen", "Advanced options": "Weitere Optionen", - "Starting date:": "Anfangsdatum:", - "Ending date: ": "Enddatum: ", - "Grades:": "Note", + "Starting date": "Anfangsdatum", + "Ending date": "Enddatum", + "Grades": "Note", "You can select here the number of grades for your election": " Sie können hier die Anzahl der Noten für Ihre Wahl auswählen ", "5 = Excellent, Very good, Good, Fair, Passable": "5 = hervorragend, sehr gut, gut, befriedigend, ausreichend", - "Participants:": "Teilnehmer :", + "Participants": "Teilnehmer", "Add here participants' emails": "Fügen Sie hier die Email Adressen der Teilnehmer hinzu.", "List voters' emails in case the election is not opened": "Falls die Wahl noch nicht sofort geöffnet werden soll, fügen Sie die Email Adressen der Teilnehmer hier zu.", "Validate": "Ok", @@ -60,7 +60,6 @@ "The election will take place from": "Die Wahl findet von", "at": "um", "to": "bis", - "Grades": "Note", "Voters' list": "Wählerliste", "Voters received a link to vote by email. Each link can be used only once!": "Die Wähler erhielten per E-Mail einen Link zur Stimmabgabe. Jeder Link kann nur einmal verwendet werden!", "Results of the election:": "Ergebnisse der Wahl", @@ -73,5 +72,10 @@ "The election is over. You can't vote anymore": "Die Wahl ist vorbei. Sie können nicht mehr wählen", "You need a token to vote in this election": "Sie brauchen eine Wertmarke, um an dieser Wahl teilzunehmen", "You seem to have already voted.": "Sie scheinen bereits abgestimmt zu haben.", - "The parameters of the election are incorrect.": "Die Parameter der Wahl sind falsch." + "The parameters of the election are incorrect.": "Die Parameter der Wahl sind falsch.", + "Access to results" : "Zugang zu den Ergebnissen", + "Immediately": "Sofort", + "At the end of the election": "Am Ende der Wahl", + "The results page will not be accessible until all participants have voted.":"Die Ergebnisseite wird nicht zugänglich sein, bis alle Teilnehmer abgestimmt haben.", + "The results page will not be accessible until the end date is reached.": "Die Ergebnisseite wird nicht zugänglich sein, bis das Enddatum erreicht ist." } diff --git a/public/locale/i18n/en/resource.json b/public/locale/i18n/en/resource.json index ed4d7ca..afdf109 100644 --- a/public/locale/i18n/en/resource.json +++ b/public/locale/i18n/en/resource.json @@ -19,12 +19,12 @@ "Candidates/Proposals": "Candidates/Proposals", "Add a proposal": "Add a proposal", "Advanced options": "Advanced options", - "Starting date:": "Starting date:", - "Ending date: ": "Ending date: ", - "Grades:": "Grades:", + "Starting date": "Starting date", + "Ending date": "Ending date", + "Grades": "Grades", "You can select here the number of grades for your election": "You can select here the number of grades for your election", "5 = Excellent, Very good, Good, Fair, Passable": "5 = Excellent, Very good, Good, Fair, Passable", - "Participants:": "Participants:", + "Participants": "Participants", "Add here participants' emails": "Add here participants' emails", "List voters' emails in case the election is not opened": "List voters' emails in case the election is not opened", "Validate": "Validate", @@ -62,7 +62,6 @@ "The election will take place from": "The election will take place from", "at": "at", "to": "to", - "Grades": "Grades", "Voters' list": "Voters' list", "Graph": "Graph", "Preference profile": "Merit profile", @@ -80,5 +79,10 @@ "The parameters of the election are incorrect.": "The parameters of the election are incorrect.", "Support us !": "Support us !", "PayPal - The safer, easier way to pay online!": "PayPal - The safer, easier way to pay online!", - "Number of votes:": "Number of votes:" + "Number of votes:": "Number of votes:", + "Access to results" : "Access to results", + "Immediately": "Immediately", + "At the end of the election": "At the end of the election", + "The results page will not be accessible until all participants have voted.":"The results page will not be accessible until all participants have voted.", + "The results page will not be accessible until the end date is reached.": "The results page will not be accessible until the end date is reached." } diff --git a/public/locale/i18n/es/resource.json b/public/locale/i18n/es/resource.json index 2b9aee8..bd8654f 100644 --- a/public/locale/i18n/es/resource.json +++ b/public/locale/i18n/es/resource.json @@ -19,9 +19,9 @@ "Candidates/Proposals": "Candidatos(as)/Propuestas", "Add a proposal": "Añadir una propuesta", "Advanced options": "Opciones avanzadas", - "Starting date:": "Fecha de inicio:", - "Ending date: ": "Fecha de finalización: ", - "Grades:": "Escala", + "Starting date": "Fecha de inicio", + "Ending date": "Fecha de finalización", + "Grades": "Escala", "You can select here the number of grades for your election": "Puede seleccionar aquí el número de niveles de la escala para su elección", "5 = Excellent, Very good, Good, Fair, Passable": "5 == Excelente, Muy bien, Bien, Regular, Pasable", "Participants:": "Participantes", @@ -62,7 +62,6 @@ "The election will take place from": "La elección tendrá lugar desde", "at": "a las", "to": "hasta", - "Grades": "Escala", "Voters' list": "Lista de votantes", "Graph": "Gráfico", "Preference profile": "Perfil de preferencia", @@ -81,5 +80,10 @@ "The election is over. You can't vote anymore": "La elección ha terminado. Ya no puedes votar.", "You need a token to vote in this election": "Necesitas una ficha para votar en esta elección", "You seem to have already voted.": "Parece que ya has votado.", - "The parameters of the election are incorrect.": "Los parámetros de la elección son incorrectos." + "The parameters of the election are incorrect.": "Los parámetros de la elección son incorrectos.", + "Access to results" : "Acceso a los resultados", + "Immediately": "Inmediatamente", + "At the end of the election": "Al final de la elección", + "The results page will not be accessible until all participants have voted.":"La página de resultados no será accesible hasta que todos los participantes hayan votado.", + "The results page will not be accessible until the end date is reached.": "No se podrá acceder a la página de resultados hasta que se alcance la fecha de finalización." } diff --git a/public/locale/i18n/fr/resource.json b/public/locale/i18n/fr/resource.json index ca527e0..5257b7f 100644 --- a/public/locale/i18n/fr/resource.json +++ b/public/locale/i18n/fr/resource.json @@ -19,19 +19,18 @@ "Candidates/Proposals": "Candidats/Propositions", "Add a proposal": "Ajouter une proposition", "Advanced options": "Options avancées", - "Starting date:": "Date de début :", - "Ending date: ": "Date de fin : ", - "Ending date:": "Date de fin : ", - "Grades:": "Mentions", + "Starting date": "Date de début", + "Ending date": "Date de fin ", + "Grades": "Mentions", "You can select here the number of grades for your election": "You pouvez choisir ici le nombre de mentions de votre élection", "5 = Excellent, Very good, Good, Fair, Passable": "5 = Excellent, Très bien, Bien, Assez bien, Passable", - "Participants:": "Participants :", + "Participants": "Participants", "Add here participants' emails": "Ajouter ici les emails des participants", "List voters' emails in case the election is not opened": "Lister ici les emails des électeurs dans le cas où l'élection n'est pas ouverte.", "Validate": "Valider", "Confirm your vote": "Confirmer votre vote", "The form contains no address.": "Aucune adresse email n'a été ajoutée.", - "The election will be opened to anyone with the link": "L'élection sera accessible à tous ceux qui disposent de ce lien", + "The election will be opened to anyone with the link": "L'élection sera accessible à tous ceux qui disposent du lien", "Start the election": "Démarrer l'élection", "Cancel": "Annuler", "Confirm": "Valider", @@ -62,7 +61,6 @@ "The election will take place from": "Le vote se déroulera du", "at": "à", "to": "au", - "Grades": "Mentions", "Voters' list": "Listes des électeurs", "Graph": "Graphique", "Preference profile": "Profil de mérites", @@ -80,5 +78,10 @@ "The parameters of the election are incorrect.": "Les paramètres de l'élection sont incorrects.", "Support us !": "Soutenez-nous !", "PayPal - The safer, easier way to pay online!": "PayPal - Le moyen le plus sûr et le plus simple de payer en ligne !", - "Number of votes:": "Nombre de votes :" + "Number of votes:": "Nombre de votes :", + "Access to results" : "Accès aux résultats", + "Immediately": "Immédiatement", + "At the end of the election": "A la fin de l'élection", + "The results page will not be accessible until all participants have voted.":"La page de résultats ne sera pas accessible tant que tous les participants n'auront pas voté.", + "The results page will not be accessible until the end date is reached.": "La page de résultats ne sera pas accessible tant que la date de fin ne sera pas atteinte." } diff --git a/public/locale/i18n/ru/resource.json b/public/locale/i18n/ru/resource.json index 65dbe6e..9d327a7 100644 --- a/public/locale/i18n/ru/resource.json +++ b/public/locale/i18n/ru/resource.json @@ -19,9 +19,9 @@ "Candidates/Proposals": "Кандидаты/Предложения", "Add a proposal": "Добавьте предложение", "Advanced options": "Расширенные настройки", - "Starting date:": "Дата начала:", - "Ending date: ": "Дата окончания: ", - "Grades:": "Оценки:", + "Starting date": "Дата начала", + "Ending date": "Дата окончания", + "Grades": "Оценки", "You can select here the number of grades for your election": "Здесь вы можете выбрать количество оценок для вашего голосования", "5 = Excellent, Very good, Good, Fair, Passable": "5 = Отлично, Очень хорошо, Хорошо, Удовлетворительно, Допустимо", "Participants:": "Участники:", @@ -62,7 +62,6 @@ "The election will take place from": "Голосование состоится", "at": "в", "to": "к", - "Grades": "Оценки", "Voters' list": "Список проголосовавших", "Graph": "Кривая", "Preference profile": "Профиль заслуг", @@ -80,5 +79,10 @@ "The parameters of the election are incorrect.": "Параметры голосвания неверны.", "Support us !": "Поддержите нас !", "PayPal - The safer, easier way to pay online!": "PayPal - Безопасный и простой способ платить онлайн!", - "Number of votes:": "Количество голосов:" + "Number of votes:": "Количество голосов:", + "Access to results" : "Доступ к результатам", + "Immediately": "Немедленно", + "At the end of the election": "По окончании выборов", + "The results page will not be accessible until all participants have voted.":"Страница результатов не будет доступна до тех пор, пока все участники не проголосуют.", + "The results page will not be accessible until the end date is reached.": "Страница результатов не будет доступна до тех пор, пока не будет достигнута конечная дата." } diff --git a/src/components/form/HelpButton.jsx b/src/components/form/HelpButton.jsx index a51b733..2976764 100644 --- a/src/components/form/HelpButton.jsx +++ b/src/components/form/HelpButton.jsx @@ -25,7 +25,7 @@ class HelpButton extends Component { render() { return ( - + {this.state.tooltipOpen ? ( date.toISOString().substring(0, 10); @@ -61,22 +61,23 @@ const timeMinusDate = date => time(date); // Retrieve the day and remove the time. Return a Date const dateMinusTime = date => new Date(date.getTime() - time(date)); -const DragHandle = sortableHandle(({children}) => ( - {children} +const DragHandle = sortableHandle(({ children }) => ( + {children} )); const displayClockOptions = () => - Array(24) - .fill(1) - .map((x, i) => ( - - )); - -const SortableCandidate = sortableElement(({candidate, sortIndex, form, t}) => ( + Array(24) + .fill(1) + .map((x, i) => ( + + )); + +const SortableCandidate = sortableElement( + ({ candidate, sortIndex, form, t }) => (
  • - + @@ -85,36 +86,37 @@ const SortableCandidate = sortableElement(({candidate, sortIndex, form, t}) => ( form.editCandidateLabel(event, sortIndex)} - onKeyPress={event => - form.handleKeypressOnCandidateLabel(event, sortIndex) - } - placeholder={t('Candidate/proposal name...')} - tabIndex={sortIndex + 1} - innerRef={ref => (form.candidateInputs[sortIndex] = ref)} - maxLength="250" + type="text" + value={candidate.label} + onChange={event => form.editCandidateLabel(event, sortIndex)} + onKeyPress={event => + form.handleKeypressOnCandidateLabel(event, sortIndex) + } + placeholder={t("Candidate/proposal name...")} + tabIndex={sortIndex + 1} + innerRef={ref => (form.candidateInputs[sortIndex] = ref)} + maxLength="250" />
    -
    {t('Delete?')}
    +
    {t("Delete?")}
    - {t('Are you sure to delete')}{' '} - {candidate.label !== '' ? ( - "{candidate.label}" + {t("Are you sure to delete")}{" "} + {candidate.label !== "" ? ( + "{candidate.label}" ) : ( - - {t('the row')} {sortIndex + 1} - - )}{' '} + + {t("the row")} {sortIndex + 1} + + )}{" "} ?
    form.removeCandidate(sortIndex)}> + key="modal-confirm" + onClick={() => form.removeCandidate(sortIndex)} + > Oui
    Non
    @@ -124,28 +126,29 @@ const SortableCandidate = sortableElement(({candidate, sortIndex, form, t}) => ( {t( - 'Write here your question or introduce simple your election (250 characters max.)', + "Write here your question or introduce simple your election (250 characters max.)" )}
  • -)); + ) +); -const SortableCandidatesContainer = sortableContainer(({items, form, t}) => { +const SortableCandidatesContainer = sortableContainer(({ items, form, t }) => { return ( -
      - {items.map((candidate, index) => ( - - ))} -
    +
      + {items.map((candidate, index) => ( + + ))} +
    ); }); @@ -156,40 +159,46 @@ class CreateElection extends Component { // default value : start at the last hour const now = new Date(); const start = new Date( - now.getTime() - minutes(now) - seconds(now) - ms(now), + now.getTime() - minutes(now) - seconds(now) - ms(now) ); - const {title} = queryString.parse(this.props.location.search); + const { title } = queryString.parse(this.props.location.search); this.state = { - candidates: [{label: ''}, {label: ''}], - title: title || '', + candidates: [{ label: "" }, { label: "" }], + title: title || "", isVisibleTipsDragAndDropCandidate: true, numGrades: 7, waiting: false, successCreate: false, redirectTo: null, isAdvancedOptionsOpen: false, + restrictResult: false, start, // by default, the election ends in a week finish: new Date(start.getTime() + 7 * 24 * 3600 * 1000), - electorEmails: [], + electorEmails: [] }; this.candidateInputs = []; this.focusInput = React.createRef(); this.handleSubmit = this.handleSubmit.bind(this); + this.handleRestrictResultCheck = this.handleRestrictResultCheck.bind(this); } handleChangeTitle = event => { - this.setState({title: event.target.value}); + this.setState({ title: event.target.value }); + }; + + handleRestrictResultCheck = event => { + this.setState({ restrictResult: event.target.value === "1" }); }; addCandidate = event => { let candidates = this.state.candidates; if (candidates.length < 100) { - candidates.push({label: ''}); - this.setState({candidates: candidates}); + candidates.push({ label: "" }); + this.setState({ candidates: candidates }); } - if (event.type === 'keypress') { + if (event.type === "keypress") { setTimeout(() => { this.candidateInputs[this.state.candidates.length - 1].focus(); }, 250); @@ -200,9 +209,9 @@ class CreateElection extends Component { let candidates = this.state.candidates; candidates.splice(index, 1); if (candidates.length === 0) { - candidates = [{label: ''}]; + candidates = [{ label: "" }]; } - this.setState({candidates: candidates}); + this.setState({ candidates: candidates }); }; editCandidateLabel = (event, index) => { @@ -212,12 +221,12 @@ class CreateElection extends Component { return candidate.label; }); this.setState({ - candidates: candidates, + candidates: candidates }); }; handleKeypressOnCandidateLabel = (event, index) => { - if (event.key === 'Enter') { + if (event.key === "Enter") { event.preventDefault(); if (index + 1 === this.state.candidates.length) { this.addCandidate(event); @@ -227,40 +236,40 @@ class CreateElection extends Component { } }; - onCandidatesSortEnd = ({oldIndex, newIndex}) => { + onCandidatesSortEnd = ({ oldIndex, newIndex }) => { let candidates = this.state.candidates; candidates = arrayMove(candidates, oldIndex, newIndex); - this.setState({candidates: candidates}); + this.setState({ candidates: candidates }); }; handleChangeNumGrades = event => { - this.setState({numGrades: event.target.value}); + this.setState({ numGrades: event.target.value }); }; toggleAdvancedOptions = () => { - this.setState({isAdvancedOptionsOpen: !this.state.isAdvancedOptionsOpen}); + this.setState({ isAdvancedOptionsOpen: !this.state.isAdvancedOptionsOpen }); }; checkFields() { - const { candidates, title } = this.state; + const { candidates, title } = this.state; - if (!candidates) { - return {ok: false, msg: AT_LEAST_2_CANDIDATES_ERROR}; - } + if (!candidates) { + return { ok: false, msg: AT_LEAST_2_CANDIDATES_ERROR }; + } - let numCandidates = 0; - candidates.forEach(c => { - if (c !== "") numCandidates += 1; - }) - if (numCandidates < 2) { - return {ok: false, msg: AT_LEAST_2_CANDIDATES_ERROR}; - } + let numCandidates = 0; + candidates.forEach(c => { + if (c !== "") numCandidates += 1; + }); + if (numCandidates < 2) { + return { ok: false, msg: AT_LEAST_2_CANDIDATES_ERROR }; + } - if (!title || title === "") { - return {ok: false, msg: NO_TITLE_ERROR}; - } - - return {ok: true, msg: "OK"}; + if (!title || title === "") { + return { ok: false, msg: NO_TITLE_ERROR }; + } + + return { ok: true, msg: "OK" }; } handleSubmit() { @@ -270,43 +279,45 @@ class CreateElection extends Component { numGrades, start, finish, - electorEmails, + electorEmails } = this.state; const endpoint = resolve( - this.context.urlServer, - this.context.routesServer.setElection, + this.context.urlServer, + this.context.routesServer.setElection ); - const {t} = this.props; - const locale=i18n.language.substring(0,2).toLowerCase()==="fr"?"fr":"en"; + const { t } = this.props; + const locale = + i18n.language.substring(0, 2).toLowerCase() === "fr" ? "fr" : "en"; const check = this.checkFields(); if (!check.ok) { - toast.error(t(check.msg), { - position: toast.POSITION.TOP_CENTER, - }); - return + toast.error(t(check.msg), { + position: toast.POSITION.TOP_CENTER + }); + return; } - this.setState({waiting: true}); + this.setState({ waiting: true }); fetch(endpoint, { - method: 'POST', + method: "POST", headers: { - 'Content-Type': 'application/json', + "Content-Type": "application/json" }, body: JSON.stringify({ title: title, - candidates: candidates.map(c => c.label).filter( c => c !== ""), + candidates: candidates.map(c => c.label).filter(c => c !== ""), on_invitation_only: electorEmails.length > 0, num_grades: numGrades, elector_emails: electorEmails, start_at: start.getTime() / 1000, finish_at: finish.getTime() / 1000, select_language: locale, - front_url : window.location.origin - }), + front_url: window.location.origin, + restrict_result: this.state.restrictResult + }) }) .then(response => response.json()) .then(result => { @@ -319,22 +330,22 @@ class CreateElection extends Component { this.setState(state => ({ redirectTo: nextPage, successCreate: true, - waiting: false, + waiting: false })); } else { - toast.error(t('Unknown error. Try again please.'), { - position: toast.POSITION.TOP_CENTER, + toast.error(t("Unknown error. Try again please."), { + position: toast.POSITION.TOP_CENTER }); - this.setState({waiting: false}); + this.setState({ waiting: false }); } }) .catch(error => error); } - handleSendNotReady = (msg) => { - const {t} = this.props; + handleSendNotReady = msg => { + const { t } = this.props; toast.error(t(msg), { - position: toast.POSITION.TOP_CENTER, + position: toast.POSITION.TOP_CENTER }); }; @@ -349,9 +360,9 @@ class CreateElection extends Component { candidates, numGrades, isAdvancedOptionsOpen, - electorEmails, + electorEmails } = this.state; - const {t} = this.props; + const { t } = this.props; const grades = i18nGrades(); const check = this.checkFields(); @@ -359,235 +370,291 @@ class CreateElection extends Component { if (successCreate) return ; return ( - - - {waiting ? : ''} -
    - - -

    {t('Start an election')}

    - -
    -
    - - - - - - - - - + + + {waiting ? : ""} + + + +

    {t("Start an election")}

    + +
    +
    + + + + + + + + + + {t( + "Write here your question or introduce simple your election (250 characters max.)" + )} +
    + {t("For example:")}{" "} + {t( - 'Write here your question or introduce simple your election (250 characters max.)', + "For the role of my representative, I judge this candidate..." )} -
    - {t('For example:')}{' '} - - {t( - 'For the role of my representative, I judge this candidate...', - )} - -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - + +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + -
    - - - - - + + + + + -
    - - - - - - - - - - {t( - 'You can select here the number of grades for your election', - )} -
    - {t('For example:')}{' '} - - {' '} - {t('5 = Excellent, Very good, Good, Fair, Passable')} - -
    - - - {grades.map((mention, i) => { - return ( - + + + +
    +
    + + + {t("Starting date")} + + + { + this.setState({ + start: new Date( + timeMinusDate(start) + + new Date(e.target.valueAsNumber).getTime() + ) + }); + }} + /> + + + + + +
    + + + {t("Ending date")} + + + { + this.setState({ + finish: new Date( + timeMinusDate(finish) + + new Date(e.target.valueAsNumber).getTime() + ) + }); + }} + /> + + + + + +
    + + + {t("Grades")} + + + + + + + {t( + "You can select here the number of grades for your election" + )} +
    + {t("For example:")}{" "} + + {" "} + {t("5 = Excellent, Very good, Good, Fair, Passable")} + +
    + + + {grades.map((mention, i) => { + return ( + {mention.label} - ); - })} - -
    -
    - - - - - - { - this.setState({electorEmails: _emails}); - }} - validateEmail={email => { - return isEmail(email); // return boolean - }} - getLabel={(email, index, removeEmail) => { - return ( -
    - {email} - removeEmail(index)}> + ); + })} + + +
    + + + {t("Participants")} + + + { + this.setState({ electorEmails: _emails }); + }} + validateEmail={email => { + return isEmail(email); // return boolean + }} + getLabel={(email, index, removeEmail) => { + return ( +
    + {email} + removeEmail(index)} + > ×
    @@ -597,7 +664,7 @@ class CreateElection extends Component {
    {t( - "If you list voters' emails, only them will be able to access the election", + "If you list voters' emails, only them will be able to access the election" )}
    @@ -612,27 +679,28 @@ class CreateElection extends Component { {check.ok ? ( + tabIndex={candidates.length + 4} + >
    - {t('Validate')} + {t("Validate")}
    -
    {t('Confirm your vote')}
    +
    {t("Confirm your vote")}
    - {t('Question of the election')} + {t("Question of the election")}
    {title}
    - {t('Candidates/Proposals')} + {t("Candidates/Proposals")}
      {candidates.map((candidate, i) => { - if (candidate.label !== '') { + if (candidate.label !== "") { return (
    • {candidate.label} @@ -645,22 +713,22 @@ class CreateElection extends Component {
    - {t('Dates')} + {t("Dates")}

    - {t('The election will take place from')}{' '} + {t("The election will take place from")}{" "} - {start.toLocaleDateString()}, {t('at')}{' '} + {start.toLocaleDateString()}, {t("at")}{" "} {start.toLocaleTimeString()} - {' '} - {t('to')}{' '} + {" "} + {t("to")}{" "} - {finish.toLocaleDateString()}, {t('at')}{' '} + {finish.toLocaleDateString()}, {t("at")}{" "} {finish.toLocaleTimeString()}

    - {t('Grades')} + {t("Grades")}
    {grades.map((mention, i) => { @@ -670,53 +738,84 @@ class CreateElection extends Component { className="badge badge-light mr-2 mt-2" style={{ backgroundColor: mention.color, - color: '#fff', - }}> + color: "#fff" + }} + > {mention.label} - ) : ( - - ); - })} -
    -
    - {t("Voters' list")} -
    -
    - {electorEmails.length > 0 ? ( - electorEmails.join(', ') - ) : ( -

    - {t('The form contains no address.')} -
    - - {t( - 'The election will be opened to anyone with the link', - )} - -

    - )} -
    -
    + ) : ( + + ); + })}
    -
    - {t('Start the election')} +
    + {t("Voters' list")}
    -
    {t('Cancel')}
    - - ) : ( - - )} - - - - +
    + {electorEmails.length > 0 ? ( + electorEmails.join(", ") + ) : ( +

    + {t("The form contains no address.")} +
    + + {t( + "The election will be opened to anyone with the link" + )} + +

    + )} +
    + {this.state.restrictResult ? ( +
    +
    +
    + + {t("Accès aux résultats")} +
    +

    + {electorEmails.length > 0 ? ( + + {t( + "The results page will not be accessible until all participants have voted." + )} + + ) : + {t( + "The results page will not be accessible until the end date is reached." + )}{" "} + ({finish.toLocaleDateString()} {t("at")}{" "} + {finish.toLocaleTimeString()}) + } + +

    +
    +
    + ) : null} +
    +
    +
    + {t("Start the election")} +
    +
    {t("Cancel")}
    + + ) : ( + + )} + +
    + +
    ); } } diff --git a/src/scss/_app.scss b/src/scss/_app.scss index ff7820a..cf2f189 100644 --- a/src/scss/_app.scss +++ b/src/scss/_app.scss @@ -154,6 +154,10 @@ li.sortable { border-radius: 50%; } +.checkround.checkround-gray{ + border-color: $gray-600; +} + /* When the radio button is checked, add a blue background */ .radio input:checked ~ .checkround { background-color: #fff; @@ -181,6 +185,10 @@ li.sortable { background: $mv-blue-color; } +/*.radio .checkround.checkround-gray:after { + background: $gray-600; +}*/ + /* The check */ .check { display: block;