You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
225 lines
5.7 KiB
225 lines
5.7 KiB
const api = {
|
|
urlServer:
|
|
process.env.NEXT_PUBLIC_SERVER_URL || "https://demo.mieuxvoter.fr/api/",
|
|
feedbackForm:
|
|
process.env.NEXT_PUBLIC_FEEDBACK_FORM ||
|
|
"https://docs.google.com/forms/d/e/1FAIpQLScuTsYeBXOSJAGSE_AFraFV7T2arEYua7UCM4NRBSCQQfRB6A/viewform",
|
|
routesServer: {
|
|
setElection: "election/",
|
|
getElection: "election/get/:slug/",
|
|
getResults: "election/results/:slug",
|
|
voteElection: "election/vote/",
|
|
},
|
|
};
|
|
|
|
const sendInviteMail = (res) => {
|
|
/**
|
|
* Send an invitation mail using a micro-service with Netlify
|
|
*/
|
|
const { title, mails, tokens, locale } = res;
|
|
|
|
if (mails.length !== tokens.length) {
|
|
throw new Error("The number of emails differ from the number of tokens");
|
|
}
|
|
|
|
const origin =
|
|
typeof window !== "undefined" && window.location.origin
|
|
? window.location.origin
|
|
: "http://localhost";
|
|
const urlVote = (pid) => new URL(`/vote/${pid}`, origin);
|
|
const urlResult = (pid) => new URL(`/result/${pid}`, origin);
|
|
|
|
const recipientVariables = {};
|
|
tokens.forEach((token, index) => {
|
|
recipientVariables[mails[index]] = {
|
|
urlVote: urlVote(token),
|
|
urlResult: urlResult(token),
|
|
};
|
|
});
|
|
|
|
const req = fetch("/.netlify/functions/send-invite-email/", {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({
|
|
recipientVariables,
|
|
title,
|
|
locale,
|
|
}),
|
|
});
|
|
|
|
return Promise.all([
|
|
new Promise((resolve, reject) => {
|
|
resolve(res);
|
|
}),
|
|
req,
|
|
]);
|
|
};
|
|
|
|
const createElection = (
|
|
title,
|
|
candidates,
|
|
{
|
|
/**
|
|
* Create an election from its title, its candidates and a bunch of options
|
|
*/
|
|
emails,
|
|
numGrades,
|
|
start,
|
|
finish,
|
|
restrictResult,
|
|
locale,
|
|
},
|
|
successCallback,
|
|
failureCallback
|
|
) => {
|
|
const endpoint = new URL(api.routesServer.setElection, api.urlServer);
|
|
|
|
console.log(endpoint.href);
|
|
|
|
fetch(endpoint.href, {
|
|
method: "POST",
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
},
|
|
body: JSON.stringify({
|
|
title,
|
|
candidates,
|
|
on_invitation_only: emails.length > 0,
|
|
num_grades: numGrades,
|
|
elector_emails: emails || [],
|
|
start_at: start,
|
|
finish_at: finish,
|
|
select_language: locale || "en",
|
|
front_url: window.location.origin,
|
|
restrict_results: restrictResult,
|
|
send_mail: false,
|
|
}),
|
|
})
|
|
.then((response) => {
|
|
if (!response.ok) {
|
|
throw Error(response.statusText);
|
|
}
|
|
return response.json();
|
|
})
|
|
.then((res) => sendInviteMail({ locale, mails: emails || [], ...res }))
|
|
.then((res) => res[0]) // remove response from mail invitations
|
|
.then(successCallback)
|
|
.catch(failureCallback || console.log);
|
|
};
|
|
|
|
const getResults = (pid, successCallback, failureCallback) => {
|
|
/**
|
|
* Fetch results from external API
|
|
*/
|
|
|
|
const endpoint = new URL(
|
|
api.routesServer.getResults.replace(new RegExp(":slug", "g"), pid),
|
|
api.urlServer
|
|
);
|
|
|
|
return fetch(endpoint.href)
|
|
.then((response) => {
|
|
if (!response.ok) {
|
|
return Promise.reject(response.text());
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(successCallback || ((res) => res))
|
|
.catch((err) => err)
|
|
.then(failureCallback || console.log);
|
|
};
|
|
|
|
const getDetails = (pid, successCallback, failureCallback) => {
|
|
/**
|
|
* Fetch data from external API
|
|
*/
|
|
|
|
const detailsEndpoint = new URL(
|
|
api.routesServer.getElection.replace(new RegExp(":slug", "g"), pid),
|
|
api.urlServer
|
|
);
|
|
return fetch(detailsEndpoint.href)
|
|
.then((response) => {
|
|
if (!response.ok) {
|
|
return Promise.reject(response.text());
|
|
}
|
|
return response.json();
|
|
})
|
|
.then(successCallback || ((res) => res))
|
|
.catch(failureCallback || console.log);
|
|
};
|
|
|
|
const castBallot = (judgments, pid, token, callbackSuccess, callbackError) => {
|
|
/**
|
|
* Save a ballot on the remote database
|
|
*/
|
|
|
|
const endpoint = new URL(api.routesServer.voteElection, api.urlServer);
|
|
|
|
const payload = {
|
|
election: pid,
|
|
grades_by_candidate: judgments,
|
|
};
|
|
if (token && token !== "") {
|
|
payload["token"] = token;
|
|
}
|
|
|
|
fetch(endpoint.href, {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify(payload),
|
|
})
|
|
.then(callbackSuccess || ((res) => res))
|
|
.catch(callbackError || console.log);
|
|
};
|
|
|
|
export const UNKNOWN_ELECTION_ERROR = "E1:";
|
|
export const ONGOING_ELECTION_ERROR = "E2:";
|
|
export const NO_VOTE_ERROR = "E3:";
|
|
export const ELECTION_NOT_STARTED_ERROR = "E4:";
|
|
export const ELECTION_FINISHED_ERROR = "E5:";
|
|
export const INVITATION_ONLY_ERROR = "E6:";
|
|
export const UNKNOWN_TOKEN_ERROR = "E7:";
|
|
export const USED_TOKEN_ERROR = "E8:";
|
|
export const WRONG_ELECTION_ERROR = "E9:";
|
|
|
|
export const apiErrors = (error, t) => {
|
|
if (error.includes(UNKNOWN_ELECTION_ERROR)) {
|
|
return t("Oops... The election is unknown.");
|
|
}
|
|
if (error.includes(ONGOING_ELECTION_ERROR)) {
|
|
return t(
|
|
"The election is still going on. You can't access now to the results."
|
|
);
|
|
}
|
|
if (error.includes(NO_VOTE_ERROR)) {
|
|
return t("No votes have been recorded yet. Come back later.");
|
|
}
|
|
if (error.includes(ELECTION_NOT_STARTED_ERROR)) {
|
|
return t("The election has not started yet.");
|
|
}
|
|
if (error.includes(ELECTION_FINISHED_ERROR)) {
|
|
return t("The election is over. You can't vote anymore");
|
|
}
|
|
if (error.includes(INVITATION_ONLY_ERROR)) {
|
|
return t("You need a token to vote in this election");
|
|
}
|
|
if (error.includes(USED_TOKEN_ERROR)) {
|
|
return t("You seem to have already voted.");
|
|
}
|
|
if (error.includes(WRONG_ELECTION_ERROR)) {
|
|
return t("The parameters of the election are incorrect.");
|
|
}
|
|
};
|
|
|
|
export {
|
|
api,
|
|
getDetails,
|
|
getResults,
|
|
createElection,
|
|
sendInviteMail,
|
|
castBallot,
|
|
};
|