[i18n] minor fixes

pull/73/head
Pierre-Louis Guhur 4 years ago committed by guhur
parent c2dc116f2a
commit eb976a5c91

@ -9,7 +9,7 @@ module.exports = {
'!app/i18n/**', '!app/i18n/**',
'!**/node_modules/**', '!**/node_modules/**',
], ],
output: './', output: '.',
options: { options: {
debug: true, debug: true,
func: { func: {
@ -32,15 +32,15 @@ module.exports = {
}, },
lngs: ['en','fr','es'], lngs: ['en','fr','es'],
ns: [ ns: [
'locale', 'resource',
'resource' 'common'
], ],
defaultLng: 'en', defaultLng: 'en',
defaultNs: 'resource', defaultNs: 'resource',
defaultValue: '__STRING_NOT_TRANSLATED__', defaultValue: '__STRING_NOT_TRANSLATED__',
resource: { resource: {
loadPath: 'i18n/{{lng}}/{{ns}}.json', loadPath: './public/locale/i18n/{{lng}}/{{ns}}.json',
savePath: 'i18n/{{lng}}/{{ns}}.json', savePath: './public/locale/i18n/{{lng}}/{{ns}}.json',
jsonIndent: 2, jsonIndent: 2,
lineEnding: '\n' lineEnding: '\n'
}, },

@ -1 +1 @@
i18next-scanner --config locale/i18n/config.js --output locale/ 'src/**/*.{js,jsx}' i18next-scanner --config i18n.config.js 'src/**/*.{js,jsx}'

@ -49,5 +49,22 @@
"Go back to homepage": "Go back to homepage", "Go back to homepage": "Go back to homepage",
"You have to judge every candidate/proposal!": "You have to judge every candidate/proposal!", "You have to judge every candidate/proposal!": "You have to judge every candidate/proposal!",
"Your participation was recorded with success!": "Your participation was recorded with success!", "Your participation was recorded with success!": "Your participation was recorded with success!",
"Thanks for your participation.": "__STRING_NOT_TRANSLATED__" "Thanks for your participation.": "Thanks for your participation.",
"Ending date:": "Ending date:",
"Excellent": "Excellent",
"Very good": "Very good",
"Good": "Good",
"Fair": "Fair",
"Passable": "Passable",
"Insufficient": "Insufficient",
"To reject": "To reject",
"Dates": "Dates",
"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": "Preference profile",
"Results of the election:": "Results of the election:"
} }

@ -2,25 +2,25 @@
"Homepage": "Página de inicio", "Homepage": "Página de inicio",
"Source code": "Código fuente", "Source code": "Código fuente",
"Who are we": "Quiénes somos", "Who are we": "Quiénes somos",
"BetterVote": "Votar mejor", "BetterVote": "VotarMejor",
"Voting platform": "Plataforma de votación", "Voting platform": "Plataforma de votación",
"Majority Judgment": "Juicio Mayoritario", "Majority Judgment": "Juicio Mayoritario",
"Start an election": "Iniciar una elección", "Start an election": "Iniciar una elección",
"Candidate/proposal name...": "Nombre del(la) candidato(a)/propuesta", "Candidate/proposal name...": "Nombre del(la) candidato(a)/propuesta...",
"Delete?": "Borrar?", "Delete?": "Borrar?",
"Are you sure to delete": "Estás seguro de quierer borrar", "Are you sure to delete": "Estás seguro de quierer borrar",
"the row": "la fila", "the row": "la fila",
"Write here your question or introduce simple your election (250 characters max.)": "Escriba aquí su pregunta o introduzca simplemente su elección (250 caracteres máx.)", "Write here your question or introduce simple your election (250 characters max.)": "Escriba aquí su pregunta o introduzca simplemente su elección (250 caracteres máx.)",
"Please add at least 2 candidates.": "Por favor, añada al menos dos canidatos(as)", "Please add at least 2 candidates.": "Por favor, añada al menos dos canidatos(as).",
"Question of the election": "Pregunta de su elección", "Question of the election": "Pregunta de su elección",
"Write here the question of your election": "Escriba aquí la pregunta de su elección", "Write here the question of your election": "Escriba aquí la pregunta de su elección",
"For example:": "Por ejemplo", "For example:": "Por ejemplo:",
"For the role of my representative, I judge this candidate...": "Para ser mi representante, yo elijo a este(a) candidato(a)....", "For the role of my representative, I judge this candidate...": "Para ser mi representante, yo elijo a este(a) candidato(a)....",
"Candidates/Proposals": "Candidatos(as)/Propuestas", "Candidates/Proposals": "Candidatos(as)/Propuestas",
"Add a proposal": "Añadir una propuesta", "Add a proposal": "Añadir una propuesta",
"Advanced options": "Opciones avanzadas", "Advanced options": "Opciones avanzadas",
"Starting date:": "Fecha de inicio", "Starting date:": "Fecha de inicio:",
"Ending date: ": "Fecha de finalización", "Ending date: ": "Fecha de finalización: ",
"Grades:": "Escala", "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", "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", "5 = Excellent, Very good, Good, Fair, Passable": "5 == Excelente, Muy bien, Bien, Regular, Pasable",
@ -49,5 +49,22 @@
"Go back to homepage": "Vuelve a la página de inicio", "Go back to homepage": "Vuelve a la página de inicio",
"You have to judge every candidate/proposal!": "¡Tienes que evaluar a todos los(as) candidatos(as)/propuestas", "You have to judge every candidate/proposal!": "¡Tienes que evaluar a todos los(as) candidatos(as)/propuestas",
"Your participation was recorded with success!": "¡Su participación fue registrada con éxito!", "Your participation was recorded with success!": "¡Su participación fue registrada con éxito!",
"Thanks for your participation.": "Muchas gracias por participar" "Thanks for your participation.": "Muchas gracias por participar",
} "Ending date:": "Fecha de finalización:",
"Excellent": "Excelente",
"Very good": "Muy bien",
"Good": "Bien",
"Fair": "Regular",
"Passable": "Pasable",
"Insufficient": "Insuficiente",
"To reject": "Rechazar",
"Dates": "Fechas",
"The election will take place from": "La elección tendrá lugar de las",
"at": "a las",
"to": "hasta",
"Grades": "Escala",
"Voters' list": "Lista de votantes",
"Graph": "Gráfico",
"Preference profile": "Perfil de preferencia",
"Results of the election:": "Resultados de la elección"
}

@ -50,5 +50,21 @@
"Go back to homepage": "Revenir à la page d'accueil", "Go back to homepage": "Revenir à la page d'accueil",
"You have to judge every candidate/proposal!": "Vous devez évaluer tous les candidats/propositions !", "You have to judge every candidate/proposal!": "Vous devez évaluer tous les candidats/propositions !",
"Your participation was recorded with success!": "Votre participation a été enregistrée avec succès !", "Your participation was recorded with success!": "Votre participation a été enregistrée avec succès !",
"Thanks for your participation.": "Merci de votre participation." "Thanks for your participation.": "Merci de votre participation.",
"Excellent": "Excellent",
"Very good": "Très bien",
"Good": "Bien",
"Fair": "Assez bien",
"Passable": "Passable",
"Insufficient": "Insuffisant",
"To reject": "A rejeter",
"Dates": "Dates",
"The election will take place from": "Le vote se déroulera du",
"at": "à",
"to": "au",
"Grades": "Mentions",
"Voters' list": "Listes des électeurs",
"Graph": "Grahique",
"Preference profile": "Profil de mérites",
"Results of the election:": "Résultats de l'élection"
} }

@ -1,18 +1,12 @@
import React, {Suspense} from 'react'; import React, {Suspense} from 'react';
import {BrowserRouter as Router} from 'react-router-dom'; import {BrowserRouter as Router} from 'react-router-dom';
import 'react-loader-spinner/dist/loader/css/react-spinner-loader.css';
import Loader from './components/loader'; import Loader from './components/loader';
import Routes from './Routes'; import Routes from './Routes';
import Header from './components/layouts/Header'; import Header from './components/layouts/Header';
import Footer from './components/layouts/Footer'; import Footer from './components/layouts/Footer';
import AppContextProvider from './AppContext'; import AppContextProvider from './AppContext';
import {i18n} from './i18n';
// const Spinner = (
// <Loader type="Puff" color="#00BFFF" height={100} width={100} timeout={1000} />
// );
function App() { function App() {
return ( return (

@ -1,3 +1,5 @@
import i18n from './i18n.jsx';
const colors = [ const colors = [
"#015411", "#015411",
"#019812", "#019812",
@ -7,7 +9,25 @@ const colors = [
"#b20616", "#b20616",
"#6f0214" "#6f0214"
]; ];
export const grades = process.env.REACT_APP_GRADES.split(", ").map((e, i) => ({
label: e, const gradeNames = [
"Excellent",
"Very good",
"Good",
"Fair",
"Passable",
"Insufficient",
"To reject",
];
export const grades = gradeNames.map((name, i) => ({
label: name,
color: colors[i] color: colors[i]
})); }));
export const i18nGrades = () => {
return gradeNames.map((name, i) => ({
label: i18n.t(name),
color: colors[i]
}));
};

@ -36,7 +36,7 @@ import {
faCogs, faCogs,
} from '@fortawesome/free-solid-svg-icons'; } from '@fortawesome/free-solid-svg-icons';
import {grades} from '../../Util'; import {i18nGrades} from '../../Util';
import {ReactMultiEmail, isEmail} from 'react-multi-email'; import {ReactMultiEmail, isEmail} from 'react-multi-email';
import 'react-multi-email/style.css'; import 'react-multi-email/style.css';
import {AppContext} from '../../AppContext'; import {AppContext} from '../../AppContext';
@ -273,6 +273,8 @@ class CreateElection extends Component {
const {electorEmails} = this.state; const {electorEmails} = this.state;
const {t} = this.props; const {t} = this.props;
const grades = i18nGrades();
if (successCreate) return <Redirect to={redirectTo} />; if (successCreate) return <Redirect to={redirectTo} />;
return ( return (
@ -385,7 +387,7 @@ class CreateElection extends Component {
), ),
}) })
}> }>
{Array(22) {Array(24)
.fill(1) .fill(1)
.map((x, i) => ( .map((x, i) => (
<option value={i} key={i}> <option value={i} key={i}>
@ -428,7 +430,7 @@ class CreateElection extends Component {
), ),
}) })
}> }>
{Array(22) {Array(24)
.fill(1) .fill(1)
.map((x, i) => ( .map((x, i) => (
<option value={i} key={i}> <option value={i} key={i}>
@ -567,21 +569,20 @@ class CreateElection extends Component {
</ul> </ul>
</div> </div>
<div className="text-white bg-primary p-1 mt-1"> <div className="text-white bg-primary p-1 mt-1">
Dates {t("Dates")}
</div> </div>
<p className="p-1 pl-3"> <p className="p-1 pl-3">
Le vote se déroulera du{' '} {t("The election will take place from")}{' '}
<b> <b>
{this.state.start.toLocaleDateString()}, à{' '} {this.state.start.toLocaleDateString()}, {t("at")}{' '}
{this.state.start.toLocaleTimeString()} {this.state.start.toLocaleTimeString()}
</b>{' '} </b>{' '}{t("to")}{' '}
au{' '}
<b> <b>
{this.state.finish.toLocaleDateString()}, à{' '} {this.state.finish.toLocaleDateString()}, {t("at")}{' '}
{this.state.finish.toLocaleTimeString()} {this.state.finish.toLocaleTimeString()}
</b> </b>
</p> </p>
<div className="text-white bg-primary p-1">Mentions</div> <div className="text-white bg-primary p-1">{t("Grades")}</div>
<div className="p-1 pl-3"> <div className="p-1 pl-3">
{grades.map((mention, i) => { {grades.map((mention, i) => {
return i < this.state.numGrades ? ( return i < this.state.numGrades ? (
@ -600,7 +601,7 @@ class CreateElection extends Component {
})} })}
</div> </div>
<div className="text-white bg-primary p-1 mt-1"> <div className="text-white bg-primary p-1 mt-1">
Liste des électeurs {t("Voters' list")}
</div> </div>
<div className="p-1 pl-3"> <div className="p-1 pl-3">
{electorEmails.length > 0 ? ( {electorEmails.length > 0 ? (

@ -110,7 +110,7 @@ class CreateSuccess extends Component {
{t('Keep these links carefully')} {t('Keep these links carefully')}
</p> </p>
<p className="small m-2 p-0"> <p className="small m-2 p-0">
<Trans i18nKey={t}> <Trans i18nKey="t">
<b>Warning</b>: you will have no other choices to recover the <b>Warning</b>: you will have no other choices to recover the
links, and we will not be able to share them with you. For links, and we will not be able to share them with you. For
example, you can bookmark them in your browser. example, you can bookmark them in your browser.

@ -1,5 +1,6 @@
import React, { Component } from "react"; import React, { Component } from "react";
import { Redirect } from "react-router-dom"; import { Redirect } from "react-router-dom";
import { withTranslation } from "react-i18next";
import { resolve } from "url"; import { resolve } from "url";
import { import {
Container, Container,
@ -11,7 +12,7 @@ import {
CardBody, CardBody,
Table Table
} from "reactstrap"; } from "reactstrap";
import { grades } from "../../Util"; import { i18nGrades } from "../../Util";
import { AppContext } from "../../AppContext"; import { AppContext } from "../../AppContext";
class Result extends Component { class Result extends Component {
@ -32,7 +33,7 @@ class Result extends Component {
collapseGraphics: false, collapseGraphics: false,
collapseProfiles: false, collapseProfiles: false,
redirectLost: false, redirectLost: false,
electionGrades: grades electionGrades: i18nGrades()
}; };
} }
@ -89,7 +90,7 @@ class Result extends Component {
12 - colSizeGradeXs * numGrades > 0 12 - colSizeGradeXs * numGrades > 0
? 12 - colSizeGradeXs * numGrades ? 12 - colSizeGradeXs * numGrades
: 12, : 12,
electionGrades: grades.slice(0, numGrades) electionGrades: i18nGrades().slice(0, numGrades)
})); }));
return response; return response;
}; };
@ -167,6 +168,7 @@ class Result extends Component {
render() { render() {
const { redirectLost, candidates, electionGrades } = this.state; const { redirectLost, candidates, electionGrades } = this.state;
const { t } = this.props;
if (redirectLost) { if (redirectLost) {
return <Redirect to={redirectLost} />; return <Redirect to={redirectLost} />;
@ -191,7 +193,7 @@ class Result extends Component {
<Row className="mt-5"> <Row className="mt-5">
<Col> <Col>
<h1>Résultat du vote :</h1> <h1>{t("Results of the election:")}</h1>
<ol> <ol>
{candidates.map((candidate, i) => { {candidates.map((candidate, i) => {
return ( return (
@ -207,7 +209,7 @@ class Result extends Component {
color: "#fff" color: "#fff"
}} }}
> >
{grades[candidate.grade].label} {i18nGrades()[candidate.grade].label}
</span> </span>
</li> </li>
); );
@ -226,7 +228,7 @@ class Result extends Component {
(this.state.collapseGraphics ? "collapsed" : "") (this.state.collapseGraphics ? "collapsed" : "")
} }
> >
Graphique {t("Graph")}
</h4> </h4>
</CardHeader> </CardHeader>
<Collapse isOpen={this.state.collapseGraphics}> <Collapse isOpen={this.state.collapseGraphics}>
@ -327,7 +329,7 @@ class Result extends Component {
(this.state.collapseProfiles ? "collapsed" : "") (this.state.collapseProfiles ? "collapsed" : "")
} }
> >
Profils de mérites {t("Preference profile")}
</h4> </h4>
</CardHeader> </CardHeader>
<Collapse isOpen={this.state.collapseProfiles}> <Collapse isOpen={this.state.collapseProfiles}>
@ -393,4 +395,4 @@ class Result extends Component {
} }
} }
export default Result; export default withTranslation()(Result);

@ -6,7 +6,7 @@ import { toast, ToastContainer } from "react-toastify";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCheck } from "@fortawesome/free-solid-svg-icons"; import { faCheck } from "@fortawesome/free-solid-svg-icons";
import { resolve } from "url"; import { resolve } from "url";
import { grades } from "../../Util"; import { i18nGrades } from "../../Util";
import { AppContext } from "../../AppContext"; import { AppContext } from "../../AppContext";
class Vote extends Component { class Vote extends Component {
@ -25,7 +25,7 @@ class Vote extends Component {
colSizeGradeMd: 1, colSizeGradeMd: 1,
colSizeGradeXs: 1, colSizeGradeXs: 1,
redirectTo: null, redirectTo: null,
electionGrades: grades electionGrades: i18nGrades()
}; };
} }
@ -85,7 +85,7 @@ class Vote extends Component {
12 - colSizeGradeXs * numGrades > 0 12 - colSizeGradeXs * numGrades > 0
? 12 - colSizeGradeXs * numGrades ? 12 - colSizeGradeXs * numGrades
: 12, : 12,
electionGrades: grades.slice(0, numGrades) electionGrades: i18nGrades().slice(0, numGrades)
})); }));
return response; return response;
}; };

Loading…
Cancel
Save