|
|
|
@ -1,31 +1,30 @@
|
|
|
|
|
import { useState } from "react";
|
|
|
|
|
import {useState} from "react";
|
|
|
|
|
import Head from "next/head";
|
|
|
|
|
import { useRouter } from "next/router";
|
|
|
|
|
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
|
|
|
|
|
import { useTranslation } from "next-i18next";
|
|
|
|
|
import { Button, Col, Container, Row } from "reactstrap";
|
|
|
|
|
import { toast, ToastContainer } from "react-toastify";
|
|
|
|
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
|
|
|
import { faCheck } from "@fortawesome/free-solid-svg-icons";
|
|
|
|
|
import { getDetails, castBallot, apiErrors } from "@services/api";
|
|
|
|
|
import {useRouter} from "next/router";
|
|
|
|
|
import {serverSideTranslations} from "next-i18next/serverSideTranslations";
|
|
|
|
|
import {useTranslation} from "next-i18next";
|
|
|
|
|
import {Button, Col, Container, Row} from "reactstrap";
|
|
|
|
|
import {toast, ToastContainer} from "react-toastify";
|
|
|
|
|
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
|
|
|
|
import {faCheck} from "@fortawesome/free-solid-svg-icons";
|
|
|
|
|
import {getDetails, castBallot, apiErrors} from "@services/api";
|
|
|
|
|
import Error from "@components/Error";
|
|
|
|
|
import { translateGrades } from "@services/grades";
|
|
|
|
|
import config from "../../../next-i18next.config.js";
|
|
|
|
|
import {translateGrades} from "@services/grades";
|
|
|
|
|
|
|
|
|
|
const shuffle = (array) => array.sort(() => Math.random() - 0.5);
|
|
|
|
|
|
|
|
|
|
export async function getServerSideProps({ query: { pid, tid }, locale }) {
|
|
|
|
|
export async function getServerSideProps({query: {pid, tid}, locale}) {
|
|
|
|
|
const [details, translations] = await Promise.all([
|
|
|
|
|
getDetails(pid),
|
|
|
|
|
serverSideTranslations(locale, [], config),
|
|
|
|
|
serverSideTranslations(locale, ["resource", "common", "locale"]),
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
if (typeof details === "string" || details instanceof String) {
|
|
|
|
|
return { props: { err: details, ...translations } };
|
|
|
|
|
return {props: {err: details, ...translations}};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!details.candidates || !Array.isArray(details.candidates)) {
|
|
|
|
|
return { props: { err: "Unknown error", ...translations } };
|
|
|
|
|
return {props: {err: "Unknown error", ...translations}};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
shuffle(details.candidates);
|
|
|
|
@ -35,7 +34,7 @@ export async function getServerSideProps({ query: { pid, tid }, locale }) {
|
|
|
|
|
...translations,
|
|
|
|
|
invitationOnly: details.on_invitation_only,
|
|
|
|
|
restrictResults: details.restrict_results,
|
|
|
|
|
candidates: details.candidates.map((name, i) => ({ id: i, label: name })),
|
|
|
|
|
candidates: details.candidates.map((name, i) => ({id: i, label: name})),
|
|
|
|
|
title: details.title,
|
|
|
|
|
numGrades: details.num_grades,
|
|
|
|
|
pid: pid,
|
|
|
|
@ -44,8 +43,8 @@ export async function getServerSideProps({ query: { pid, tid }, locale }) {
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const VoteBallot = ({ candidates, title, numGrades, pid, err, token }) => {
|
|
|
|
|
const { t } = useTranslation();
|
|
|
|
|
const VoteBallot = ({candidates, title, numGrades, pid, err, token}) => {
|
|
|
|
|
const {t} = useTranslation();
|
|
|
|
|
|
|
|
|
|
if (err) {
|
|
|
|
|
return <Error value={apiErrors(err, t)}></Error>;
|
|
|
|
@ -138,11 +137,11 @@ const VoteBallot = ({ candidates, title, numGrades, pid, err, token }) => {
|
|
|
|
|
lg={colSizeGradeLg}
|
|
|
|
|
key={gradeId}
|
|
|
|
|
className="text-center p-0"
|
|
|
|
|
style={{ lineHeight: 2 }}
|
|
|
|
|
style={{lineHeight: 2}}
|
|
|
|
|
>
|
|
|
|
|
<small
|
|
|
|
|
className="nowrap bold badge"
|
|
|
|
|
style={{ backgroundColor: grade.color, color: "#fff" }}
|
|
|
|
|
style={{backgroundColor: grade.color, color: "#fff"}}
|
|
|
|
|
>
|
|
|
|
|
{grade.label}
|
|
|
|
|
</small>
|
|
|
|
@ -180,7 +179,7 @@ const VoteBallot = ({ candidates, title, numGrades, pid, err, token }) => {
|
|
|
|
|
className="check"
|
|
|
|
|
>
|
|
|
|
|
<small
|
|
|
|
|
className="nowrap d-lg-none ml-2 bold badge"
|
|
|
|
|
className="nowrap d-lg-none ms-2 bold badge"
|
|
|
|
|
style={
|
|
|
|
|
judgments.find((judgment) => {
|
|
|
|
|
return (
|
|
|
|
@ -191,11 +190,11 @@ const VoteBallot = ({ candidates, title, numGrades, pid, err, token }) => {
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
})
|
|
|
|
|
? { backgroundColor: grade.color, color: "#fff" }
|
|
|
|
|
? {backgroundColor: grade.color, color: "#fff"}
|
|
|
|
|
: {
|
|
|
|
|
backgroundColor: "transparent",
|
|
|
|
|
color: "#000",
|
|
|
|
|
}
|
|
|
|
|
backgroundColor: "transparent",
|
|
|
|
|
color: "#000",
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
{grade.label}
|
|
|
|
@ -230,11 +229,11 @@ const VoteBallot = ({ candidates, title, numGrades, pid, err, token }) => {
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
})
|
|
|
|
|
? { backgroundColor: grade.color, color: "#fff" }
|
|
|
|
|
? {backgroundColor: grade.color, color: "#fff"}
|
|
|
|
|
: {
|
|
|
|
|
backgroundColor: "transparent",
|
|
|
|
|
color: "#000",
|
|
|
|
|
}
|
|
|
|
|
backgroundColor: "transparent",
|
|
|
|
|
color: "#000",
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/>
|
|
|
|
|
</label>
|
|
|
|
@ -253,12 +252,12 @@ const VoteBallot = ({ candidates, title, numGrades, pid, err, token }) => {
|
|
|
|
|
onClick={handleSubmitWithoutAllRate}
|
|
|
|
|
className="btn btn-dark "
|
|
|
|
|
>
|
|
|
|
|
<FontAwesomeIcon icon={faCheck} className="mr-2" />
|
|
|
|
|
<FontAwesomeIcon icon={faCheck} className="me-2" />
|
|
|
|
|
{t("Submit my vote")}
|
|
|
|
|
</Button>
|
|
|
|
|
) : (
|
|
|
|
|
<Button type="submit" className="btn btn-success ">
|
|
|
|
|
<FontAwesomeIcon icon={faCheck} className="mr-2" />
|
|
|
|
|
<FontAwesomeIcon icon={faCheck} className="me-2" />
|
|
|
|
|
{t("Submit my vote")}
|
|
|
|
|
</Button>
|
|
|
|
|
)}
|
|
|
|
|