From 5944b090488b4ca0dd74eb678ae0e66c71e52e12 Mon Sep 17 00:00:00 2001 From: emergent-agent-e1 Date: Sat, 8 Nov 2025 21:35:15 +0000 Subject: [PATCH] auto-commit for 8033ed4c-21fc-4cc9-a507-2516fe7b0026 --- frontend/src/screens/QRScannerScreen.tsx | 251 +++++++++++++++++++++++ 1 file changed, 251 insertions(+) create mode 100644 frontend/src/screens/QRScannerScreen.tsx diff --git a/frontend/src/screens/QRScannerScreen.tsx b/frontend/src/screens/QRScannerScreen.tsx new file mode 100644 index 00000000..faf88063 --- /dev/null +++ b/frontend/src/screens/QRScannerScreen.tsx @@ -0,0 +1,251 @@ +import React, { useState, useEffect } from 'react'; +import { View, Text, StyleSheet, TouchableOpacity, Alert } from 'react-native'; +import { CameraView, Camera } from 'expo-camera'; +import { Ionicons } from '@expo/vector-icons'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; + +export default function QRScannerScreen({ navigation }: any) { + const insets = useSafeAreaInsets(); + const [hasPermission, setHasPermission] = useState(null); + const [scanned, setScanned] = useState(false); + + useEffect(() => { + requestCameraPermission(); + }, []); + + const requestCameraPermission = async () => { + const { status } = await Camera.requestCameraPermissionsAsync(); + setHasPermission(status === 'granted'); + }; + + const handleBarCodeScanned = ({ type, data }: any) => { + setScanned(true); + Alert.alert( + 'QR Code Scanned', + `Type: ${type}\nData: ${data}`, + [ + { + text: 'Scan Again', + onPress: () => setScanned(false), + }, + { + text: 'OK', + onPress: () => navigation.goBack(), + }, + ] + ); + }; + + if (hasPermission === null) { + return ( + + Requesting camera permission... + + ); + } + + if (hasPermission === false) { + return ( + + + navigation.goBack()} style={styles.backButton}> + + + QR Scanner + + + + + Camera Permission Denied + + Please enable camera access in your device settings to scan QR codes. + + + Request Permission Again + + + + ); + } + + return ( + + + {/* Header Overlay */} + + navigation.goBack()} style={styles.backButton}> + + + Scan QR Code + + + + {/* Scanning Frame */} + + + + + + + + + Position the QR code within the frame + + + + {/* Bottom Actions */} + + {scanned && ( + setScanned(false)} + > + + Scan Again + + )} + + + + ); +} + +const styles = StyleSheet.create({ + container: { + flex: 1, + backgroundColor: '#000', + }, + camera: { + flex: 1, + }, + header: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + paddingHorizontal: 16, + paddingVertical: 16, + backgroundColor: 'rgba(0, 0, 0, 0.5)', + }, + backButton: { + width: 40, + height: 40, + borderRadius: 20, + backgroundColor: 'rgba(255, 255, 255, 0.2)', + alignItems: 'center', + justifyContent: 'center', + }, + headerTitle: { + fontSize: 18, + fontWeight: '700', + color: '#FFF', + }, + scannerContainer: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, + scannerFrame: { + width: 250, + height: 250, + position: 'relative', + }, + corner: { + position: 'absolute', + width: 40, + height: 40, + borderColor: '#EE2A35', + }, + cornerTopLeft: { + top: 0, + left: 0, + borderTopWidth: 4, + borderLeftWidth: 4, + borderTopLeftRadius: 8, + }, + cornerTopRight: { + top: 0, + right: 0, + borderTopWidth: 4, + borderRightWidth: 4, + borderTopRightRadius: 8, + }, + cornerBottomLeft: { + bottom: 0, + left: 0, + borderBottomWidth: 4, + borderLeftWidth: 4, + borderBottomLeftRadius: 8, + }, + cornerBottomRight: { + bottom: 0, + right: 0, + borderBottomWidth: 4, + borderRightWidth: 4, + borderBottomRightRadius: 8, + }, + instructionText: { + marginTop: 32, + fontSize: 16, + color: '#FFF', + textAlign: 'center', + backgroundColor: 'rgba(0, 0, 0, 0.5)', + paddingHorizontal: 24, + paddingVertical: 12, + borderRadius: 8, + }, + bottomContainer: { + padding: 32, + alignItems: 'center', + }, + scanAgainButton: { + flexDirection: 'row', + alignItems: 'center', + backgroundColor: '#EE2A35', + paddingHorizontal: 24, + paddingVertical: 12, + borderRadius: 12, + }, + scanAgainText: { + fontSize: 16, + fontWeight: '600', + color: '#FFF', + marginLeft: 8, + }, + permissionContainer: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + padding: 32, + }, + permissionTitle: { + fontSize: 20, + fontWeight: '700', + color: '#1F2937', + marginTop: 24, + marginBottom: 12, + }, + permissionText: { + fontSize: 16, + color: '#6B7280', + textAlign: 'center', + marginBottom: 24, + }, + settingsButton: { + backgroundColor: '#EE2A35', + paddingHorizontal: 24, + paddingVertical: 12, + borderRadius: 12, + }, + settingsButtonText: { + fontSize: 16, + fontWeight: '600', + color: '#FFF', + }, +});