fix: clean up responsive

pull/89/head
Pierre-Louis Guhur 1 year ago
parent 4e9ebd7df2
commit a1c1d47a0e

@ -1,3 +1,4 @@
import { isValidElement } from 'react';
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Row, Col, Button } from 'reactstrap';
@ -5,33 +6,35 @@ import { Row, Col, Button } from 'reactstrap';
interface ButtonProps {
children?: React.ReactNode;
icon?: IconProp;
customIcon?: JSX.Element;
position?: 'left' | 'right';
[props: string]: any;
}
const ButtonWithIcon = ({
icon,
customIcon,
children,
position = 'left',
...props
}: ButtonProps) => {
if (icon && position === 'left') {
if ((icon || customIcon) && position === 'left') {
return (
<Button {...props}>
<Row className="gx-2 align-items-end">
<Col className="col-auto">
<FontAwesomeIcon icon={icon} />
{customIcon ? customIcon : <FontAwesomeIcon icon={icon} />}
</Col>
<Col className="col-auto">{children}</Col>
</Row>
</Button>
);
} else if (icon && position === 'right') {
} else if ((icon || customIcon) && position === 'right') {
return (
<Button {...props}>
<Row className="gx-2 align-items-end">
<Col className="col-auto">{children}</Col>
<Col className="col-auto">
<FontAwesomeIcon icon={icon} />
{customIcon ? customIcon : <FontAwesomeIcon icon={icon} />}
</Col>
</Row>
</Button>

@ -41,7 +41,7 @@ const CopyField = (props) => {
className="btn btn-success"
type="button"
>
<FontAwesomeIcon icon={iconOpen} className="mr-2" />
<FontAwesomeIcon icon={iconOpen} />
{t("Go")}
</Button> */}
@ -54,7 +54,7 @@ const CopyField = (props) => {
type="button"
>
{text}
<FontAwesomeIcon icon={iconCopy} className="ml-2" />
<FontAwesomeIcon icon={iconCopy} />
</Button>
</div>
<UncontrolledTooltip placement="top" target="tooltip" trigger="click">

@ -6,18 +6,17 @@ import { faArrowLeft, faCheck } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
const { Row, Col, Container } = require('reactstrap');
const Step = ({ name, position, active, check, onClick }) => {
const DesktopStep = ({ name, position, active, checked, onClick }) => {
const { t } = useTranslation();
const disabled = !active && !check;
const disabled = !active && !checked ? ' disabled' : '';
const activeClass = active ? 'bg-white text-primary' : 'bg-secondary';
return (
<Col className="col-auto" role={onClick ? 'button' : ''} onClick={onClick}>
<Row
className={`align-items-center creation-step ${
active ? 'active' : ''
} ${disabled ? 'disabled' : ''}`}
>
<Col className="col-auto badge align-items-center justify-content-center d-flex">
<div>{check ? <FontAwesomeIcon icon={faCheck} /> : position}</div>
<Row className={`align-items-center creation-step ${disabled} `}>
<Col
className={`${activeClass} creation-step-icon desktop_step col-auto align-items-center justify-content-center d-flex`}
>
{checked ? <FontAwesomeIcon icon={faCheck} /> : position}
</Col>
<Col className="col-auto name">{t(`admin.step-${name}`)}</Col>
</Row>
@ -25,6 +24,20 @@ const Step = ({ name, position, active, check, onClick }) => {
);
};
const MobileStep = ({ position, active, checked, onClick }) => {
const disabled = !active && !checked ? ' bg-secondary disabled' : '';
const activeClass = active ? 'bg-white text-primary' : 'bg-secondary';
return (
<div
className={`${disabled} ${activeClass} mobile_step align-items-center justify-content-center d-flex me-2 fw-bold`}
role={onClick ? 'button' : ''}
onClick={onClick}
>
{checked ? <FontAwesomeIcon icon={faCheck} /> : position}
</div>
);
};
export const creationSteps = ['candidate', 'params', 'confirm'];
interface GoToStep {
@ -56,26 +69,28 @@ export const ProgressSteps = ({
const gotosteps = [goToCandidates, goToParams];
return (
<Row className={`w-100 m-5 d-flex ${className}`} {...props}>
<Col className="col-lg-3 col-6 mb-3">
<Row className={`w-100 ms-2 mt-4 m-md-5 d-flex ${className}`} {...props}>
<Col className="col-lg-3 col-8 mb-3 d-none d-md-block">
{step === 'candidate' ? null : (
<Row className="gx-2 align-items-end">
<Row
role="button"
onClick={goToCandidates}
className="gx-2 align-items-end"
>
<Col className="col-auto">
<FontAwesomeIcon icon={faArrowLeft} />
</Col>
<Col role="button" onClick={goToCandidates} className="col-auto">
{t('admin.candidates-back-step')}
</Col>
<Col className="col-auto">{t('admin.candidates-back-step')}</Col>
</Row>
)}
</Col>
<Col className="col-lg-6 col-12">
<Row className="w-100 gx-5 justify-content-center">
<Col className="d-none d-md-block col-lg-6 col-12">
<Row className="w-100 gx-4 gx-md-5 justify-content-center">
{creationSteps.map((name, i) => (
<Step
<DesktopStep
name={name}
active={step === name}
check={i < stepId}
checked={i < stepId}
key={i}
position={i + 1}
onClick={gotosteps[i]}
@ -83,6 +98,17 @@ export const ProgressSteps = ({
))}
</Row>
</Col>
<Col className="d-block d-md-none col-lg-6 col-12 d-flex">
{creationSteps.map((name, i) => (
<MobileStep
active={step === name}
checked={i < stepId}
key={i}
position={i + 1}
onClick={gotosteps[i]}
/>
))}
</Col>
<Col className="col-3"></Col>
</Row>
);

@ -15,34 +15,37 @@ interface InputProps {
}
export type ButtonRef = HTMLButtonElement;
const CustomDatePicker = ({ date, setDate }) => {
const CustomDatePicker = ({ date, setDate, className = '', ...props }) => {
const { t } = useTranslation();
const ExampleCustomInput = forwardRef<ButtonRef, InputProps>(
({ value, onClick }, ref) => (
<button onClick={onClick} ref={ref}>
<Row className="p-2 align-items-end">
<Col className="col-auto me-auto">
<Row className="gx-3 align-items-end">
<Col className="col-auto">
<FontAwesomeIcon icon={faCalendarDays} />
</Col>
<Col className="col-auto">
{t('admin.until')} {new Date(value).toDateString()}
</Col>
</Row>
</Col>
<Col className="col-auto">
<FontAwesomeIcon className="text-muted" icon={faChevronDown} />
</Col>
</Row>
</button>
<div className="d-grid">
<button onClick={onClick} ref={ref}>
<Row className="p-2 align-items-end">
<Col className="col-auto me-auto">
<Row className="gx-3 align-items-end">
<Col className="col-auto">
<FontAwesomeIcon icon={faCalendarDays} />
</Col>
<Col className="col-auto">
{t('admin.until')} {new Date(value).toDateString()}
</Col>
</Row>
</Col>
<Col className="col-auto">
<FontAwesomeIcon className="text-muted" icon={faChevronDown} />
</Col>
</Row>
</button>
</div>
)
);
return (
<DatePicker
selected={date}
className={className}
customInput={<ExampleCustomInput value={null} onClick={null} />}
onChange={(date) => setDate(date)}
/>

@ -9,7 +9,7 @@ const Error = ({ msg }) => {
<Container className="full-height-container">
<Row>
<Link href="/">
<a className="d-block ml-auto mr-auto mb-4">
<a className="d-block mx-auto mb-4">
<img src="/logos/logo.svg" alt="logo" height="128" />
</a>
</Link>

@ -8,7 +8,7 @@ import Button from '@components/Button';
const InputField = ({ value, onDelete }) => {
return (
<Button
icon={faXmark}
customIcon={<FontAwesomeIcon icon={faXmark} onClick={onDelete} />}
className="bg-light text-primary border-0"
outline={true}
style={{ boxShadow: 'unset' }}
@ -24,7 +24,9 @@ const ListInput = ({ onEdit, inputs, validator }) => {
const { t } = useTranslation();
const handleDelete = (position: number) => {
onEdit({ ...inputs }.splice(position));
const inputCopy = [...inputs];
inputCopy.splice(position, 1);
onEdit(inputCopy);
};
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {

@ -1,6 +1,6 @@
const Switch = ({ toggle, state }) => {
const Switch = ({ toggle, state, className = '' }) => {
return (
<div className="form-check form-switch">
<div className={`${className} form-check form-switch`}>
<input
onChange={toggle}
className="form-check-input"

@ -18,17 +18,24 @@ const AccessResults = () => {
};
return (
<Container className="bg-white container-fluid p-4">
<Row>
<Col className="col-auto me-auto">
<h4 className="text-dark">{t('admin.access-results')}</h4>
<p className="text-muted">{t('admin.access-results-desc')}</p>
</Col>
<Col className="col-auto d-flex align-items-center">
<>
<Container className="bg-white p-3 p-md-4">
<div className="d-flex">
<div className="me-auto">
<h4 className="text-dark mb-0">{t('admin.access-results')}</h4>
<p className="text-muted d-none d-md-block">
{t('admin.access-results-desc')}
</p>
</div>
<Switch toggle={toggle} state={election.restrictResult} />
</Col>
</Row>
</Container>
</div>
</Container>
{election.restrictResult ? (
<Container className="text-white d-md-none p-3">
{t('admin.access-results-desc')}
</Container>
) : null}
</>
);
};

@ -14,8 +14,8 @@ const ButtonWithConfirm = ({ className, label, onDelete }) => {
<div className="input-group-append cancelButton">
<button type="button" className={'btn ' + className} onClick={toggle}>
<div className="annuler">
<img className="ml-0" src="/arrow-dark-left.svg" />
<p className="ml-0">Annuler</p>
<img src="/arrow-dark-left.svg" />
<p>Annuler</p>
</div>
</button>
<Modal
@ -44,7 +44,7 @@ const ButtonWithConfirm = ({ className, label, onDelete }) => {
onDelete();
}}
>
<FontAwesomeIcon icon={faTrashAlt} className="mr-2" />
<FontAwesomeIcon icon={faTrashAlt} />
{t('Yes')}
</Button>
</ModalFooter>

@ -43,16 +43,16 @@ const CandidateField = ({
const toggleSet = () => setModalSet((m) => !m);
const toggleDel = () => setModalDel((m) => !m);
const activeClass = active
? 'bg-white text-secondary'
: 'border border-dashed border-2 border-light border-opacity-25';
return (
<Row
className={`${
className || ''
} p-2 my-3 border border-dashed border-2 border-light border-opacity-25 align-items-center ${
active ? 'active' : ''
}`}
className={`${activeClass} align-items-center ${className}`}
{...props}
>
<Col onClick={toggleSet} className="cursor-pointer col-10 me-auto">
<Col onClick={toggleSet} role="button" className="col-10 me-auto">
<Row className="gx-3">
<Col className="col-2 justify-content-start align-items-center d-flex">
<Image
@ -74,6 +74,7 @@ const CandidateField = ({
{active ? (
<FontAwesomeIcon
icon={faTrashCan}
className="text-warning"
onClick={() => setModalDel((m) => !m)}
/>
) : (

@ -44,28 +44,20 @@ const CandidateModal = ({ isOpen, position, toggle }) => {
{candidate.name ? (
<h4 className="text-center">{candidate.name}</h4>
) : null}
<Row className="mt-5 mb-3">
<Col className="col-auto me-auto">
<Button
onClick={toggle}
color="dark"
icon={faArrowLeft}
outline={true}
>
{t('admin.candidate-confirm-back')}
</Button>
</Col>
<Col className="col-auto ">
<Button
icon={faTrashAlt}
outline={true}
color="primary"
onClick={removeCandidate}
>
{t('admin.candidate-confirm-ok')}
</Button>
</Col>
</Row>
<div className="mt-5 gap-2 d-grid mb-3 d-md-flex">
<Button
onClick={toggle}
color="dark"
icon={faArrowLeft}
outline={true}
className="me-md-auto"
>
{t('admin.candidate-confirm-back')}
</Button>
<Button icon={faTrashAlt} color="danger" onClick={removeCandidate}>
{t('admin.candidate-confirm-ok')}
</Button>
</div>
</ModalBody>
</Modal>
);

@ -141,28 +141,20 @@ const CandidateModal = ({ isOpen, position, toggle }) => {
// maxLength="250"
/>
</div>
<Row className="mt-5 mb-3">
<Col className="col-auto me-auto">
<Button
onClick={toggle}
color="dark"
outline={true}
icon={faArrowLeft}
>
{t('common.cancel')}
</Button>
</Col>
<Col className="col-auto ">
<Button
outline={true}
color="primary"
onClick={save}
icon={faPlus}
>
{t('common.save')}
</Button>
</Col>
</Row>
<div className="mt-5 gap-2 d-grid mb-3 d-md-flex">
<Button
onClick={toggle}
color="dark"
className="me-md-auto"
outline={true}
icon={faArrowLeft}
>
{t('common.cancel')}
</Button>
<Button color="primary" onClick={save} icon={faPlus}>
{t('common.save')}
</Button>
</div>
</Form>
</Col>
</ModalBody>

@ -29,18 +29,28 @@ const CandidatesField = ({ onSubmit }) => {
}, [candidates]);
return (
<Container className="candidate flex-grow-1 mt-5 flex-column d-flex justify-content-between">
<Container className="candidate flex-grow-1 my-5 flex-column d-flex justify-content-between">
<div className="d-flex flex-column">
<h4 className="mb-4">{t('admin.add-candidates')}</h4>
<Alert msg={error} />
{candidates.map((candidate, index) => {
return <CandidateField key={index} position={index} />;
})}
<div className="d-flex flex-column mx-2 mx-md-0">
{candidates.map((candidate, index) => {
return (
<CandidateField
key={index}
position={index}
className="px-1 py-3 my-3"
/>
);
})}
</div>
</div>
<div className="mb-5 d-flex justify-content-center">
<Container className="my-5 d-md-flex d-grid justify-content-md-center">
<Button
outline={true}
color="secondary"
className="bg-blue"
onClick={onSubmit}
disabled={disabled}
icon={faArrowRight}
@ -48,7 +58,7 @@ const CandidatesField = ({ onSubmit }) => {
>
{t('admin.candidates-submit')}
</Button>
</div>
</Container>
</Container>
);
};

@ -46,7 +46,7 @@ const CandidatesField = () => {
const { t } = useTranslation();
const election = useElection();
return (
<Container className="bg-white p-4">
<Container className="bg-white p-4 mt-3 mt-md-0">
<Row>
<Col className="col-auto me-auto">
<h5 className="text-dark">{t('admin.confirm-candidates')}</h5>
@ -56,7 +56,11 @@ const CandidatesField = () => {
</Col>
</Row>
{election.candidates.map((_, i) => (
<CandidateField position={i} key={i} className="text-primary" />
<CandidateField
position={i}
key={i}
className="text-primary m-0 py-2"
/>
))}
</Container>
);
@ -71,16 +75,19 @@ const ConfirmField = ({ onSubmit, goToCandidates, goToParams }) => {
fluid="xl"
className="my-5 flex-column d-flex justify-content-center"
>
<Container className="px-0 d-md-none mb-5">
<h4>{t('admin.confirm-title')}</h4>
</Container>
<Row>
<Col className="col-lg-3 col-12">
<Container className="py-4">
<Container className="py-4 d-none d-md-block">
<h4>{t('common.the-vote')}</h4>
</Container>
<TitleField />
<CandidatesField />
</Col>
<Col className="col-lg-9 col-12">
<Container className="py-4">
<Col className="col-lg-9 col-12 mt-3 mt-md-0">
<Container className="py-4 d-none d-md-block">
<h4>{t('common.the-params')}</h4>
</Container>
<AccessResults />
@ -89,17 +96,18 @@ const ConfirmField = ({ onSubmit, goToCandidates, goToParams }) => {
<Private />
</Col>
</Row>
<div className="my-5 d-flex justify-content-center">
<Container className="my-5 d-md-flex d-grid justify-content-md-center">
<Button
outline={true}
color="secondary"
className="bg-blue"
onClick={onSubmit}
icon={faArrowRight}
position="right"
>
{t('admin.confirm-submit')}
</Button>
</div>
</Container>
</Container>
);
};

@ -45,7 +45,7 @@ const GradeField = ({ value }) => {
<div
style={style}
onClick={toggle}
className="p-2 m-1 fw-bold rounded-1 d-flex justify-content-between gap-3"
className="py-2 px-3 m-1 fw-bold rounded-1 d-flex justify-content-between gap-3"
>
<div className={grade.active ? '' : 'text-decoration-line-through'}>
{grade.name}

@ -59,22 +59,16 @@ const Grades = () => {
const dispatch = useElectionDispatch();
return (
<Container className="bg-white container-fluid p-4 mt-1">
<Row>
<Col className="col-auto me-auto">
<h4 className="text-dark">{t('common.grades')}</h4>
<p className="text-muted">{t('admin.grades-desc')}</p>
</Col>
<Col className="col-auto d-flex align-items-center">
<Row className="gx-1">
{grades.map((_, i) => (
<Col className="col-auto">
<GradeField value={i} key={i} />
</Col>
))}
{/* <AddField /> */}
</Row>
</Col>
<Container className="bg-white p-3 p-md-4 mt-1">
<h4 className="text-dark mb-0">{t('common.grades')}</h4>
<p className="text-muted">{t('admin.grades-desc')}</p>
<Row className="gx-1">
{grades.map((_, i) => (
<Col className="col-auto">
<GradeField value={i} key={i} />
</Col>
))}
{/* <AddField /> */}
</Row>
</Container>
);

@ -30,15 +30,15 @@ const LimitDate = () => {
const remainingDays = Math.ceil((endDate.getTime() - now.getTime()) / oneDay);
return (
<Container className="bg-white container-fluid p-4 mt-1">
<Row>
<Col className="col-auto me-auto">
<h4 className="text-dark">
<Container className="bg-white p-3 p-md-4 mt-1">
<div className="d-flex">
<div className="me-auto">
<h4 className="text-dark mb-0">
{t('admin.limit-duration')}
{hasDate ? (
<>
{' '}
<div className="badge ml-3 text-bg-light text-black-50">
<div className="badge text-bg-light text-black-50">
{`${t('admin.ending-in')} ${remainingDays} ${t(
'common.days'
)}`}
@ -47,18 +47,15 @@ const LimitDate = () => {
) : null}
</h4>
{desc === '' ? null : <p className="text-muted">{desc}</p>}
</Col>
<Col className="col-auto d-flex align-items-center">
</div>
<div className="col-auto d-flex align-items-center">
<Switch toggle={toggle} state={hasDate} />
</Col>
</Row>
</div>
</div>
{hasDate ? (
<Row>
<Col className="col-auto">
<DatePicker date={endDate} setDate={setEndDate} />
</Col>
<Col className="col-auto"></Col>
</Row>
<div className="mt-3">
<DatePicker date={endDate} setDate={setEndDate} />
</div>
) : null}
</Container>
);

@ -11,23 +11,29 @@ const ParamsField = ({ onSubmit }) => {
const { t } = useTranslation();
return (
<Container className="params flex-grow-1 my-5 flex-column d-flex justify-content-between">
<div className="d-flex flex-column">
<AccessResults />
<LimitDate />
<Grades />
<Private />
</div>
<div className="my-4 d-flex justify-content-center">
<Button
outline={true}
color="secondary"
onClick={onSubmit}
icon={faArrowRight}
position="right"
>
{t('admin.params-submit')}
</Button>
<Container className="params d-flex flex-column flex-grow-1 my-5">
<Container className="px-0 d-md-none mb-5">
<h4>{t('admin.params-title')}</h4>
</Container>
<div className="d-flex flex-grow-1 flex-column justify-content-between">
<div className="d-flex flex-column">
<AccessResults />
<LimitDate />
<Grades />
<Private />
</div>
<Container className="my-5 d-md-flex d-grid justify-content-md-center">
<Button
outline={true}
color="secondary"
className="bg-blue"
onClick={onSubmit}
icon={faArrowRight}
position="right"
>
{t('admin.params-submit')}
</Button>
</Container>
</div>
</Container>
);

@ -44,34 +44,41 @@ const Private = () => {
};
return (
<Container className="bg-white container-fluid p-4 mt-1">
<Row>
<Col className="col-auto me-auto">
<h4 className="text-dark">{t('admin.private-title')}</h4>
<p className="text-muted">{t('admin.private-desc')}</p>
</Col>
<Col className="col-auto d-flex align-items-center">
<>
<Container className="bg-white p-3 p-md-4 mt-1">
<div className="d-flex">
<div className="me-auto">
<h4 className="mb-0 text-dark">{t('admin.private-title')}</h4>
<p className="text-muted d-none d-md-block">
{t('admin.private-desc')}
</p>
</div>
<Switch toggle={toggle} state={election.restrictVote} />
</Col>
</Row>
</div>
{election.restrictVote ? (
<>
<ListInput
onEdit={handleEmails}
inputs={election.emails}
validator={validateEmail}
/>
<Row className="text-bg-light bt-3 p-2 text-muted fw-bold d-none d-md-block">
<Col className="col-auto">
<FontAwesomeIcon icon={faCircleInfo} />
</Col>
<Col className="col-auto d-flex align-items-center">
{t('admin.private-tip')}
</Col>
</Row>
</>
) : null}
</Container>
{election.restrictVote ? (
<>
<ListInput
onEdit={handleEmails}
inputs={election.emails}
validator={validateEmail}
/>
<Row className="text-bg-light bt-3 p-2 text-muted fw-bold">
<Col className="col-auto">
<FontAwesomeIcon icon={faCircleInfo} />
</Col>
<Col className="col-auto d-flex align-items-center">
{t('admin.private-tip')}
</Col>
</Row>
</>
<Container className="text-white d-md-none p-3">
{t('admin.access-results-desc')}
</Container>
) : null}
</Container>
</>
);
};

@ -12,11 +12,7 @@ const TrashButton = ({ className, label, onClick }) => {
return (
<div className="input-group-append cancelButton">
<FontAwesomeIcon
onClick={toggle}
icon={faTrashAlt}
className="mr-2 cursorPointer"
/>
<FontAwesomeIcon onClick={toggle} icon={faTrashAlt} role="button" />
<Modal
isOpen={visibled}
toggle={toggle}
@ -43,7 +39,7 @@ const TrashButton = ({ className, label, onClick }) => {
onClick();
}}
>
<FontAwesomeIcon icon={faTrashAlt} className="mr-2" />
<FontAwesomeIcon icon={faTrashAlt} />
{t('Yes')}
</Button>
</ModalFooter>

@ -18,7 +18,7 @@ const VoteButtonWithConfirm = ({ action }) => {
onClick={toggle}
>
<div className="annuler">
<FontAwesomeIcon icon={faCheck} className="mr-2 my-auto" />
<FontAwesomeIcon icon={faCheck} className="my-auto" />
{t('Submit my vote')}
</div>
</button>

@ -16,13 +16,7 @@ const Facebook = (props) => {
'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=500,width=700'
);
};
return (
<img
src="/facebook.svg"
onClick={handleClick}
className="cursorPointer mr-2"
/>
);
return <img src="/facebook.svg" onClick={handleClick} role="button" />;
};
export default Facebook;

@ -16,13 +16,7 @@ const Twitter = (props) => {
'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=500,width=700'
);
};
return (
<img
src="/twitter.svg"
onClick={handleClick}
className="cursorPointer mr-2"
/>
);
return <img src="/twitter.svg" onClick={handleClick} role="button" />;
};
export default Twitter;

@ -39,11 +39,7 @@ const Footer = () => {
),
},
{
component: (
<div>
<LanguageSelector />
</div>
),
component: <LanguageSelector selectedSize={14} />,
},
];

@ -1,9 +1,11 @@
/* eslint react/prop-types: 0 */
import { useState } from 'react';
import { Collapse, Navbar, Nav, NavItem, Button } from 'reactstrap';
import { Collapse, Nav, NavItem, Button } from 'reactstrap';
import Link from 'next/link';
import Image from 'next/image';
import { useTranslation } from 'next-i18next';
import LanguageSelector from './LanguageSelector';
import openMenuIcon from '../../public/open-menu-icon.svg';
const Header = () => {
const [isOpen, setOpen] = useState(false);
@ -13,104 +15,106 @@ const Header = () => {
const { t } = useTranslation('resource');
return (
<header className="mobile-header">
<Navbar light className="nav-mobile" expand="lg">
<div className="navbar-header">
<Button onClick={toggle} className="navbar-toggle pt-0 mt-0">
<img src="/open-menu-icon.svg" alt="" height="50" />
</Button>
</div>
<>
<Image
onClick={toggle}
role="button"
className="btn_menu"
src={openMenuIcon}
alt="open menu icon"
height="50"
width="50"
/>
<Collapse isOpen={isOpen} navbar>
<Nav className="ml-auto navbar-nav-scroll" navbar>
<div className="d-flex flex-row justify-content-between nav-logo">
<Link href="/" className="navbar-brand navbar-brand-mobile">
<img src="/logos/logo.svg" alt="logo" height="80" />
</Link>
<Collapse isOpen={isOpen} navbar>
<Nav className="navbar-nav-scroll" navbar>
<div className="d-flex flex-row justify-content-between nav-logo">
<Link href="/" className="navbar-brand navbar-brand-mobile">
<img src="/logos/logo.svg" alt="logo" height="80" />
</Link>
<Button
<Button
onClick={toggle}
className="navbar-toggle navbar-close-button"
>
<img height="20" src="/close-menu-icon.svg" alt="logo" />
</Button>
</div>
<div>
<NavItem>
<Link
href="/"
onClick={toggle}
className="navbar-toggle navbar-close-button"
className="navbar-my-link nav-link"
>
<img height="20" src="/close-menu-icon.svg" alt="logo" />
</Button>
</div>
<div>
<NavItem>
<Link
href="/"
onClick={toggle}
className="navbar-my-link nav-link"
>
Le jugement majoritaire
</Link>
</NavItem>
Le jugement majoritaire
</Link>
</NavItem>
<NavItem>
<Link
href="/"
onClick={toggle}
className="navbar-my-link nav-link"
>
Qui sommes-nous ?
</Link>
</NavItem>
<NavItem>
<Link
href="/"
onClick={toggle}
className="navbar-my-link nav-link"
>
Qui sommes-nous ?
</Link>
</NavItem>
<NavItem>
<Link
href="/"
onClick={toggle}
className="navbar-my-link nav-link"
>
Foire aux questions
</Link>
</NavItem>
<NavItem>
<Link
href="/"
onClick={toggle}
className="navbar-my-link nav-link"
>
Foire aux questions
</Link>
</NavItem>
<NavItem>
<Link
href="/"
onClick={toggle}
className="navbar-my-link nav-link"
>
On parle de nous
</Link>
</NavItem>
<NavItem>
<Link
href="/"
onClick={toggle}
className="navbar-my-link nav-link"
>
On parle de nous
</Link>
</NavItem>
<NavItem>
<Link
href="/"
onClick={toggle}
className="navbar-my-link nav-link"
>
Nous contactez
</Link>
</NavItem>
<NavItem>
<Link
href="/"
onClick={toggle}
className="navbar-my-link nav-link"
>
Nous contactez
</Link>
</NavItem>
<NavItem>
<LanguageSelector />
</NavItem>
</div>
<NavItem>
<LanguageSelector selectedSize={24} />
</NavItem>
</div>
<NavItem className="navbar-credits-container">
<Button className="btn-primary btn-nav">
<a href="/">Soutenez-nous</a>
</Button>
<NavItem className="navbar-credits-container">
<Button className="btn-primary btn-nav">
<a href="/">Soutenez-nous</a>
</Button>
<hr />
<div className="navbar-credits sharing sharing-mobile">
<p>Partagez lapplication Mieux voter</p>
<Link href="https://www.facebook.com/mieuxvoter.fr/">
<img src="/facebook.svg" className="mr-2" />
</Link>
<Link href="https://twitter.com/mieux_voter">
<img src="/twitter.svg" className="mr-2" />
</Link>
</div>
</NavItem>
</Nav>
</Collapse>
</Navbar>
</header>
<hr />
<div className="navbar-credits sharing sharing-mobile">
<p>Partagez lapplication Mieux voter</p>
<Link href="https://www.facebook.com/mieuxvoter.fr/">
<img src="/facebook.svg" />
</Link>
<Link href="https://twitter.com/mieux_voter">
<img src="/twitter.svg" />
</Link>
</div>
</NavItem>
</Nav>
</Collapse>
</>
);
};

@ -2,11 +2,13 @@
import { useState } from 'react';
import { Collapse, Navbar, NavbarToggler, Nav, NavItem } from 'reactstrap';
import Link from 'next/link';
import Image from 'next/image';
import Head from 'next/head';
import { useTranslation } from 'next-i18next';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faRocket } from '@fortawesome/free-solid-svg-icons';
import LanguageSelector from './LanguageSelector';
import logoColor from '../public/logos/logo-color.svg';
const Header = () => {
const [isOpen, setOpen] = useState(false);
@ -24,9 +26,9 @@ const Header = () => {
<Link href="/" className="navbar-brand">
<div className="d-flex flex-row">
<div className="align-self-center">
<img src="/logos/logo-color.svg" alt="logo" height="32" />
<Image src={logoColor} alt="logo" height="32" />
</div>
<div className="align-self-center ml-2">
<div className="align-self-center">
<div className="logo-text">
<h1>
{t('Voting platform')}
@ -38,11 +40,11 @@ const Header = () => {
</Link>
<NavbarToggler onClick={toggle} />
<Collapse isOpen={isOpen} navbar>
<Nav className="ml-auto" navbar>
<Nav className="me-auto" navbar>
<NavItem>
<Link href="/new/" className="text-primary nav-link">
{' '}
<FontAwesomeIcon icon={faRocket} className="mr-2" />
<FontAwesomeIcon icon={faRocket} />
{t('Start an election')}
</Link>
</NavItem>

@ -1,7 +1,7 @@
import { useRouter } from 'next/router';
import ReactFlagsSelect from 'react-flags-select';
const LanguageSelector = () => {
const LanguageSelector = (props) => {
const router = useRouter();
let localeShort = router.locale.substring(0, 2).toUpperCase();
if (localeShort === 'EN') localeShort = 'GB';
@ -20,8 +20,8 @@ const LanguageSelector = () => {
}
selected={localeShort}
customLabels={{ GB: 'English', FR: 'Francais' }}
{...props}
className="menu-flags"
selectedSize={14}
/>
);
};

@ -109,10 +109,10 @@ const ConfirmElection = ({
);
const participate = invitationOnly ? null : (
<>
<Col className="col-lg-3 text-center mr-10">
<Col className="col-lg-3 text-center">
<Link href={`/vote/${pid}`}>
<a target="_blank" rel="noreferrer" className="btn btn-success">
<FontAwesomeIcon icon={faVoteYea} className="mr-2" />
<FontAwesomeIcon icon={faVoteYea} />
{t('resource.participateBtn')}
</a>
</Link>
@ -222,7 +222,7 @@ const ConfirmElection = ({
<Col className="text-center col-lg-3">
<Link href={`/result/${pid}`}>
<a target="_blank" rel="noreferrer" className="btn btn-secondary">
<FontAwesomeIcon icon={faPollH} className="mr-2" />
<FontAwesomeIcon icon={faPollH} />
{t("resource.resultsBtn")}
</a>
</Link>

@ -387,7 +387,7 @@ const CreateElection = (props) => {
// return (
// <span
// key={i}
// className="badge badge-light mr-2 mt-2 "
// className="badge badge-light mt-2 "
// style={{
// backgroundColor: mention.color,
// color: "#fff",
@ -442,7 +442,7 @@ const CreateElection = (props) => {
// />
// <div className="mt-2 mailMutedText">
// <small className="text-muted">
// <FontAwesomeIcon icon={faExclamationCircle} className="mr-2" />
// <FontAwesomeIcon icon={faExclamationCircle} />
// {t("Copier-coller les emails des participants depuis un fichier Excel")}
// </small>
// </div>

@ -16,7 +16,7 @@ const FAQ = () => {
return (
<Container>
<Row>
<Link href="/" className="d-block ml-auto mr-auto mb-4">
<Link href="/" className="d-block mb-4">
<img src="/logos/logo-line-white.svg" alt="logo" height="128" />
</Link>
</Row>

@ -47,7 +47,7 @@ const StartForm = () => {
onChange={(e) => setTitle(e.target.value)}
/>
<p className="pt-0 mt-0 mr-0 maxLength">250</p>
<p className="pt-0 mt-0 maxLength">250</p>
</Row>
<Row>
<Link href={{ pathname: CREATE_ELECTION, query: { title: title } }}>
@ -146,7 +146,6 @@ const ExperienceRow = () => {
src={arrowRight}
width={22}
height={22}
className="mr-2"
alt="icon arrow right"
/>
</Button>

@ -16,7 +16,7 @@ const LegalNotices = (props) => {
return (
<Container>
<Row>
<Link href="/" className="d-block ml-auto mr-auto mb-4">
<Link href="/" className="d-block mb-4">
<img src="/logos/logo-line-white.svg" alt="logo" height="128" />
</Link>
</Row>

@ -16,7 +16,7 @@ const PrivacyPolicy = (props) => {
return (
<Container>
<Row>
<Link href="/" className="d-block ml-auto mr-auto mb-4">
<Link href="/" className="d-block mb-4">
<img src="/logos/logo-line-white.svg" alt="logo" height="128" />
</Link>
</Row>

@ -211,9 +211,7 @@ const Result = ({ candidates, numGrades, title, pid, err, finish }) => {
className="d-flex panel-title justify-content-between"
>
<div className="d-flex">
<span className="resultPositionCard mr-2">
{i + 1}
</span>
<span className="resultPositionCard ">{i + 1}</span>
<span className="candidateName">
{candidate.name}
</span>
@ -232,11 +230,11 @@ const Result = ({ candidates, numGrades, title, pid, err, finish }) => {
</span>
<FontAwesomeIcon
icon={faChevronDown}
className="ml-2 openIcon"
className="openIcon"
/>
<FontAwesomeIcon
icon={faChevronUp}
className="ml-2 closeIcon"
className="closeIcon"
/>
</div>
</span>
@ -298,7 +296,7 @@ const Result = ({ candidates, numGrades, title, pid, err, finish }) => {
{t('Comment interpréter les résultats')}
<FontAwesomeIcon
icon={faChevronRight}
className="ml-2 closeIcon"
className="closeIcon"
/>
</Link>
</Row>

@ -318,7 +318,7 @@ const CreateElection = (props) => {
// className="text-white mt-3 mb-1"
// onClick={toggleAdvancedOptions}
// >
// <FontAwesomeIcon icon={faCogs} className="mr-2" />
// <FontAwesomeIcon icon={faCogs} />
// {t("resource.advancedOptions")}
// </Button>
// </Col>
@ -351,7 +351,7 @@ const CreateElection = (props) => {
// <span className="text-dark">
// {t("At the end of the election")}
// </span>
// <HelpButton className="ml-2">
// <HelpButton >
// {t(
// "No one will be able to see the result until the end date is reached or until all participants have voted."
// )}
@ -529,7 +529,7 @@ const CreateElection = (props) => {
// return (
// <span
// key={i}
// className="badge badge-light mr-2 mt-2 "
// className="badge badge-light mt-2 "
// style={{
// backgroundColor: mention.color,
// color: "#fff",
@ -605,7 +605,7 @@ const CreateElection = (props) => {
// className="btn btn-dark float-right btn-block"
// onClick={handleSendNotReady}
// >
// <FontAwesomeIcon icon={faCheck} className="mr-2" />
// <FontAwesomeIcon icon={faCheck} />
// {t("Confirm")}
// </Button>
// )}

@ -200,7 +200,7 @@ const VoteBallot = ({ candidates, title, numGrades, pid, err, token }) => {
onClick={toggleDesktop}
>
{t('Je participe au vote')}
<img src="/arrow-white.svg" className="mr-2" />
<img src="/arrow-white.svg" />
</Button>
<Button
type="submit"
@ -208,7 +208,7 @@ const VoteBallot = ({ candidates, title, numGrades, pid, err, token }) => {
onClick={toggleMobile}
>
{t('Je participe au vote')}
<img src="/arrow-white.svg" className="mr-2" />
<img src="/arrow-white.svg" />
</Button>
</Row>
<Row className="noAds my-0">
@ -290,17 +290,17 @@ const VoteBallot = ({ candidates, title, numGrades, pid, err, token }) => {
<Row className="sectionTwoRowThreeCol">
<Button className="btn btn-block btn-secondary btn-sectionTwoHome">
Découvrez le jugement majoritaire
<img src="/arrow-white.svg" className="mr-2" />
<img src="/arrow-white.svg" />
</Button>
</Row>
</Row>
<Row className="sharing">
<p>Partagez lapplication Mieux voter</p>
<Link href="https://www.facebook.com/mieuxvoter.fr/">
<img src="/facebook.svg" className="mr-2" />
<img src="/facebook.svg" />
</Link>
<Link href="https://twitter.com/mieux_voter">
<img src="/twitter.svg" className="mr-2" />
<img src="/twitter.svg" />
</Link>
</Row>
</section>
@ -341,7 +341,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 bold badge"
style={
judgments.find((judgment) => {
return (
@ -436,7 +436,7 @@ const VoteBallot = ({ candidates, title, numGrades, pid, err, token }) => {
/>
) : (
<Button type="submit" className="mt-5 btn btn-transparent">
<FontAwesomeIcon icon={faCheck} className="mr-2" />
<FontAwesomeIcon icon={faCheck} />
{t('Submit my vote')}
</Button>
)}
@ -486,7 +486,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 bold badge"
style={
judgments.find((judgment) => {
return (
@ -610,7 +610,7 @@ const VoteBallot = ({ candidates, title, numGrades, pid, err, token }) => {
<VoteButtonWithConfirm action={handleSubmitWithoutAllRate} />
) : (
<Button type="submit" className="my-3 btn btn-transparent">
<FontAwesomeIcon icon={faCheck} className="mr-2" />
<FontAwesomeIcon icon={faCheck} />
{t('Submit my vote')}
</Button>
)}

@ -123,11 +123,11 @@ const VoteSuccess = ({ title, invitationOnly, pid, err }) => {
<h2 className="confirmH2">{t('resource.voteSuccess')}</h2>
<Button className="voteDesktop mx-auto mt-4 mb-5">
{t('Voir les résultats')}
<img src="/arrow-white.svg" className="mr-2" />
<img src="/arrow-white.svg" />
</Button>
<Button className="voteMobile mx-auto mt-4 mb-5">
{t('Voir les résultats')}
<img src="/arrow-white.svg" className="mr-2" />
<img src="/arrow-white.svg" />
</Button>
</Col>
</Row>
@ -144,7 +144,7 @@ const VoteSuccess = ({ title, invitationOnly, pid, err }) => {
<Link href="/">
<div>
{t('En savoir plus')}
<FontAwesomeIcon icon={faChevronRight} className="ml-2" />
<FontAwesomeIcon icon={faChevronRight} />
</div>
</Link>
</Col>
@ -178,7 +178,7 @@ const VoteSuccess = ({ title, invitationOnly, pid, err }) => {
<div className="mx-auto my-5">
<Row className="justify-content-center">
<Link href="https://www.facebook.com/mieuxvoter.fr/">
<img src="/facebook.svg" className="mr-2" />
<img src="/facebook.svg" />
</Link>
<p className="m-0">
{t('Faites découvrir lapplication a vos amis')}

@ -61,6 +61,7 @@
"admin.candidates-submit": "Validate the candidates",
"admin.candidates-back-step": "Back to candidates",
"admin.params-submit": "Validate the parameters",
"admin.params-title": "Your parameters",
"admin.access-results": "Immediate access to the results",
"admin.access-results-desc": "No one can access to the results as long as the vote is not closed.",
"admin.limit-duration": "Limit the length of the vote",
@ -78,5 +79,6 @@
"admin.private-placeholder": "Add here the emails of the participants.",
"admin.confirm-question": "Question of your vote",
"admin.confirm-candidates": "Candidates",
"admin.confirm-submit": "Start the vote"
"admin.confirm-submit": "Start the vote",
"admin.confirm-title": "Confirm your vote"
}

@ -61,6 +61,7 @@
"admin.candidates-submit": "Valider les candidats",
"admin.candidates-back-step": "Retour aux candidats",
"admin.params-submit": "Valider les paramètres",
"admin.params-title": "Vos paramètres",
"admin.access-results": "Accès immédiat aux résultats",
"admin.access-results-desc": "Personne ne pourra accéder aux résultats tant que le vote n'est pas clôturé.",
"admin.limit-duration": "Limiter la durée du vote",
@ -78,5 +79,6 @@
"admin.private-placeholder": "Ajoutez ici les emails des participants.",
"admin.confirm-question": "Question de votre vote",
"admin.confirm-candidates": "Candidats",
"admin.confirm-submit": "Démarrer le vote"
"admin.confirm-submit": "Démarrer le vote",
"admin.confirm-title": "Confirmer votre vote"
}

@ -8,11 +8,12 @@
font-size: 16px;
}
.badge {
width: 24px;
height: 24px;
background-color: black; // , 0.2);
}
}
.creation-step-icon {
width: 24px;
height: 24px;
background-color: black; // , 0.2);
}
.creation-step.active {
@ -71,3 +72,14 @@
.params {
max-width: 1070px;
}
.desktop_step {
width: 24px;
height: 24px;}
.mobile_step {
width: 32px;
height: 32px;}
.disabled {
opacity: 0.6;
}

@ -2,6 +2,7 @@
body {
background-color: $mv-blue-color;
font-weight: 500;
}
h1,
h2,
@ -384,9 +385,6 @@ ol.result > li {
background: #F2F0FF!important;
}
.cursor-pointer {
cursor: pointer;
}
.hide {
display: none;
@ -399,3 +397,11 @@ ol.result > li {
outline: none;
}
a, a:hover {
text-decoration: none;
}
.bg-blue {
background-color: $mv-blue-color!important;
}

@ -20,11 +20,11 @@
// @import '../../node_modules/bootstrap/scss/tables';
@import '../../node_modules/bootstrap/scss/forms';
@import '../../node_modules/bootstrap/scss/buttons';
// @import '../../node_modules/bootstrap/scss/transitions';
@import '../../node_modules/bootstrap/scss/transitions';
// @import '../../node_modules/bootstrap/scss/dropdown';
// @import '../../node_modules/bootstrap/scss/button-group';
// @import '../../node_modules/bootstrap/scss/nav';
// @import '../../node_modules/bootstrap/scss/navbar';
@import '../../node_modules/bootstrap/scss/nav';
@import '../../node_modules/bootstrap/scss/navbar';
// @import '../../node_modules/bootstrap/scss/card';
// @import '../../node_modules/bootstrap/scss/accordion';
// @import '../../node_modules/bootstrap/scss/breadcrumb';
@ -33,7 +33,7 @@
// @import '../../node_modules/bootstrap/scss/alert';
// @import '../../node_modules/bootstrap/scss/progress';
// @import '../../node_modules/bootstrap/scss/list-group';
// @import '../../node_modules/bootstrap/scss/close';
@import '../../node_modules/bootstrap/scss/close';
// @import '../../node_modules/bootstrap/scss/toasts';
@import '../../node_modules/bootstrap/scss/modal';
// @import '../../node_modules/bootstrap/scss/tooltip';

@ -1,3 +1,5 @@
@use "sass:map";
.btn {
//width: 165px;
padding: 8px 24px;
@ -56,6 +58,21 @@
}
.btn:not([class*="btn-outline-"]):hover {
background-color: rgb(255, 255, 255, 0.2);
border-color: white;
color: inherit;
border-color: inherit;
border-width: 2px;
box-shadow: unset;
}
.btn.btn-danger:hover {
color: map.get($theme-colors, "danger");
border-color: map.get($theme-colors, "danger");
border-width: 2px;
box-shadow: unset;
}
.btn_menu {
position: absolute;
top: 20px;
right: 20px;
}

@ -14,7 +14,7 @@
background-color: #fff;
color: $datepicker__text-color;
border: 2px solid $datepicker__border-color;
box-shadow: 0px 8px 8px rgba(143, 136, 186, 0.11);
box-shadow: $box-shadow-lg; // 0px 8px 8px rgba(143, 136, 186, 0.11);
border-radius: $datepicker__border-radius;
display: inline-block;
position: relative;
@ -409,6 +409,7 @@
}
.react-datepicker__input-container {
width: 100%;
position: relative;
display: inline-block;
/* Inside auto layout */

@ -3,10 +3,14 @@
width: 40px;
background-color: #c3bfd8;
border: unset;
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3.5' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3.5' fill='%23fff'/%3e%3c/svg%3e");
}
.form-switch .form-check-input:checked {
background-color: #0d6efd;
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3.5' fill='%23fff'/%3e%3c/svg%3e");
}
.form-switch input {
outline: none;
}

Loading…
Cancel
Save