Scanner.js (2720B)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | import { useState, useEffect } from "react"; import { Alert, Button, Dimensions, StyleSheet, TextInput, View, } from "react-native"; import { CameraView, Camera } from "expo-camera"; import styles, { colors } from "../styles"; const { width } = Dimensions.get("window"); const SCAN_AREA_SIZE = width * 0.7; export default function Scanner({ value, onChange }) { const [hasPermission, setHasPermission] = useState(null); const [useCamera, setUseCamera] = useState(false); const [scanned, setScanned] = useState(false); useEffect(() => { (async () => { const { status } = await Camera.requestCameraPermissionsAsync(); setHasPermission(status === "granted"); })(); }, []); const handleScanned = ({ data }) => { if (!data) { Alert.alert("Scan Failed", "No data found in QR code"); return; } setScanned(true); onChange(data); setUseCamera(false); }; return ( <View style={{ marginVertical: 8 }}> <Button title={useCamera ? "Use Manual Entry" : "Scan QR Code"} color={colors.darkGreen} onPress={() => { setUseCamera(!useCamera); setScanned(false); }} /> {useCamera ? ( !scanned ? ( <View style={{ height: SCAN_AREA_SIZE * 1.4, marginTop: 10 }}> <CameraView style={{ flex: 1 }} onBarcodeScanned={scanned ? undefined : handleScanned} barcodeScannerSettings={{ barcodeTypes: ["qr"] }} /> <View style={cameraStyles.overlay}> <View style={cameraStyles.topBottomOverlay} /> <View style={cameraStyles.middleRow}> <View style={cameraStyles.sideOverlay} /> <View style={cameraStyles.scanArea} /> <View style={cameraStyles.sideOverlay} /> </View> <View style={cameraStyles.topBottomOverlay} /> </View> </View> ) : null ) : ( <TextInput style={[styles.input, { marginTop: 10 }]} placeholder="Enter Produce ID" value={value} onChangeText={onChange} /> )} </View> ); } const cameraStyles = StyleSheet.create({ overlay: { ...StyleSheet.absoluteFillObject, justifyContent: "center", alignItems: "center", }, topBottomOverlay: { flex: 1, width: "100%", backgroundColor: "rgba(0,0,0,0.5)", }, middleRow: { flexDirection: "row", }, sideOverlay: { flex: 1, backgroundColor: "rgba(0,0,0,0.5)", }, scanArea: { width: SCAN_AREA_SIZE, height: SCAN_AREA_SIZE, borderWidth: 2, borderColor: colors.midGreen, }, }); |