segregated the ScannedDataBox from the QRScannerScreen , so that Historyscreen can use the ScannedDataBox
This commit is contained in:
125
components/ScannedDataBox.tsx
Normal file
125
components/ScannedDataBox.tsx
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { View, Text, StyleSheet, Image, TouchableOpacity } from 'react-native';
|
||||||
|
import QRCode from 'react-native-qrcode-svg';
|
||||||
|
import { Ionicons } from '@expo/vector-icons';
|
||||||
|
|
||||||
|
interface ScannedDataBoxProps {
|
||||||
|
data: string;
|
||||||
|
scanResult: any;
|
||||||
|
dataType: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ScannedDataBox: React.FC<ScannedDataBoxProps> = ({ data, scanResult, dataType }) => {
|
||||||
|
const extractedData = data.split('\n')[1]?.split('Data: ')[1] || '';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.dataBox}>
|
||||||
|
<View style={styles.row}>
|
||||||
|
<Image source={require('../assets/ScanIcon3.png')} style={styles.scan_icon} />
|
||||||
|
<Text style={styles.payload}>{extractedData}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={styles.divider} />
|
||||||
|
<Text style={styles.timestampText}>{new Date().toLocaleString()}</Text>
|
||||||
|
<View style={styles.qrContainer}>
|
||||||
|
<QRCode value={extractedData} size={100} backgroundColor="transparent" />
|
||||||
|
<Text style={styles.resultText}>
|
||||||
|
Result: {scanResult && scanResult.positive > 0 ? 'DANGEROUS' : 'SAFE'}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
<View style={styles.divider} />
|
||||||
|
<Text style={styles.typeText}>Type: {dataType}</Text>
|
||||||
|
<Text style={styles.blankLine}>{'\n'}</Text>
|
||||||
|
<Text style={styles.checksText}>Checks</Text>
|
||||||
|
<Text style={styles.checksText}>Secure Connection: ✘</Text>
|
||||||
|
<Text style={styles.checksText}>Virus Total Check: ✘</Text>
|
||||||
|
<Text style={styles.checksText}>Redirects: 2</Text>
|
||||||
|
<View style={styles.iconContainer}>
|
||||||
|
<TouchableOpacity style={styles.iconButton}>
|
||||||
|
<Ionicons name="share-social" size={24} color="#2196F3" />
|
||||||
|
<Text style={styles.iconText}>Share</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<TouchableOpacity style={styles.iconButton}>
|
||||||
|
<Ionicons name="open" size={24} color="#2196F3" />
|
||||||
|
<Text style={styles.iconText}>Open</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
row: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
scan_icon: {
|
||||||
|
width: 50,
|
||||||
|
height: 50,
|
||||||
|
marginRight: 8,
|
||||||
|
},
|
||||||
|
payload: {
|
||||||
|
fontSize: 20,
|
||||||
|
color: '#000',
|
||||||
|
marginBottom: 1,
|
||||||
|
},
|
||||||
|
dataBox: {
|
||||||
|
padding: 20,
|
||||||
|
backgroundColor: '#ffe6f0',
|
||||||
|
borderRadius: 10,
|
||||||
|
shadowColor: '#000',
|
||||||
|
shadowOffset: { width: 0, height: 2 },
|
||||||
|
shadowOpacity: 0.2,
|
||||||
|
shadowRadius: 5,
|
||||||
|
elevation: 3,
|
||||||
|
zIndex: 1,
|
||||||
|
},
|
||||||
|
qrContainer: {
|
||||||
|
alignItems: 'center',
|
||||||
|
marginVertical: 10,
|
||||||
|
},
|
||||||
|
blankLine: {
|
||||||
|
height: 20,
|
||||||
|
},
|
||||||
|
divider: {
|
||||||
|
height: 1,
|
||||||
|
backgroundColor: '#ddd',
|
||||||
|
marginVertical: 10,
|
||||||
|
alignSelf: 'stretch',
|
||||||
|
},
|
||||||
|
timestampText: {
|
||||||
|
fontSize: 12,
|
||||||
|
color: '#000',
|
||||||
|
marginBottom: 10,
|
||||||
|
},
|
||||||
|
resultText: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: '#ff0000',
|
||||||
|
marginBottom: 10,
|
||||||
|
textAlign: 'center',
|
||||||
|
},
|
||||||
|
typeText: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: '#000',
|
||||||
|
marginBottom: 10,
|
||||||
|
},
|
||||||
|
checksText: {
|
||||||
|
fontSize: 16,
|
||||||
|
color: '#000',
|
||||||
|
marginBottom: 5,
|
||||||
|
},
|
||||||
|
iconContainer: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
marginTop: 10,
|
||||||
|
},
|
||||||
|
iconButton: {
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
|
iconText: {
|
||||||
|
color: '#2196F3',
|
||||||
|
marginTop: 5,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default ScannedDataBox;
|
||||||
@@ -1,23 +1,34 @@
|
|||||||
import React, { useContext } from 'react';
|
import React, { useContext, useState } from 'react';
|
||||||
import { View, Text, StyleSheet, FlatList } from 'react-native';
|
import { View, Text, StyleSheet, FlatList, TouchableOpacity } from 'react-native';
|
||||||
import { QRCodeContext } from '../types';
|
import { QRCodeContext } from '../types';
|
||||||
|
import ScannedDataBox from '../components/ScannedDataBox';
|
||||||
|
|
||||||
const HistoryScreen: React.FC = () => {
|
const HistoryScreen: React.FC = () => {
|
||||||
const qrCodeContext = useContext(QRCodeContext);
|
const qrCodeContext = useContext(QRCodeContext);
|
||||||
|
|
||||||
// Safely access qrCodes and handle the case when the context is null
|
const { qrCodes, setCurrentScannedData } = qrCodeContext || { qrCodes: [], setCurrentScannedData: () => {} };
|
||||||
const qrCodes = qrCodeContext ? qrCodeContext.qrCodes : [];
|
|
||||||
|
const [selectedData, setSelectedData] = useState<string | null>(null);
|
||||||
|
const [scanResult, setScanResult] = useState<any>(null); // KI for testing
|
||||||
|
const [dataType, setDataType] = useState<string>(''); // KIV
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Text style={styles.welcomeText}>History Screen</Text>
|
<Text style={styles.welcomeText}>History Screen</Text>
|
||||||
|
{selectedData && (
|
||||||
|
<ScannedDataBox data={selectedData} scanResult={scanResult} dataType={dataType} />
|
||||||
|
)}
|
||||||
<FlatList
|
<FlatList
|
||||||
data={qrCodes}
|
data={qrCodes}
|
||||||
renderItem={({ item }) => (
|
renderItem={({ item }) => (
|
||||||
<View style={styles.dataBox}>
|
<TouchableOpacity onPress={() => setSelectedData(item)}>
|
||||||
<Text style={styles.dataText}>{item}</Text>
|
<View style={styles.dataBox}>
|
||||||
</View>
|
<Text style={styles.dataText}>{item}</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableOpacity>
|
||||||
)}
|
)}
|
||||||
keyExtractor={(item, index) => index.toString()}
|
keyExtractor={(item, index) => index.toString()}
|
||||||
|
contentContainerStyle={styles.flatListContent}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
@@ -47,6 +58,9 @@ const styles = StyleSheet.create({
|
|||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
color: '#000',
|
color: '#000',
|
||||||
},
|
},
|
||||||
|
flatListContent: {
|
||||||
|
paddingBottom: 100, // Add padding to the bottom so that it wont kenna hidden by nav bar
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default HistoryScreen;
|
export default HistoryScreen;
|
||||||
|
|||||||
0
screens/QRCodeProvider.tsx
Normal file
0
screens/QRCodeProvider.tsx
Normal file
@@ -7,6 +7,7 @@ import { Ionicons } from '@expo/vector-icons'; // For icons
|
|||||||
import { useNavigation } from '@react-navigation/native';
|
import { useNavigation } from '@react-navigation/native';
|
||||||
import * as ImagePicker from 'expo-image-picker';
|
import * as ImagePicker from 'expo-image-picker';
|
||||||
import QRCode from 'react-native-qrcode-svg';
|
import QRCode from 'react-native-qrcode-svg';
|
||||||
|
import ScannedDataBox from '../components/ScannedDataBox';
|
||||||
|
|
||||||
|
|
||||||
//-----------------FUNCTIONS DECLARED HERE------------------//
|
//-----------------FUNCTIONS DECLARED HERE------------------//
|
||||||
@@ -244,97 +245,39 @@ const QRScannerScreen: React.FC<QRScannerScreenProps> = ({ clearScanData }) => {
|
|||||||
<Ionicons name="image" size={24} color="#fff" />
|
<Ionicons name="image" size={24} color="#fff" />
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
|
|
||||||
</View>
|
|
||||||
|
|
||||||
{/* The CONTENT , the popup for the scanned data */}
|
{/* The CONTENT , the popup for the scanned data */}
|
||||||
|
{/* This is called from ../components/ScannedDataBox*/}
|
||||||
|
</View>
|
||||||
{scannedData !== '' && (
|
{scannedData !== '' && (
|
||||||
<View style={styles.dataBox}>
|
<View style={styles.scannedDataBox}>
|
||||||
<View style={styles.row}>
|
<ScannedDataBox data={scannedData} scanResult={scanResult} dataType={dataType} />
|
||||||
<Image source={require('../assets/ScanIcon3.png')} style={styles.scan_icon} />
|
|
||||||
<Text style={styles.payload}>{extractedData}</Text>
|
|
||||||
</View>
|
|
||||||
<View style={styles.divider} />
|
|
||||||
<Text style={styles.timestampText}>{new Date().toLocaleString()}</Text>
|
|
||||||
<View style={styles.qrContainer}>
|
|
||||||
<QRCode value={extractedData} size={100} backgroundColor="transparent" />
|
|
||||||
<Text style={styles.resultText}>
|
|
||||||
Result: {scanResult && scanResult.positive > 0 ? 'DANGEROUS' : 'SAFE'}
|
|
||||||
</Text>
|
|
||||||
</View>
|
|
||||||
<View style={styles.divider} />
|
|
||||||
<Text style={styles.typeText}>Type: {dataType}</Text>
|
|
||||||
<Text style={styles.blankLine}>{'\n'}</Text>
|
|
||||||
<Text style={styles.checksText}>Checks</Text>
|
|
||||||
<Text style={styles.checksText}>Secure Connection: ✘</Text>
|
|
||||||
<Text style={styles.checksText}>Virus Total Check: ✘</Text>
|
|
||||||
<Text style={styles.checksText}>Redirects: 2</Text>
|
|
||||||
<View style={styles.iconContainer}>
|
|
||||||
<TouchableOpacity style={styles.iconButton}>
|
|
||||||
<Ionicons name="share-social" size={24} color="#2196F3" />
|
|
||||||
<Text style={styles.iconText}>Share</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
<TouchableOpacity style={styles.iconButton}>
|
|
||||||
<Ionicons name="open" size={24} color="#2196F3" />
|
|
||||||
<Text style={styles.iconText}>Open</Text>
|
|
||||||
</TouchableOpacity>
|
|
||||||
</View>
|
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
// Container for the main screen
|
|
||||||
container: {
|
container: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
backgroundColor: '#f8f0fc',
|
backgroundColor: '#f8f0fc',
|
||||||
padding: 20,
|
padding: 20,
|
||||||
},
|
},
|
||||||
|
|
||||||
// Row for aligning items horizontally
|
|
||||||
row: {
|
|
||||||
flexDirection: 'row',
|
|
||||||
alignItems: 'center',
|
|
||||||
},
|
|
||||||
|
|
||||||
// Icon for scanned data
|
|
||||||
scan_icon: {
|
|
||||||
width: 50, // Adjust the size as needed
|
|
||||||
height: 50,
|
|
||||||
marginRight: 8, // Space between icon and text
|
|
||||||
},
|
|
||||||
|
|
||||||
// Text for payload display
|
|
||||||
payload: {
|
|
||||||
fontSize: 20,
|
|
||||||
color: '#000',
|
|
||||||
marginBottom: 1,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Banner container
|
|
||||||
banner: {
|
banner: {
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
marginBottom: 20,
|
marginBottom: 20,
|
||||||
},
|
},
|
||||||
|
|
||||||
// Text for the header
|
|
||||||
headerText: {
|
headerText: {
|
||||||
fontSize: 24,
|
fontSize: 24,
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
color: '#ff69b4',
|
color: '#ff69b4',
|
||||||
},
|
},
|
||||||
|
|
||||||
// Container for splash screen
|
|
||||||
splashContainer: {
|
splashContainer: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
backgroundColor: '#f8f0fc',
|
backgroundColor: '#f8f0fc',
|
||||||
},
|
},
|
||||||
|
|
||||||
// Container for camera view
|
|
||||||
cameraContainer: {
|
cameraContainer: {
|
||||||
height: '60%',
|
height: '60%',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
@@ -342,124 +285,21 @@ const styles = StyleSheet.create({
|
|||||||
borderRadius: 10,
|
borderRadius: 10,
|
||||||
overflow: 'hidden',
|
overflow: 'hidden',
|
||||||
},
|
},
|
||||||
|
|
||||||
// Camera style
|
|
||||||
camera: {
|
camera: {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
},
|
},
|
||||||
|
|
||||||
// Button for flashlight
|
|
||||||
flashButton: {
|
flashButton: {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
bottom: 20,
|
bottom: 20,
|
||||||
left: 100, // Adjust this value to move it more or less to the left
|
left: 100,
|
||||||
width: 50,
|
width: 50,
|
||||||
height: 50,
|
height: 50,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
backgroundColor: '#000',
|
backgroundColor: '#000',
|
||||||
borderRadius: 25, // Half of width and height to make it a circle
|
borderRadius: 25,
|
||||||
},
|
},
|
||||||
|
|
||||||
// Box for displaying scanned data
|
|
||||||
dataBox: {
|
|
||||||
position: 'absolute',
|
|
||||||
top: '10%',
|
|
||||||
left: '5%',
|
|
||||||
right: '5%',
|
|
||||||
padding: 20,
|
|
||||||
backgroundColor: '#ffe6f0',
|
|
||||||
borderRadius: 10,
|
|
||||||
shadowColor: '#000',
|
|
||||||
shadowOffset: { width: 0, height: 2 },
|
|
||||||
shadowOpacity: 0.2,
|
|
||||||
shadowRadius: 5,
|
|
||||||
elevation: 3,
|
|
||||||
zIndex: 1, // Ensure it appears above other elements
|
|
||||||
},
|
|
||||||
|
|
||||||
// Container for QR code
|
|
||||||
qrContainer: {
|
|
||||||
alignItems: 'center',
|
|
||||||
marginVertical: 10,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Style for QR code image
|
|
||||||
qrCodeImage: {
|
|
||||||
marginVertical: 10,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Blank line for spacing
|
|
||||||
blankLine: {
|
|
||||||
height: 20, // Adjust the height to control the space between lines
|
|
||||||
},
|
|
||||||
|
|
||||||
// Divider line
|
|
||||||
divider: {
|
|
||||||
height: 1,
|
|
||||||
backgroundColor: '#ddd',
|
|
||||||
marginVertical: 10,
|
|
||||||
alignSelf: 'stretch',
|
|
||||||
},
|
|
||||||
|
|
||||||
// Text for timestamp
|
|
||||||
timestampText: {
|
|
||||||
fontSize: 12,
|
|
||||||
color: '#000',
|
|
||||||
marginBottom: 10,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Text for result
|
|
||||||
resultText: {
|
|
||||||
fontSize: 16,
|
|
||||||
color: '#ff0000',
|
|
||||||
marginBottom: 10,
|
|
||||||
textAlign: 'center',
|
|
||||||
},
|
|
||||||
|
|
||||||
// Text for data type
|
|
||||||
typeText: {
|
|
||||||
fontSize: 16,
|
|
||||||
color: '#000',
|
|
||||||
marginBottom: 10,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Text for checks
|
|
||||||
checksText: {
|
|
||||||
fontSize: 16,
|
|
||||||
color: '#000',
|
|
||||||
marginBottom: 5,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Container for icons
|
|
||||||
iconContainer: {
|
|
||||||
flexDirection: 'row',
|
|
||||||
justifyContent: 'space-between',
|
|
||||||
marginTop: 10,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Style for icon button
|
|
||||||
iconButton: {
|
|
||||||
flexDirection: 'column',
|
|
||||||
alignItems: 'center',
|
|
||||||
},
|
|
||||||
|
|
||||||
// Text for icon button
|
|
||||||
iconText: {
|
|
||||||
color: '#2196F3',
|
|
||||||
marginTop: 5,
|
|
||||||
},
|
|
||||||
|
|
||||||
// Text for welcome message
|
|
||||||
welcomeText: {
|
|
||||||
textAlign: 'center',
|
|
||||||
fontSize: 20,
|
|
||||||
marginVertical: 10,
|
|
||||||
color: 'black',
|
|
||||||
},
|
|
||||||
|
|
||||||
// Button for test scan
|
|
||||||
testButton: {
|
testButton: {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
bottom: 1,
|
bottom: 1,
|
||||||
@@ -468,18 +308,29 @@ const styles = StyleSheet.create({
|
|||||||
padding: 10,
|
padding: 10,
|
||||||
borderRadius: 5,
|
borderRadius: 5,
|
||||||
},
|
},
|
||||||
|
|
||||||
// Button for gallery
|
|
||||||
galleryButton: {
|
galleryButton: {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
bottom: 20,
|
bottom: 20,
|
||||||
right: 100, // Adjust this value to move it more or less to the right
|
right: 100,
|
||||||
width: 50,
|
width: 50,
|
||||||
height: 50,
|
height: 50,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
backgroundColor: '#000',
|
backgroundColor: '#000',
|
||||||
borderRadius: 25, // Half of width and height to make it a circle
|
borderRadius: 25,
|
||||||
|
},
|
||||||
|
scannedDataBox: {
|
||||||
|
position: 'absolute',
|
||||||
|
top: '10%',
|
||||||
|
left: '5%',
|
||||||
|
right: '5%',
|
||||||
|
zIndex: 2,
|
||||||
|
},
|
||||||
|
welcomeText: {
|
||||||
|
textAlign: 'center',
|
||||||
|
fontSize: 20,
|
||||||
|
marginVertical: 10,
|
||||||
|
color: 'black',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
13
types.ts
13
types.ts
@@ -1,8 +1,11 @@
|
|||||||
import { createContext } from 'react';
|
import { createContext } from 'react';
|
||||||
|
|
||||||
export type QRCodeContextType = {
|
interface QRCodeContextProps {
|
||||||
qrCodes: string[];
|
qrCodes: { data: string, bookmarked: boolean }[];
|
||||||
setQrCodes: (codes: string[]) => void;
|
setQrCodes: (codes: { data: string, bookmarked: boolean }[]) => void;
|
||||||
};
|
setCurrentScannedData: (data: string) => void;
|
||||||
|
toggleBookmark: (index: number) => void;
|
||||||
|
deleteQRCode: (index: number) => void;
|
||||||
|
}
|
||||||
|
|
||||||
export const QRCodeContext = createContext<QRCodeContextType | null>(null);
|
export const QRCodeContext = createContext<QRCodeContextProps | null>(null);
|
||||||
|
|||||||
Reference in New Issue
Block a user