JSFiddle - React, Tailwind, and code Playground
by Josh Pullen
HTML
<!--
Create timer that keeps you on track to do n questions in m minutes
(default 23 questions in 35 minutes)
-->
CSS
h1 {
text-align: center;
}
label {
display: block;
margin-bottom: 8px;
}
input[type="number"] {
font-size: 24px;
padding: 4px 8px;
}
JavaScript
import { html, render, useState, useReducer, useEffect, useCallback } from "https://unpkg.com/htm/preact/standalone.module.js";
function App() {
const [settings, setSettings] = useState(null);
const { time, status, start, pause, reset } = useStopwatch();
if (settings === null) {
const onSubmit = (event) => {
event.preventDefault();
const data = new FormData(event.target);
reset();
setSettings({
totalTime: 60 * Number(data.get("totalTime")),
questions: Number(data.get("questions"))
});
}
return html`
<h1>LSAT Timer</h1>
<form onSubmit=${onSubmit}>
<label>
<div>Number of questions:</div>
<input type="number" name="questions" defaultValue=${23} />
</label>
<label>
<div>Total time (minutes):</div>
<input type="number" name="totalTime" defaultValue=${35} />
</label>
<div>
<input type="submit" value="Confirm" />
</div>
</form>
`;
}
const durationPerQuestion = settings.totalTime / settings.questions;
const currentQuestion = 1 + Math.floor(time / durationPerQuestion);
const timeSpentOnQuestion = (time % durationPerQuestion) / durationPerQuestion;
return html`
<h1>Question ${currentQuestion}</h1>
<div
style=${{
position: "fixed",
top: 0,
left: 0,
background: "#eee",
width: `${timeSpentOnQuestion * 100}%`,
height: "100%",
zIndex: -1
}}
/>
<div>
${status === "on" ? html`
<button onClick=${pause}>Pause</button>
` : html`
<button onClick=${start}>Start</button>
`}
</div>
<div style=${{ display: "flex", position: "fixed", bottom: 4, left: 4, right: 4, gap: 4 }}>
<button onClick=${() => setSettings(null)} style=${{ flex: "1 1 0" }}>Reset</button>
</div>
`;
}
function getTime(state) {
switch (state.status) {
case "off":
return...