Tracker made in React for keeping track of HP and MP and so on.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

105 lines
3.3 KiB

import React, {ChangeEvent, useCallback, useMemo, useState} from 'react';
import './App.css';
import {Col, Container, Form, InputGroup, Row,} from "react-bootstrap";
import {Character, CharacterStatus, hpToHealth, SPType} from "./CharacterStatus";
import DefaultPortrait from "./default-portrait.svg"
function App() {
const [maxHp, _setMaxHp] = useState(50)
const [hp, _setHp] = useState(40)
const setHp = useCallback(function (v: number) {
v = Math.floor(v)
if (Number.isNaN(v) || v < 0 || v > maxHp || v === hp) {
return
}
_setHp(v)
}, [hp, maxHp])
const setHpMax = useCallback(function (v: number) {
v = Math.floor(v)
if (Number.isNaN(v) || v < 0 || v > 9999 || v === maxHp) {
return
}
if (v < hp) {
setHp(v)
}
_setMaxHp(v)
}, [hp, maxHp, setHp])
const onHpChange = useCallback(
(e: ChangeEvent<HTMLInputElement>) => setHp(parseInt(e.target.value)), [setHp])
const onMaxHpChange = useCallback(
(e: ChangeEvent<HTMLInputElement>) => setHpMax(parseInt(e.target.value)), [setHpMax])
const [maxMp, _setMaxMp] = useState(1)
const [mp, _setMp] = useState(1)
const setMp = useCallback(function (v: number) {
v = Math.floor(v)
if (Number.isNaN(v) || v < 0 || v > maxMp || v === mp) {
return
}
_setMp(v)
}, [mp, maxMp])
const setMpMax = useCallback(function (v: number) {
v = Math.floor(v)
if (Number.isNaN(v) || v < 0 || v > 9999 || v === maxMp) {
return
}
if (v < mp) {
setMp(v)
}
_setMaxMp(v)
}, [mp, maxMp, setMp])
const onMpChange = useCallback(
(e: ChangeEvent<HTMLInputElement>) => setMp(parseInt(e.target.value)), [setMp])
const onMaxMpChange = useCallback(
(e: ChangeEvent<HTMLInputElement>) => setMpMax(parseInt(e.target.value)), [setMpMax])
const character = useMemo<Character>(() => ({
name: "Test",
level: 26,
hp: hp,
maxHp: maxHp,
mp: 40,
maxMp: 50,
ip: 3,
maxIp: 6,
sp: 3,
spType: SPType.FabulaPoints,
portraitUrl: DefaultPortrait,
health: hpToHealth(hp, maxHp),
turnsTotal: 3,
turnsLeft: 2,}), [hp, maxHp, mp, maxMp])
return <React.Fragment>
<Container fluid>
<Row>
<Col>
<InputGroup>
<InputGroup.Text>Max HP</InputGroup.Text>
<Form.Control type="number" max="9999" min="0" step="1" value={maxHp} onChange={onMaxHpChange} />
</InputGroup>
</Col>
<Col>
<InputGroup>
<InputGroup.Text>Current HP</InputGroup.Text>
<Form.Control type="number" max={maxHp} min="0" step="1" value={hp} onChange={onHpChange} />
</InputGroup>
</Col>
</Row>
<Row>
<Col>
<InputGroup>
<InputGroup.Text>Max MP</InputGroup.Text>
<Form.Control type="number" max="9999" min="0" step="1" value={maxMp} onChange={onMaxMpChange} />
</InputGroup>
</Col>
<Col>
<InputGroup>
<InputGroup.Text>Current MP</InputGroup.Text>
<Form.Control type="number" max={maxMp} min="0" step="1" value={mp} onChange={onMpChange} />
</InputGroup>
</Col>
</Row>
</Container>
<CharacterStatus character={character} active={false} />
</React.Fragment>;
}
export default App;