parent
56836e5ea1
commit
c8ae7147e6
@ -0,0 +1,30 @@
|
||||
import {UncontrolledAlert} from 'reactstrap';
|
||||
import {useTranslation} from "next-i18next";
|
||||
|
||||
const AlertDismissible = ({msg, color}) => {
|
||||
const {t} = useTranslation();
|
||||
|
||||
if (msg) {
|
||||
return (
|
||||
<UncontrolledAlert color={color}>
|
||||
<h4 className={`${color}-heading`}>{t(msg)}</h4>
|
||||
<p>
|
||||
<a
|
||||
href={`mailto:${CONTACT_MAIL}?subject=[HELP]`}
|
||||
className="btn btn-success m-auto"
|
||||
>
|
||||
{t("error.help")}
|
||||
</a>
|
||||
</p>
|
||||
</UncontrolledAlert >
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
AlertDismissible.defaultProps = {
|
||||
color: 'danger'
|
||||
};
|
||||
|
||||
export default AlertDismissible;
|
@ -1,24 +0,0 @@
|
||||
import { useState } from 'react'
|
||||
import { Alert, Button } from 'react-bootstrap';
|
||||
import { faTimes, faExclamationCircle } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
export default function AlertDismissibleExample() {
|
||||
const [show, setShow] = useState(true);
|
||||
|
||||
if (show) {
|
||||
return (
|
||||
<Alert className="preventWarning">
|
||||
<Alert.Heading>
|
||||
<div>
|
||||
<FontAwesomeIcon icon={faExclamationCircle} className="mr-2" />
|
||||
<span>2 candidats minimum</span>
|
||||
</div>
|
||||
<FontAwesomeIcon onClick={() => setShow(false)} icon={faTimes} className="mr-2" />
|
||||
</Alert.Heading>
|
||||
|
||||
</Alert>
|
||||
);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -1,186 +1,170 @@
|
||||
import {useState, useEffect} from 'react'
|
||||
import ButtonWithConfirm from "./ButtonWithConfirm";
|
||||
import TrashButton from "./TrashButton";
|
||||
import {
|
||||
Row,
|
||||
Col,
|
||||
Label,
|
||||
Input,
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
Button, Modal, ModalHeader, ModalBody, Form
|
||||
} from "reactstrap";
|
||||
import {useTranslation} from "react-i18next";
|
||||
import {
|
||||
sortableHandle
|
||||
} from "react-sortable-hoc";
|
||||
import HelpButton from "@components/form/HelpButton";
|
||||
import AddPicture from "@components/form/AddPicture";
|
||||
import {
|
||||
faPlus, faCogs, faCheck, faTrash
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
||||
const DragHandle = sortableHandle(({children}) => (
|
||||
<span className="input-group-text indexNumber">{children}</span>
|
||||
));
|
||||
|
||||
const CandidateField = ({avatar, label, description, candIndex, onDelete, onAdd, ...inputProps}) => {
|
||||
const {t} = useTranslation();
|
||||
const [visibled, setVisibility] = useState(false);
|
||||
const toggle = () => setVisibility(!visibled)
|
||||
|
||||
|
||||
|
||||
const [selected, setSelectedState] = useState(false);
|
||||
const [className, setClassName] = useState("none");
|
||||
const [trashIcon, setTrashIcon] = useState("none");
|
||||
const [plusIcon, setPlusIcon] = useState("none");
|
||||
|
||||
const addCandidate = () => {
|
||||
if (label != "") {
|
||||
toggle();
|
||||
onAdd();
|
||||
setSelectedState(!selected);
|
||||
}
|
||||
else {}
|
||||
}
|
||||
if (label != "") {
|
||||
const type = "button";
|
||||
}
|
||||
else {
|
||||
const type = "submit";
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setClassName("candidateButton " + (selected ? "candidateAdded" : ""))
|
||||
}, [selected]);
|
||||
useEffect(() => {
|
||||
setPlusIcon("mr-2 cursorPointer " + (selected ? "trashIcon" : ""))
|
||||
}, [selected]);
|
||||
useEffect(() => {
|
||||
setTrashIcon("trashIcon " + (selected ? "displayTrash" : ""))
|
||||
}, [selected]);
|
||||
|
||||
const addFunction = () => {
|
||||
addCandidate();
|
||||
setSelectedState(!selected);
|
||||
}
|
||||
const removeCandidate = () => {
|
||||
onDelete();
|
||||
toggle();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
const [image, setImage] = useState(null);
|
||||
const [createObjectURL, setCreateObjectURL] = useState(null);
|
||||
|
||||
const uploadToClient = (event) => {
|
||||
if (event.target.files && event.target.files[0]) {
|
||||
const i = event.target.files[0];
|
||||
setImage(i);
|
||||
setCreateObjectURL(URL.createObjectURL(i));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<Row className="rowNoMargin">
|
||||
<div className={className}>
|
||||
<div className="avatarThumb">
|
||||
<img src={createObjectURL} alt="" />
|
||||
<input placeholder="Ajouter un candidat" className="candidate-placeholder ml-2" value={label} />
|
||||
</div>
|
||||
|
||||
<FontAwesomeIcon onClick={toggle} icon={faPlus} className={plusIcon} />
|
||||
<div className={trashIcon}><TrashButton label={label} onDelete={onDelete} /></div>
|
||||
</div>
|
||||
|
||||
<Modal
|
||||
isOpen={visibled}
|
||||
toggle={toggle}
|
||||
className="modal-dialog-centered"
|
||||
>
|
||||
|
||||
<ModalHeader className='closeModalAddCandidate' toggle={toggle}>
|
||||
|
||||
</ModalHeader>
|
||||
<ModalBody>
|
||||
<Col className="addCandidateCard">
|
||||
<InputGroup className="addCandidateForm">
|
||||
<Form>
|
||||
<InputGroupAddon addonType="prepend" className="addCandidateHeader">
|
||||
<DragHandle>
|
||||
<h6>Ajouter un participant</h6>
|
||||
<p>Ajoutez une photo, le nom et une description au candidat.</p>
|
||||
<div className="ajout-avatar">
|
||||
<div>
|
||||
<div className="avatar-placeholer">
|
||||
<img src={createObjectURL} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="avatar-text">
|
||||
<h4>Photo <span> (facultatif)</span></h4>
|
||||
|
||||
<p>Importer une photo.<br />format : jpg, png, pdf</p>
|
||||
<div className="btn-ajout-avatar">
|
||||
<input type="file" name="myImage" id="myImage" value={avatar} onChange={uploadToClient} />
|
||||
<label className="inputfile" htmlFor="myImage">Importer une photo</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<img src="/avatar.svg" />
|
||||
</DragHandle>
|
||||
</InputGroupAddon>
|
||||
<Label className="addCandidateText">Nom et prenom</Label>
|
||||
<Input
|
||||
type="text"
|
||||
value={label}
|
||||
{...inputProps}
|
||||
placeholder={t("resource.candidatePlaceholder")}
|
||||
tabIndex={candIndex + 1}
|
||||
maxLength="250"
|
||||
autoFocus
|
||||
className="addCandidateText"
|
||||
required
|
||||
/>
|
||||
<Label>Description (Facultatif)</Label>
|
||||
<Input
|
||||
type="text"
|
||||
defaultValue={description}
|
||||
maxLength="250"
|
||||
/>
|
||||
<Row className="removeAddButtons">
|
||||
|
||||
<ButtonWithConfirm className="removeButton" label={label} onDelete={removeCandidate} />
|
||||
|
||||
<Button type={type} className="addButton" label={label} onClick={addCandidate}>
|
||||
<FontAwesomeIcon icon={faPlus} />
|
||||
<span>Ajouter</span>
|
||||
</Button>
|
||||
|
||||
</Row>
|
||||
</Form>
|
||||
</InputGroup>
|
||||
</Col>
|
||||
</ModalBody></Modal>
|
||||
{/* <Col xs="auto" className="align-self-center pl-0">
|
||||
<HelpButton>
|
||||
{t(
|
||||
"Enter the name of your candidate or proposal here (250 characters max.)"
|
||||
)}
|
||||
</HelpButton>
|
||||
</Col> */}
|
||||
</Row>
|
||||
);
|
||||
// import {useState, useEffect} from 'react'
|
||||
// import ButtonWithConfirm from "./ButtonWithConfirm";
|
||||
// import TrashButton from "./TrashButton";
|
||||
// import {
|
||||
// Row,
|
||||
// Col,
|
||||
// Label,
|
||||
// Input,
|
||||
// InputGroup,
|
||||
// InputGroupAddon,
|
||||
// Button, Modal, ModalHeader, ModalBody, Form
|
||||
// } from "reactstrap";
|
||||
// import {useTranslation} from "react-i18next";
|
||||
// import HelpButton from "@components/form/HelpButton";
|
||||
// import AddPicture from "@components/form/AddPicture";
|
||||
// import {
|
||||
// faPlus, faCogs, faCheck, faTrash
|
||||
// } from "@fortawesome/free-solid-svg-icons";
|
||||
// import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
|
||||
// const DragHandle = sortableHandle(({children}) => (
|
||||
// <span className="input-group-text indexNumber">{children}</span>
|
||||
// ));
|
||||
|
||||
// const CandidateField = ({avatar, label, description, candIndex, onDelete, onAdd, ...inputProps}) => {
|
||||
const CandidateField = (props) => {
|
||||
// const {t} = useTranslation();
|
||||
// const [visibled, setVisibility] = useState(false);
|
||||
// const toggle = () => setVisibility(!visibled)
|
||||
|
||||
// const [selected, setSelectedState] = useState(false);
|
||||
// const [className, setClassName] = useState("none");
|
||||
// const [trashIcon, setTrashIcon] = useState("none");
|
||||
// const [plusIcon, setPlusIcon] = useState("none");
|
||||
|
||||
// const addCandidate = () => {
|
||||
// if (label != "") {
|
||||
// toggle();
|
||||
// onAdd();
|
||||
// setSelectedState(!selected);
|
||||
// }
|
||||
// else {}
|
||||
// }
|
||||
// const type = label != "" ? "button" : "submit";
|
||||
|
||||
// useEffect(() => {
|
||||
// setClassName("candidateButton " + (selected ? "candidateAdded" : ""))
|
||||
// }, [selected]);
|
||||
// useEffect(() => {
|
||||
// setPlusIcon("mr-2 cursorPointer " + (selected ? "trashIcon" : ""))
|
||||
// }, [selected]);
|
||||
// useEffect(() => {
|
||||
// setTrashIcon("trashIcon " + (selected ? "displayTrash" : ""))
|
||||
// }, [selected]);
|
||||
|
||||
// const addFunction = () => {
|
||||
// addCandidate();
|
||||
// setSelectedState(!selected);
|
||||
// }
|
||||
// const removeCandidate = () => {
|
||||
// onDelete();
|
||||
// toggle();
|
||||
|
||||
// }
|
||||
|
||||
//const [image, setImage] = useState(null);
|
||||
// const [createObjectURL, setCreateObjectURL] = useState(null);
|
||||
|
||||
// const uploadToClient = (event) => {
|
||||
// if (event.target.files && event.target.files[0]) {
|
||||
// const i = event.target.files[0];
|
||||
// setImage(i);
|
||||
// setCreateObjectURL(URL.createObjectURL(i));
|
||||
// }
|
||||
// };
|
||||
|
||||
return (<p>FOO</p>);
|
||||
// return (
|
||||
// <Row className="rowNoMargin">
|
||||
// <div className={className}>
|
||||
// <div className="avatarThumb">
|
||||
// <img src={createObjectURL} alt="" />
|
||||
// <input placeholder="Ajouter un candidat" className="candidate-placeholder ml-2" value={label} />
|
||||
// </div>
|
||||
//
|
||||
// <FontAwesomeIcon onClick={toggle} icon={faPlus} className={plusIcon} />
|
||||
// <div className={trashIcon}><TrashButton label={label} onDelete={onDelete} /></div>
|
||||
// </div>
|
||||
//
|
||||
// <Modal
|
||||
// isOpen={visibled}
|
||||
// toggle={toggle}
|
||||
// className="modal-dialog-centered"
|
||||
// >
|
||||
//
|
||||
// <ModalHeader className='closeModalAddCandidate' toggle={toggle}>
|
||||
//
|
||||
// </ModalHeader>
|
||||
// <ModalBody>
|
||||
// <Col className="addCandidateCard">
|
||||
// <InputGroup className="addCandidateForm">
|
||||
// <Form>
|
||||
// <InputGroupAddon addonType="prepend" className="addCandidateHeader">
|
||||
// { //<DragHandle>
|
||||
// }
|
||||
// <h6>Ajouter un participant</h6>
|
||||
// <p>Ajoutez une photo, le nom et une description au candidat.</p>
|
||||
// <div className="ajout-avatar">
|
||||
// <div>
|
||||
// <div className="avatar-placeholer">
|
||||
// <img src={createObjectURL} />
|
||||
// </div>
|
||||
// </div>
|
||||
// <div className="avatar-text">
|
||||
// <h4>Photo <span> (facultatif)</span></h4>
|
||||
//
|
||||
// <p>Importer une photo.<br />format : jpg, png, pdf</p>
|
||||
// <div className="btn-ajout-avatar">
|
||||
// <input type="file" name="myImage" id="myImage" value={avatar} onChange={uploadToClient} />
|
||||
// <label className="inputfile" htmlFor="myImage">Importer une photo</label>
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>
|
||||
// <img src="/avatar.svg" />
|
||||
// { //</InputGroupAddon></DragHandle>
|
||||
// }
|
||||
// </InputGroupAddon>
|
||||
// <Label className="addCandidateText">Nom et prenom</Label>
|
||||
// <Input
|
||||
// type="text"
|
||||
// value={label}
|
||||
// {...inputProps}
|
||||
// placeholder={t("resource.candidatePlaceholder")}
|
||||
// tabIndex={candIndex + 1}
|
||||
// maxLength="250"
|
||||
// autoFocus
|
||||
// className="addCandidateText"
|
||||
// required
|
||||
// />
|
||||
// <Label>Description (Facultatif)</Label>
|
||||
// <Input
|
||||
// type="text"
|
||||
// defaultValue={description}
|
||||
// maxLength="250"
|
||||
// />
|
||||
// <Row className="removeAddButtons">
|
||||
//
|
||||
// <ButtonWithConfirm className="removeButton" label={label} onDelete={removeCandidate} />
|
||||
//
|
||||
// <Button type={type} className="addButton" label={label} onClick={addCandidate}>
|
||||
// <FontAwesomeIcon icon={faPlus} />
|
||||
// <span>Ajouter</span>
|
||||
// </Button>
|
||||
//
|
||||
// </Row>
|
||||
// </Form>
|
||||
// </InputGroup>
|
||||
// </Col>
|
||||
// </ModalBody></Modal>
|
||||
// {/* <Col xs="auto" className="align-self-center pl-0">
|
||||
// <HelpButton>
|
||||
// {t(
|
||||
// "Enter the name of your candidate or proposal here (250 characters max.)"
|
||||
// )}
|
||||
// </HelpButton>
|
||||
// </Col> */}
|
||||
// </Row >
|
||||
// );
|
||||
}
|
||||
|
||||
export default CandidateField
|
||||
|
@ -1,10 +1,36 @@
|
||||
module.exports = {
|
||||
i18n: {
|
||||
defaultLocale: "fr",
|
||||
locales: ["en", "fr"],
|
||||
},
|
||||
react: {
|
||||
useSuspense: false,
|
||||
wait: true
|
||||
}
|
||||
};
|
||||
// https://www.i18next.com/overview/configuration-options#logging
|
||||
debug: process.env.NODE_ENV === 'development',
|
||||
i18n: {
|
||||
defaultLocale: 'en',
|
||||
locales: ['en', 'fr'],
|
||||
},
|
||||
ns: ["resource"],
|
||||
defaultNS: "resource",
|
||||
defaultValue: "__STRING_NOT_TRANSLATED__",
|
||||
/** To avoid issues when deploying to some paas (vercel...) */
|
||||
localePath: typeof window === 'undefined' ?
|
||||
require('path').resolve('./public/locales') : '/locales',
|
||||
|
||||
reloadOnPrerender: process.env.NODE_ENV === 'development',
|
||||
|
||||
/**
|
||||
* @link https://github.com/i18next/next-i18next#6-advanced-configuration
|
||||
*/
|
||||
// saveMissing: false,
|
||||
// strictMode: true,
|
||||
// serializeConfig: false,
|
||||
// react: { useSuspense: false }
|
||||
}
|
||||
// const path = require('path')
|
||||
// module.exports = {
|
||||
// i18n: {
|
||||
// defaultLocale: "fr",
|
||||
// locales: ["en", "fr"],
|
||||
// },
|
||||
// localePath: path.resolve('./public/locales'),
|
||||
// // react: {
|
||||
// // useSuspense: false,
|
||||
// // wait: true
|
||||
// // }
|
||||
// };
|
||||
|
File diff suppressed because it is too large
Load Diff