Compare commits
	
		
			5 commits
		
	
	
		
			83aeeea050
			...
			1815547daf
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 1815547daf | |||
| a0752bb73a | |||
| 0677419d40 | |||
| b65740e214 | |||
| d285587754 | 
					 7 changed files with 232 additions and 69 deletions
				
			
		
							
								
								
									
										89
									
								
								0PLAN.org
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								0PLAN.org
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,89 @@ | ||||||
|  | #+title: Frontend | ||||||
|  | 
 | ||||||
|  | * Plan | ||||||
|  | 
 | ||||||
|  | ** 0.2 | ||||||
|  | 
 | ||||||
|  | - [-] use localStorage to store user | ||||||
|  |   - [ ] add barcode scanner to get the user | ||||||
|  |   - [X] allow editing | ||||||
|  |   - [X] add UserSelect component | ||||||
|  | - [X] integrate script for starting build qemu system | ||||||
|  | - [X] add org file to the repository after cleanup | ||||||
|  | 
 | ||||||
|  | ** 0.3 | ||||||
|  | 
 | ||||||
|  | - [ ] versioned schema support | ||||||
|  |   - [ ] barschema table | ||||||
|  |   - [ ] function to check | ||||||
|  |   - [ ] function to set | ||||||
|  |   - [ ] initial creation of tables at version 1 assuming OK if tables exist | ||||||
|  | 
 | ||||||
|  | ** 0.4 | ||||||
|  | 
 | ||||||
|  | - [ ] add inventory check table | ||||||
|  | - [ ] add inventory item check table | ||||||
|  | - [ ] create new check | ||||||
|  | - [ ] check item | ||||||
|  | - [ ] close check | ||||||
|  | - [ ] inventory check component | ||||||
|  | 
 | ||||||
|  | ** Later | ||||||
|  | 
 | ||||||
|  | - [ ] add static token support | ||||||
|  |   - [ ] hardwired token for the React.JS app? | ||||||
|  | - [ ] authentication | ||||||
|  |   - [ ] login/logout | ||||||
|  |   - [ ] allow API calls only with login token | ||||||
|  | 
 | ||||||
|  | * Finished | ||||||
|  | 
 | ||||||
|  | ** 0.1 | ||||||
|  | 
 | ||||||
|  | - [X] statically compiled binary HTTP server | ||||||
|  | - [X] include directory tree contents | ||||||
|  | - [X] handle frontend with mime type | ||||||
|  | - [X] move app to / again | ||||||
|  | - [X] load certificates | ||||||
|  | - [X] deployment preparations | ||||||
|  |   - [X] crosscompilation - no, compile in qemu or on separate host | ||||||
|  |   - [X] connect to postgres | ||||||
|  |   - [X] use qr-scanner - no, qr-barcode-scanner is needed | ||||||
|  |   - [X] rsync + build in qemu or host without react (filters or something) | ||||||
|  | - [X] API infrastructure | ||||||
|  |   - [X] handle API calls | ||||||
|  |   - [X] API registry syntax | ||||||
|  |   - [X] lookup barcode in DB | ||||||
|  |   - [X] separate module brmbar-data for queries | ||||||
|  |   - [X] separate module api-servlets | ||||||
|  | 
 | ||||||
|  | * Qemu | ||||||
|  | 
 | ||||||
|  | #+BEGIN_SRC | ||||||
|  | wget img zip # 2019-04-08-raspbian-stretch.zip | ||||||
|  | unzip 2019-04-08-raspbian-stretch.zip | ||||||
|  | sudo mkdir /mnt/image | ||||||
|  | sudo mount -o loop,offset=4194304 2019-04-08-raspbian-stretch.img /mnt/image/ | ||||||
|  | # In qemu-system-armhf terminal! | ||||||
|  | cp kernel, DT | ||||||
|  | umount /mnt/image | ||||||
|  | resize img | ||||||
|  | #+END_SRC | ||||||
|  | 
 | ||||||
|  | sources.list - archive debian (remove rpi), archive raspberry | ||||||
|  | https://archive.raspberrypi.org/debian/ | ||||||
|  | https://archive.debian.org/debian/ | ||||||
|  | apt-get --no | ||||||
|  | 
 | ||||||
|  | * React - Vite | ||||||
|  | 
 | ||||||
|  | #+BEGIN_SRC sh | ||||||
|  |   npm create vite@latest | ||||||
|  |   # "frontend" | ||||||
|  |   # React | ||||||
|  |   # Javascript | ||||||
|  |   cd frontend | ||||||
|  |   npm install | ||||||
|  |   npm run dev | ||||||
|  |   npm run build | ||||||
|  | #+END_SRC | ||||||
|  | @ -47,6 +47,7 @@ | ||||||
| (define -db-user- (make-parameter #f)) | (define -db-user- (make-parameter #f)) | ||||||
| (define -db-name- (make-parameter #f)) | (define -db-name- (make-parameter #f)) | ||||||
| (define -db-pass- (make-parameter #f)) | (define -db-pass- (make-parameter #f)) | ||||||
|  | (define -db-enabled- (make-parameter #t)) | ||||||
| 
 | 
 | ||||||
| (command-line | (command-line | ||||||
|  print-help |  print-help | ||||||
|  | @ -82,6 +83,8 @@ | ||||||
|       (-db-user- dbuser)) |       (-db-user- dbuser)) | ||||||
|  (-dp (dbpass) "Database password" |  (-dp (dbpass) "Database password" | ||||||
|       (-db-pass- dbpass)) |       (-db-pass- dbpass)) | ||||||
|  |  (-dd () "Disable database" | ||||||
|  |       (-db-enabled- #f)) | ||||||
|  ) |  ) | ||||||
| 
 | 
 | ||||||
| (define ssl? (and (-certificate-) (-key-) #t)) | (define ssl? (and (-certificate-) (-key-) #t)) | ||||||
|  | @ -120,7 +123,8 @@ | ||||||
| (print "current user id: " (current-user-id)) | (print "current user id: " (current-user-id)) | ||||||
| (print "current effective user id: " (current-effective-user-id)) | (print "current effective user id: " (current-effective-user-id)) | ||||||
| 
 | 
 | ||||||
| (bar-db-init! (-db-name-) (-db-host-) (-db-user-) (-db-pass-)) | (when (-db-enabled-) | ||||||
|  |   (bar-db-init! (-db-name-) (-db-host-) (-db-user-) (-db-pass-))) | ||||||
| 
 | 
 | ||||||
| (define (handle-api-calls) | (define (handle-api-calls) | ||||||
|   (define plst (cdr (uri-path (request-uri (current-request))))) |   (define plst (cdr (uri-path (request-uri (current-request))))) | ||||||
|  |  | ||||||
|  | @ -1,13 +1,84 @@ | ||||||
| import { useState } from 'react'; | import { useState, useEffect } from 'react'; | ||||||
| import BarcodeScannerComponent from 'react-qr-barcode-scanner'; | import BarcodeScannerComponent from 'react-qr-barcode-scanner'; | ||||||
| import { Container, Row, Col } from 'react-bootstrap'; | 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 Table from 'react-bootstrap/Table'; | ||||||
| import Alert from 'react-bootstrap/Alert'; | import Alert from 'react-bootstrap/Alert'; | ||||||
|  | import Form from 'react-bootstrap/Form'; | ||||||
|  | import Button from 'react-bootstrap/Button'; | ||||||
| 
 | 
 | ||||||
| import './App.css'; | import './App.css'; | ||||||
| import 'bootstrap/dist/css/bootstrap.min.css'; | import 'bootstrap/dist/css/bootstrap.min.css'; | ||||||
| 
 | 
 | ||||||
| function App() { | 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 [reqAccount, setReqAccount] = useState(''); | ||||||
|     const [actAccount, setActAccount] = useState(''); |     const [actAccount, setActAccount] = useState(''); | ||||||
|     const [balance, setBalance] = useState(-1); |     const [balance, setBalance] = useState(-1); | ||||||
|  | @ -37,7 +108,7 @@ function App() { | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
| 	<Container> | 	<> | ||||||
| 	    <Row> | 	    <Row> | ||||||
| 		<Col> | 		<Col> | ||||||
| 		    <BarcodeScannerComponent | 		    <BarcodeScannerComponent | ||||||
|  | @ -71,7 +142,7 @@ function App() { | ||||||
| 		    <Alert variant={msgType}>{statusMsg}</Alert> | 		    <Alert variant={msgType}>{statusMsg}</Alert> | ||||||
| 		</Col> | 		</Col> | ||||||
| 	    </Row> | 	    </Row> | ||||||
| 	</Container> | 	</> | ||||||
|     ); |     ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,64 +0,0 @@ | ||||||
| #!/bin/sh |  | ||||||
| # |  | ||||||
| # install-eggs.sh |  | ||||||
| # |  | ||||||
| # Local installer of CHICKEN eggs required for building. |  | ||||||
| # |  | ||||||
| # ISC License |  | ||||||
| # |  | ||||||
| # Copyright 2023 Brmlab, z.s. |  | ||||||
| # Dominik Pantůček <dominik.pantucek@trustica.cz> |  | ||||||
| # |  | ||||||
| # Permission to use, copy, modify, and/or distribute this software |  | ||||||
| # for any purpose with or without fee is hereby granted, provided |  | ||||||
| # that the above copyright notice and this permission notice appear |  | ||||||
| # in all copies. |  | ||||||
| #  |  | ||||||
| # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL |  | ||||||
| # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |  | ||||||
| # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE |  | ||||||
| # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR |  | ||||||
| # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS |  | ||||||
| # OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, |  | ||||||
| # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |  | ||||||
| # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |  | ||||||
| # |  | ||||||
| 
 |  | ||||||
| # Source root directory |  | ||||||
| owd=$(pwd) |  | ||||||
| cd $(dirname "$0") |  | ||||||
| SRCDIR=$(pwd) |  | ||||||
| cd "$owd" |  | ||||||
| 
 |  | ||||||
| # Make temporary prefix directory (eggs shared throwaway files) |  | ||||||
| TMPDIR=$(mktemp -d) |  | ||||||
| 
 |  | ||||||
| # Installs given egg locally |  | ||||||
| chicken_install() { |  | ||||||
|     echo "Installing $1 ..." |  | ||||||
|     # CHICKEN_INSTALL_PREFIX="$TMPDIR" \ |  | ||||||
|     # 			  CHICKEN_REPOSITORY_PATH="$SRCDIR/eggs-arm":`./cross-chicken-arm/bin/arm-chicken-install -repository` \ |  | ||||||
|     # 			  CHICKEN_INSTALL_REPOSITORY="$SRCDIR/eggs-arm" \ |  | ||||||
|     # 			  ./cross-chicken-arm/bin/arm-chicken-install "$1" 2>&1 | \ |  | ||||||
|     # 	sed -u 's/^/  /' |  | ||||||
| #    CHICKEN_INSTALL_PREFIX="$TMPDIR" \ |  | ||||||
| 			  ./cross-chicken-arm/bin/arm-chicken-install "$1" 2>&1 | \ |  | ||||||
| 	sed -u 's/^/  /' |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| # Removes throwaway files |  | ||||||
| chicken_cleanup() { |  | ||||||
|     echo "Cleaning up ..." |  | ||||||
|     rm -fr ${TMPDIR} |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| # Always cleanup |  | ||||||
| trap chicken_cleanup INT QUIT |  | ||||||
| 
 |  | ||||||
| # Install required eggs |  | ||||||
| chicken_install spiffy |  | ||||||
| chicken_install openssl |  | ||||||
| chicken_install postgresql |  | ||||||
| 
 |  | ||||||
| # Normal termination cleanup |  | ||||||
| chicken_cleanup |  | ||||||
|  | @ -57,6 +57,7 @@ chicken_install openssl | ||||||
| chicken_install spiffy | chicken_install spiffy | ||||||
| chicken_install postgresql | chicken_install postgresql | ||||||
| chicken_install json | chicken_install json | ||||||
|  | chicken_install posix-groups | ||||||
| 
 | 
 | ||||||
| # Normal termination cleanup | # Normal termination cleanup | ||||||
| chicken_cleanup | chicken_cleanup | ||||||
|  |  | ||||||
|  | @ -1,4 +1,28 @@ | ||||||
| #!/bin/sh | #!/bin/sh | ||||||
|  | # | ||||||
|  | # build-in-qemu.sh | ||||||
|  | # | ||||||
|  | # Expects running armhf qemu system, builds the binary inside. | ||||||
|  | # | ||||||
|  | # ISC License | ||||||
|  | # | ||||||
|  | # Copyright 2025 Brmlab, z.s. | ||||||
|  | # Dominik Pantůček <dominik.pantucek@trustica.cz> | ||||||
|  | # | ||||||
|  | # Permission to use, copy, modify, and/or distribute this software | ||||||
|  | # for any purpose with or without fee is hereby granted, provided | ||||||
|  | # that the above copyright notice and this permission notice appear | ||||||
|  | # in all copies. | ||||||
|  | #  | ||||||
|  | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL | ||||||
|  | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED | ||||||
|  | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE | ||||||
|  | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR | ||||||
|  | # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | ||||||
|  | # OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, | ||||||
|  | # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||||||
|  | # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||||
|  | # | ||||||
| 
 | 
 | ||||||
| if [ -z "$1" ] ; then | if [ -z "$1" ] ; then | ||||||
|     echo "Usage: $0 password" |     echo "Usage: $0 password" | ||||||
|  |  | ||||||
							
								
								
									
										38
									
								
								tools/run-build-qemu-system.sh
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								tools/run-build-qemu-system.sh
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,38 @@ | ||||||
|  | #!/bin/sh | ||||||
|  | # | ||||||
|  | # run-build-qemu-system.sh | ||||||
|  | # | ||||||
|  | # Runs the emulated armhf system for building the application. | ||||||
|  | # | ||||||
|  | # ISC License | ||||||
|  | # | ||||||
|  | # Copyright 2025 Brmlab, z.s. | ||||||
|  | # Dominik Pantůček <dominik.pantucek@trustica.cz> | ||||||
|  | # | ||||||
|  | # Permission to use, copy, modify, and/or distribute this software | ||||||
|  | # for any purpose with or without fee is hereby granted, provided | ||||||
|  | # that the above copyright notice and this permission notice appear | ||||||
|  | # in all copies. | ||||||
|  | #  | ||||||
|  | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL | ||||||
|  | # WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED | ||||||
|  | # WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE | ||||||
|  | # AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR | ||||||
|  | # CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS | ||||||
|  | # OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, | ||||||
|  | # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | ||||||
|  | # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||||||
|  | # | ||||||
|  | 
 | ||||||
|  | qemu-system-armhf \ | ||||||
|  |     -machine raspi2b \ | ||||||
|  |     -nographic \ | ||||||
|  |     -dtb bcm2710-rpi-3-b-plus.dtb \ | ||||||
|  |     -m 1G \ | ||||||
|  |     -smp 4 \ | ||||||
|  |     -kernel kernel7.img \ | ||||||
|  |     -sd 2019-04-08-raspbian-stretch.img \ | ||||||
|  |     -append "rw earlyprintk loglevel=8 console=ttyAMA0,115200 root=/dev/mmcblk0p2 rootdelay=1 dwc_otg.fiq_fsm_enable=0" \ | ||||||
|  |     -usb \ | ||||||
|  |     -device usb-net,netdev=net0 \ | ||||||
|  |     -netdev user,id=net0,hostfwd=tcp::2222-:22 | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue