update react
This commit is contained in:
parent
804ce323bf
commit
7d4f1151fa
40 changed files with 3573 additions and 14078 deletions
110
src/app/input-form.tsx
Normal file
110
src/app/input-form.tsx
Normal file
|
@ -0,0 +1,110 @@
|
|||
import {useState} from 'react';
|
||||
import ValidatingInputNumberField from "./validating-input-number-field.tsx";
|
||||
import {actionLoadedMaze, actionLoadingFailed, actionStartedLoading} from "./state/action.ts";
|
||||
import styles from "./input-form.module.css";
|
||||
import "./input-form.css";
|
||||
|
||||
export default function InputForm({state, dispatch}) {
|
||||
const [width, setWidth] = useState(10);
|
||||
const [height, setHeight] = useState(10);
|
||||
const [id, setId] = useState(null as number);
|
||||
const [algorithm, setAlgorithm] = useState('wilson');
|
||||
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
dispatch(actionStartedLoading());
|
||||
const url = `https://manuel.friedli.info/labyrinth/create/json?w=${width}&h=${height}&id=${id || ''}&algorithm=${algorithm}`;
|
||||
fetch(url)
|
||||
.then(response => response.json())
|
||||
// .then(result => new Promise(resolve => setTimeout(resolve, 600, result)))
|
||||
.then(result => {
|
||||
dispatch(actionLoadedMaze(result));
|
||||
})
|
||||
.catch(reason => {
|
||||
console.error("Failed to fetch maze data.", reason);
|
||||
dispatch(actionLoadingFailed(reason));
|
||||
});
|
||||
};
|
||||
const validateWidthHeightInput = value => {
|
||||
if (isNaN(value) || "" === value || (Math.floor(value) !== Number(value))) {
|
||||
return {
|
||||
valid: false,
|
||||
message: "Must be an integer greater than 1.",
|
||||
value
|
||||
};
|
||||
}
|
||||
if (value < 1) {
|
||||
return {
|
||||
valid: false,
|
||||
message: "Must be greater than 1.",
|
||||
value
|
||||
};
|
||||
}
|
||||
return {
|
||||
valid: true,
|
||||
value
|
||||
};
|
||||
};
|
||||
const validateIdInput = value => {
|
||||
// FIXME doesn't handle strings with characters correctly (e.g. "asdf" yields an empty value, due to "type=number").
|
||||
if (isNaN(value) || ("" !== value && ((Math.floor(value) !== Number(value))))) {
|
||||
return {
|
||||
valid: false,
|
||||
message: "Must be empty or an integer",
|
||||
value
|
||||
};
|
||||
}
|
||||
return {
|
||||
valid: true,
|
||||
value
|
||||
}
|
||||
};
|
||||
return (
|
||||
<form onSubmit={handleSubmit}>
|
||||
<div className={styles.inputform}>
|
||||
<ValidatingInputNumberField id={"width"}
|
||||
label={"Width"}
|
||||
value={width}
|
||||
constraints={{
|
||||
min: 2
|
||||
}}
|
||||
validatorFn={validateWidthHeightInput}
|
||||
disabled={state.loading}
|
||||
onChange={setWidth}
|
||||
/>
|
||||
<ValidatingInputNumberField id={"height"}
|
||||
label={"Height"}
|
||||
value={height}
|
||||
constraints={{
|
||||
min: 2
|
||||
}}
|
||||
validatorFn={validateWidthHeightInput}
|
||||
disabled={state.loading}
|
||||
onChange={setHeight}
|
||||
/>
|
||||
<ValidatingInputNumberField id={"id"}
|
||||
label={"ID (optional)"}
|
||||
value={id}
|
||||
validatorFn={validateIdInput}
|
||||
disabled={state.loading}
|
||||
onChange={setId}
|
||||
/>
|
||||
<label htmlFor="algorithm">Algorithm:</label>
|
||||
<select id={"algorithm"}
|
||||
value={algorithm}
|
||||
disabled={state.loading}
|
||||
onChange={e => setAlgorithm(e.target.value)}>
|
||||
<option value="wilson">Wilson</option>
|
||||
<option value="random">Random Depth First</option>
|
||||
</select>
|
||||
</div>
|
||||
<button type={"submit"}
|
||||
disabled={state.loading
|
||||
|| isNaN(width)
|
||||
|| isNaN(height)
|
||||
}
|
||||
className={styles.submitbutton}>{state.loading ? "Loading ..." : "Create Maze!"}
|
||||
</button>
|
||||
</form>
|
||||
);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue