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)
-->
JavaScript
import { html, render, useState, useReducer, useEffect, useCallback } from "https://unpkg.com/htm/preact/standalone.module.js";
function AppWrapper({ children }) {
return html`
<div
style=${{
width: "100vw",
height: "100vh",
display: "flex",
flexDirection: "column",
justifyContent: "center",
overflowY: "auto"
}}
>
<h1>LSAT Timer</h1>
${children}
</div>
`;
}
function App() {
const [settings, setSettings] = useState(null);
const { time, status, start, pause, reset } = useStopwatch();
const safeReset = () => {
if (confirm("Are you sure you want to reset?")) {
reset();
}
}
if (settings === null) {
const onSubmit = (event) => {
event.preventDefault();
console.log(event.target);
}
return html`
<${AppWrapper}>
<form onSubmit=${onSubmit}>
<label>
<div>Number of questions:</div>
<input type="number" defaultValue=${23} />
</label>
<label>
<div>Total time (minutes):</div>
<input type="number" defaultValue=${35} />
</label>
<div>
<input type="submit" value="Confirm" />
</div>
</form>
</>
`;
}
return html`
<${AppWrapper}>
<div>${time}</div>
${status === "off" && html`
<button onClick=${start}>Start</button>
${time > 0 && html`<button onClick=${safeReset}>Reset</button>`}
`}
${status === "on" && html`
<button onClick=${pause}>Pause</button>
`}
</>
`;
}
function getTime(state) {
switch (state.status) {
case "off":
return state.startValue;
case "on":
return state.startValue + (Date.now() - state.startTime) / 1000;
default:
return 0;
}
}
function reducer(state, action) {
switch (action.type) {
case "START":
return {
status: "on",
startTime: Date.now(),
...