149 lines
3.1 KiB
JavaScript
149 lines
3.1 KiB
JavaScript
import { useState, useEffect } from 'react';
|
|
import BarcodeScannerComponent from 'react-qr-barcode-scanner';
|
|
import Container from 'react-bootstrap/Container';
|
|
import Row from 'react-bootstrap/Row';
|
|
import Col from 'react-bootstrap/Col';
|
|
import Table from 'react-bootstrap/Table';
|
|
import Alert from 'react-bootstrap/Alert';
|
|
import Form from 'react-bootstrap/Form';
|
|
import Button from 'react-bootstrap/Button';
|
|
|
|
import './App.css';
|
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
|
|
|
function App() {
|
|
// Ensure we have persistent (informal) user information
|
|
const [user, setUser] = useState("");
|
|
useEffect(() => {
|
|
const user = localStorage.getItem('user');
|
|
if (user) {
|
|
setUser(user);
|
|
}
|
|
}, []);
|
|
useEffect(() => {
|
|
localStorage.setItem('user', user);
|
|
}, [user]);
|
|
|
|
// If no user, must be scanned/set otherwise
|
|
return (
|
|
<Container>
|
|
{user === "" ?
|
|
<NoUserView setUser={setUser} />
|
|
:
|
|
<UserView user={user} setUser={setUser} />}
|
|
</Container>
|
|
);
|
|
}
|
|
|
|
function NoUserView({setUser}) {
|
|
const [preUser, setPreUser] = useState("");
|
|
return (
|
|
<>
|
|
<Row>
|
|
<Col>
|
|
<Form.Group>
|
|
<Form.Label>User:</Form.Label>
|
|
<Form.Control type="text" placeholder="Username"
|
|
value={preUser} onChange={(v) => setPreUser(v.target.value)} />
|
|
<Form.Text>Which user is using this App?</Form.Text>
|
|
</Form.Group>
|
|
</Col>
|
|
</Row>
|
|
<Row>
|
|
<Col>
|
|
Scanner
|
|
</Col>
|
|
</Row>
|
|
<Row>
|
|
<Col>
|
|
<Button variant="primary"
|
|
onClick={() => setUser(preUser)}>Set!</Button>
|
|
</Col>
|
|
</Row>
|
|
</>
|
|
);
|
|
}
|
|
|
|
function UserView({user, setUser}) {
|
|
return (
|
|
<Row>
|
|
<Col>
|
|
{user}
|
|
</Col>
|
|
<Col>
|
|
<Button variant="info" onClick={() => setUser('')}>Change</Button>
|
|
</Col>
|
|
<BarItemScanner />
|
|
</Row>
|
|
);
|
|
}
|
|
|
|
function BarItemScanner() {
|
|
const [reqAccount, setReqAccount] = useState('');
|
|
const [actAccount, setActAccount] = useState('');
|
|
const [balance, setBalance] = useState(-1);
|
|
const [statusMsg, setStatusMsg] = useState('');
|
|
const [msgType, setMsgType] = useState('info');
|
|
|
|
const handleScan = async (err, result) => {
|
|
if (result) {
|
|
const ra = result.text;
|
|
setReqAccount(ra);
|
|
setStatusMsg('Loading');
|
|
setMsgType('primary');
|
|
try {
|
|
const resp = await fetch('/api/barcode/' + ra);
|
|
if (resp.ok) {
|
|
const json = await resp.json();
|
|
setActAccount(ra);
|
|
setBalance(json.amount);
|
|
setStatusMsg('OK');
|
|
setMsgType('success');
|
|
}
|
|
} catch(ex) {
|
|
setMsgType('danger');
|
|
setStatusMsg(ex.message);
|
|
}
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<Row>
|
|
<Col>
|
|
<BarcodeScannerComponent
|
|
width={"100%"}
|
|
height={"auto"}
|
|
onUpdate={handleScan}
|
|
delay={1500}
|
|
/>
|
|
</Col>
|
|
</Row>
|
|
<Row>
|
|
<Col>
|
|
<Table>
|
|
<tr>
|
|
<th>Requested:</th>
|
|
<td>{reqAccount}</td>
|
|
</tr>
|
|
<tr>
|
|
<th>Loaded:</th>
|
|
<td>{actAccount}</td>
|
|
</tr>
|
|
<tr>
|
|
<th>Balance:</th>
|
|
<td>{balance}</td>
|
|
</tr>
|
|
</Table>
|
|
</Col>
|
|
</Row>
|
|
<Row>
|
|
<Col>
|
|
<Alert variant={msgType}>{statusMsg}</Alert>
|
|
</Col>
|
|
</Row>
|
|
</>
|
|
);
|
|
}
|
|
|
|
export default App;
|