working on creating and integrating the required native modules and implementing the iCamera SDK display on the React Native side.
This commit is contained in:
137
App.tsx
137
App.tsx
@@ -16,8 +16,9 @@ import Login from './src/components/Login';
|
|||||||
import Register from './src/components/Register';
|
import Register from './src/components/Register';
|
||||||
import { authAPI } from './src/services/authAPI';
|
import { authAPI } from './src/services/authAPI';
|
||||||
import { networkService } from './src/services/networkService';
|
import { networkService } from './src/services/networkService';
|
||||||
|
import { ScannerScreen } from './src/screens/ScannerScreen';
|
||||||
|
|
||||||
type Screen = 'login' | 'register' | 'home';
|
type Screen = 'login' | 'register' | 'home' | 'scanner';
|
||||||
const { MyNativeModule } = NativeModules;
|
const { MyNativeModule } = NativeModules;
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
@@ -28,6 +29,7 @@ function App() {
|
|||||||
const [currentUser, setCurrentUser] = useState<any>(null);
|
const [currentUser, setCurrentUser] = useState<any>(null);
|
||||||
const [qrCode, setQrCode] = useState<string | null>(null);
|
const [qrCode, setQrCode] = useState<string | null>(null);
|
||||||
const [isGeneratingQR, setIsGeneratingQR] = useState(false);
|
const [isGeneratingQR, setIsGeneratingQR] = useState(false);
|
||||||
|
const [scannedCodes, setScannedCodes] = useState<any[]>([]);
|
||||||
|
|
||||||
// Initialize app
|
// Initialize app
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -111,7 +113,36 @@ Logged In: ${status.authentication.isLoggedIn ? 'Yes' : 'No'}
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateQRCode = async () => {
|
const handleScanResult = (result: any) => {
|
||||||
|
console.log('Scan result:', result);
|
||||||
|
setScannedCodes(prev => [
|
||||||
|
{
|
||||||
|
code: result.code,
|
||||||
|
format: result.format,
|
||||||
|
timestamp: new Date().toLocaleTimeString(),
|
||||||
|
},
|
||||||
|
...prev,
|
||||||
|
]);
|
||||||
|
Alert.alert(
|
||||||
|
'✓ Scanned Successfully',
|
||||||
|
`Code: ${result.code}\nFormat: ${result.format}`,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
text: 'Close',
|
||||||
|
onPress: () => setCurrentScreen('home'),
|
||||||
|
},
|
||||||
|
]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const openScanner = () => {
|
||||||
|
setCurrentScreen('scanner');
|
||||||
|
} catch (error) {
|
||||||
|
Alert.alert('Error', 'Failed to get app status');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const generateQRCode = async () => {
|
||||||
if (!currentUser?.email) {
|
if (!currentUser?.email) {
|
||||||
Alert.alert('Error', 'No user email available');
|
Alert.alert('Error', 'No user email available');
|
||||||
return;
|
return;
|
||||||
@@ -129,9 +160,9 @@ Logged In: ${status.authentication.isLoggedIn ? 'Yes' : 'No'}
|
|||||||
} finally {
|
} finally {
|
||||||
setIsGeneratingQR(false);
|
setIsGeneratingQR(false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderScreen = () => {
|
const renderScreen = () => {
|
||||||
switch (currentScreen) {
|
switch (currentScreen) {
|
||||||
case 'login':
|
case 'login':
|
||||||
return (
|
return (
|
||||||
@@ -147,6 +178,13 @@ Logged In: ${status.authentication.isLoggedIn ? 'Yes' : 'No'}
|
|||||||
onRegisterSuccess={navigateToHome}
|
onRegisterSuccess={navigateToHome}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
case 'scanner':
|
||||||
|
return (
|
||||||
|
<ScannerScreen
|
||||||
|
presignedUrl="https://your-backend-presigned-url.com"
|
||||||
|
onScan={handleScanResult}
|
||||||
|
/>
|
||||||
|
);
|
||||||
case 'home':
|
case 'home':
|
||||||
return (
|
return (
|
||||||
<ScrollView style={styles.homeContainer} contentContainerStyle={styles.scrollContent}>
|
<ScrollView style={styles.homeContainer} contentContainerStyle={styles.scrollContent}>
|
||||||
@@ -175,6 +213,15 @@ Logged In: ${status.authentication.isLoggedIn ? 'Yes' : 'No'}
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<View style={styles.buttonContainer}>
|
<View style={styles.buttonContainer}>
|
||||||
|
<TouchableOpacity
|
||||||
|
style={styles.scannerButton}
|
||||||
|
onPress={openScanner}
|
||||||
|
>
|
||||||
|
<Text style={styles.buttonText}>
|
||||||
|
📱 Scan QR/Barcode
|
||||||
|
</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
<TouchableOpacity
|
<TouchableOpacity
|
||||||
style={styles.qrButton}
|
style={styles.qrButton}
|
||||||
onPress={generateQRCode}
|
onPress={generateQRCode}
|
||||||
@@ -194,6 +241,23 @@ Logged In: ${status.authentication.isLoggedIn ? 'Yes' : 'No'}
|
|||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
{scannedCodes.length > 0 && (
|
||||||
|
<View style={styles.scannedContainer}>
|
||||||
|
<Text style={styles.scannedTitle}>
|
||||||
|
Scanned Codes ({scannedCodes.length})
|
||||||
|
</Text>
|
||||||
|
{scannedCodes.slice(0, 5).map((item, index) => (
|
||||||
|
<View key={index} style={styles.scannedItem}>
|
||||||
|
<Text style={styles.scannedCode}>{item.code}</Text>
|
||||||
|
<View style={styles.scannedFooter}>
|
||||||
|
<Text style={styles.scannedFormat}>{item.format}</Text>
|
||||||
|
<Text style={styles.scannedTime}>{item.timestamp}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
|
||||||
<Text style={styles.infoText}>
|
<Text style={styles.infoText}>
|
||||||
{isOnline
|
{isOnline
|
||||||
? 'Your data is synced with the cloud'
|
? 'Your data is synced with the cloud'
|
||||||
@@ -204,10 +268,10 @@ Logged In: ${status.authentication.isLoggedIn ? 'Yes' : 'No'}
|
|||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Show loading screen while initializing
|
// Show loading screen while initializing
|
||||||
if (!isInitialized) {
|
if (!isInitialized) {
|
||||||
return (
|
return (
|
||||||
<SafeAreaProvider>
|
<SafeAreaProvider>
|
||||||
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
|
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
|
||||||
@@ -216,14 +280,14 @@ Logged In: ${status.authentication.isLoggedIn ? 'Yes' : 'No'}
|
|||||||
</View>
|
</View>
|
||||||
</SafeAreaProvider>
|
</SafeAreaProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SafeAreaProvider>
|
<SafeAreaProvider>
|
||||||
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
|
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
|
||||||
{renderScreen()}
|
{renderScreen()}
|
||||||
</SafeAreaProvider>
|
</SafeAreaProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
@@ -310,6 +374,13 @@ const styles = StyleSheet.create({
|
|||||||
marginBottom: 30,
|
marginBottom: 30,
|
||||||
width: '100%',
|
width: '100%',
|
||||||
},
|
},
|
||||||
|
scannerButton: {
|
||||||
|
backgroundColor: '#9333ea',
|
||||||
|
paddingHorizontal: 20,
|
||||||
|
paddingVertical: 14,
|
||||||
|
borderRadius: 25,
|
||||||
|
alignItems: 'center',
|
||||||
|
},
|
||||||
qrButton: {
|
qrButton: {
|
||||||
backgroundColor: '#10b981',
|
backgroundColor: '#10b981',
|
||||||
paddingHorizontal: 20,
|
paddingHorizontal: 20,
|
||||||
@@ -336,6 +407,52 @@ const styles = StyleSheet.create({
|
|||||||
fontWeight: '600',
|
fontWeight: '600',
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
},
|
},
|
||||||
|
scannedContainer: {
|
||||||
|
width: '100%',
|
||||||
|
marginBottom: 20,
|
||||||
|
backgroundColor: 'white',
|
||||||
|
borderRadius: 12,
|
||||||
|
padding: 16,
|
||||||
|
shadowColor: '#000',
|
||||||
|
shadowOffset: { width: 0, height: 2 },
|
||||||
|
shadowOpacity: 0.1,
|
||||||
|
shadowRadius: 4,
|
||||||
|
elevation: 3,
|
||||||
|
},
|
||||||
|
scannedTitle: {
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: '600',
|
||||||
|
color: '#333',
|
||||||
|
marginBottom: 12,
|
||||||
|
},
|
||||||
|
scannedItem: {
|
||||||
|
backgroundColor: '#f5f5f5',
|
||||||
|
borderLeftWidth: 4,
|
||||||
|
borderLeftColor: '#9333ea',
|
||||||
|
paddingHorizontal: 12,
|
||||||
|
paddingVertical: 10,
|
||||||
|
marginBottom: 8,
|
||||||
|
borderRadius: 4,
|
||||||
|
},
|
||||||
|
scannedCode: {
|
||||||
|
fontSize: 13,
|
||||||
|
fontWeight: '600',
|
||||||
|
color: '#000',
|
||||||
|
marginBottom: 4,
|
||||||
|
},
|
||||||
|
scannedFooter: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
},
|
||||||
|
scannedFormat: {
|
||||||
|
fontSize: 11,
|
||||||
|
color: '#666',
|
||||||
|
fontWeight: '500',
|
||||||
|
},
|
||||||
|
scannedTime: {
|
||||||
|
fontSize: 11,
|
||||||
|
color: '#999',
|
||||||
|
},
|
||||||
infoText: {
|
infoText: {
|
||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
color: '#888',
|
color: '#888',
|
||||||
|
|||||||
13
index.js
13
index.js
@@ -7,3 +7,16 @@ import App from './App';
|
|||||||
import { name as appName } from './app.json';
|
import { name as appName } from './app.json';
|
||||||
LogBox.ignoreAllLogs();
|
LogBox.ignoreAllLogs();
|
||||||
AppRegistry.registerComponent(appName, () => App);
|
AppRegistry.registerComponent(appName, () => App);
|
||||||
|
|
||||||
|
|
||||||
|
// 1. Hook (Easiest) ⭐
|
||||||
|
// const scanner = useCameraScanner({
|
||||||
|
// presignedUrl: 'https://...',
|
||||||
|
// onScanResult: (result) => console.log(result.code),
|
||||||
|
// });
|
||||||
|
|
||||||
|
// 2. Ready Screen
|
||||||
|
//<ScannerScreen presignedUrl="..." onScan={handleScan} />
|
||||||
|
|
||||||
|
// 3. Direct Module
|
||||||
|
// const { ICameraSDK } = NativeModules;
|
||||||
Reference in New Issue
Block a user