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/pages/admin/[pid]/[tid].tsx

487 lines
16 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import {useState, useEffect} from 'react';
import Head from 'next/head';
import {useRouter} from 'next/router';
import {useTranslation} from 'next-i18next';
import {serverSideTranslations} from 'next-i18next/serverSideTranslations';
import {
Collapse,
Container,
Row,
Col,
Input,
Label,
InputGroup,
Button,
Card,
CardBody,
Modal,
ModalHeader,
ModalBody,
ModalFooter,
} from 'reactstrap';
import {GetStaticProps} from 'next';
import {getElection} from '@services/api';
import {getGradeColor} from '@services/grades';
import {ElectionContextInterface} from '@services/ElectionContext';
import {CandidateItem} from '@services/type';
// import {ReactMultiEmail, isEmail} from "react-multi-email";
// import "react-multi-email/style.css";
// import {toast, ToastContainer} from "react-toastify";
// import "react-toastify/dist/ReactToastify.css";
// import queryString from "query-string";
// import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
// import {
// faPlus,
// faTrashAlt,
// faCheck,
// faCogs,
// faExclamationTriangle,
// faArrowLeft,
// faExclamationCircle
// } from "@fortawesome/free-solid-svg-icons";
// import {useAppContext} from "@services/context";
// import {createElection} from "@services/api";
// import {translateGrades} from "@services/grades";
// import HelpButton from "@components/admin/HelpButton";
// import Loader from "@components/wait";
// import CandidatesField from "@components/admin/CandidatesField";
// import ConfirmModal from "@components/admin/ConfirmModal";
export async function getServerSideProps({query, locale}) {
const {pid, tid: token} = query;
const electionRef = pid.replaceAll("-", "");
const [payload, translations] = await Promise.all([
getElection(electionRef),
serverSideTranslations(locale, ["resource"]),
]);
if ("msg" in payload) {
return {props: {err: payload.msg, ...translations}};
}
const grades = payload.grades.map((g, i) => ({...g, active: true}));
const candidates: Array<CandidateItem> = payload.candidates.map(c => ({...c, active: true}))
const description = JSON.parse(payload.description)
const randomOrder = description["randomOrder"]
const context: ElectionContextInterface = {
name: payload.name,
description: description["description"],
ref: payload.ref,
dateStart: payload.date_start,
dateEnd: payload.date_end,
hideResults: payload.hide_results,
forceClose: payload.force_close,
restricted: payload.restricted,
randomOrder,
emails: [],
grades,
candidates
}
return {
props: {
context,
token: token || "",
...translations,
},
};
}
const CreateElection = ({context, token}) => {
const {t} = useTranslation();
// // default value : start at the last hour
// const now = new Date();
// const [title, setTitle] = useState("");
// const [candidates, setCandidates] = useState([{label: ""}, {description: ""}]);
// const [numGrades, setNumGrades] = useState(5);
// const [waiting, setWaiting] = useState(false);
// const [isAdvancedOptionsOpen, setAdvancedOptionsOpen] = useState(false);
// const [isAddCandidateMOpen, setAddCandidateMOpen] = useState(false);
// const [isTimeLimited, setTimeLimited] = useState(false);
// const [restrictResult, setRestrictResult] = useState(false);
// const [restrictVote, setRestrictVote] = useState(false);
// const [start, setStart] = useState(
// new Date(now.getTime() - minutes(now) - seconds(now) - ms(now))
// );
// const [finish, setFinish] = useState(
// new Date(start.getTime() + 7 * 24 * 3600 * 1000)
// );
// const [emails, setEmails] = useState([]);
// // set the title on loading
// const router = useRouter();
// useEffect(() => {
// if (!router.isReady) return;
// const {title: urlTitle} = router.query;
// setTitle(urlTitle || "");
// }, [router.isReady]);
// const handleIsTimeLimited = (event) => {
// setTimeLimited(event.target.value === "1");
// };
// const handleRestrictResultCheck = (event) => {
// setRestrictResult(event.target.value === "1");
// };
// const handleRestrictVote = (event) => {
// setRestrictVote(event.target.value === "1");
// };
// const toggleAdvancedOptions = () => {
// setAdvancedOptionsOpen(!isAdvancedOptionsOpen);
// };
// const toggleAddCandidateM = () => {
// setAddCandidateMOpen(!isAddCandidateMOpen);
// };
// const addCandidate = () => {
// if (candidates.length < 1000) {
// candidates.push({label: ""});
// setCandidates(candidates);
// }
// };
// const checkFields = () => {
// if (!candidates) {
// return {ok: false, msg: AT_LEAST_2_CANDIDATES_ERROR};
// }
// let numCandidates = 0;
// candidates.forEach((c) => {
// if (c.label !== "") numCandidates += 1;
// });
// if (numCandidates < 2) {
// return {ok: false, msg: AT_LEAST_2_CANDIDATES_ERROR};
// }
// if (!title || title === "") {
// return {ok: false, msg: NO_TITLE_ERROR};
// }
// return {ok: true, msg: "OK"};
// };
// const handleSubmit = () => {
// const check = checkFields();
// if (!check.ok) {
// toast.error(t(check.msg), {
// position: toast.POSITION.TOP_CENTER,
// });
// return;
// }
// setWaiting(true);
// createElection(
// title,
// candidates.map((c) => c.label).filter((c) => c !== ""),
// {
// mails: emails,
// numGrades,
// start: start.getTime() / 1000,
// finish: finish.getTime() / 1000,
// restrictResult: restrictResult,
// restrictVote: restrictVote,
// locale: router.locale.substring(0, 2).toLowerCase(),
// },
// (result) => {
// if (result.id) {
// router.push(`/new/confirm/${result.id}`);
// } else {
// toast.error(t("Unknown error. Try again please."), {
// position: toast.POSITION.TOP_CENTER,
// });
// setWaiting(false);
// }
// }
// );
// };
// const [visibled, setVisibility] = useState(false);
// const toggle = () => setVisibility(!visibled)
// const handleSendNotReady = (msg) => {
// toast.error(t(msg), {
// position: toast.POSITION.TOP_CENTER,
// });
// };
// const check = checkFields();
// const grades = translateGrades(t);
const [showModal, setShowModal] = useState(false);
return <p>FOO</p>;
};
// <Container className="addCandidatePage">
// <Head>
// <meta
// key="og:title"
// property="og:title"
// content={t("common.application")}
// />
// <meta
// property="og:description"
// key="og:description"
// content={t("resource.valueProp")}
// />
// </Head>
// <ToastContainer />
// {waiting ? <Loader /> : ""}
// <form onSubmit={handleSubmit} autoComplete="off">
// <Row className="stepForm">
// <Col className="stepFormCol">
// <img src="/icone-one-white.svg" />
// <h4>Les candidats</h4>
// </Col>
// <Col className="stepFormCol">
// <img src="/icone-two-dark.svg" />
// <h4>Paramètres du vote</h4>
// </Col>
// <Col className="stepFormCol">
// <img src="/icone-three-dark.svg" />
// <h4>Confirmation</h4>
//
// </Col>
// </Row>
//
// <div className="settings-modal-body">
// <Row>
// <Col xs="10" lg="10">
// <Label for="title">{t("Access to results")} {t("Immediately")}</Label>
// <p>{t("No one will be able to see the result until the end date is reached or until all participants have voted.")}</p>
// </Col>
// <Col l xs="2" lg="2">
// <CustomInput
// type="switch"
// id="restrict_result_false"
// name={handleRestrictResultCheck}
// />
// </Col>
// </Row>
// <hr className="mt-2 mb-2" />
// <Row>
// <Col md="10">
// <Label for="title">{t("Voting time")}</Label>
// </Col>
// <Col l md="2">
// <CustomInput
// type="switch"
// id="is_time_limited_true"
// name={handleIsTimeLimited}
// value={"1"}
// />
// </Col>
// </Row>
// <div
// className={
// (isTimeLimited ? "d-block " : "d-none") + " bg-light p-3"
// }
// >
// <Row>
// <Col xs="12" md="3" lg="3">
// <span className="label">- {t("Starting date")}</span>
// </Col>
// <Col xs="6" md="4" lg="3">
// <input
// className="form-control"
// type="date"
// value={dateToISO(start)}
// onChange={(e) => {
// setStart(
// new Date(
// timeMinusDate(start) +
// new Date(e.target.valueAsNumber).getTime()
// )
// );
// }}
// />
// </Col>
// <Col xs="6" md="5" lg="3">
// <select
// className="form-control"
// value={getOnlyValidDate(start).getHours()}
// onChange={(e) =>
// setStart(
// new Date(
// dateMinusTime(start).getTime() +
// e.target.value * 3600000
// )
// )
// }
// >
// {displayClockOptions()}
// </select>
// </Col>
// </Row>
//
// <Row className="mt-2">
// <Col xs="12" md="3" lg="3">
// <span className="label">- {t("Ending date")}</span>
// </Col>
// <Col xs="6" md="4" lg="3">
// <input
// className="form-control"
// type="date"
// value={dateToISO(finish)}
// min={dateToISO(start)}
// onChange={(e) => {
// setFinish(
// new Date(
// timeMinusDate(finish) +
// new Date(e.target.valueAsNumber).getTime()
// )
// );
// }}
// />
// </Col>
// <Col xs="6" md="5" lg="3">
// <select
// className="form-control"
// value={getOnlyValidDate(finish).getHours()}
// onChange={(e) =>
// setFinish(
// new Date(
// dateMinusTime(finish).getTime() +
// e.target.value * 3600000
// )
// )
// }
// >
// {displayClockOptions()}
// </select>
// </Col>
// </Row>
// </div>
// <hr className="mt-2 mb-2" />
// <Row>
// <Col xs="9">
// <Label>{t("Grades")}</Label>
// <p>{t("You can select here the number of grades for your election")}</p>
// </Col>
// <Col xs="3">
// <div className="numGradesContainer justify-content-end" tabIndex={candidates.length + 3}
// onChange={(e) => setNumGrades(e.target.value)}>
// <Label className="numGrades">
// <Input type="radio" name="radio" value="5" />
// <div className="customCheckmarck numGradeFive"></div>
// </Label>
// <Label className="numGrades">
// <Input type="radio" checked="checked" name="radio" value="6" />
// <div className="customCheckmarck numGradeSix"></div>
// </Label>
// <Label className="numGrades">
// <Input type="radio" name="radio" value="7" />
// <div className="customCheckmarck numGradeSeven"></div>
// </Label>
// </div>
// </Col>
// <Col
// xs="12"
// md="9"
// lg="9"
// >
// {grades.map((mention, i) => {
// return (
// <span
// key={i}
// className="badge badge-light mt-2 "
// style={{
// backgroundColor: mention.color,
// color: "#fff",
// opacity: i < numGrades ? 1 : 0.3,
// }}
// >
// {mention.label}
// </span>
// );
// })}
// </Col>
// </Row>
// <hr className="mt-2 mb-2" />
// <Row>
// <Col xs="10" lg="10">
// <Label for="title">{t("Vote privée")}</Label>
// <p>{t("Uniquement les personnes invités par mail pourront participé au vote")}</p>
// </Col>
// <Col l xs="2" lg="2">
// <CustomInput
// type="switch"
// id="restrict_vote_false"
// name={handleRestrictVote}
// />
// </Col>
// </Row>
// <hr className="mt-2 mb-2" />
// <Row>
// <Col xs="12">
// <Label>{t("Participants")}</Label>
// <p>{t("If you list voters' emails, only them will be able to access the election")}</p>
// <ReactMultiEmail
// placeholder={t("Add here participants' emails")}
// emails={emails}
// onChange={setEmails}
// validateEmail={(email) => {
// return isEmail(email); // return boolean
// }}
// getLabel={(email, index, removeEmail) => {
// return (
// <div data-tag key={index}>
// {email}
// <span
// data-tag-handle
// onClick={() => removeEmail(index)}
// >
// ×
// </span>
// </div>
// );
// }}
// />
// <div className="mt-2 mailMutedText">
// <small className="text-muted">
// <FontAwesomeIcon icon={faExclamationCircle} />
// {t("Copier-coller les emails des participants depuis un fichier Excel")}
// </small>
// </div>
// </Col>
// </Row>
// <hr className="mt-2 mb-2" />
// <Col xs="12" md="3">
//
// </Col>
// </div>
// <div className="justify-content-center">
// {check.ok ? (
// <ConfirmModal
// title={title}
// candidates={candidates}
// isTimeLimited={isTimeLimited}
// start={start}
// finish={finish}
// emails={emails}
// restrictResult={restrictResult}
// restrictVote={restrictVote}
// grades={grades.slice(0, numGrades)}
// className={"btn float-right btn-block"}
// tabIndex={candidates.length + 1}
// confirmCallback={handleSubmit}
// />
// ) : (
//
// <Button onClick={toggle} className="cursorPointer btn-validation mb-5" >{t("Confirm")}<img src="/arrow-white.svg" /></Button>
//
// )}
// </div></form>
//
//
// </Container >
// );
// };
export default CreateElection;