Implement progress bar

main
Felix Martin 2021-04-05 18:59:44 -04:00
parent 04f35e52f6
commit 16b0830139
3 changed files with 95 additions and 19 deletions

View File

@ -2,6 +2,7 @@
"name": "my-app",
"version": "0.1.0",
"private": true,
"homepage": "/makeachoice",
"dependencies": {
"@testing-library/jest-dom": "^5.11.10",
"@testing-library/react": "^11.2.6",

View File

@ -19,7 +19,7 @@
<div id="main">
<div class="header">
<h1>Make a choice</h1>
<h2>Make a choice</h2>
</div>
<div class="content">

View File

@ -10,6 +10,22 @@ function shuffleArray(array) {
}
}
function choicesToMarkdown(choices) {
const choiceNames = choices.map((c) => c.choice);
const choiceWidth = Math.max(
...choiceNames.concat("Choice").map((x) => x.length + 3)
);
const countWidth = 6;
let r = "| Choice".padEnd(choiceWidth, " ") + "| Count |\n";
r += "|".padEnd(choiceWidth, "-") + "|-------|\n";
for (const c of choices) {
r += ("| " + c.choice).padEnd(choiceWidth, " ") + "| ";
r += c.count.toString().padStart(countWidth, " ") + "|\n";
}
return r;
}
class Decision {
constructor(indexA, indexB, choices) {
this.indexA = indexA;
@ -37,7 +53,7 @@ class Options extends React.Component {
constructor(props) {
super(props);
this.state = {
choicesText: null,
choicesText: "",
choices: [],
decisions: null,
decisionsMade: null,
@ -75,27 +91,49 @@ class Options extends React.Component {
});
}
startAgain() {
this.setState({
decisions: null,
currentDecision: null,
decisionsMade: null,
});
}
renderChoosing() {
const current = this.state.currentDecision;
const decision = this.state.decisions[current];
const progress = (current / this.state.decisions.length) * 100;
return (
<div className="pure-g">
let choiceA = decision.choiceA;
let choiceB = decision.choiceB;
const maxChoiceLetters = Math.max(choiceA.length, choiceB.length);
let fullText = null;
if (maxChoiceLetters > 20) {
fullText = (
<div className="pure-u-1 space-1">
<div className="pure-u-9-24">
<p>{decision.choiceA}</p>
<p>{choiceA}</p>
</div>
<div className="pure-u-6-24" />
<div className="pure-u-9-24">
<p>{decision.choiceB}</p>
<p>{choiceB}</p>
</div>
</div>
);
choiceA = choiceA.slice(0, 20) + "...";
choiceB = choiceB.slice(0, 20) + "...";
}
return (
<div className="pure-g">
{fullText}
<div className="pure-u-1 space-1">
<button
className="pure-button pure-u-9-24 button-warning"
onClick={() => this.makeChoice(decision.indexA)}
>
a
{choiceA}
</button>
<div className="pure-u-1-24" />
<button
@ -109,9 +147,14 @@ class Options extends React.Component {
className="pure-button pure-u-9-24 button-warning"
onClick={() => this.makeChoice(decision.indexB)}
>
b
{choiceB}
</button>
</div>
<div className="pure-u-1 space-1">
<progress className="pure-u-1" max="100" value={progress}>
{" "}
</progress>
</div>
</div>
);
}
@ -146,9 +189,10 @@ class Options extends React.Component {
<fieldset className="pure-group">
<textarea
onChange={(event) => this.choicesOnChange(event)}
value={this.state.choicesText}
className="pure-input-1"
placeholder="Enter one choice per line"
></textarea>
/>
</fieldset>
</form>
</div>
@ -190,15 +234,22 @@ class Options extends React.Component {
return {
choice: choice,
count: 0,
relativeCount: 0,
};
});
let totalCount = 0;
for (const i of this.state.decisionsMade) {
if (i !== -1) {
choices[i].count += 1;
totalCount += 1;
}
}
for (let c of choices) {
c.relativeCount = (c.count / totalCount) * 100;
}
choices.sort((a, b) => b.count - a.count);
let choicesToRender = choices.map((choice, index) => {
@ -206,21 +257,45 @@ class Options extends React.Component {
<tr key={index}>
<td>{choice.choice}</td>
<td>{choice.count}</td>
<td>
<progress max="100" value={choice.relativeCount} />
</td>
</tr>
);
});
let choicesMarkdown = choicesToMarkdown(choices);
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 className="pure-g">
<div className="pure-u-1">
<table className="pure-table space-1">
<thead>
<tr>
<th>Choice</th>
<th>Count</th>
<th></th>
</tr>
</thead>
<tbody>{choicesToRender}</tbody>
</table>
</div>
<button
className="pure-button button-warning pure-u-1-4 space-1"
onClick={() => this.startAgain()}
>
Start again
</button>
<div className="pure-u-3-4" />
<button
className="pure-button button-secondary pure-u-1-4 space-1"
onClick={() => {
navigator.clipboard.writeText(choicesMarkdown);
}}
>
Copy result
</button>
<div className="pure-u-3-4" />
</div>
);
}