fix: minor issues

pull/89/head
Pierre-Louis Guhur 1 year ago
parent 58dfd1eee0
commit 7055245ecd

@ -1,31 +1,34 @@
import {Container} from 'reactstrap';
import {useTranslation} from 'next-i18next';
import {CONTACT_MAIL} from '@services/constants';
import Button from '@components/Button'
import {faEnvelope} from '@fortawesome/free-solid-svg-icons';
import { Container } from 'reactstrap';
import { useTranslation } from 'next-i18next';
import { CONTACT_MAIL } from '@services/constants';
import Button from '@components/Button';
import { faEnvelope } from '@fortawesome/free-solid-svg-icons';
const Error = ({msg}) => {
const {t} = useTranslation();
if (!msg) return null;
const Error = ({ children }) => {
const { t } = useTranslation();
if (!children) return null;
return (
<Container className="full-height-container">
<h4>{t("common.error")}</h4>
<div className="text-black text-center shadow-lg border-dark border border-2 p-3 my-3 bg-white">{msg}</div>
<div className="flex-fill d-flex align-items-center bg-secondary pt-3 pb-5">
<Container style={{ maxWidth: '700px' }} className="mb-5 ">
<h4>{t('common.error')}</h4>
<p>{children}</p>
<a
href={`mailto:${CONTACT_MAIL}?subject=[HELP]`}
className="d-grid"
>
<Button
color="secondary"
outline={true}
className="text-white"
icon={faEnvelope}>
{t('error.help')}
</Button>
</a >
</Container >
<a
href={`mailto:${CONTACT_MAIL}?subject=[HELP]`}
className="d-md-flex d-grid"
>
<Button
color="secondary"
outline={true}
className="text-white"
icon={faEnvelope}
>
{t('error.help')}
</Button>
</a>
</Container>
</div>
);
};

@ -18,7 +18,6 @@ const Experiencediv = () => {
/>
</div>
<div className="d-md-block d-none vote_background"></div>
<h3>{t('home.experience-name')}</h3>
<Container className="my-5">
<Row className="sectionTwodivTwodiv mb-5">

@ -1,20 +1,20 @@
import Image from 'next/image';
import {useTranslation} from 'next-i18next';
import {CSSProperties, useEffect, useState} from 'react';
import {faArrowRight} from '@fortawesome/free-solid-svg-icons';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import {Col, Container, Row} from 'reactstrap';
import { useTranslation } from 'next-i18next';
import { CSSProperties, useEffect, useState } from 'react';
import { faArrowRight } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Col, Container, Row } from 'reactstrap';
import Button from '@components/Button';
import ButtonCopy from '@components/ButtonCopy';
import Share from '@components/Share';
import ErrorMessage from '@components/Error';
import AdminModalEmail from '@components/admin/AdminModalEmail';
import {BallotPayload, ErrorPayload} from '@services/api';
import {AppTypes, useAppContext} from '@services/context';
import {displayRef, isEnded} from '@services/utils';
import {RESULTS} from '@services/routes';
import { BallotPayload, ErrorPayload } from '@services/api';
import { AppTypes, useAppContext } from '@services/context';
import { displayRef, isEnded } from '@services/utils';
import { RESULTS } from '@services/routes';
import Logo from './Logo';
import {FORM_FEEDBACK, MAJORITY_JUDGMENT_LINK} from '@services/constants';
import { FORM_FEEDBACK, MAJORITY_JUDGMENT_LINK } from '@services/constants';
import urne from '../public/urne.svg';
import star from '../public/star.svg';
import logo from '../public/logo-red-blue.svg';
@ -25,8 +25,8 @@ export interface WaitingBallotInterface {
error?: ErrorPayload;
}
const ButtonResults = ({election}) => {
const {t} = useTranslation();
const ButtonResults = ({ election }) => {
const { t } = useTranslation();
if (!election.hideResults || isEnded(election.date_end)) {
return (
@ -42,14 +42,18 @@ const ButtonResults = ({election}) => {
};
const DiscoverMajorityJudgment = () => {
const {t} = useTranslation();
const { t } = useTranslation();
return (
<Col className="d-flex flex-column justify-content-between bg-secondary p-4 text-white">
<div>
<h5>{t('vote.discover-mj')}</h5>
<p>{t('vote.discover-mj-desc')}</p>
</div>
<a href={MAJORITY_JUDGMENT_LINK} target="_blank" rel="noopener noreferrer">
<a
href={MAJORITY_JUDGMENT_LINK}
target="_blank"
rel="noopener noreferrer"
>
<div className="d-flex align-items-center">
<div className="me-2">{t('common.about')}</div>
<FontAwesomeIcon icon={faArrowRight} />
@ -60,7 +64,7 @@ const DiscoverMajorityJudgment = () => {
};
const SupportBetterVote = () => {
const {t} = useTranslation();
const { t } = useTranslation();
return (
<Col className="d-flex flex-column justify-content-between text-secondary p-4 bg-white">
<div>
@ -81,7 +85,7 @@ const SupportBetterVote = () => {
};
const Thanks = () => {
const {t} = useTranslation();
const { t } = useTranslation();
return (
<>
<h5>{t('vote.thanks')}</h5>
@ -99,13 +103,13 @@ interface InfoInterface extends WaitingBallotInterface {
display: string;
}
const Info = ({ballot, error, display}: InfoInterface) => {
const {t} = useTranslation();
const Info = ({ ballot, error, display }: InfoInterface) => {
const { t } = useTranslation();
if (!ballot) return null;
if (error) {
return <ErrorMessage msg={error.detail[0].msg} />;
return <ErrorMessage>{error.detail[0].msg}</ErrorMessage>;
}
return (
@ -132,7 +136,7 @@ const Info = ({ballot, error, display}: InfoInterface) => {
);
};
export default ({ballot, error}: WaitingBallotInterface) => {
export default ({ ballot, error }: WaitingBallotInterface) => {
const [_, dispatch] = useAppContext();
const [urneProperties, setUrne] = useState<CSSProperties>({
@ -154,7 +158,7 @@ export default ({ballot, error}: WaitingBallotInterface) => {
});
useEffect(() => {
dispatch({type: AppTypes.FULLPAGE, value: true});
dispatch({ type: AppTypes.FULLPAGE, value: true });
setUrne((urne) => ({
...urne,
@ -193,7 +197,7 @@ export default ({ballot, error}: WaitingBallotInterface) => {
}, 3000);
const timer3 = setTimeout(() => {
setBallot({display: 'grid'});
setBallot({ display: 'grid' });
}, 4500);
return () => {

@ -44,7 +44,7 @@ const InfoElection = ({ election, error, display }: InfoElectionInterface) => {
>
<div className="d-flex flex-column align-items-center">
{error && error.detail ? (
<ErrorMessage msg={error.detail[0].msg} />
<ErrorMessage>{error.detail[0].msg}</ErrorMessage>
) : null}
{election && election.ref ? (

@ -1,7 +1,6 @@
import {useRouter} from 'next/router';
import { useRouter } from 'next/router';
import ReactFlagsSelect from 'react-flags-select';
import {getLocaleShort} from '@services/utils';
import { getLocaleShort } from '@services/utils';
const LanguageSelector = (props) => {
const router = useRouter();
@ -10,7 +9,9 @@ const LanguageSelector = (props) => {
const selectHandler = (e) => {
let locale = e.toLowerCase();
if (locale === 'gb') locale = 'en';
router.push('', '', {locale});
const { pathname, asPath, query } = router;
// change just the locale and maintain all other route information including href's query
router.push({ pathname, query }, asPath, { locale });
};
return (
@ -20,8 +21,8 @@ const LanguageSelector = (props) => {
// ["GB", "FR", "ES", "DE", "RU"]
['GB', 'FR']
}
selected={localeShort == "en" ? "GB" : localeShort.toUpperCase()}
customLabels={{GB: 'English', FR: 'Francais'}}
selected={localeShort == 'en' ? 'GB' : localeShort.toUpperCase()}
customLabels={{ GB: 'English', FR: 'Francais' }}
{...props}
className="menu-flags"
/>

@ -1,37 +1,37 @@
import Link from 'next/link'
import {useTranslation} from 'next-i18next';
import {serverSideTranslations} from 'next-i18next/serverSideTranslations';
import {faArrowRight} from '@fortawesome/free-solid-svg-icons';
import {Container} from 'reactstrap';
import Link from 'next/link';
import { useTranslation } from 'next-i18next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
import { faArrowRight } from '@fortawesome/free-solid-svg-icons';
import { Container } from 'reactstrap';
import ErrorMessage from '@components/Error';
import {RESULTS} from '@services/routes'
import {displayRef} from '@services/utils'
import Blur from '@components/Blur'
import { RESULTS } from '@services/routes';
import { displayRef } from '@services/utils';
import Blur from '@components/Blur';
import Button from '@components/Button';
export const getServerSideProps = async ({query: {pid, tid}, locale}) => {
export const getServerSideProps = async ({ query: { pid, tid }, locale }) => {
return {
props: {
...(await serverSideTranslations(locale, ['resource'])),
token: tid,
electionRef: pid.replaceAll("-", "")
electionRef: pid.replaceAll('-', ''),
},
}
}
};
};
const End = ({electionRef, token}) => {
const {t} = useTranslation();
const End = ({ electionRef, token }) => {
const { t } = useTranslation();
return (
<>
<Blur />
<div className="w-100 h-100 d-flex flex-column justify-content-center align-items-center">
<ErrorMessage msg={t('error.ended-election')} />
<ErrorMessage>{t('error.ended-election')}</ErrorMessage>
<Container className="full-height-container">
<Link
className="d-grid w-100 mt-5"
href={`${RESULTS}/${displayRef(electionRef)}/${token ? token : ""}`}>
href={`${RESULTS}/${displayRef(electionRef)}/${token ? token : ''}`}
>
<Button
color="secondary"
outline={true}
@ -39,7 +39,8 @@ const End = ({electionRef, token}) => {
icon={faArrowRight}
position="right"
>
{t('vote.go-to-results')}</Button>
{t('vote.go-to-results')}
</Button>
</Link>
</Container>
</div>

@ -3,18 +3,11 @@ import Head from 'next/head';
import Image from 'next/image';
import { useTranslation } from 'next-i18next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
import { useRouter } from 'next/router';
import Link from 'next/link';
import {
Container,
Collapse,
Card,
CardHeader,
CardBody,
Button,
} from 'reactstrap';
import { Container, Collapse, Card, CardHeader, CardBody } from 'reactstrap';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
faArrowRight,
faChevronDown,
faChevronRight,
faChevronUp,
@ -24,6 +17,7 @@ import ErrorMessage from '@components/Error';
import CSVLink from '@components/CSVLink';
import Logo from '@components/Logo';
import MeritProfile from '@components/MeritProfile';
import Button from '@components/Button';
import { getResults } from '@services/api';
import {
GradeResultInterface,
@ -31,7 +25,7 @@ import {
MeritProfileInterface,
CandidateResultInterface,
} from '@services/type';
import { getUrlAdmin, RESULTS } from '@services/routes';
import { getUrlAdmin, getUrlVote, RESULTS } from '@services/routes';
import { displayRef } from '@services/utils';
import { getMajorityGrade } from '@services/majorityJudgment';
import avatarBlue from '../../../public/avatarBlue.svg';
@ -50,7 +44,7 @@ export async function getServerSideProps({ query, locale }) {
]);
if ('msg' in payload) {
return { props: { err: payload.msg, ...translations } };
return { props: { err: payload.msg, electionRef, ...translations } };
}
const numGrades = payload.grades.length;
@ -473,18 +467,37 @@ interface ResultPageInterface {
result?: ResultInterface;
token?: string;
err?: ErrorInterface;
electionRef?: string;
}
const ResultPage = ({ result, token, err }: ResultPageInterface) => {
const ResultPage = ({
result,
token,
err,
electionRef,
}: ResultPageInterface) => {
const { t } = useTranslation();
const router = useRouter();
if (err && err.message !== '') {
return <ErrorMessage msg={err.message} />;
if (err && err.message.startsWith('No votes')) {
const urlVote = getUrlVote(electionRef, token);
return (
<ErrorMessage>
{
<>
<p>{t('result.no-votes')}</p>
<Link href={urlVote}>
<Button color="primary" icon={faArrowRight} position="right">
{t('result.go-to-vote')}
</Button>
</Link>
</>
}
</ErrorMessage>
);
}
if (!result) {
return <ErrorMessage msg="error.catch22" />;
return <ErrorMessage>{t('error.catch22')}</ErrorMessage>;
}
if (

@ -65,7 +65,7 @@ const GoToBallotConfirmDesktop = ({ electionRef, token }) => {
</Row>
<Row>
<Link href="https://mieuxvoter.fr/le-jugement-majoritaire">
<Button className="btn-black mt-2 mb-5">
<Button color="black" outline={true} className="mt-2 mb-5">
{t('common.about-mj')}
</Button>
</Link>

@ -167,6 +167,8 @@
"admin.go-to-result": "View results",
"result.download": "Download results",
"result.go-to-admin": "Manage the election",
"result.go-to-vote": "Would you go to the voting page?",
"result.no-votes": "No vote has been recorded yet.",
"result.merit-profile": "Merit profile of the candidate",
"result.has-closed": "Closed since",
"result.opened": "The election is opened",

@ -168,6 +168,8 @@
"admin.go-to-result": "Voir les résultats",
"result.download": "Télécharger les résultats",
"result.go-to-admin": "Administrer le vote",
"result.go-to-vote": "Souhaitez-vous accéder au vote ?",
"result.no-votes": "Aucun vote n'a encore été enregistré.",
"result.has-closed": "Terminée depuis",
"result.closed": "L'élection est terminée",
"result.opened": "L'élection est en cours",

@ -17,6 +17,9 @@
border-style: solid;
border-radius: 0px;
}
.btn:hover {
color: #afafaf;
}
*[class*='btn-outline-'] {
box-shadow: 0px 4px 0px;
border-width: 2px;
@ -67,7 +70,7 @@
.btn-outline-secondary:hover {
background-color: white!important;
border-color: $mv-blue-color;
color: $mv-blue-color;
color: $mv-blue-color!important;
}
.btn.btn-danger:hover {
color: map.get($theme-colors, 'danger');

@ -50,6 +50,8 @@ $font-sizes: (
6: $font-size-base * 0.75,
);
$hover-color: white;
@import '_bootstrap.scss';
@import 'app.scss';
@import '_button.scss';

Loading…
Cancel
Save