Files
makeachoice/src/index.js

240 lines
5.7 KiB
JavaScript

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
function shuffleArray(array) {
/* https://stackoverflow.com/a/12646864 */
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}
class Decision {
constructor(indexA, indexB, choices) {
this.indexA = indexA;
this.indexB = indexB;
this.choiceA = choices[indexA];
this.choiceB = choices[indexB];
}
static createDecisions(choices) {
let decisions = [];
for (var i = 0; i < choices.length; i++) {
for (var j = 0; j < choices.length; j++) {
if (i !== j) {
let d = new Decision(i, j, choices);
decisions.push(d);
}
}
}
shuffleArray(decisions);
return decisions;
}
}
class Options extends React.Component {
constructor(props) {
super(props);
this.state = {
choicesText: null,
choices: [],
decisions: null,
decisionsMade: null,
currentDecision: null,
};
}
startChoosing() {
this.setState({
decisions: Decision.createDecisions(this.state.choices),
decisionsMade: [],
currentDecision: 0,
});
}
choicesTextToChoices(choicesText) {
let choices = choicesText.split("\n");
choices = choices.filter((choice) => choice.length > 0);
return choices;
}
choicesOnChange(event) {
let choicesText = event.target.value;
let choices = this.choicesTextToChoices(choicesText);
this.setState({
choicesText: choicesText,
choices: choices,
});
}
makeChoice(i) {
this.setState({
currentDecision: this.state.currentDecision + 1,
decisionsMade: this.state.decisionsMade.concat([i]),
});
}
renderChoosing() {
const current = this.state.currentDecision;
const decision = this.state.decisions[current];
return (
<div className="pure-g">
<div className="pure-u-1 space-1">
<div className="pure-u-9-24">
<p>{decision.choiceA}</p>
</div>
<div className="pure-u-6-24" />
<div className="pure-u-9-24">
<p>{decision.choiceB}</p>
</div>
</div>
<div className="pure-u-1 space-1">
<button
className="pure-button pure-u-9-24 button-warning"
onClick={() => this.makeChoice(decision.indexA)}
>
a
</button>
<div className="pure-u-1-24" />
<button
className="pure-button pure-u-4-24 button-secondary"
onClick={() => this.makeChoice(-1)}
>
neutral
</button>
<div className="pure-u-1-24" />
<button
className="pure-button pure-u-9-24 button-warning"
onClick={() => this.makeChoice(decision.indexB)}
>
b
</button>
</div>
</div>
);
}
renderButton() {
let choices = this.state.choices;
let button = null;
if (choices.length > 1 && choices[1]) {
button = (
<button
className="pure-button pure-button-primary space-1"
onClick={() => this.startChoosing()}
>
Start choosing
</button>
);
} else {
button = (
<button className="pure-button pure-button-disabled space-1">
Start choosing
</button>
);
}
return button;
}
renderChoiceInputField() {
return (
<div className="pure-u-1">
<h2 className="content-subhead">Type or paste your choices</h2>
<form className="pure-form" onSubmit={() => this.onSubmit}>
<fieldset className="pure-group">
<textarea
onChange={(event) => this.choicesOnChange(event)}
className="pure-input-1"
placeholder="Enter one choice per line"
></textarea>
</fieldset>
</form>
</div>
);
}
renderCurrentChoices() {
let choices = this.state.choices;
let choicesToRender = choices.map((choice, index) => {
return <li key={index}>{choice}</li>;
});
let button = this.renderButton();
return (
<div className="pure-u-1">
<h2 className="content-subhead">Your choices</h2>
<div className="pure-menu">
<ul>{choicesToRender}</ul>
</div>
<div>{button}</div>
</div>
);
}
renderSpecifyChoices() {
let input = this.renderChoiceInputField();
let output = this.renderCurrentChoices();
return (
<div className="pure-g">
{input}
{output}
</div>
);
}
renderResult() {
let choices = this.state.choices.map((choice, index) => {
return {
choice: choice,
count: 0,
};
});
for (const i of this.state.decisionsMade) {
if (i !== -1) {
choices[i].count += 1;
}
}
choices.sort((a, b) => b.count - a.count);
let choicesToRender = choices.map((choice, index) => {
return (
<tr key={index}>
<td>{choice.choice}</td>
<td>{choice.count}</td>
</tr>
);
});
return (
<div className="pure-u-1">
<table class="pure-table space-1">
<thead>
<tr>
<th>Choice</th>
<th>Count</th>
</tr>
</thead>
<tbody>{choicesToRender}</tbody>
</table>
</div>
);
}
render() {
if (!this.state.decisions) {
return this.renderSpecifyChoices();
} else if (this.state.currentDecision < this.state.decisions.length) {
return this.renderChoosing();
} else {
return this.renderResult();
}
}
}
ReactDOM.render(<Options />, document.getElementById("root"));