diff --git a/components/WaitingBallot.tsx b/components/WaitingBallot.tsx index c448b6f..a03130d 100644 --- a/components/WaitingBallot.tsx +++ b/components/WaitingBallot.tsx @@ -53,7 +53,7 @@ const InfoElection = ({election, error, display}: InfoElectionInterface) => { {t('admin.success-election')} - {election && election.private ? + {election && election.restricted ?
{t('admin.success-emails')}
diff --git a/components/admin/AdminModalEmail.tsx b/components/admin/AdminModalEmail.tsx index 488f2ba..103256f 100644 --- a/components/admin/AdminModalEmail.tsx +++ b/components/admin/AdminModalEmail.tsx @@ -28,7 +28,9 @@ const AdminModalEmail = ({isOpen, toggle, electionId, adminToken}: AdminModalEma } const handleSubmit = () => { + console.log(election); sendAdminMail(email, election.name, adminUrl); + toggle(); }; const disabled = !email || !validateMail(email); @@ -52,10 +54,11 @@ const AdminModalEmail = ({isOpen, toggle, electionId, adminToken}: AdminModalEma

{t('admin.modal-desc')}

-

{t('admin.modal-disclaimer')}

+

{t('admin.modal-email')}

+

{t('admin.modal-disclaimer')}

{ const {t} = useTranslation(); + const submitReference = useRef(null); const election = useElection(); const dispatch = useElectionDispatch(); @@ -28,6 +29,20 @@ const CandidatesField = ({onSubmit}) => { } }, [candidates]); + useEffect(() => { + if (!disabled && submitReference.current) { + submitReference.current.focus(); + } + }, [disabled, submitReference]); + + + const handleKeyPress = (e: KeyboardEvent) => { + console.log(e.key) + if (e.key == "Enter" && !disabled) { + onSubmit(); + } + } + return (
@@ -51,10 +66,12 @@ const CandidatesField = ({onSubmit}) => { outline={true} color="secondary" className="bg-blue" + ref={submitReference} onClick={onSubmit} disabled={disabled} icon={faArrowRight} position="right" + onKeyPress={handleKeyPress} > {t('admin.candidates-submit')} diff --git a/components/admin/ConfirmField.tsx b/components/admin/ConfirmField.tsx index a0ef748..a22c06e 100644 --- a/components/admin/ConfirmField.tsx +++ b/components/admin/ConfirmField.tsx @@ -1,5 +1,6 @@ import {useState} from 'react' import {useTranslation} from 'next-i18next'; +import {NextRouter, useRouter} from 'next/router'; import { faPen, faArrowRight, @@ -71,6 +72,7 @@ const submitElection = ( election: ElectionContextInterface, successCallback: Function, failureCallback: Function, + router: NextRouter, ) => { const candidates = election.candidates.filter(c => c.active).map((c: CandidateItem) => ({name: c.name, description: c.description, image: c.image})) const grades = election.grades.filter(c => c.active).map((g: GradeItem, i: number) => ({name: g.name, value: i})) @@ -87,18 +89,19 @@ const submitElection = ( election.randomOrder, async (payload: ElectionPayload) => { const id = payload.id; - const tokens = payload.tokens; + const tokens = payload.invites; if (typeof election.emails !== 'undefined' && election.emails.length > 0) { - if (typeof payload.tokens === 'undefined' || payload.tokens.length === election.emails.length) { + if (typeof payload.invites === 'undefined' || payload.invites.length !== election.emails.length) { throw Error('Can not send invite emails'); } - const urlVotes = payload.tokens.map((token: string) => getUrlVote(id.toString(), token)); + const urlVotes = payload.invites.map((token: string) => getUrlVote(id.toString(), token)); const urlResult = getUrlResults(id.toString()); await sendInviteMails( election.emails, election.name, urlVotes, urlResult, + router, ); } successCallback(payload); @@ -111,12 +114,13 @@ const submitElection = ( const ConfirmField = ({onSubmit, onSuccess, onFailure, goToCandidates, goToParams}) => { const {t} = useTranslation(); const election = useElection(); + const router = useRouter(); const handleSubmit = () => { onSubmit(); - submitElection(election, onSuccess, onFailure); + submitElection(election, onSuccess, onFailure, router); } const numCandidates = election.candidates.filter(c => c.active && c.name != "").length; diff --git a/components/layouts/LanguageSelector.tsx b/components/layouts/LanguageSelector.tsx index e5678b7..a9d1da7 100644 --- a/components/layouts/LanguageSelector.tsx +++ b/components/layouts/LanguageSelector.tsx @@ -5,7 +5,7 @@ import {getLocaleShort} from '@services/utils'; const LanguageSelector = (props) => { const router = useRouter(); - const localeShort = getLocaleShort(); + const localeShort = getLocaleShort(router); const selectHandler = (e) => { let locale = e.toLowerCase(); diff --git a/functions/send-emails/index.ts b/functions/send-emails/index.ts index 416dc39..50f7c4d 100644 --- a/functions/send-emails/index.ts +++ b/functions/send-emails/index.ts @@ -15,7 +15,6 @@ const { FROM_EMAIL_ADDRESS, REPLY_TO_EMAIL_ADDRESS, } = process.env; -console.log("MAILGUN URL", MAILGUN_URL) const mailgun = new Mailgun(formData); const mg = mailgun.client({ @@ -25,7 +24,6 @@ const mg = mailgun.client({ }); -console.log("I18N config", i18n) i18next.init(i18n, (err, t) => { if (err) return console.log('something went wrong loading', err); t("foo"); @@ -34,8 +32,6 @@ i18next.init(i18n, (err, t) => { Handlebars.registerHelper('i18n', (str: string): string => { - console.log("I18N", str) - console.log("I18Next", i18next, i18next.t) return (i18next != undefined ? i18next.t(str) : str); } ); @@ -60,6 +56,7 @@ const handler: Handler = async (event) => { }; } + console.log("EVENT BODY", event.body) const {recipients, action, locale} = JSON.parse(event.body) as RequestPayload; if (!recipients) { diff --git a/public/locales/en/resource.json b/public/locales/en/resource.json index fc01533..af5433e 100644 --- a/public/locales/en/resource.json +++ b/public/locales/en/resource.json @@ -70,11 +70,12 @@ "admin.candidates-submit": "Validate the candidates", "admin.candidates-back-step": "Back to candidates", "admin.modal-title": "Managing an election", - "admin.modal-desc": "This link allows you to modify your election. Keep it carefully, or fill out this form to receive a copy by mail.", + "admin.modal-desc": "This link allows you to modify your election. Keep it carefully, as it will not be provided to you again.", + "admin.modal-email": "To receive a copy of this link by email, fill out this form.", "admin.modal-disclaimer": "We do not store any mail. Thus, we will not send you any advertising content.", "admin.modal-email-placeholder": "Your mail address", "admin.order-title": "Random order", - "admin.order-desc": "To avoid cognitive bias, we recommend that candidates appear in random order on the ballot.", + "admin.order-desc": "To avoid any cognitive bias, we recommend that candidates appear in random order on the ballot.", "admin.params-submit": "Validate the parameters", "admin.params-title": "Your parameters", "admin.access-results": "Immediate access to the results", diff --git a/public/locales/fr/resource.json b/public/locales/fr/resource.json index c513a20..2d4edf2 100644 --- a/public/locales/fr/resource.json +++ b/public/locales/fr/resource.json @@ -76,8 +76,9 @@ "admin.limit-duration": "Limiter la durée du vote", "admin.limit-duration-desc": "", "admin.modal-title": "Administration du vote", - "admin.modal-desc": "Ce lien vous permet de modifier votre vote. Conservez le précieusement, ou remplissez votre adresse email ci-dessous pour en recevoir une copie", - "admin.modal-disclaimer": "Nous ne stockons aucun email. Nous ne vous enverrons donc aucun contenu publicitaire.", + "admin.modal-desc": "Ce lien vous permet de modifier votre vote. Conservez le précieusement, ca il ne vous sera pas transmis une seconde fois.", + "admin.modal-email": "Pour recevoir une copie par courriel, indiquez nous votre adresse courrielle", + "admin.modal-disclaimer": "Nous ne stockons aucune adresse courrielle. Nous ne vous enverrons donc aucun contenu publicitaire.", "admin.modal-email-placeholder": "Votre adresse email", "admin.photo": "Photo", "admin.optional": "facultatif", diff --git a/services/api.ts b/services/api.ts index 39580c8..164269c 100644 --- a/services/api.ts +++ b/services/api.ts @@ -34,7 +34,7 @@ export const createElection = async ( const endpoint = new URL(api.routesServer.setElection, api.urlServer); if (!restricted && numVoters > 0) { - throw Error("Set the election as not private!"); + throw Error("Set the election as not restricted!"); } try { @@ -45,13 +45,16 @@ export const createElection = async ( }, body: JSON.stringify({ name, - description, + description: JSON.stringify({ + description: description, + randomOrder: randomOrder + }), candidates, grades, + num_voters: numVoters, hide_results: hideResults, force_close: forceClose, - random_order: randomOrder, - private: restricted, + restricted, }), }) if (req.ok && req.status === 200) { @@ -227,11 +230,11 @@ export interface ElectionPayload { date_end: string; hide_results: boolean; force_close: boolean; - private: boolean; + restricted: boolean; id: number; grades: Array; candidates: Array; - tokens: Array; + invites: Array; admin: string; } diff --git a/services/mail.ts b/services/mail.ts index 9027127..e1a5e96 100644 --- a/services/mail.ts +++ b/services/mail.ts @@ -1,3 +1,4 @@ +import {NextRouter} from 'next/router'; import {getLocaleShort} from './utils'; export const sendInviteMails = async ( @@ -5,6 +6,7 @@ export const sendInviteMails = async ( name: string, urlVotes: Array, urlResult: string | URL, + router: NextRouter, ) => { /** @@ -26,7 +28,7 @@ export const sendInviteMails = async ( }; }); - const locale = getLocaleShort(); + const locale = getLocaleShort(router); const req = await fetch('/.netlify/functions/send-emails', { method: 'POST', @@ -57,7 +59,7 @@ export const sendAdminMail = async ( throw new Error('Incorrect format for the email'); } - const req = await fetch('/.netlify/functions/send-emails/', { + const req = await fetch('/.netlify/functions/send-emails', { method: 'POST', headers: { 'Content-Type': 'application/json', diff --git a/services/utils.ts b/services/utils.ts index 2035042..9e9010a 100644 --- a/services/utils.ts +++ b/services/utils.ts @@ -2,11 +2,9 @@ * This file contains several utils functions */ -import {useRouter} from 'next/router'; - -export const getLocaleShort = (): string => { - const router = useRouter(); +import {NextRouter} from 'next/router'; +export const getLocaleShort = (router: NextRouter): string => { if (!router.locale) { return router.defaultLocale.substring(0, 2).toUpperCase(); } diff --git a/tests/netlify-send-emails.sh b/tests/netlify-send-emails.sh index 97b7191..7553596 100755 --- a/tests/netlify-send-emails.sh +++ b/tests/netlify-send-emails.sh @@ -2,13 +2,15 @@ # This file tests the netlify function for sending emails # Check if the port is already used or not -is_using=$(lsof -i:9999 | awk -F ' ' '{ print $1 }') +port=${1:-9999} + +is_using=$(lsof -i:$port | awk -F ' ' '{ print $1 }') if [ -z "$is_using" ]; then - echo "Starting a server on port 9999"; - netlify functions:serve --port 9999 & + echo "Starting a server on port $port"; + netlify functions:serve --port $port & elif ! [[ "$is_using" =~ .*"node".* ]]; then echo "$is_using" - echo "The port 9999 is already used and not by us :-(" + echo "The port $port is already used and not by us :-(" exit 1; else echo "The server is running." @@ -18,7 +20,7 @@ fi SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) send_emails () { - res=$(netlify functions:invoke --port 9999 send-emails --payload "$(cat $1)") + res=$(netlify functions:invoke --port $port send-emails --payload "$(cat $1)") echo "$res" # status=$(echo "$res" | head -n 1 | cut -d ',' -f 1 | cut -d ':' -f 2) status=$(echo "$res" | jq '.["status"]')