From 5729def6ca5eeea93ffdb5801be3bf4753c039ee Mon Sep 17 00:00:00 2001 From: Aaron Louie Date: Wed, 2 Sep 2020 12:13:16 -0400 Subject: [PATCH] Adds manual ID number entry screen. Former-commit-id: ffbc16d1223ac8cf4e144a06fd58d3d421f85903 --- App.tsx | 33 +++++++++++++---- app.json | 4 +-- components/Print.tsx | 5 ++- components/Scan.tsx | 59 +++++++++++++++++++++++++++++-- models/BarcodeScannerAppState.tsx | 1 + package-lock.json | 5 +++ package.json | 1 + 7 files changed, 96 insertions(+), 12 deletions(-) diff --git a/App.tsx b/App.tsx index 04b51ab..5eed4d9 100644 --- a/App.tsx +++ b/App.tsx @@ -14,7 +14,7 @@ import { import {expo as appExpo} from './app.json'; import {CancelButton} from './components/Common'; import {BarCodeDisplay, PrintButton, PrintingMessage} from './components/Print'; -import {ScanButton, Scanner} from './components/Scan'; +import {IdNumberInput, InputIdButton, ScanButton, Scanner} from './components/Scan'; import {colors, styles} from './components/Styles'; import {BarcodeScannerAppState} from './models/BarcodeScannerAppState'; import {ElementProps, StateProps} from './models/ElementProps'; @@ -29,6 +29,7 @@ export default function Main() { const [barCodeData, setBarCodeData] = useState(''); const [date, setDate] = useState(new Date()); const [locationStr, setLocationStr] = useState('4321'); + const [errorMessage, setErrorMessage] = useState(''); useEffect(() => { BarCodeScanner.requestPermissionsAsync().then((value: PermissionResponse) => { @@ -41,20 +42,31 @@ export default function Main() { }, []); const _doNothing = () => {}; - const _scan = () => setAppState(BarcodeScannerAppState.SCANNING); + const _scan = () => { + setErrorMessage(''); + setAppState(BarcodeScannerAppState.SCANNING); + }; + const _inputIdNumber = () => { + setErrorMessage(''); + setAppState(BarcodeScannerAppState.INPUT); + }; const _print = () => setAppState(BarcodeScannerAppState.PRINTING); const _home = () => setAppState(BarcodeScannerAppState.DEFAULT); const _settings = () => setAppState(BarcodeScannerAppState.SETTINGS); const handleBarCodeScanned = (e: BarCodeEvent) => { // Make sure the data is the right length. + // Scanned barcodes will be exactly 14 digits long. + // Manually-entered ID numbers will be exactly 9 digits long. const barCodeString = e.data; - const pattern = /^[\d]{14}$/; + const pattern = /^[\d]{14}$|^[\d]{9}$/; if (pattern.test(barCodeString)) { - setBarCodeData(e.data); + const cardId = e.data.slice(0, 9); + setBarCodeData(cardId); setDate(new Date()); setAppState(BarcodeScannerAppState.SCANNED); } else { + setErrorMessage(`The barcode data "${e.data}" is not from a valid ID card.`); setAppState(BarcodeScannerAppState.ERROR); } }; @@ -63,12 +75,13 @@ export default function Main() { return + Something went wrong. Try again. + >{errorMessage === '' ? 'Something went wrong. Try again.' : errorMessage} } @@ -90,7 +103,7 @@ export default function Main() { } - function SettingsModal(props: ElementProps): ReactElement { + function SettingsScreen(props: ElementProps): ReactElement { const [inputStr, setInputStr] = useState(locationStr); const pattern = /^[\d]{4}$/; const hasErrors = () => { @@ -141,6 +154,7 @@ export default function Main() { case BarcodeScannerAppState.DEFAULT: return + ; case BarcodeScannerAppState.PRINTED: return ; @@ -160,8 +174,13 @@ export default function Main() { onScanned={handleBarCodeScanned} onCancel={_home} />; + case BarcodeScannerAppState.INPUT: + return ; case BarcodeScannerAppState.SETTINGS: - return ; + return ; default: return ; } diff --git a/app.json b/app.json index fc4d748..f63eaa6 100644 --- a/app.json +++ b/app.json @@ -19,7 +19,7 @@ ], "ios": { "supportsTablet": true, - "bundleIdentifier": "com.ajlouie.uvacovid19testingkiosk" + "bundleIdentifier": "com.sartography.uvacovid19testingkiosk" }, "web": { "favicon": "./assets/favicon.png" @@ -31,7 +31,7 @@ "web" ], "android": { - "package": "com.ajlouie.uvacovid19testingkiosk" + "package": "com.sartography.uvacovid19testingkiosk" } } } diff --git a/components/Print.tsx b/components/Print.tsx index 90a43ee..e0a6ba8 100644 --- a/components/Print.tsx +++ b/components/Print.tsx @@ -7,6 +7,7 @@ import {BarCodeProps, ButtonProps, PrintingProps} from '../models/ElementProps'; import {colors, styles} from './Styles'; import AsyncStorage from '@react-native-community/async-storage'; import * as Print from 'expo-print'; +import {format} from 'date-fns' enum PrintStatus { SAVING = 'SAVING', @@ -35,7 +36,7 @@ const _renderBarCodeRects = (props: PrintingProps): string => { } const _propsToDataString = (props: BarCodeProps): string => { - return `${props.id}-${props.date.getTime()}-${props.location}`; + return props.id + format(props.date, 'yyyymmdd') + props.location; } const _save = (props: PrintingProps): Promise => { @@ -45,6 +46,8 @@ const _save = (props: PrintingProps): Promise => { date: props.date, location: props.location, }; + console.log('storageKey', storageKey); + console.log('storageVal', storageVal); return AsyncStorage.setItem(storageKey, JSON.stringify(storageVal)); } diff --git a/components/Scan.tsx b/components/Scan.tsx index 92f091c..926d78f 100644 --- a/components/Scan.tsx +++ b/components/Scan.tsx @@ -1,7 +1,7 @@ -import {BarCodeScanner} from 'expo-barcode-scanner'; +import {BarCodeEvent, BarCodeScanner} from 'expo-barcode-scanner'; import React, {ReactElement, useState} from 'react'; import {View, Text} from 'react-native'; -import {Button} from 'react-native-paper'; +import {Button, DefaultTheme, HelperText, Subheading, TextInput, Title} from 'react-native-paper'; import {ButtonProps, ScannerProps} from '../models/ElementProps'; import {colors, styles} from './Styles'; @@ -63,3 +63,58 @@ export const ScanButton = (props: ButtonProps): ReactElement => { labelStyle={styles.btnLg} >Scan Barcode; }; + +export const InputIdButton = (props: ButtonProps): ReactElement => { + return ; +}; + +export const IdNumberInput = (props: ScannerProps): ReactElement => { + const [inputStr, setInputStr] = useState(''); + const pattern = /^[\d]{9}$/; + const hasErrors = () => { + return !pattern.test(inputStr); + }; + + const onSubmit = () => { + console.log('onSubmit inputStr =', inputStr); + props.onScanned({type: '', data: inputStr}); + } + + return + Settings + + + Please double check that you have entered the number correctly. Entering an incorrect ID number will prevent patients from receiving their test results. + + setInputStr(inputStr)} + mode="outlined" + theme={DefaultTheme} + /> + + ID number must be exactly 9 digits. No other characters are allowed. + + + + + ; +}; diff --git a/models/BarcodeScannerAppState.tsx b/models/BarcodeScannerAppState.tsx index c11e1e6..e7a8c2d 100644 --- a/models/BarcodeScannerAppState.tsx +++ b/models/BarcodeScannerAppState.tsx @@ -3,6 +3,7 @@ export enum BarcodeScannerAppState { DEFAULT = 'DEFAULT', SCANNING = 'SCANNING', SCANNED = 'SCANNED', + INPUT = 'INPUT', PRINTING = 'PRINTING', PRINTED = 'PRINTED', ERROR = 'ERROR', diff --git a/package-lock.json b/package-lock.json index 2dfe024..e9fc283 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5440,6 +5440,11 @@ "whatwg-url": "^7.0.0" } }, + "date-fns": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.16.1.tgz", + "integrity": "sha512-sAJVKx/FqrLYHAQeN7VpJrPhagZc9R4ImZIWYRFZaaohR3KzmuK88touwsSwSVT8Qcbd4zoDsnGfX4GFB4imyQ==" + }, "dayjs": { "version": "1.8.34", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.34.tgz", diff --git a/package.json b/package.json index b473441..f3558ac 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "dependencies": { "@react-native-community/async-storage": "^1.12.0", "@react-native-community/netinfo": "^5.9.6", + "date-fns": "^2.16.1", "expo": "~38.0.8", "expo-barcode-scanner": "~8.2.1", "expo-print": "~9.0.1",