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/components/WaitingElection.tsx

212 lines
5.8 KiB

import Image from 'next/image';
import { useTranslation } from 'next-i18next';
import { CSSProperties, useEffect, useState } from 'react';
import { faArrowRight } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import Button from '@components/Button';
import ButtonCopy from '@components/ButtonCopy';
import Share from '@components/Share';
import ErrorMessage from '@components/Error';
import AdminModalEmail from '@components/admin/AdminModalEmail';
import { ElectionCreatedPayload, ErrorPayload } from '@services/api';
import { AppTypes, useAppContext } from '@services/context';
import { getUrlVote, getUrlResults } from '@services/routes';
import urne from '../public/urne.svg';
import star from '../public/star.svg';
import { Container } from 'reactstrap';
export interface WaitingBallotInterface {
election?: ElectionCreatedPayload;
error?: ErrorPayload;
}
interface InfoElectionInterface extends WaitingBallotInterface {
display: string;
}
const InfoElection = ({ election, error, display }: InfoElectionInterface) => {
const { t } = useTranslation();
const [modal, setModal] = useState(false);
const toggleModal = () => setModal((m) => !m);
if (!election) return null;
const urlVote = getUrlVote(election.ref);
const urlResults = getUrlResults(election.ref);
return (
<div
style={{
display: display,
transition: 'display 2s',
}}
>
<div className="d-flex flex-column align-items-center">
{error && error.detail ? (
<ErrorMessage>{error.detail[0].msg}</ErrorMessage>
) : null}
{election && election.ref ? (
<>
<h4 className="text-center">{t('admin.success-election')}</h4>
{election && election.restricted ? (
<h5 className="text-center">{t('admin.success-emails')}</h5>
) : (
<div className="d-grid w-100">
<ButtonCopy
text={t('admin.success-copy-vote')}
content={urlVote}
/>
<ButtonCopy
text={t('admin.success-copy-result')}
content={urlResults}
/>
</div>
)}
<div className="d-grid w-100">
<Button
customIcon={<FontAwesomeIcon icon={faArrowRight} />}
position="right"
color="secondary"
outline={true}
onClick={toggleModal}
className="mt-3 py-3 px-4"
>
{t('admin.go-to-admin')}
</Button>
</div>
<Share title={t('common.share-short')} />
<AdminModalEmail
toggle={toggleModal}
isOpen={modal}
electionRef={election.ref}
adminToken={election.admin}
/>
</>
) : null}
</div>
</div>
);
};
export default ({ election, error }: WaitingBallotInterface) => {
const [_, dispatch] = useAppContext();
const [urneProperties, setUrne] = useState<CSSProperties>({
width: 0,
height: 0,
marginBottom: 0,
});
const [starProperties, setStar] = useState<CSSProperties>({
width: 0,
height: 0,
marginLeft: 100,
marginBottom: 0,
});
const [urneContainerProperties, setUrneContainer] = useState<CSSProperties>({
height: '100vh',
});
const [electionProperties, setElection] = useState<CSSProperties>({
display: 'none',
});
useEffect(() => {
dispatch({ type: AppTypes.FULLPAGE, value: true });
setUrne((urne) => ({
...urne,
width: 300,
height: 300,
}));
const timer = setTimeout(() => {
setStar((star) => ({
...star,
width: 150,
height: 150,
marginLeft: 150,
marginBottom: 300,
}));
}, 1000);
const timer2 = setTimeout(() => {
// setElection({display: "block"});
setUrneContainer((urneContainer) => ({
...urneContainer,
height: '50vh',
}));
setStar((star) => ({
...star,
width: 100,
height: 100,
marginLeft: 100,
marginBottom: 200,
}));
setUrne((urne) => ({
...urne,
width: 200,
height: 200,
}));
}, 3000);
const timer3 = setTimeout(() => {
setElection({ display: 'grid' });
}, 4500);
return () => {
clearTimeout(timer);
clearTimeout(timer2);
clearTimeout(timer3);
};
}, []);
return (
<Container
className="d-flex h-100 w-100 align-items-center flex-column"
style={{
maxWidth: '400px',
}}
>
<div
style={{
transition: 'width 2s, height 2s',
height: urneContainerProperties.height,
}}
className="d-flex align-items-center"
>
<div
className="position-relative"
style={{
transition: 'width 2s, height 2s, margin-bottom 2s',
zIndex: 2,
marginTop: urneProperties.marginBottom,
height: urneProperties.height,
width: urneProperties.width,
}}
>
<Image src={urne} alt="urne" fill={true} />
</div>
<div
className="position-absolute"
style={{
transition: 'width 2s, height 2s, margin-left 2s, margin-bottom 2s',
marginLeft: starProperties.marginLeft,
marginBottom: starProperties.marginBottom,
height: starProperties.height,
width: starProperties.width,
}}
>
<Image src={star} fill={true} alt="urne" />
</div>
</div>
<InfoElection
election={election}
error={error}
display={electionProperties.display}
/>
</Container>
);
};