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.
mvfront-react/services/api.js

229 lines
5.5 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 { id, title, mails, tokens, locale } = res;
if (!mails || !mails.length) {
throw new Error("No emails are provided.");
}
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, token) => new URL(`/vote/${pid}/${token}`, origin);
const urlResult = (pid) => new URL(`/result/${pid}`, origin);
const recipientVariables = {};
tokens.forEach((token, index) => {
recipientVariables[mails[index]] = {
urlVote: urlVote(id, token),
urlResult: urlResult(id),
};
});
const req = fetch("/.netlify/functions/send-invite-email/", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
recipientVariables,
title,
locale,
}),
});
return req.then((any) => res);
};
const createElection = (
title,
candidates,
{
/**
* Create an election from its title, its candidates and a bunch of options
*/
mails,
numGrades,
start,
finish,
restrictResult,
locale,
},
successCallback,
failureCallback
) => {
const endpoint = new URL(api.routesServer.setElection, api.urlServer);
console.log(endpoint.href);
const onInvitationOnly = mails && mails.length > 0;
fetch(endpoint.href, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title,
candidates,
on_invitation_only: onInvitationOnly,
num_grades: numGrades,
elector_emails: mails || [],
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) => {
if (onInvitationOnly) {
return sendInviteMail({ locale, mails: mails, ...res });
}
return res;
})
.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(failureCallback || ((err) => err));
};
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 || ((err) => err))
.then((res) => res);
};
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("error.e1");
}
if (error.includes(ONGOING_ELECTION_ERROR)) {
return t("error.e2");
}
if (error.includes(NO_VOTE_ERROR)) {
return t("error.e3");
}
if (error.includes(ELECTION_NOT_STARTED_ERROR)) {
return t("error.e4");
}
if (error.includes(ELECTION_FINISHED_ERROR)) {
return t("error.e5");
}
if (error.includes(INVITATION_ONLY_ERROR)) {
return t("error.e6");
}
if (error.includes(USED_TOKEN_ERROR)) {
return t("error.e7");
}
if (error.includes(WRONG_ELECTION_ERROR)) {
return t("error.e8");
} else {
return t("error.catch22");
}
};
export {
api,
getDetails,
getResults,
createElection,
sendInviteMail,
castBallot,
};