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/src/components/views/CreateElection.js

231 lines
9.3 KiB

import React, {Component} from "react";
import {
Container,
Row,
Col,
Input,
Label,
InputGroup,
InputGroupAddon,
Button
} from 'reactstrap';
import {ToastContainer} from 'react-toastify';
import HelpButton from "../form/HelpButton";
import {arrayMove, sortableContainer, sortableElement, sortableHandle} from 'react-sortable-hoc';
import ButtonWithConfirm from "../form/ButtonWithConfirm";
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import {faPlus, faTrashAlt, faCheck } from '@fortawesome/free-solid-svg-icons';
const DragHandle = sortableHandle(({children}) => <span className="input-group-text indexNumber">{children}</span>);
const SortableCandidate = sortableElement(({candidate, sortIndex, form}) => <li className="sortable">
<Row key={"rowCandidate" + sortIndex}>
<Col>
<InputGroup >
<InputGroupAddon addonType="prepend" >
<DragHandle >
<span >{sortIndex + 1}</span>
</DragHandle>
</InputGroupAddon>
<Input type="text" value={candidate.label}
onChange={(event) => form.editCandidateLabel(event, sortIndex)}
onKeyPress={(event) => form.handleKeypressOnCandidateLabel(event, sortIndex)}
placeholder="Nom du candidat ou de la proposition ..."
tabIndex={ sortIndex + 1}
innerRef={(ref) => form.candidateInputs[sortIndex] = ref}
maxLength="250"/>
<ButtonWithConfirm className="btn btn-primary input-group-append border-light">
<div key="button"><FontAwesomeIcon icon={faTrashAlt} /></div>
<div key="modal-title">Suppression ?</div>
<div key="modal-body">Êtes-vous sûr de vouloir supprimer {(candidate.label!=="")?<b>"{candidate.label}"</b>:<span>la ligne {sortIndex+1}</span>} ?
</div>
<div key="modal-confirm" onClick={() => form.removeCandidate(sortIndex)}>Oui</div>
<div key="modal-cancel">Non</div>
</ButtonWithConfirm>
</InputGroup>
</Col>
<Col xs="auto" className="align-self-center pl-0">
<HelpButton id={"helpCandidate"+sortIndex}>
Saisissez ici le nom de votre candidat ou de votre proposition (250 caractères max.)
</HelpButton>
</Col>
</Row>
</li>);
const SortableCandidatesContainer = sortableContainer(({items, form}) => {
return <ul className="sortable">{items.map((candidate, index) => (
<SortableCandidate key={`item-${index}`} index={index} sortIndex={index} candidate={candidate} form={form}/>
))}</ul>;
});
class CreateElection extends Component {
constructor(props) {
super(props);
this.state = {
candidates:[{label:""},{label:""}],
title:null,
isVisibleTipsDragAndDropCandidate:true
};
this.candidateInputs = [];
this.focusInput= React.createRef();
}
handleChangeTitle= (event) => {
this.setState({title: event.target.value});
};
addCandidate = (event) => {
let candidates = this.state.candidates;
if (candidates.length < 100) {
candidates.push({label:""});
this.setState({ candidates: candidates});
}
if(event.type === 'keypress'){
setTimeout(()=>{ this.candidateInputs[this.state.candidates.length-1].focus()},250);
}
};
removeCandidate = (index) => {
let candidates = this.state.candidates;
candidates.splice(index, 1);
console.log(candidates.length);
if(candidates.length===0){
candidates=[{label:""}];
}
this.setState({candidates: candidates});
};
editCandidateLabel = (event, index) => {
let candidates = this.state.candidates;
candidates[index].label = event.currentTarget.value;
this.setState({candidates: candidates});
};
handleKeypressOnCandidateLabel = (event, index) => {
if(event.key === 'Enter'){
event.preventDefault();
if(index+1===this.state.candidates.length){
this.addCandidate(event);
}else{
this.candidateInputs[index+1].focus();
}
}
};
onCandidatesSortEnd = ({oldIndex, newIndex}) => {
let candidates = this.state.candidates;
candidates = arrayMove(candidates, oldIndex, newIndex);
this.setState({candidates: candidates});
};
handleSubmit= (event) => {
event.preventDefault();
};
componentWillMount() {
const params = new URLSearchParams(this.props.location.search);
this.setState({title:params.get("title")?params.get("title"):""});
}
render(){
const params = new URLSearchParams(this.props.location.search);
return(
<Container>
<ToastContainer/>
<form onSubmit={this.handleSubmit} autoComplete="off" >
<Row>
<Col ><h3>Démarrer un vote</h3></Col>
</Row>
<hr />
<Row className="mt-4">
<Col xs="12" >
<Label for="title">Question du vote :</Label>
</Col>
<Col>
<Input placeholder="Saisissez ici la question de votre vote" tabIndex="1" name="title" id="title" innerRef={this.focusInput} autoFocus defaultValue={params.get("title")?params.get("title"):""} onChange={this.handleChangeTitle} maxLength="250" />
</Col>
<Col xs="auto" className="align-self-center pl-0">
<HelpButton id="helpTitle">
Posez ici votre question ou introduisez simplement votre vote (250 caractères max.)
<br /><u>Par exemple :</u> <em>Pour être mon représentant, je juge ce candidat ...</em>
</HelpButton>
</Col>
</Row>
<Row className="mt-4">
<Col xs="12" >
<Label for="title">Candidats / Propositions :</Label>
</Col>
<Col xs="12" >
<SortableCandidatesContainer items={this.state.candidates} onSortEnd={this.onCandidatesSortEnd}
form={this} useDragHandle/>
</Col>
</Row>
<Row className="mb-4" >
<Col className="text-right" >
<Button className="btn-secondary"
tabIndex={this.state.candidates.length+2}
type="button"
onClick={(event)=>this.addCandidate(event)}>
<FontAwesomeIcon icon={faPlus} className="mr-2" />Ajouter une proposition</Button>
</Col>
<Col xs="auto" />
</Row>
<hr />
<Row className="mt-4 justify-content-md-center">
<Col xs="12" md="3" >
<ButtonWithConfirm className="btn btn-success float-right btn-block ">
<div key="button"><FontAwesomeIcon icon={faCheck} className="mr-2" />Valider</div>
<div key="modal-title">Confirmation</div>
<div key="modal-body">
<div>Voici votre vote :</div>
<div className="border border-primary p-2 mt-4 mb-4">
<h4 className="m-0">{this.state.title}</h4>
<ul className="m-0">
{
this.state.candidates.map((candidate,i) => {
if(candidate.label!==""){
return <li key={i}>{candidate.label}</li>
}else{
return <li className="d-none" />
}
})
}
</ul>
</div>
<p>Une fois validé, vous ne pourrez plus le modifier, souhaitez-vous continuer ?</p>
</div>
<div key="modal-confirm" onClick={() => {}}>Oui</div>
<div key="modal-cancel">Non</div>
</ButtonWithConfirm>
</Col>
</Row>
</form>
</Container>
)
}
}
export default CreateElection;