mirror of
https://github.com/pezkuwichain/pezkuwi-mobile-app.git
synced 2026-06-12 15:51:01 +00:00
auto-commit for 8033ed4c-21fc-4cc9-a507-2516fe7b0026
This commit is contained in:
@@ -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<boolean | null>(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 (
|
||||
<View style={styles.container}>
|
||||
<Text>Requesting camera permission...</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
if (hasPermission === false) {
|
||||
return (
|
||||
<View style={[styles.container, { paddingTop: insets.top }]}>
|
||||
<View style={styles.header}>
|
||||
<TouchableOpacity onPress={() => navigation.goBack()} style={styles.backButton}>
|
||||
<Ionicons name="arrow-back" size={24} color="#FFF" />
|
||||
</TouchableOpacity>
|
||||
<Text style={styles.headerTitle}>QR Scanner</Text>
|
||||
<View style={{ width: 40 }} />
|
||||
</View>
|
||||
<View style={styles.permissionContainer}>
|
||||
<Ionicons name="camera-off" size={64} color="#6B7280" />
|
||||
<Text style={styles.permissionTitle}>Camera Permission Denied</Text>
|
||||
<Text style={styles.permissionText}>
|
||||
Please enable camera access in your device settings to scan QR codes.
|
||||
</Text>
|
||||
<TouchableOpacity style={styles.settingsButton} onPress={requestCameraPermission}>
|
||||
<Text style={styles.settingsButtonText}>Request Permission Again</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<CameraView
|
||||
style={styles.camera}
|
||||
facing="back"
|
||||
onBarcodeScanned={scanned ? undefined : handleBarCodeScanned}
|
||||
barcodeScannerSettings={{
|
||||
barcodeTypes: ['qr'],
|
||||
}}
|
||||
>
|
||||
{/* Header Overlay */}
|
||||
<View style={[styles.header, { paddingTop: insets.top + 16 }]}>
|
||||
<TouchableOpacity onPress={() => navigation.goBack()} style={styles.backButton}>
|
||||
<Ionicons name="arrow-back" size={24} color="#FFF" />
|
||||
</TouchableOpacity>
|
||||
<Text style={styles.headerTitle}>Scan QR Code</Text>
|
||||
<View style={{ width: 40 }} />
|
||||
</View>
|
||||
|
||||
{/* Scanning Frame */}
|
||||
<View style={styles.scannerContainer}>
|
||||
<View style={styles.scannerFrame}>
|
||||
<View style={[styles.corner, styles.cornerTopLeft]} />
|
||||
<View style={[styles.corner, styles.cornerTopRight]} />
|
||||
<View style={[styles.corner, styles.cornerBottomLeft]} />
|
||||
<View style={[styles.corner, styles.cornerBottomRight]} />
|
||||
</View>
|
||||
<Text style={styles.instructionText}>
|
||||
Position the QR code within the frame
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{/* Bottom Actions */}
|
||||
<View style={styles.bottomContainer}>
|
||||
{scanned && (
|
||||
<TouchableOpacity
|
||||
style={styles.scanAgainButton}
|
||||
onPress={() => setScanned(false)}
|
||||
>
|
||||
<Ionicons name="refresh" size={24} color="#FFF" />
|
||||
<Text style={styles.scanAgainText}>Scan Again</Text>
|
||||
</TouchableOpacity>
|
||||
)}
|
||||
</View>
|
||||
</CameraView>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
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',
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user